在iOS系統,App的前台運行和後台運行,行為是不同的,iOS操作系統對後台運行做了諸多限制,為了能夠讓系統運行更流程和更省電。
App的狀態如下圖:
對於後台運行,首先需要確定設備是否支持多任務,在iOS4.0 之前是否沒辦法做到多任務的,不過現在iOS4.0的設備已經很少了。
[cpp]
UIDevice* device = [UIDevice currentDevice];
BOOL backgroundSupported = NO;
if ([device respondsToSelector:@selector(isMultitaskingSupported)])
backgroundSupported = device.multitaskingSupported;
有三種方式可以在App切後台後,獲得後台執行,第一種是執行有限時間的後台任務,第二種通過本地通知執行定時任務,第三種執行長運行後台任務(系統開發的音樂播放等)
第一種,使用beginBackgroundTaskWithExpirationHandler:在applicationDidEnterBackground裡調用
[cpp]
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
// Clean up any unfinished task business by marking where you
// stopped or ending the task outright.
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Do the work associated with the task, preferably in chunks.
// your code
NSLog(@" %f",application.backgroundTimeRemaining);
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
});
}
第二種,使用本地系統通知 view plaincopyprint?
- (void)scheduleAlarmForDate:(NSDate*)theDate
{
UIApplication* app = [UIApplication sharedApplication];
NSArray* oldNotifications = [app scheduledLocalNotifications];
// Clear out the old notification before scheduling a new one.
if ([oldNotifications count] > 0)
[app cancelAllLocalNotifications];
// Create a new notification.
UILocalNotification* alarm = [[UILocalNotification alloc] init];
if (alarm)
{
alarm.fireDate = theDate;
alarm.timeZone = [NSTimeZone defaultTimeZone];
alarm.repeatInterval = 0;
alarm.soundName = @"alarmsound.caf";
alarm.alertBody = @"Time to wake up!";
[app scheduleLocalNotification:alarm];
}
}
第三種調用系統指定的後台運行任務,有一下這些,例如GPS 音樂等
Apps that play audible content to the user while in the background, such as a music player app
Apps that record audio content while in the background.
Apps that keep users informed of their location at all times, such as a navigation app
Apps that support Voice over Internet Protocol (VoIP)
Apps that need to download and process new content regularly
Apps that receive regular updates from external accessories
在項目中,我用的是第一種,大致就是每次在app在切後台,發送一些網絡請求去server,遇到個問題,就是如果采用異步方式發送請求時,未等App收到回復,程序已切到後台,所以把其改成同步請求,如:
[cpp]
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]];
NSError *error;
NSURLResponse *response;
NSData *data= [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
可正常收到response,暫時解決了個問題。但對於有數個請求,執行效率是一個問題。