Reputation: 21
I'm coding an iOS App which uses an URL Request to a PHP document to send and receive data. Here is my code.
NSString *myRequestString = [NSString stringWithFormat:@"userid=%@&recieverid=%@&messege=%@&type=%@&password=%@", ownID, _friendID, content_encoded, msg_type, password];
NSData *myRequestData = [NSData dataWithBytes: [myRequestString UTF8String] length: [myRequestString length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: @"something.php"]];
[request setHTTPMethod: @"POST"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"content-type"];
[request setHTTPBody: myRequestData];
//My activiy Indicator starts here
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Now send a request and get Response
NSData *returnData = [NSURLConnection sendSynchronousRequest: request returningResponse: nil error: nil];
NSString *result = [[NSString alloc] initWithBytes:[returnData bytes] length:[returnData length] encoding:NSUTF8StringEncoding];
//Here some internal coding happens...
dispatch_async(dispatch_get_main_queue(), ^(void) {
//Stopping activity indicator
});
});
But if the user locks his Phone while he sends the data (possible in other apps like Snapchat etc as well) the app freezes when the user returns and has to reopen it. I want to know if theres a better way of doing if the app connects to the Server and the user closes the app that doesn't let this error occur.
Thank you :) Anton And sorry about my poor english Im not a native speaker.
Upvotes: 0
Views: 234
Reputation: 437622
I'd suggest:
Specifying a background task identifier, as suggested by John Woods, so that if the user leaves the app in the middle of the request, it will attempt to continue the network request in the background.
Use sendAsynchronousRequest
rather than dispatching sendSynchronousRequest
to the background.
Make sure you correctly detect and handle errors (because it's not entirely clear to me whether the problem rests in the code of your question or whatever processing you're doing with it later).
Unrelated, but I'd avoid using the bytes
-related NSData
methods.
Thus:
// I'm guessing that you're percent encoding `messege` [sic], but I'd do it for all of those parameters (notably password)
NSString *myRequestString = [NSString stringWithFormat:@"userid=%@&recieverid=%@&messege=%@&type=%@&password=%@", ownID, _friendID, content_encoded, msg_type, password];
// Use `dataUsingEncoding` rather than bytes rendition:
//
// NSData *myRequestData = [NSData dataWithBytes: [myRequestString UTF8String] length: [myRequestString length]];
NSData *myRequestData = [myRequestString dataUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: @"something.php"]];
[request setHTTPMethod: @"POST"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"content-type"];
[request setHTTPBody: myRequestData];
// start background task
UIBackgroundTaskIdentifier __block task = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:task];
task = UIBackgroundTaskInvalid;
}];
// activity indicator starts here
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (!data) {
NSLog(@"%s: sendAsynchronousRequest error: %@", __PRETTY_FUNCTION__, connectionError);
} else {
// use NSData rendition rather than bytes rendition:
//
// NSString *result = [[NSString alloc] initWithBytes:[returnData bytes] length:[returnData length] encoding:NSUTF8StringEncoding];
NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
// here some internal coding happens...
}
// stop activity indicator here
// stop background task
if (task != UIBackgroundTaskInvalid) {
[[UIApplication sharedApplication] endBackgroundTask:task];
task = UIBackgroundTaskInvalid;
}
}];
Upvotes: 6
Reputation: 22926
You have to implement a background task. When the phone locks, all apps transition to a background "inactive" state. You need to implement a long running background task.
Upvotes: 0