Search code examples
iosswiftalamofireswift2xcode7

Authenticated http request swift Alamofire


I'm struggling with getting this to work to make request to my API. Without a token works, but when I try to add additional headers, things turn to be complicated, for me.

First, the structure. one class called: APIAsyncTask that makes the requests

one class called APIParams, just a data holder to send parameters to the APIAsyncTask class.

one class called DatabaseAPI that makes that builds the parameters, and send that to the APIAsyncTask class.

DatabaseAPI

func someMethod()
{
    let task = APIAsyncTasks()
    task.registerCallback { (error, result) -> Void in
        print("Finished task, back at DatabaseAPI")
    }
    let params2 = APIParams(request: .GET, apiPath: "Posts/1", apiToken: "4iTX-56w")
    task.APIrequest(params2)
}

APIAsyncTask

This part is for fixing another error, because manager was not global, the task got cancelled quickly.

var manager : Manager!

init(authenticatedRequest : Bool, token: String?)
{
    manager = Alamofire.Manager()
    print("Pre \(manager.session.configuration.HTTPAdditionalHeaders?.count)")
    if(authenticatedRequest && token != nil)
    {
        var defaultHeaders = Alamofire.Manager.sharedInstance.session.configuration.HTTPAdditionalHeaders!   
        defaultHeaders["Authorization"] = "bearer \(token)"
        let configuration = Manager.sharedInstance.session.configuration
        configuration.HTTPAdditionalHeaders = defaultHeaders

        manager = Alamofire.Manager(configuration: configuration)
    }
    print("Post \(manager.session.configuration.HTTPAdditionalHeaders?.count)")
}

After some decision making, it comes down to this part.

 private func GetRequest(url: String!,token : String?, completionHandler: (JSON?, NSURLRequest?, NSHTTPURLResponse?, NSError?) -> () ) -> ()
{
    print("Begin Get Request")

    if(token != nil)//if token is not nil, make authenticated request
    {
        print("just before request: \(manager.session.configuration.HTTPAdditionalHeaders?.count)")
        manager.request(.GET, url, parameters: nil, encoding: .JSON).responseJSON { (request, response, json, error) in
            print("Get Request (authenticated), inside alamofire request")
            var resultJson : JSON?
            if(json != nil)
            {
                resultJson = JSON(json!)
            }
            completionHandler(resultJson, request, response, error)
        }
    }
    else
    {
     //working part without token

So as the code is now, I get an error on completing:

runtime error

Mattt himself gives the answer of using Alamofire.Manager.sharedInstance.session.configuration.HTTPAdditionalHeaders , so that should be fine...

I suspect it has something to do with the multiple threads, according to this blog. Or, since it is something about CFNetwork, it could be because my API does not use SSL? I disabled NSAppTransportSecurity

I'm kind of new to swift, so examples would be really appreciated! Thankyou!


Solution

  • So the majority of your code looks solid.

    The error leads me to believe that CFNetwork is having difficulty figuring out how to compute the protection space for the challenge. I would also assume you are getting a basic auth challenge since you are attaching an Authorization header.

    Digging through your logic a bit more with this in mind led me to see that your not attaching your token to the string properly inside the Authorization header. You need to do the following instead.

    defaultHeaders["Authorization"] = "bearer \(token!)"
    

    Otherwise your Authorization header value is going to include Optional(value) instead of just value.

    That's the only issue I can see at the moment. If you could give that a try and comment back that would be great. I'll update my answer accordingly if that doesn't actually solve your problem.

    Best of luck!