how to use Alamofire with custom headers
SwiftAfnetworkingAlamofireSwift Problem Overview
I am just starting to take a look at Mattt's wonderful new Alamofire swift networking library and am not quite sure how one would use it with custom headers.
The code i am trying to convert from AFNetworking to Alamofire is this:
let request = NSMutableURLRequest(URL: url)
request.setValue(authorizationToken, forHTTPHeaderField:"Authorization")
Swift Solutions
Solution 1 - Swift
According to the official documentation, modifying the session configuration is not recommended:
> This is not recommended for Authorization or Content-Type headers. > Instead, use URLRequestConvertible and ParameterEncoding, > respectively.
So an example usage of URLRequestConvertible for authorization would be:
enum Router: URLRequestConvertible {
static let baseUrlString = "some url string"
case Get(query: String)
var URLRequest: NSMutableURLRequest {
let (path: String, parameters: [String: AnyObject]?) = {
switch self {
case .Get(let query):
return ("/get", ["q": query])
}
}()
let URL = NSURL(string: Router.baseUrlString)!
let URLRequest = NSMutableURLRequest(URL: URL.URLByAppendingPathComponent(path))
// set header fields
URLRequest.setValue("a", forHTTPHeaderField: "Authorization")
let encoding = Alamofire.ParameterEncoding.URL
return encoding.encode(URLRequest, parameters: parameters).0
}
}
and when you want to make a request:
Manager.sharedInstance.request(Router.Get(query: "test"))
More info about URLRequestConvertible: https://github.com/Alamofire/Alamofire#urlrequestconvertible
Old Answer
As of Alamofire v1.0 Pers answer no longer works. In the new version additional headers should be added to the HTTPAdditionalHeaders
property of NSURLSessionConfiguration
Alamofire.Manager.sharedInstance.session.configuration.HTTPAdditionalHeaders = ["Authorization": authorizationToken]
More info here: https://github.com/Alamofire/Alamofire/issues/111
Solution 2 - Swift
For headers that change from request to request, you can pass them directly to the request method. From the docs:
> Adding a custom HTTP header to a Request is supported directly in the global request method. This makes it easy to attach HTTP headers to a Request that can be constantly changing.
And the example given:
let headers = [ "Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==", "Content-Type": "application/x-www-form-urlencoded" ]
Alamofire.request(.GET, "https://httpbin.org/get", headers: headers)
.responseJSON { response in
debugPrint(response)
}
If, however, you wish to set headers that do not change, it is recommended that you do so on the NSURLConfiguration object, as others have mentioned here.
Solution 3 - Swift
At this time , Swift 3.0 , Xcode 8.x, Alamofire 4.x:
You can use custom header as below:
let headers: HTTPHeaders = [
"Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==",
"Accept": "application/json"
]
Alamofire.request("https://httpbin.org/headers", headers: headers).responseJSON { response in
debugPrint(response)
}
For reference
Solution 4 - Swift
I've created a static headers method in a separate APIManager class.
import Foundation
import Alamofire
class APIManager {
class func headers() -> HTTPHeaders {
var headers: HTTPHeaders = [
"Content-Type": "application/json",
"Accept": "application/json"
]
if let authToken = UserDefaults.standard.string(forKey: "auth_token") {
headers["Authorization"] = "Token" + " " + authToken
}
return headers
}
}
And I use it in requests:
Alamofire.request(urlString,
method: .get,
headers:APIManager.headers())
Solution 5 - Swift
NOTE: this was before 1.0. It no longer works, look at the accepted answer instead.
You use the defaultHeaders property on the Manager singleton to add headers, like this:
Alamofire.Manager.sharedInstance.defaultHeaders.updateValue(authorizationToken, forKey: "Authorization")
At least it works for me. :)
Solution 6 - Swift
Because I dislike setting these things globally (and sometimes I send them, sometimes I don't), I wrote a wrapper method to set the headers with each call.
import Alamofire
public class Service: NSObject {
private class func request(method: Alamofire.Method, URLString: URLStringConvertible, parameters: [String : AnyObject]?, encoding: ParameterEncoding = .URL, headers: [String: String]? = nil) -> Request {
let (request, error) = encoding.encode(NSURLRequest(URL: NSURL(string: URLString.URLString)!), parameters: parameters)
let mutableURLRequest = request as! NSMutableURLRequest
mutableURLRequest.HTTPMethod = method.rawValue
if let heads = headers {
for (field, value) in heads {
mutableURLRequest.setValue(value, forHTTPHeaderField: field)
}
}
return Alamofire.request(mutableURLRequest)
}
}
It can be called as follows...
Service.request(.POST, URLString: "http://httpbin.org/post", parameters: ["example-param": "example-param-value"], encoding: .JSON, headers: ["example-header-field": "example-value"])/*.whatever you want to do with it*/
It could certainly be cleaned up with some error checking, but this should give you the gist of it. It's all based on Alamofire 1.2.
Solution 7 - Swift
Alamofire 4.x, XCode 9.1, Swift 4.x
When Headers cause problem while sending it in the request, then we need to encode parameter, for this we do JSONEncoding.prettyPrinted or JSONEncoding.default like :
let url = "http:\your.url.string\"
let parameter = ["Username":"name", "Password":"123"]
let headers = ["Content-Type" : "application/json"]
Alamofire.request(url, method : .post, parameters : parameter, encoding : JSONEncoding.default , headers : headers).responseData { dataResponse in
print(dataResponse.request as Any) // your request
print(dataResponse.response as Any) // your response
}
Solution 8 - Swift
Setting below code will only works in iOS 8 and above.
Alamofire.Manager.sharedInstance.session.configuration.HTTPAdditionalHeaders = headers
Below is the full code which works for iOS 7 and iOS 8
let URL = NSURL(string: request.url!)
var mutableURLRequest = NSMutableURLRequest(URL: URL!)
mutableURLRequest.HTTPMethod = Alamofire.Method.GET.rawValue
// Adding headers
var defaultHeaders = Alamofire.Manager.sharedInstance.session.configuration.HTTPAdditionalHeaders ?? [:]
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
configuration.HTTPAdditionalHeaders = defaultHeaders
// Adding parameters
let manager = Alamofire.Manager(configuration: configuration)
let urlReq = ParameterEncoding.URL.encode(mutableURLRequest, parameters: request.params).0
aReq = manager.request(urlReq)
aReq!.responseJSON { (req, response, JSON, error) in }
More info : GitHub - Alamofire Issues
Solution 9 - Swift
You can pass an NSMutableURLRequest
object directly to Alamofire, since it has an extension for NSMutableURLRequest
that adopts URLRequestConvertible
. So there's no need to create your own class to just add an Authorization header. It's as simple as this:
let request = NSMutableURLRequest(URL: url)
request.setValue(authorizationToken, forHTTPHeaderField:"Authorization")
Alamofire.request(request)
.responseJSON { (_, _, JSON, error) in }
Solution 10 - Swift
let aManager = Manager.sharedInstance
aManager.session.configuration.HTTPAdditionalHeaders = [
"Authorization": "Some authentication Token here" ]
let URL = "some url string"
request(.GET, URL, encoding: .JSON)
.responseJSON {
(request, response, data, error) -> Void in
if(error != nil)
{
if let delegate = self.delegate {
delegate.connectionDidFinishedErrorResponceForAction!(1, andWithResponse: nil)
}
println("\(error!.localizedDescription)")
}
else {
if let delegate = self.delegate {
delegate.connectionDidFinishedForAction!(1, andWithResponse: nil)
}
println("req:\(request) \n res:\(response) \n json:\(data!) \n \(error) ")
}
}
Solution 11 - Swift
For Alamofire 5:
let path = BaseServiceApi().baseUrl + "login"
let params = [
"phone": "+92322222222",
"password" : "123123123"
] as [String : Any]
let request = AF.request(path, method: .post, parameters: params, encoding: JSONEncoding.default, headers: APIManager.headers(), interceptor: nil)
request.responseDecodable(of: UserModel?.self) {(resposnse) in
let user = resposnse.value
print(user)
}
APIManger Class for headers:
class APIManager
{
class func headers() -> HTTPHeaders
{
let headers: HTTPHeaders = [
"Content-Type": "application/json",
"Accept": "application/json"
]
return headers
}
}