介紹
此次iOS7對程序後臺運行進行了增強,可是僅僅是增強而已,要想像Android程序那樣自由固然就別想了,蘋果這麼作主要仍是出於電池使用時間考慮,可是此次的增強對大部分程序基本夠用。服務器
在介紹以前, 咱們先回顧一下在iOS7以前的後臺運行相關的知識。在iOS7以前(iOS4以後)主要有三類的應用程序可以後臺運行:網絡
- 音頻播放
- 後臺定位服務
- IP電話
除了這三種應用,其餘程序只能是在進入後臺以前向系統請求一個額外的運行時間(最長爲10分鐘),並在該時間內來進行後臺運行操做,如保存用戶信息,上傳或下載數據,進行視頻編碼等操做。session
- (void)applicationDidEnterBackground:(UIApplication *)application { static UIBackgroundTaskIdentifier task; task = [application beginBackgroundTaskWithExpirationHandler:^{ task = UIBackgroundTaskInvalid; }; //執行後臺操做 [application endBackgroundTask:task]; }
此次iOS7支持了兩種新的程序後臺運行模式:app
-
須要按期請求數據的程序能夠在系統中註冊,這樣程序就能夠在後臺被按期喚醒來下載新的數據。這種狀況須要在程序的Info.plist文件中UIBackgroundModes項增長fetch類型,同時經過setMinimumBackgroundFetchInterval:方法來設置程序按期獲取數據的最小時間間隔。你須要實現application: performFetchWithCompletionHandler: 代理方法並在該方法內執行下載操做。ide
-
程序還能夠經過後臺消息推送服務來通知用戶有新的內需能夠下載,同時激活後臺下載操做。這種須要在UIBackgroundModes項中增長remote-notification值,同時你須要實現AppDelegate方法 application:didReceiveRemoteNotification:fetchCompletionHandler:來執行你的下載操做。測試
無論是支持fetch或remote-notification後臺運行模式的程序,都有可能被系統在合適的時候啓動或從後臺掛起狀態移除調。在fetch模式下,系統會利用有效的信息來決定啓動或激活程序的最佳時期。例如:系統可能會在網絡情況良好或者設備剛解鎖的時候讓程序執行fetch操做。支持remote-notifiaction的程序,能夠在接收到推送消息的時候被喚醒,但在用戶接收到推送消息以前,程序能夠經過按期獲取的形式下載最新內容,並在隨後的推送消息以前就已經準備好將內容展示給用戶。fetch
爲了執行後臺下載操做,程序應該使用新增的NSURLSession類,該類在以前的NSURLConnectoin的基礎上提供了更簡潔、基於任務的接口來啓動並執行NSURLRequest對象。一個NSURLSession對象能夠啓動多個下載或上傳任務,並在代理方法裏面來處理來自服務器的認證請求。ui
實現
如今咱們來實現fetch和remote-notifiaction兩種後臺運行。
1. 設置
在Xcode5.0裏面Capabilities下能夠直接經過勾選的方式選擇應用須要支持的後臺運行的類型(可多選哦),咱們選中Background fetch和Remote notification兩項。並在程序的Info.plist文件中的Required background modes中添加fetch和remote-notification兩項。
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下運行程序,程序並不會啓動,可是你能看到它給後臺發了請求。
Remote Notifications
相似要實現remote-notification模式,須要在原來支持push的條件下實現application:didReceiveRemoteNotification:fetchCompletionHandler:代理方法,程序在後臺收到payload中包含"content-available = 1"的推送消息時,會執行該代理方法。(由於模擬器沒法模擬消息推送,iPad版本的iOS7還沒提供下載,因此我暫時無法親測)。
總結
總的來講實現上沒有什麼太複雜的東西,關鍵是你怎麼樣將這兩種新的後臺運行模式應用到你的程序中。