0

I do a post request using Async

[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)

I have the call backs for when the connection has stopped and in here I call my method for stopping the UIActivityIndicatorView

-(void)connectionDidFinishLoading:(NSURLConnection*)connection
{
NSLog(@"Connection finish");
[self stopAnimatingSpinner];
}

Heres the stop animating method (I have tried a combination and all of the below stop, remove hide methods

-(void)stopAnimatingSpinner{

[submittingActivity stopAnimating];
submittingActivity.hidden = YES;
[submittingActivity removeFromSuperview];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];

}

Now the problem is sometimes it stops sometimes it doesnt and is very random. If I move the stopping of the activity to the finish parsing of my data instead of relying on the connection callbacks the behaviour is exactly the same. Sometimes they stop sometimes they don't?

The only thing I can think of is that the connection is blocking the main thread but why would it work sometimes and not others?

Alex McPherson
  • 3,185
  • 3
  • 30
  • 41
  • Do you get "Connection finish" printed at your console everytime? – Gaurav Wadhwani Apr 13 '13 at 14:30
  • @GauravWadhwani yes I always get the log so the methods called just the UI doesnt update..very strange as said sometimes it works others not? – Alex McPherson Apr 13 '13 at 14:31
  • Try commenting out the 'removeFromSuperView' and then try..am guessing it may work..OR as mentioned in the answer below by H2CO3, run the UI updates on main thread,if you aren't already doing so.. – Gaurav Wadhwani Apr 13 '13 at 14:33
  • @GauravWadhwani I did try this same behaviour I am afraid I think its to do with what H2C03 just mentioned...but thanks will report back after more tests. – Alex McPherson Apr 13 '13 at 14:38

2 Answers2

0

Two principal problems:

  1. If you use the sendAsynchronousRequest: (etc.) method of NSURLConnection, then only the completion block will be called upon completion, and the connectionDidFinishLoading: delegate method isn't. That's another API.

  2. If you're updating the UI, you should always do so on the main thread. Otherwise your program invokes undefined behavior. So wrap the code which stops the animation in a block that's dispatched on the main thread:

    dispatch_sync(dispatch_get_main_queue(), ^{ [self stopAnimatingSpinner]; });

  • Hey H2CO3 I did assume it might have been this I will give this a try and report back. thanks – Alex McPherson Apr 13 '13 at 14:40
  • this seems to crash the app and becomes unresponsive i.e cant do anything and nothing in the log...I did try before...dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // Add code here to do background processing }); but it stops after an amount of time but not when I expect it to?? – Alex McPherson Apr 13 '13 at 14:45
  • @AlexMcPherson I don't understand the second problem, could you please rephrase it? –  Apr 13 '13 at 14:53
  • I used dispatch_sync(dispatch_get_main_queue(), ^{ [self stopAnimatingSpinner]; }); as mentioned and the app freezes and is non responsive doesn't crash and nothing reported in the log...I dont understand how to get around it I ve also tried dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) which seems to stop the spinner however after an unexpected time? – Alex McPherson Apr 13 '13 at 14:55
  • @AlexMcPherson Then something else is also screwed up. –  Apr 13 '13 at 14:58
  • I gathered that...could the problem be this part of the request? request queue:[NSOperationQueue mainQueue] or should I do the request some other way? – Alex McPherson Apr 13 '13 at 14:59
  • @AlexMcPherson I don't know, honestly. When I do this kind of request handling and UI updating, then I use what I wrote and it works. Maybe you can try `dispatch_async()` as well, that tends to work too. –  Apr 13 '13 at 15:02
  • I changed this dispatch_sync to this dispatch_async notice the async and it appears to work will do some more testing... – Alex McPherson Apr 13 '13 at 15:08
0

If you are invoking NSURLConnection from main thread, then your completion handler also will be called from main thread. Hence, you should not invoke dispatch_sync when stopping the spinner.

sixthcent
  • 1,150
  • 7
  • 6
  • I changed it to dispatch_async and this seems to work will do some more tests. – Alex McPherson Apr 13 '13 at 15:11
  • I would think you don't need to use GCD at all in this case as the completion handler is already on main thread. So, just calling [self stopAnimatingSpinner] would suffice. – sixthcent Apr 13 '13 at 15:13
  • I am afraid not because I have been doing this all along and the reason for this question is sometimes it fires others not this async has been the most stable till no and hasnt not worked as yet but will keep testing it out. – Alex McPherson Apr 13 '13 at 15:14