標籤:des style class blog c code
【推送喚醒(Remote Notifications)】
在iOS6和之前,推送的類型是很單一的,無非就是顯示標題內容,指定聲音等。使用者通過解鎖進入你的應用後,appDelegate中通過推送開啟應用的回調將被調用,然後你再擷取資料,進行顯示。這和沒有後台擷取時的開啟應用後再擷取資料重新整理的問題是一樣的。
在iOS7中這個行為發生了一些改變,我們有機會使裝置在接收到遠端推送後讓系統喚醒裝置和我們的後台應用,並先執行一段代碼來準備資料和UI,然後再提示使用者有推送。這時使用者如果解鎖裝置進入應用後將不會再有任何載入過程,新的內容將直接得到呈現。
1、啟用推送喚醒。
更改Info.plist,在UIBackgroundModes下加入remote-notification即可開啟,當然同樣的更簡單直接的辦法是使用Capabilities。
2、更改推送的payload。
在iOS7中,如果想要使用推送來喚醒應用運行代碼的話,需要在payload中加入content-available,並設定為1。
1 aps { 2 content-available: 13 alert: {...}4 }
3、實現推送喚醒代碼並通知系統。
在appDelegate中實現?-application:didReceiveRemoteNotification:fetchCompletionHandle:。這部分內容後台擷取部分完全一樣。
Apple將限制此類推送的頻率,當頻率超過一定限制後,帶有content-available標誌的推送將會被阻塞,以保證使用者裝置不被頻繁喚醒。按照Apple的說法,這個頻率在一小時內個位元次的推送的話不會有太大問題。
【後台傳輸(?Background Transfer Service)】
iOS7引入了後台傳輸的相關方式,用來保證應用退出後資料下載或者上傳能繼續進行。這種傳輸是由iOS系統進行管理的,沒有時間限制,也不要求應用運行在前台。
想要實現後台傳輸,就必須使用iOS7的新的網路連接的類,NSURLSession。這是iOS7中引入用以替代陳舊的NSURLConnection的類。
1、建立NSURLSession。
1 - (NSURLSession *)backgroundSession 2 { 3 //Use dispatch_once_t to create only one background session. If you want more than one session, do with different identifier 4 static NSURLSession *session = nil; 5 static dispatch_once_t onceToken; 6 dispatch_once(&onceToken, ^{ 7 NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfiguration:@"com.yourcompany.appId.BackgroundSession"]; 8 session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil]; 9 });10 return session;11 }
2、加入對應的傳輸用的NSURLSessionTask,並啟動下載。
1 //@property (nonatomic) NSURLSession *session; 2 //@property (nonatomic) NSURLSessionDownloadTask *downloadTask; 3 4 - (NSURLSession *)backgroundSession 5 { 6 //... 7 } 8 9 - (void) beginDownload10 {11 NSURL *downloadURL = [NSURL URLWithString:DownloadURLString];12 NSURLRequest *request = [NSURLRequest requestWithURL:downloadURL];13 self.session = [self backgroundSession];14 self.downloadTask = [self.session downloadTaskWithRequest:request];15 [self.downloadTask resume];16 }
3、最後一步是在appDelegate中實現-application:handleEventsForBackgroundURLSession:completionHandler:
1 //AppDelegate.m 2 - (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier 3 completionHandler:(void (^)())completionHandler 4 { 5 //Check if all transfers are done, and update UI 6 //Then tell system background transfer over, so it can take new snapshot to show in App Switcher 7 completionHandler(); 8 9 //You can also pop up a local notification to remind the user10 //...11 }
一旦後台傳輸的狀態發生變化(包括正常結束和失敗)的時候,應用將被喚醒並運行appDelegate中的回調,接下來NSURLSessionTask的委託方法將在後台被調用。雖然上面的例子中直接在appDelegate中call了completionHandler,但是實際上更好的選擇是在appDelegate中暫時持有completionHandler,然後在NSURLSessionTask的delegate方法中檢查是否確實完成了傳輸並更新UI後,再調用completionHandler。另外,你的應用到現在為止只是在後台運行,想要提醒使用者傳輸完成的話,也許你還需要在這個時候發送一個本地推送(記住在這個時候你的應用是可以執行代碼的,雖然是在後台),這樣使用者可以注意到你的應用的變化並回到應用,並開始已經準備好資料和介面。
後台傳輸只會通過wifi來進行。
參考:http://onevcat.com/2013/08/ios7-background-multitask/