Search code examples
iosnsurlconnectionswift2alamofire

Use Alamofire to Set HTTP Headers and HTTP Body


I have been using NSURLConnection to make requests and I would like to migrate the codes to Alamofire.

Here is my NSURLConnection code.

var requestString: NSString = "http://api.domainname.com/api/v1/auth/register";
var url: NSURL = NSURL(string: requestString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!)!;

var urlRequest: NSMutableURLRequest = NSMutableURLRequest(URL: url);
urlRequest.setValue("\(base64LoginString)", forHTTPHeaderField: "Authorization");
urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type");
urlRequest.setValue("application/json", forHTTPHeaderField: "Accept");

var httpBodyDictionary: NSMutableDictionary = NSMutableDictionary();
httpBodyDictionary.setObject(self.emailTextField.text, forKey: "email");
httpBodyDictionary.setObject(self.usernameTextField.text, forKey: "username");
httpBodyDictionary.setObject(self.passwordTextField.text, forKey: "password");

urlRequest.HTTPMethod = "POST";

NSURLConnection.sendAsynchronousRequest(urlRequest, queue: NSOperationQueue.mainQueue(), completionHandler: { (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
    if(data != nil) {
          //PROCESS DATA
    }
});

I have however tried Alamofire but I cant make it work..

ALAMOFIRE

var defaultHeaders = Alamofire.Manager.sharedInstance.session.configuration.HTTPAdditionalHeaders ?? [:]
defaultHeaders["Authorization"] = "\(base64LoginString))"
defaultHeaders["Content-Type"] = "application/json)"
defaultHeaders["Accept"] = "application/json)"

let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
configuration.HTTPAdditionalHeaders = defaultHeaders;

let manager = Alamofire.Manager(configuration: configuration)


var requestString: NSString = "http://api.domainname.com/api/v1/auth/register";
var url: NSURL = NSURL(string: requestString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!)!;

var urlRequest: NSMutableURLRequest = NSMutableURLRequest(URL: url);
urlRequest.HTTPMethod = Alamofire.Method.POST.rawValue;

let parameters = ["email": self.emailTextField.text,
        "username": self.usernameTextField.text,
        "password": self.passwordTextField.text]

do {
        urlRequest.HTTPBody = try NSJSONSerialization.dataWithJSONObject(parameters, options: NSJSONWritingOptions())
} catch {
    // No-op
}

Alamofire.request(urlRequest).responseJSON(completionHandler: { (urlRequest, urlResponse, result) -> Void in
        print(urlResponse);        
    //print(result);
})

Could anyone please point to the right direction please? I have spent the whole day trying to make it work.

Note: Using Swift 2/ XCode 7 Beta 6

UPDATE tried Rob's suggestion but instead I get this returned, this does not happen when I use NSURLConnection

PRINTED RESPONSE

Optional(<NSHTTPURLResponse: 0x7fdbc222a2b0> { URL: http://api.domainname.com/api/v1/auth/register } { status code: 422, headers {
    "Cache-Control" = "no-cache, proxy-revalidate";
    Connection = "Keep-Alive";
    "Content-Type" = "application/json";
    Date = "Thu, 10 Sep 2015 14:35:13 GMT";
    Server = "nginx/1.8.0";
    "Set-Cookie" = "laravel_session=eyJpdiI6InZjSVwvcVd3NjR6SitZSlZNMGdXdElRPT0iLCJ2YWx1ZSI6IjJBeXdWTHRlRUNQa2RTSFBDYlU0bWlBRkF3c0pzcEx2YzQxdXk0ZnlxZ2xERUkrWmFZNlNISUlyZmpnWjZkamdxVFJXaGxOQmFtVlZZWElWdnFYdlBRPT0iLCJtYWMiOiI5MWY2NjU4ODViYjhlYWM4N2YwOTg2ZTA2OWYzNmU1MmE3ZWEzN2E5ZTA5ZjA5YjMyYmExN2FmMzFhZjRiMmJhIn0%3D; expires=Thu, 10-Sep-2015 16:35:13 GMT; Max-Age=7200; path=/; httponly";
    "Transfer-Encoding" = Identity;
} })

Solution

  • You don't have to set Content-Type or Accept. You also don't have to set the request body nor use NSJSONSerialization yourself. Alamofire gets you out of the weeds of constructing requests. So you might do something like:

    let requestString = "http://api.domainname.com/api/v1/auth/register"
    
    let parameters = [
        "email"    : emailTextField.text!,
        "username" : usernameTextField.text!,
        "password" : passwordTextField.text!
    ]
    
    let headers = ["Authorization": base64LoginString]
    
    Alamofire.request(.POST, requestString, parameters: parameters, encoding: .JSON, headers: headers).responseJSON { request, response, result in
        print(response)
    }
    

    Or, alternatively, if you don't want to build the base64LoginString yourself, you might also be able to do something like:

    Alamofire.request(.POST, requestString, parameters: parameters, encoding: .JSON)
        .authenticate(user: user, password: password)
        .responseJSON { request, response, result in
            print(response)
    }
    

    If it's still not working, I'd suggest (a) edit your question, sharing the precise error messages; and (b) observe both your old code and the new code in a tool like Charles and identify how precisely the two requests differ.