iOS Advanced Programming: Understanding iOS 4 Multitasking
In the old days of iOS when you pressed the home button the application you where running in your iphone used to quit instantly. Today with iOS 4 you have a few more options.
Multitasking is the most relevant feature included in iOS 4. If you build an application on Xcode against iOS 4 it is supposed to support multitasking, which is great but it doesn’t really mean that your app can keep running all the time. Apple is not ready to allow that because of battery life and memory.
How it works?
In the previous versions of iOS when you pressed the home button your iPhone used to call the method “applicationWillTerminate” in the app delegate and your app had five seconds to complete whatever it was doing before the OS dumped your process.
Now when you tap the home button iOS calls the method “applicationDidEnterBackground” and if you relaunch the app it calls “applicationWillEnterForeground”, and you can close them by double clicking the home button and holding one icon in the list of the background apps, then your application will call the “applicationWillTerminate” method and exit.
Ok, multitasking on the iPhone is great, but it may not run all the time in the background, then what can it do? Well there is a very short list of what your app can do. Here it is:
1. VOIP connections
2. Play audio
3. React to navigation changes
You have to create an entry in your plist file to say that your app will do this in background, if not, nothing will happen when you double click the home button. Besides these three items I mentioned there are two more. One of them is that you can request time to finish the operation you were running. This sounds very convenient, you may think that you can ask for time enough to finish a 1GB download over a 3G network but you can’t. Actually you have a very few minutes to finish and depending on the operation you’ll get only a few seconds before the OS kills your process. The other thing you can do in the background is send local notifications, these are just alerts sent to the user from your app in the background.
In contrast you can see that the things that you cannot do is much larger. But the most relevant are:
1. No OpenGL
2.- No network operations
And you should:
1. Save state when possible
2. Release large objects when going to background
For this tutorial i will show you how to request time to finish operations on your app (the most complex operation you can do with multitasking) and how to send local notifications.
Requesting time to finish operations
Open Xcode and create a new View-Based Application. Find your app delegate the implementation file in the Classes folder. Inside create an attribute called backgroundTask after the @synthetize of window and viewController like this:
UIBackgroundTaskIdentifier backgroundTask;
Now locate the applicationDidEnterBackground method. As this method is called when your app goes to background it is great time to request time here.
Next, add this block inside. A block is a small amount of code that can be executed with more priority. I will talk about Blocks in a future tutorial.
backgroundTask = [application beginBackgroundTaskWithExpirationHandler: ^{ dispatch_async(dispatch_get_main_queue(), ^{ if (backgroundTask != UIBackgroundTaskInvalid) { [application endBackgroundTask:backgroundTask]; backgroundTask = UIBackgroundTaskInvalid; } }); }];
Here we asked for time to finish our operation. It is not executed when the compiler reaches it, we are just telling it that if we need more time to finish an operation, it can use it. Now you can do your long operation:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // Here goes your operation //. //. //. // done! dispatch_async(dispatch_get_main_queue(), ^{ if (backgroundTask != UIBackgroundTaskInvalid) { // if you don't call endBackgroundTask, the OS will exit your app. [application endBackgroundTask:backgroundTask]; backgroundTask = UIBackgroundTaskInvalid; } }); });
This was another block of code, every time you see ^{ it means it is a block of code. As i said, i will talk about blocks in a future tutorial. In the previous code where I wrote “// Here goes your operation” you can replace it with the following code to see how much time has been given to you:
[NSThread sleepForTimeInterval:3]; NSLog(@"Time remaining: %f",[application backgroundTimeRemaining]);
This just waits for three seconds and writes the given time to the console.
Using Local Notifications
Notifications can be scheduled anywhere in your application, when the user taps a button, launches an app, etc. they can be fired in any state of the app.
Here we are going to schedule one notification to be fired after ten seconds the app is launched and the user will be notified even if you send the app to the background, close it or keep running it.
In the application delegate class find applicationDidFinishLaunchingWithOptions. and before the “return yes” statement add the following code:
application.applicationIconBadgeNumber = 0; UILocalNotification *local = [[UILocalNotification alloc] init]; // create date/time information local.fireDate = [NSDate dateWithTimeIntervalSinceNow:10]; local.timeZone = [NSTimeZone defaultTimeZone]; // set notification details local.alertBody = @"Hello! i’m a local notification"; local.alertAction = @"View"; // set the badge on the app icon local.applicationIconBadgeNumber = 1; // Gather any custom data you need to save with the notification NSDictionary *customInfo = [NSDictionary dictionaryWithObject:@"Black" forKey:@"Color"]; local.userInfo = customInfo; // Schedule it [[UIApplication sharedApplication] scheduleLocalNotification:local]; [local release];
First we reset the badge. It is the little number in a red circle that appears in the top right corner of the icon of an app, like mail for example. Then we set the parameters. I set the icon badge to “1” simulating that i got mail, a nd the userInfo to save information, I’m saving the value “Black” for the key “Color”.
Conclusion
In this tutorial we talked about the truth of iphone multitasking and how it really works.
Of course there is more to talk about multitasking in iOS, but if i didn’t wrote about it is because i only wanted to tell you the most important things. If you want to learn more about this subject i recommend you to read the apple’s iOS 4 documentation.