三种方式使得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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/297876.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

漫水填充及Photoshop中魔术棒选择工具的实现

今天写程序中有一个地方用到了漫水填充&#xff08;FloodFill&#xff09;。所谓漫水填充&#xff0c;简单来说&#xff0c;如下图中左图&#xff0c;白布上有一块红色的斑点&#xff0c;在这个红色的斑点上点一下&#xff0c;就自动选中了和该点相连的红色的区域&#xff0c;接…

Hibernate注解之@Enumerated

Enumerated(valueEnumType.ORDINAL)采用枚举类型的序号值与数据库进行交互&#xff0c; 此时数据库的数据类型需要是数值类型&#xff0c;例如在实际操作中 CatTest ct new CatTest(); ct.setColor(Color.BLUE); 当我们将对象gt保存到数据库中的时候&#xff0c;数据库中存储的…

ios支付宝支付失败不回调_iOS 支付宝网页支付回调问题

今天遇到支付宝网页支付回调的问题当手机里面没有支付宝客户端的时候&#xff0c;会自动调起网页支付页面&#xff0c;但是我发现我原来写在AppDelegate.m里面的代码没走。造成的结果是&#xff0c;不管是支付成功&#xff0c;还是退出支付&#xff0c;都没有反应。解决办法4&g…

代理管家app_亲亲小保社保管家app2021下载_亲亲小保社保管家app最新版下载

亲亲小保社保管家是一款便捷社保服务软件&#xff0c;为用户提供全面便捷的社保公积金服务&#xff0c;可以解决生活中的各种居住&#xff0c;社会保障等&#xff0c;感兴趣的朋友快来下载亲亲小保社保管家吧。亲亲小保社保管家app特色1.、社保服务、社保代理、社保托管、工资代…

上大学后男生的两种变化

1 一只处女座的喵。。。2 螃蟹怎么都没想到自己有一天会变成糖葫芦3 还以为厨师被劫持了4 未来感十足的红绿灯概念设计……5 外国留学生的眼中中文6 上大学后男生的两种变化&#xff0c;可太真实了7 你这样欺负人我要报警哦8 一年级的题你点的每个赞&#xff0c;我都认真当成了…

linux怎么杀死线程c语言,教程-linux下c语言编程 第一弹-线程的使用

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼/*linux下最常用的应该就是pthread线程库了本教程就是关于pthread的关于线程是什么东西我就不赘述了 百科上都有*/#include#include//pthread库的头文件//声明并定义一个函数void*function(void*data){printf("start\n")…

ADO.NET笔记——基本概念

ADO.NET中的主要对象&#xff1a; Connection&#xff1a;连接对象。用于建立从应用程序到数据库服务器指定数据库的连接通道Command&#xff1a;命令对象。用于执行增删查改等数据库语句命令DataReader&#xff1a;数据阅读器对象。用于从数据库逐行返回数据DataAdapter&#…

关于 Azure SQL 数据库你不知道的 5 件事

点击上方蓝字关注“汪宇杰博客”原文&#xff1a;Azure Tips and Tricks翻译&#xff1a;汪宇杰Azure SQL Database如果您喜欢 SQL Server&#xff0c;那么您可能也喜欢 Azure SQL 数据库。Azure SQL 数据库是 Azure 中的 SQL Server 即服务。你负责处理数据&#xff0c;Azure …

如何在PowerPoint中插入带语法高亮的程序代码

最近在做Python的PPT时发现&#xff0c;向PowerPoint中插入带格式的源代码甚是不便&#xff0c;经搜索有篇文章说的还是很管用的&#xff0c;可以借鉴一下&#xff1a; Syntax highlighting source code in Word and PowerPoint 能导出格式的编辑器就比较多了&#xff0c;我用的…

win7共享xp打印机_解决共享打印机不能使用的问题

针式打印机如何设置共享打印找不到驱动就需要重新下载安装适合版本的驱动&#xff0c;以及.INF文件网络打印机连接模式步骤&#xff1a;a.预先得知网络打印机的IP地址&#xff0c;打开它的共享b.【开始】-【设备与打印机】-【添加打印机】-【添加本地打印机】c.选择TCP/IP接口-…

网页固定宽度布局

&#xff08;一个固定宽度div布局&#xff09; <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"http://www.w3.org/1999/xhtml"> <h…

rk3399性能_AIIA AI公布首轮评估结果:瑞芯微RK3399数据抢眼

人工智能产业发展联盟(AIIA)正式发布“AIIA DNN benchmark V0.5”首轮评估结果。该评估在AIIA权威测试平台完成&#xff0c;基于端侧推断任务的深度神经网络处理器基准测试。在四大典型应用场景下&#xff0c;能够客观反映具有深度学习处理能力的处理器或加速器的性能水平。评估…

世界上最欢乐的职业,可能就是蹦极的工作人员了!

1 他们叫的有多大声我笑的就有多大声▼2 这个手动转向灯可太可爱了▼3 真正的倒立洗头▼4 看看&#xff01;脚踏两只船多危险&#xff01;▼5 穿上这件衣服你和猪八戒就只差一个肚子了▼6 螳螂才是真正的拟态大神▼7 你是哪种&#xff1f;▼

linux系统管理命令使用,Linux系统管理使用之基本命令(1)

基本命令1.Linux的基本原则&#xff1a;1、由目的单一的小程序组成&#xff1b;组合小程序完成复杂任务&#xff1b;2、一切皆文件&#xff1b;3、尽量避免捕获用户接口&#xff1b;(尽量不和用户进行交互&#xff0c;就是一个程序一但开始运行&#xff0c;就不需要用户进行任何…

Apache-Jmeter监控服务资源

Jmeter本身没有监控服务器资源的功能&#xff0c;需要添加额外的插件&#xff0c;插件参考的网址&#xff1a;http://www.jmeter-plugins.org/ 一、监控原理图二、Jmeter-Plugs和PerfMonAgent的下载和安装&#xff08;1&#xff09;Jmeter-Plugs的下载网址http://www.jmeter-pl…

VS2022+.NET6 RC1+C#10,.NET开发起飞

9月14号发布了.NET6 RC1版本&#xff0c;代表着.NET6已基本定型了。小长假在家升级环境实操一番&#xff0c;VS2022.NET6C#10&#xff0c;那感觉简直了&#xff01;VS2022超强智能提示&#xff0c;极致简化的ASP.NET Core开发框架&#xff0c;再加上C#10各种炫酷新语法&#xf…

AS3.0第一个实例:(Hello World)

Hello World的实现 运行环境&#xff1a;Adobe Flash CS4 运行语言&#xff1a; Action Script 3.0 操作步骤&#xff1a; 路径: ...\FlashAs 文件夹内 1、新建一个文件夹AsScript(可自定义) 用来放置as文件&#xff0c;新建一个ActionScript 文件 起名为HelloWorld.as, 写入下…

语言怎么得到直流电压并采样_交流电AC如何转换成直流电DC?

交流电和直流电是什么&#xff0c;有什么区别&#xff1f;交流(AC)是指电流方向随时间作周期性变化的为交流电&#xff0c;在一个周期内的运行平均值为零。通常波形为正弦波形&#xff0c;交流电可以有效传输电力。但实际上还有应用其他的波形&#xff0c;例如三角形波、正方形…

深度学习 占用gpu内存 使用率为0_深度解析MegEngine亚线性显存优化技术

作者 | 旷视研究院 编辑 | Linda 基于梯度检查点的亚线性显存优化方法 [1] 由于较高的计算 / 显存性价比受到关注。MegEngine 经过工程扩展和优化&#xff0c;发展出一套行之有效的加强版亚线性显存优化技术&#xff0c;既可在计算存储资源受限的条件下&#xff0c;轻松训练更深…

jq select操作全集

添加option $("#ID option").each(function(){if($(this).val()111){$(this).remove();}});移除option $("<option value111>UPS Ground</option>").appendTo($("#ID"));取得下拉选单的选取值 $("#testSelect option:selected&…