Alamofire.request.responseData must call in main thread?

Created on 11 Mar 2016  路  7Comments  路  Source: Alamofire/Alamofire

I did this in background thread:

Alamofire.request(request.method, request.URLString, parameters: request.parameters, encoding: request.encoding, headers: request.headers).responseData 

but when I debug with Instruments,it shows the Alamofire request and responseData clousure are also run in main thread,why?

Most helpful comment

From the code,
public func response<T: ResponseSerializerType>( queue queue: dispatch_queue_t? = nil, responseSerializer: T, completionHandler: Response<T.SerializedObject, T.ErrorObject> -> Void) -> Self
If you do not specify a queue,it will use a default value of nil, and
dispatch_async(queue ?? dispatch_get_main_queue()) { completionHandler(response) }
nil means main queue is used then.

Hope this can help you.

All 7 comments

From the code,
public func response<T: ResponseSerializerType>( queue queue: dispatch_queue_t? = nil, responseSerializer: T, completionHandler: Response<T.SerializedObject, T.ErrorObject> -> Void) -> Self
If you do not specify a queue,it will use a default value of nil, and
dispatch_async(queue ?? dispatch_get_main_queue()) { completionHandler(response) }
nil means main queue is used then.

Hope this can help you.

@wizzardchao Oh,you are right!

Why is the main thread a reasonable default? In a simple script, this means requests can never be executed! If I'm missing something fundamental, I'd appreciate an answer on that SO question.

@reitzig, because Alamofire executes in the background, your main thread completes and exits the program before Alamofire has a chance to finish. You'll need to implement a RunLoop to keep your main thread alive until Alamofire has completed.

As an aside, you'll need to do this for _any_ executable runs processes in the background.

import Foundation
import Alamofire

var shouldRun = true

Alamofire.request("https://httpbin.org/get").responseJSON { response in
    print(response.request)  // original URL request
    print(response.response) // HTTP URL response
    print(response.data)     // server data
    print(response.result)   // result of response serialization

    print(response)
    shouldRun = false
}

print("Done")

let loop = RunLoop.current
let loopShouldStart = loop.run(mode: RunLoopMode.defaultRunLoopMode, before: Date(timeIntervalSinceNow: 2))

while (shouldRun && loopShouldStart) { }

Done
Optional(https://httpbin.org/get)
Optional( { URL: https://httpbin.org/get } { status code: 200, headers {
"Access-Control-Allow-Origin" = "";
"Content-Length" = 330;
"Content-Type" = "application/json";
Date = "Tue, 21 Feb 2017 21:05:32 GMT";
Server = nginx;
"access-control-allow-credentials" = true;
} })
Optional(330 bytes)
SUCCESS
SUCCESS: {
args = {
};
headers = {
Accept = "
/*";
"Accept-Encoding" = "gzip;q=1.0, compress;q=0.5";
"Accept-Language" = "en-US;q=1.0";
Host = "httpbin.org";
"User-Agent" = "Unknown/Unknown (Unknown; build:Unknown; OS X 10.12.3) Unknown";
};
origin = "97.105.19.61";
url = "https://httpbin.org/get";
}

@joshfreemanIO Thanks for your response!

In fact, I observe that Almofire does not execute the request: if I do what you propose, the application hangs. (I'm on a MacOS target, if that's relevant.)
I also tried calling the request on Alamofire.SessionManager(configuration: URLSessionConfiguration.background(withIdentifier: "some-id")) but that didn't help either.

And in my real application (resp. it's unit test) I'm getting Error Domain=NSURLErrorDomain Code=-1 "unknown error" in what I think is the same setup (but an iOS target).

Aha! I needed to do .response(queue: DispatchQueue(label: "hds-fiddling")) in addition.

Still seeing that error in the production project, though. :/

Turns out the issue in production was unrelated: using URLSessionConfiguration.background(withIdentifier: "my-id") as parameter for Alamofire.Sessionmanager(configuration: _) turns out not to be a good idea, for what ever reason. The error message is very obscure, and it's weird that the same thing seems to work in another project. Is there a bug here, or am I doing something very wrong?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

solomon23 picture solomon23  路  3Comments

yokesharun picture yokesharun  路  3Comments

matthijsotterloo picture matthijsotterloo  路  3Comments

badrinathvm picture badrinathvm  路  3Comments

Tulleb picture Tulleb  路  3Comments