主要功能連接在這裏
http://my.oschina.net/u/1418722/blog/317422
在介紹以前, 咱們先回顧一下在 iOS7 以前的後臺運行相關的知識。在 iOS7 以前(iOS4 以後)主要有三類的應用程序可以後臺運行:
音頻播放
後臺定位服務
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 還沒提供下載,因此我暫時無法親測)。