4

I have a method which handles a Apple Push Notification Service remote notification. When this method is executed, I want it to call my server and do a HTTP POST request using the Alamofire library. I want to execute another method that will handle the response of the POST request.

The problem for me is that I am using an existing API to fetch a profile from the server in this POST request. So I need to use this existing API and figure out when this profile fetch is specifically triggered from the remote notification.

Since Alamofire requests are done in a background queue, how would I go about doing an execution of a method after receiving the profile back from the server?

What would be a good option to solving this issue?

Thank you!

The Nomad
  • 7,155
  • 14
  • 65
  • 100
  • Why not just use a standard Alamofire `response` block in your POST request? When your app receives a response, your `response` block will be executed and can then call any logic you like. – Jonathan Hersh Jan 05 '15 at 01:13
  • @JonathanHersh I am already using the `response` block to handle the fetching profile response, but was wondering if there was a special way to pass in a `closure` to handle specific instances. For this instance I am fetching the profile in response to a `remote notification`. Other times when I fetch the profile, it is just being called. – The Nomad Jan 05 '15 at 01:17
  • Sorry, it's not clear what you're asking. The response block **is** a closure. – Jonathan Hersh Jan 05 '15 at 01:17
  • @JonathanHersh My idea was to hopefully be able to differentiate when fetching a profile (server api call) whether it was from a remote notification or just a normal call. I supposed I will just set a `Bool` flag for this. – The Nomad Jan 05 '15 at 01:19
  • Hard to say more without seeing your code. Your app's logic should be able to determine for itself whether it is starting a request as a result of a push notification. – Jonathan Hersh Jan 05 '15 at 01:21
  • @JonathanHersh The reason I need to differentiate to see if a result of push notification is that I want to show an `alert` that will have info received from the profile fetch. I think I will just set a flag in my `AppDelegate` to tell my execution of showing the alert to be done. – The Nomad Jan 05 '15 at 01:32

3 Answers3

4

Since Alamofire requests are done in a background queue, how would I go about doing an execution of a method after receiving the profile back from the server?

Response handling is built in to Alamofire. You can do something like this (adapted from the docs):

Alamofire.request(.POST, "http://httpbin.org/get", parameters: ["foo": "bar"])
         .response { (request, response, data, error) in
                     println(request)
                     println(response)
                     println(error)
                   }

Note the .response method call, which adds a completion handler to the request object; the completion handler is invoked by Alamofire when the request completes (or fails).

Todd Agulnick
  • 1,945
  • 11
  • 10
  • Also, the .responseJSON method is very useful. – boidkan Jan 08 '15 at 15:44
  • as this is asynchronous code, you have to catch if Alamofire throws. Is that the case? Or will you always have access to response.result.error? – Cmag Aug 17 '16 at 01:03
1

It wasn't clear from your question formulation what problem you were trying to solve. But you've clarified your intent in the question comments above.

As I understand the problem now, you're got some code that updates a profile on the server and handles the server's response. The code is called in two contexts, one initiated by a manual request from the user, another initiated by a push notification. In the first case, you don't want to generate an alert after you process the response from the server, but in the second case you do.

You do indeed have a closure that you can use to handle the different behavior even though the difference happens in the asynchronous part of the process. Here's a sketch (not actual working code) of how that might look:

func updateProfile(parameters: [String:String], showAlert: Bool) {
    Alamofire.request(.POST, "http://myserver.com/profile", parameters: parameters)
             .response { (request, response, data, error) in
                         if (error == nil) {
                           processProfileResponse(response)
                           if showAlert {
                             showProfileWasUpdatedAlert()
                           }
                         }
                   }      

}

Note the showAlert parameter passed in to the updateProfile method. If you pass in true, it calls the showProfileWasUpdatedAlert method to show your alert after receiving the server's response. Note that this boolean value is "captured" by the closure that handles the Alamofire response because the closure was defined inside the updateProfile function.

This, IMHO, is a better approach than declaring an app global inside your AppDelegate.

Todd Agulnick
  • 1,945
  • 11
  • 10
1

Here you go

func AlamofireRequest(method: Alamofire.Method, URLString: URLStringConvertible, parameters: [String : AnyObject]?, encoding: ParameterEncoding, headers: [String : String]?) -> Alamofire.Result<String>? {
    var finishFlag = 0
    var AlamofireResult: Alamofire.Result<String>? = nil
    Alamofire.request(method, URLString, parameters: parameters, encoding: encoding, headers: headers)
        .responseString { (_, _, result) -> Void in
            if result.isSuccess {
                finishFlag = 1
                AlamofireResult = result
            }
            else {
                finishFlag = -1
            }
    }
    while finishFlag == 0 {
        NSRunLoop.currentRunLoop().runMode(NSDefaultRunLoopMode, beforeDate: NSDate.distantFuture())
    }
    return AlamofireResult
}
Dicky Tsang
  • 6,135
  • 4
  • 20
  • 18