1

I'm going to crazy trying to figure out how to prevent the rest of my code from executing before a session dataTaskWithRequest is finished. No matter what I do, the data task won't .resume() until everything else finishes. Nothing works. Not using a a while loop. Not putting the task inside a separate thread (dispatch_async). I'm at my wits end. To make matters worse, I feel like I'm overlooking something simple because it seems nobody else is asking this question.

dbconfession
  • 1,147
  • 2
  • 23
  • 36
  • Take a look at at this article. I think that you are looking for dispatch_group_enter/leave to solved your problem. http://commandshift.co.uk/blog/2014/03/19/using-dispatch-groups-to-wait-for-multiple-web-services/ – Christopher Harris May 02 '16 at 00:13
  • See http://stackoverflow.com/questions/31264172/how-can-i-get-the-data-from-nsurlsession-sharedsession-datataskwithrequest – Eric Aya May 02 '16 at 09:44

1 Answers1

0

NSURLSession is an asynchronous loading system. When you tell it to start, it begins fetching data in its own thread, and your code continues to run. If you want to have code that executes after the request returns data, the easiest way is to put that code in a completion handler block (by calling dataTaskWithRequest:completionHandler:).

dgatwood
  • 10,129
  • 1
  • 28
  • 49
  • Sorry. I should clarify. I do have the request and response inside the completion handler. Just after the block, I have task.resume() and just after that I have a conditional loop that should continue until the task's state is .Completed. The problem is that because the block won't execute until everything else has completed, the while loop runs infinitely, never executing the request inside the task. – dbconfession May 02 '16 at 04:21
  • The session itself normally executes those completion blocks on the same run loop/dispatch queue from which they were scheduled. You're blocking that run loop by spinning in a while loop. Don't do that. Put the code after the while loop into the completion handler block instead, and ditch the while loop entirely. Let the method return so that the main run loop is idle. That will not only fix the problem, but will also use a lot less battery, because spinning waiting for a variable to change wastes a lot of CPU cycles. – dgatwood May 02 '16 at 04:28
  • Ok. But where is the line drawn? When you say the rest of the code after the completion block, that's the rest of my code which is a lot. What does the .resume() wait for before it executes the task's thread? From what I've experience, I'm unable to have ANY code after the task block otherwise the task doesn't execute until everything else is completed. – dbconfession May 02 '16 at 04:32
  • The task probably is executing, but it can't return data to your program until your method returns, because your method is still running, tying up the main thread, so NSURLSession can't run the completion handler block. After you call resume, you should do very little in the rest of that method, returning control as quickly as possible so that the main run loop is no longer busy, and the completion handler block can run. (Alternatively, you can use `sessionWithConfiguration:delegate:delegateQueue` to run the completion blocks on a different queue, but I wouldn't suggest that approach.) – dgatwood May 02 '16 at 04:45
  • This is starting to make a little more sense. So code outside the block that .resume waits for is limited to the function to which it resides? As long as there is no other code within the function, the response will be returned regardless of there being more code after the function call? – dbconfession May 02 '16 at 05:02
  • No, it needs to return all the way back to the run loop (i.e. none of your code can be running). Otherwise, the URL request will block until it can run code in the run loop. You can run code in other threads, of course, just not in the main thread. – dgatwood May 02 '16 at 05:04
  • Initially when I wanted to create another thread, I had started looking on here. But it was advised instead to use dispatch. So I understand correctly, you're saying that instead of dispatching, I should use an actual thread ? If so, can you either email me with how to create a new thread with swift, or direct me to a link that explains? – dbconfession May 02 '16 at 13:42
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/110842/discussion-between-dbconfession-and-dgatwood). – dbconfession May 02 '16 at 13:50