14

I'm trying to make a GET request with Alamofire in Swift. I need to set the following headers:

Content-Type: application/json
Accept: application/json

I could hack around it and do it directly specifying the headers for the request, but I want to do it with ParameterEncoding, as is suggested in the library. So far I have this:

Alamofire.request(.GET, url, encoding: .JSON)
    .validate()
    .responseJSON { (req, res, json, error) in
        if (error != nil) {
            NSLog("Error: \(error)")
            println(req)
            println(res)
        } else {
            NSLog("Success: \(url)")
            var json = JSON(json!)
        }
}

Content-Type is set, but not Accept. How can I do this properly?

jlhonora
  • 10,179
  • 10
  • 46
  • 70
  • 1
    The best approach I can come up with right now is to add it to the `defaultHeaders` property of the `AlamoFire.Manager` – David Berry Feb 06 '15 at 21:22
  • @David How would that go exactly? I tried `Alamofire.Manager.defaultHTTPHeaders().updateValue(value: "application/json", forKey: "Accept")` with no luck – jlhonora Feb 06 '15 at 21:31
  • 1
    You'll actually need to change it in the `manager.session.configuration. HTTPAdditionalHeaders` property. Changing it there will make the change apply to all subsequent requests. Another possibliity is to add a `Request` modeled on `validate` that allowed me to set a header on the fly. That way you could change it for a single request. – David Berry Feb 06 '15 at 21:51

5 Answers5

15

I ended up using URLRequestConvertible https://github.com/Alamofire/Alamofire#urlrequestconvertible

enum Router: URLRequestConvertible {
    static let baseUrlString = "someUrl"

    case Get(url: String)

    var URLRequest: NSMutableURLRequest {
        let path: String = {
            switch self {
            case .Get(let url):
                return "/\(url)"
            }
        }()

        let URL = NSURL(string: Router.baseUrlString)!
        let URLRequest = NSMutableURLRequest(URL:
                           URL.URLByAppendingPathComponent(path))

        // set header fields
        URLRequest.setValue("application/json",
                            forHTTPHeaderField: "Content-Type")
        URLRequest.setValue("application/json",
                            forHTTPHeaderField: "Accept")

        return URLRequest.0
    }
}

And then just:

Alamofire.request(Router.Get(url: ""))
    .validate()
    .responseJSON { (req, res, json, error) in
        if (error != nil) {
            NSLog("Error: \(error)")
            println(req)
            println(res)
        } else {
            NSLog("Success")
            var json = JSON(json!)
            NSLog("\(json)")
        }
}

Another way to do it is to specify it for the whole session, check @David's comment above:

Alamofire.Manager.sharedInstance.session.configuration
         .HTTPAdditionalHeaders?.updateValue("application/json",
                                             forKey: "Accept")
jlhonora
  • 10,179
  • 10
  • 46
  • 70
  • This is an even better approach than my comment above. – David Berry Feb 06 '15 at 21:53
  • The router answer now throws 2 errors in Swift 2. On the `enum Router:` we get `Type 'Router' does not conform to protocol 'URLRequestConvertible'` and on `return URLRequest.0` we get `Value of type 'NSMutableURLRequest' has no member'0'`. – Craig.Pearce Jan 30 '16 at 16:29
  • @Craig.Pearce good one, changed to `NSMutableURLRequest`. I'm not able to test it right now, so let me know if it's still broken – jlhonora Feb 01 '16 at 16:19
6

Example directly from Alamofire github page:

Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
         .validate(statusCode: 200..<300)
         .validate(contentType: ["application/json"])
         .response { (_, _, _, error) in
                  println(error)
         }

In your case add what you want:

Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
         .validate(statusCode: 200..<300)
         .validate(contentType: ["application/json"])
         .validate(Accept: ["application/json"])
         .response { (_, _, _, error) in
                  println(error)
         }
hasan
  • 23,815
  • 10
  • 63
  • 101
  • 1
    Nope, that gives me `Accept: */*`. I need it to be specifically `application/json` – jlhonora Feb 06 '15 at 20:55
  • 2
    `.validate(Accept: ["application/json"])` doesn't work either, XCode shows the following error: `Incorrect argument label in call (have 'Accept:', expected 'contentType:')` – jlhonora Feb 06 '15 at 21:08
3

Simple way to use get method with query map and response type json

var parameters: [String:Any] = [
            "id": "3"  
        ]
var headers: HTTPHeaders = [
            "Content-Type":"application/json",
            "Accept": "application/json"
        ]
Alamofire.request(url, method: .get,
 parameters: parameters,
encoding: URLEncoding.queryString,headers:headers)
.validate(statusCode: 200..<300)
            .responseData { response in     
                switch response.result {
                case .success(let value):  
                case .failure(let error):    
                }
3
Alamofire.request(url, method: .post, parameters:parameters, encoding: JSONEncoding.default).responseJSON { response in
     ...      
}

it's work

pacification
  • 5,838
  • 4
  • 29
  • 51
1

Try this:

URLRequest.setValue("application/json",
                    forHTTPHeaderField: "Content-Type")
URLRequest.setValue("application/json",
                    forHTTPHeaderField: "Accept")
Adriaan
  • 17,741
  • 7
  • 42
  • 75
Berlin
  • 2,115
  • 2
  • 16
  • 28