一:了解multitasking
background apps(可以在后台运行的任务):
1:play audio
2:get location
3:voip stream
4:request time to finish
5: create notifications
二:多任务生命周期
1:程序加载成功
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
2:程序将要失去活跃状态
- (void)applicationWillResignActive:(UIApplication *)application
3:程序已经进入后台运行
- (void)applicationDidEnterBackground:(UIApplication *)application
4:程序将要进入前台运行
- (void)applicationWillEnterForeground:(UIApplication *)application
5:程序进入活跃状态
- (void)applicationDidBecomeActive:(UIApplication *)application
6:程序退出
- (void)applicationWillTerminate:(UIApplication *)application
从启动到转入后台,从后台转入前台,退出,生命周期函数调用顺序
1->5->2->3->4->5->6
三:转入后台后请求一段时间完成操作
- UIBackgroundTaskIdentifier backgroundTask;
- - (void)applicationDidEnterBackground:(UIApplication *)application {
- // tell the OS you're about to begin a background task that may need time to finish
- backgroundTask = [application beginBackgroundTaskWithExpirationHandler: ^{
- // 如果超时这个block将被调用
- dispatch_async(dispatch_get_main_queue(), ^{
- if (backgroundTask != UIBackgroundTaskInvalid)
- {
- // do whatever needs to be done
- [application endBackgroundTask:backgroundTask];
- backgroundTask = UIBackgroundTaskInvalid;
- }
- });
- }];
- // Start the long-running task
- dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
- // Do the work!
- [NSThread sleepForTimeInterval:5];
- NSLog(@"Time remaining: %f",[application backgroundTimeRemaining]);
- [NSThread sleepForTimeInterval:5];
- NSLog(@"Time remaining: %f",[application backgroundTimeRemaining]);
- [NSThread sleepForTimeInterval:5];
- NSLog(@"Time remaining: %f",[application backgroundTimeRemaining]);
- // done!
- // call endBackgroundTask - should be executed back on
- // main thread
- 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;
- }
- });
- });
- NSLog(@"Reached the end of ApplicationDidEnterBackground - I'm done!");
- }
四:本地消息
1:创建一个本地消息
- -(IBAction) scheduleNotification {
- UILocalNotification *local = [[UILocalNotification alloc] init];
- // create date/time information
- local.fireDate = [NSDate dateWithTimeIntervalSinceNow:15];
- local.timeZone = [NSTimeZone defaultTimeZone];
- // set notification details
- local.alertBody = @"Missing you already!";
- 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:@"ABCD1234" forKey:@"yourKey"];
- local.userInfo = customInfo;
- // Schedule it!
- [[UIApplication sharedApplication] scheduleLocalNotification:local];
- [local release];
- }
2:delegate 处理方法
- - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
- // Override point for customization after application launch.
- // Add the view controller's view to the window and display.
- [window addSubview:viewController.view];
- [window makeKeyAndVisible];
- //程序启动是检查是否有UILocalNotification,如果有跳出提示框
- // reset badge
- application.applicationIconBadgeNumber = 0;
- // If the app was closed, and we launched from the notification
- UILocalNotification *local =
- [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
- if (local) {
- UIAlertView *alert = [[UIAlertView alloc]
- initWithTitle:@"You came back! (App was closed)"
- message:@"Nice to see you again!" delegate:nil
- cancelButtonTitle:@"Okay" otherButtonTitles:nil];
- [alert show];
- [alert release];
- }
- return YES;
- }
- //如果程序完全退出,此方法不会被调用,而是先调用didFinishLaunchingWithOptions把程序启动起来。如果该程序在后台运行收到消息时直接调用该方法
- - (void)application:(UIApplication *)application
- didReceiveLocalNotification:(UILocalNotification *)local {
- // reset badge number
- application.applicationIconBadgeNumber = 0;
- if (local) {
- // get custom info from dictionary
- NSString *customInfo = [local.userInfo objectForKey:@"yourKey"];
- //
- UIAlertView *alert = [[UIAlertView alloc]
- initWithTitle:@"You came back! (App was running)"
- message:customInfo delegate:nil
- cancelButtonTitle:@"Okay" otherButtonTitles:nil];
- [alert show];
- [alert release];
- }
- }
五:后台播放音乐
1:读取文件
- - (void)viewDidLoad {
- [super viewDidLoad];
- self.playPauseButton.titleLabel.text == @"play";
- // grab the path to the caf file
- NSString *soundFilePath =
- [[NSBundle mainBundle] pathForResource: @"Rainstorm"
- ofType: @"mp3"];
- NSURL *fileURL = [[NSURL alloc] initFileURLWithPath: soundFilePath];
- // create a new AVAudioPlayer initialized with the URL to the file
- AVAudioPlayer *newPlayer =
- [[AVAudioPlayer alloc] initWithContentsOfURL: fileURL
- error: nil];
- [fileURL release];
- // set our ivar equal to the new player
- self.player = newPlayer;
- [newPlayer release];
- // preloads buffers, gets ready to play
- [player prepareToPlay];
- // set delegate so we can get called back when the sound has finished playing
- [player setDelegate: self];
- //重要的两行
- // set category of audio
- [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
- // announce that we want to hook up to remote UI events
- [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
- }
2:重写canBecomeFirstResponder 方法,使改view 可以成为第一响应者
- -(BOOL) canBecomeFirstResponder {
- return YES;
- }
3:显示view时,设置为第一响应者
- -(void) viewDidAppear:(BOOL)animated {
- [self becomeFirstResponder];
- }
4:实现remoteControlReceivedWithEvent方法使程序接收 iphone 自动音乐控制事件
- -(void) remoteControlReceivedWithEvent:(UIEvent *)event {
- switch (event.subtype) {
- case UIEventSubtypeRemoteControlTogglePlayPause:
- [self playPause];
- default:
- break;
- }
- }
5:info.plist 设置,可以设置多种形式
- <key>UIBackgroundModes</key>
- <array>
- <string>audio</string>
- </array>
六:NSUserDefaults 问题
如果程序在后台挂起,在转入到前台后不会调用viewDidLoad 方法,所以要在viewDidLoad 方法里面注册UIApplicationWillEnterForegroundNotification ,调用loadSettings
- -(void) loadSettings: (NSNotification *) notification {
- NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
- [defaults synchronize];
- }
- // Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- - (void)viewDidLoad {
- [self loadSettings:nil];
- NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
- [notificationCenter addObserver:self
- selector:@selector(loadSettings:)
- name:UIApplicationWillEnterForegroundNotification
- object:nil];
- [super viewDidLoad];
- }
七:去除后台运行inof.list
application dose not run in background 设置为 true