三种方式使得iOS应用能够在后台进行数据更新和下载
来源:互联网 发布:win10更改网络为家庭 编辑:程序博客网 时间:2024/05/18 16:57
首先在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:urlcompletionHandler:^(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:sessionConfigdelegate:selfdelegateQueue:[NSOperationQueue mainQueue]];});return session;}- (void) application:(UIApplication *)applicationdidReceiveRemoteNotification:(NSDictionary *)userInfofetchCompletionHandler:(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 *)sessiondownloadTask:(NSURLSessionDownloadTask *)downloadTaskdidResumeAtOffset:(int64_t)fileOffsetexpectedTotalBytes:(int64_t)expectedTotalBytes{}- (void) URLSession:(NSURLSession *)sessiondownloadTask:(NSURLSessionDownloadTask *)downloadTaskdidWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWrittentotalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{}
后台的任务完成后如果应用没有在前台运行,需要实现UIApplication的两个delegate让系统唤醒应用
- (void) application:(UIApplication *)applicationhandleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler{// 你必须重新建立一个后台 seesiong 的参照// 否则 NSURLSessionDownloadDelegate 和 NSURLSessionDelegate 方法会因为// 没有 对 session 的 delegate 设定而不会被调用。参见上面的 backgroundURLSessionNSURLSession *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.cnblogs.com/pandas/p/4334871.html
0 0
- 三种方式使得iOS应用能够在后台进行数据更新和下载
- 三种方式使得iOS应用能够在后台进行数据更新和下载
- 三种方式使得iOS应用能够在后台进行数据更新和下载
- 三种方式使得iOS应用能够在后台进行数据更新和下载
- ios开发——日常之三种方式使得iOS应用能够在后台进行数据更新和下载
- 让应用停留在后台模式的三种方式
- iOS后台进行数据更新和下载
- ios应用在后台运行时间讨论
- ios应用在后台运行时间讨论
- 在后台下载图片
- 数据在后台修改 删除 更新 正确代码(共享)
- iOS程序在后台进行任务的方法
- WPF中,怎么在后台代码进行数据绑定
- 后台进行数据更新和下载
- 后台进行数据更新和下载
- 将ios代码在后台(子线程)执行的两种简单方式
- 百度Frontia应用数据存储在后台运行不起来
- 【Hibernate】把Hibernate在后台查询到的数据通过Struts标签在前台进行输出
- C/C++中的getline函数总结
- Hbase thrift 写数据Broken pipe问题
- Java实现Excel的导入和导出
- arm-linux安装Ubuntu12.4开发环境(三)安装nfs server
- 求解集合A与B的差集
- 三种方式使得iOS应用能够在后台进行数据更新和下载
- 用expect实现自动化输入密码
- JAVA 面向对象 一
- Javascript模块化编程(二):AMD规范
- Hbase学习8_ 启动hbase 报错 Address already in use 的解决办法
- Linux下GIPO的操作
- Android随笔之——PackageManager详解
- 继承
- Codeforces 219C Color Stripe 贪心