简体   繁体   中英

Does URLSession.dataTask(with:completionHandler:) always call completionHandler only once?

After I create a new session data task with URLSession.dataTask(with:completionHandler:) and start the task by calling its resume() method, given that the app doesn't crash while the request is running, is it safe for me to assume that completionHandler (passed to URLSession.dataTask(with:completionHandler:) above) will always eventually get called only once, even if something weird happens with the network request (like if the connection drops) or with the app (like if it goes into the background)?

Note: I'm not explicitly calling cancel() or suspend() on the task. Just resume() .

I want to know the answer to this question because (from my app's main thread) I'm creating and starting (one after the other) multiple asynchronous network requests and want to know when the last one has finished.

Specifically, I'm working on an app that has a custom class called Account . On launch, the app (assuming it finds an account access token stored in UserDefaults ) creates only one instance of that class and stores it to a global variable (across the entire app) called account , which represents the app's currently-logged-in account.

I've added a stored var (instance) property to Account called pendingGetFooRequestCount (for example) and set it to 0 by default. Every time I make a call to Account.getFoo() (an instance method), I add 1 to pendingGetFooRequestCount (right before calling resume() ). Inside completionHandler (passed to URLSession.dataTask(with:completionHandler:) and (to be safe) inside a closure passed to DispatchQueue.main.async() , I first subtract 1 from pendingGetFooRequestCount and then check if pendingGetFooRequestCount is equal to 0 . If so, I know the last get-foo request has finished, and I can call another method to continue the flow.

How's my logic? Will this work as expected? Should I be doing this another way? Also, do I even need to decrement pendingGetFooRequestCount on the main thread?

URLRequest has a timeoutInterval property, its default value is 60 seconds. If there is no response by then, the completion is called with non-nil error.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM