Reputation: 22926
Considering the below code, I moved my app from a synchronous to asynchronous calls to stop the UI freezing. -- Everything works fine except a few small details.
When it was synchronous calls they always returned a value (even if it took a long time (5 or 6 seconds)) However now:
The ASync calls are sometimes really fast other times take 8 or 9 seconds ( I have fiber internet also)
The text data they are fetching sometimes seemingly doesn't return or they time out as the myLabel text ends up getting set with 'NULL' - I know it's not the website I'm using the API for as it always returns a value for Sync calls and in the browser.
Any ideas? Thanks!
EDIT: Error response from logs is: Response: Error: (null)
[NSURLConnection sendAsynchronousRequest:requestGBP queue:operationQueue completionHandler: ^(NSURLResponse* response, NSData* data, NSError* error)
{
responseGBP = data;
NSString *json_stringGBP = [[NSString alloc] initWithData:responseGBP encoding:NSASCIIStringEncoding];
self.feedGBP = [parser objectWithString:json_stringGBP error:nil];
NSString *GBP = [NSString stringWithFormat:@"Info Last: %@" feedGBP ObjectForKey:@"value"]];
[myLabel setText:GBP];
}];
EDIIT:: I also see "should not be able to get here" printed in the log window alot?! it's not part of my NSLog code!
Upvotes: 1
Views: 836
Reputation: 3239
Depends on your Queue, How and where are you intializing your operationQueue
?
more importantly when are you calling the asynchronous connections ?
if you're calling them from within a UIView that animates, like a tableView or a scrollView, the queue will behave this way while the table/scrollView is scrolling.
To also be able to debug more info, you need to NSLog(@"Response: %@\r\nError: %@", response, error)
But form my experience I highly suspect the first case is causing this, you can also try using a default queue instead of your own, something like this(Not recommended, but might helps with debugging):
[NSURLConnection sendAsynchronousRequest:requestGBP queue:[NSOperationQueue currentQueue] completionHandler: ^(NSURLResponse* response, NSData* data, NSError* error)
EDIT 1: Adding a simple code change to make things a bit easier
So as I suspected, you're firing calls from within animating views which causes the delays sometimes, what I would do is revert the aSync connections to Sync ones, but call them on a background thread instead.
Here's how things should look (Untested code, might contain errors or need some tweaking)
Move your call into a new method, call it something like performRequest:(URLRequest*)req;
-(void)performRequest:(URLRequest*)aRequest{
NSError *err;
NSURLResponse *response;
NSData *returnData;
returnData = [NSURLConnection sendSynchronousRequest:aRequest
returningResponse:&response
error:&err];
if(!err && nil != returnData){
//Perform action with your data here
//IMPORTANT: if you have to use the data to update the UI again, then you
//Must perform that on the main thread, this code will always be called in the
//background thread, to do that simply do a call using GCD on the main Queue, like this
dispatch_async(dispatch_get_main_queue(), ^{
//Do only your UI updates here
});
}else{
NSLog(@"An error has occurred: %@", err);
}
}
And whenever you need to perform the network request, (from within your animations, etc..) you simply call it in a background thread, like this
//Place this right after you create your requestGBP request
[self performSelectorInBackground:@selector(performRequest:) withObject:requestGBP];
Give it a try this way and let me know how things for for you !
Upvotes: 1
Reputation: 21966
Check if error isn't nil, and in this case print it, it will help you understanding the problem. I'll also riassume here what said in the comments about the encoding (by CodaFi), and about updating the UI on the main thread (this isn't the cause of the problem, but it might become annoying later):
[NSURLConnection sendAsynchronousRequest:requestGBP queue:operationQueue completionHandler: ^(NSURLResponse* response, NSData* data, NSError* error)
{
if(error)
{
NSLog(@"%@",error);
}
else
{
// Get the right string encoding:
NSStringEncoding encoding= NSASCIIStringEncoding; // This in case the page will
// not return any encoding.
if(response.textEncodingName)
{
encoding= CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding((__bridge CFStringRef) text.encodingName));
// A bit messy right? Don't get lost, read these functions on the
// documentation: http://developer.apple.com/library/ios/#documentation/CoreFoundation/Reference/CFStringRef/Reference/reference.html
}
responseGBP = data;
NSString *json_stringGBP = [[NSString alloc] initWithData:responseGBP encoding: encoding];
self.feedGBP = [parser objectWithString:json_stringGBP error:nil];
NSString *GBP = [NSString stringWithFormat:@"Info Last: %@" feedGBP ObjectForKey:@"value"]];
// Update the UI on main thread:
[myLabel performSelectorOnMainThread: @selector(setText:) withObject: GBP waitUntilDone: NO];
}
}];
Upvotes: 1