iOS7程序后台運行


介紹

這次 iOS7 對程序后台運行進行了加強,但是僅僅是加強而已,要想像 Android 程序那樣自由當然就別想了,蘋果這么做主要還是出於電池使用時間考慮,但是這次的加強對大部分程序基本夠用。

在介紹之前, 我們先回顧一下在 iOS7 之前的后台運行相關的知識。在 iOS7 之前(iOS4 之后)主要有三類的應用程序能夠后台運行:

  1. 音頻播放
  2. 后台定位服務
  3. IP 電話

除了這三種應用,其他程序只能是在進入后台之前向系統請求一個額外的運行時間(最長為 10 分鍾),並在該時間內來進行后台運行操作,如保存用戶信息,上傳或下載數據,進行視頻編碼等操作。

 

- (void)applicationDidEnterBackground:(UIApplication *)application
{
	static UIBackgroundTaskIdentifier task;
	task = [application beginBackgroundTaskWithExpirationHandler:^{
     task = UIBackgroundTaskInvalid;
 	};
	// 執行后台操作
	[application endBackgroundTask:task];
}

這次 iOS7 支持了兩種新的程序后台運行模式:

 

  • 需要定期請求數據的程序可以在系統中注冊,這樣程序就可以在后台被定期喚醒來下載新的數據。這種情況需要在程序的 Info.plist 文件中 UIBackgroundModes 項增加 fetch 類型,同時通過 setMinimumBackgroundFetchInterval: 方法來設置程序定期獲取數據的最小時間間隔。你需要實現 application:performFetchWithCompletionHandler: 代理方法並在該方法內執行下載操作。

  • 程序還可以通過后台消息推送服務來通知用戶有新的內需可以下載,同時激活后台下載操作。這種需要在 UIBackgroundModes 項中增加 remote-notification 值,同時你需要實現 AppDelegate 方法 application:didReceiveRemoteNotification:fetchCompletionHandler: 來執行你的下載操作。

不管是支持 fetch 或 remote-notification 后台運行模式的程序,都有可能被系統在合適的時候啟動或從后台掛起狀態移除調。在 fetch 模式下,系統會利用有效的信息來決定啟動或激活程序的最佳時期。例如:系統可能會在網絡狀況良好或者設備剛解鎖的時候讓程序執行 fetch 操作。支持 remote-notifiaction 的程序,可以在接收到推送消息的時候被喚醒,但在用戶接收到推送消息之前,程序可以通過定期獲取的形式下載最新內容,並在隨后的推送消息之前就已經准備好將內容展現給用戶。

為了執行后台下載操作,程序應該使用新增的 NSURLSession 類,該類在之前的 NSURLConnectoin 的基礎上提供了更簡潔、基於任務的接口來啟動並執行 NSURLRequest 對象。一個 NSURLSession 對象可以啟動多個下載或上傳任務,並在代理方法里面來處理來自服務器的認證請求。

實現

現在我們來實現 fetch 和 remote-notifiaction 兩種后台運行。

1. 設置

在 Xcode5.0 里面 Capabilities 下可以直接通過勾選的方式選擇應用需要支持的后台運行的類型(可多選哦),我們選中 Background fetch 和 Remote notification 兩項。並在程序的 Info.plist 文件中的 Required background modes 中添加 fetch 和 remote-notification 兩項。

Multitasking SettingMultitasking Setting

2. Background Fetch

 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    [application setMinimumBackgroundFetchInterval:
     UIApplicationBackgroundFetchIntervalMinimum];
    return YES;
}

- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
    NSURL *url = [NSURL URLWithString:@"http://127.0.0.1:3000/update.do"];
    NSURLSession *updateSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
    [updateSession dataTaskWithHTTPGetRequest:url
                            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                NSDictionary *messageInfo = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
                                NSLog(@"messageInfo:%@",messageInfo);
                                completionHandler(UIBackgroundFetchResultNewData);
                            }];
}

首先在 application:didFinishLaunchingWithOptions: 中設置 minimun background fetch interval 類型為 UIApplicationBackgroundFetchIntervalMinimum(默認為 UIApplicationBackgroundFetchIntervalNever),然后實現代理方法 application:performFetchWithCompletionHandler: 中實現數據請求。

 

為了測試程序后台運行,我們可以新建一個 Scheme,選中 Background Fetch(Launch due to a background fetch event),然后在該 Scheme 下運行程序,程序並不會啟動,但是你能看到它給后台發了請求。

New SchemeNew Scheme

Remote Notifications

類似要實現 remote-notification 模式,需要在原來支持 push 的條件下實現 application:didReceiveRemoteNotification:fetchCompletionHandler: 代理方法,程序在后台收到 payload 中包含 "content-available = 1" 的推送消息時,會執行該代理方法。(因為模擬器無法模擬消息推送,iPad 版本的 iOS7 還沒提供下載,所以我暫時沒法親測)。

總結

總的來說實現上沒有什么太復雜的東西,關鍵是你怎么樣將這兩種新的后台運行模式應用到你的程序中。

Posted by XiaoYi_HD - 6月 23 2013
如需轉載,請注明: 本文來自 Esoft Mobile


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM