日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

三种方式使得iOS应用能够在后台进行数据更新和下载

發布時間:2023/12/4 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 三种方式使得iOS应用能够在后台进行数据更新和下载 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

三種方式使得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 *)application performFetchWithCompletionHandler:(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 *)applicationdidReceiveRemoteNotification:(NSDictionary *)userInfofetchCompletionHandler:(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 *)sessiondownloadTask:(NSURLSessionDownloadTask *)downloadTaskdidFinishDownloadingToURL:(NSURL *)location {NSLog(@"downloadTask:%@ didFinishDownloadingToURL:%@", downloadTask.taskDescription, location); // 必須用 NSFileManager 將文件復制到應用的存儲中,因為臨時文件在方法返回后會被刪除 // ... // 通知 UI 刷新 } - (void) URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(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 *)applicationhandleEventsForBackgroundURLSession:(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(); } }

原文地址

轉載于:https://www.cnblogs.com/pandas/p/4334871.html

總結

以上是生活随笔為你收集整理的三种方式使得iOS应用能够在后台进行数据更新和下载的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。