三種方式使得iOS應用能夠在後台進行資料更新和下載

來源:互聯網
上載者:User

標籤:

三種方式使得iOS程式即使在關閉或崩潰的情況下也能夠在後台持續進行一些任務,比如更新程式介面快照,下載檔案等。這三個方法分別是 Background Fetch,Remote Notification和NSURLSession的backgroundSessionConfiguration

Background Fetch開啟

首先在info plist檔案中開啟UIBackgroundModes的Background fetch。或者手動編輯這個值

<key>UIBackgroundModes</key><array>     <string>fetch</string></array>

iOS預設不進行background fetch,需要設定一個時間的間隔

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{     //UIApplicationBackgroundFetchIntervalMinimum表示儘可能頻繁去擷取,如果需要指定至少多少時間更新一次就需要給定一個時間值     [application setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];     return YES;}

最後在App Delegate裡實現下面的方法,這個方法只能在30秒內完成。

- (void) application:(UIApplication *)applicationperformFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{     NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];     NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration];     NSURL *url = [[NSURL alloc] initWithString:@"http://yourserver.com/data.json"];     NSURLSessionDataTask *task = [session dataTaskWithURL:url               completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {          if (error) {               completionHandler(UIBackgroundFetchResultFailed);               return;          }          // 解析響應/資料以決定新內容是否可用          BOOL hasNewData = ...          if (hasNewData) {               completionHandler(UIBackgroundFetchResultNewData);          } else {               completionHandler(UIBackgroundFetchResultNoData);          }     }];     // 開始任務     [task resume];}
測試
  • 通過查看UIApplication的applicationState
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{     NSLog(@"Launched in background %d", UIApplicationStateBackground == application.applicationState);     return YES;}
Remote Notification

在普通的遠程通知裡帶上content-available標誌就可以在通知使用者同時在後台進行更新。通知結構如下

{     "aps" : {          "content-available" : 1     },     "content-id" : 42}

接收一條帶有content-available的通知會調用下面的方法

- (void)application:(UIApplication *)application          didReceiveRemoteNotification:(NSDictionary *)userInfo          fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{     NSLog(@"Remote Notification userInfo is %@", userInfo);     NSNumber *contentID = userInfo[@"content-id"];     // 根據 content ID 進行操作     completionHandler(UIBackgroundFetchResultNewData);}
利用NSURLSession進行background transfer task

使用[NSURLSessionConfiguration backgroundSessionConfiguration]建立一個背景工作,當應用退出後,崩潰或進程被關掉都還是會運行。

範例,先處理一條遠程通知,並將NSURLSessionDownloadTask添加到後台傳輸服務隊列。

- (NSURLSession *)backgroundURLSession{     static NSURLSession *session = nil;     static dispatch_once_t onceToken;     dispatch_once(&onceToken, ^{          NSString *identifier = @"io.objc.backgroundTransferExample";          NSURLSessionConfiguration* sessionConfig = [NSURLSessionConfiguration backgroundSessionConfiguration:identifier];          session = [NSURLSession sessionWithConfiguration:sessionConfig               delegate:self               delegateQueue:[NSOperationQueue mainQueue]];     });     return session;}- (void) application:(UIApplication *)application     didReceiveRemoteNotification:(NSDictionary *)userInfo     fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{     NSLog(@"Received remote notification with userInfo %@", userInfo);     NSNumber *contentID = userInfo[@"content-id"];     NSString *downloadURLString = [NSString stringWithFormat:@"http://yourserver.com/downloads/%d.mp3", [contentID intValue]];     NSURL* downloadURL = [NSURL URLWithString:downloadURLString];     NSURLRequest *request = [NSURLRequest requestWithURL:downloadURL];     NSURLSessionDownloadTask *task = [[self backgroundURLSession] downloadTaskWithRequest:request];     task.taskDescription = [NSString stringWithFormat:@"Podcast Episode %d", [contentID intValue]];     //執行resume保證開始了任務     [task resume];     completionHandler(UIBackgroundFetchResultNewData);}

下載完成後調用NSURLSessionDownloadDelegate的委託方法,這些委託方法全部是必須實現的。瞭解所有類型session task的生命週期可以參考官方文檔:https://developer.apple.com/library/ios/documentation/cocoa/Conceptual/URLLoadingSystem/NSURLSessionConcepts/NSURLSessionConcepts.html#//apple_ref/doc/uid/10000165i-CH2-SW42

#Pragma Mark - NSURLSessionDownloadDelegate- (void) URLSession:(NSURLSession *)session     downloadTask:(NSURLSessionDownloadTask *)downloadTask     didFinishDownloadingToURL:(NSURL *)location{     NSLog(@"downloadTask:%@ didFinishDownloadingToURL:%@", downloadTask.taskDescription, location);     // 必須用 NSFileManager 將檔案複製到應用的儲存中,因為臨時檔案在方法返回後會被刪除     // ...     // 通知 UI 重新整理}- (void) URLSession:(NSURLSession *)session     downloadTask:(NSURLSessionDownloadTask *)downloadTaskdidResumeAtOffset:(int64_t)fileOffset     expectedTotalBytes:(int64_t)expectedTotalBytes{}- (void) URLSession:(NSURLSession *)session     downloadTask:(NSURLSessionDownloadTask *)downloadTask     didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten     totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{}

背景任務完成後如果應用沒有在前台運行,需要實現UIApplication的兩個delegate讓系統喚醒應用

- (void) application:(UIApplication *)application     handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler{     // 你必須重建立立一個後台 seesiong 的參照     // 否則 NSURLSessionDownloadDelegate 和 NSURLSessionDelegate 方法會因為     // 沒有 對 session 的 delegate 設定而不會被調用。參見上面的 backgroundURLSession     NSURLSession *backgroundSession = [self backgroundURLSession];     NSLog(@"Rejoining session with identifier %@ %@", identifier, backgroundSession);     // 儲存 completion handler 以在處理 session 事件後更新 UI     [self addCompletionHandler:completionHandler forSession:identifier];}- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session{     NSLog(@"Background URL session %@ finished events.", session);     if (session.configuration.identifier) {          // 調用在 -application:handleEventsForBackgroundURLSession: 中儲存的 handler          [self callCompletionHandlerForSession:session.configuration.identifier];     }}- (void)addCompletionHandler:(CompletionHandlerType)handler forSession:(NSString *)identifier{     if ([self.completionHandlerDictionary objectForKey:identifier]) {          NSLog(@"Error: Got multiple handlers for a single session identifier. This should not happen.");     }     [self.completionHandlerDictionary setObject:handler forKey:identifier];}- (void)callCompletionHandlerForSession: (NSString *)identifier{     CompletionHandlerType handler = [self.completionHandlerDictionary objectForKey: identifier];     if (handler) {          [self.completionHandlerDictionary removeObjectForKey: identifier];          NSLog(@"Calling completion handler for session %@", identifier);          handler();     }}
 

 

轉載地址:http://www.starming.com/index.php?v=index&view=69

三種方式使得iOS應用能夠在後台進行資料更新和下載

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.