iOS7 多任务管理

本文主要是看了WWDC 2013 - Session 204 - What's New with Multitasking 做出的翻译和总结, 文字/视频链接如下

文字链接 : 文字
视频链接 : 视频


该session主要讲的是iOS7比iOS6在多任务管理上新增了这些API.

  • 后台应用刷新
  • 远程推送
  • 后台传输服务

iOS6的时候, 尽管你锁屏了, 一些程序的后台任务也会继续运行直到完成.

iOS7的时候做了改进, 锁屏之后手机很快就会进入睡眠状态, 任务就会被挂起 但是, 当手机被唤醒了, 例如在看邮件的时候, 你的应用程序就能利用这些时间片去继续执行后台任务.

iOS7之后, 建议使用NSURLSession.

应用程序进入后台后仍然有几分钟的时间可以处理任务, 但是这几分钟不保证是连续的. 也就是说有可能会被强行中断, 例如内存不足的时候系统会杀死后台应用程序.

新概念 :
App Switcher, app在进入后台之前系统会先拍个快照, 这样你在切换应用程序的界面就会看到退出时的app的界面. 这种行为为 : State Restoration

App Switcher

需要注意的是 : 在App Switch划走app在iOS6的时候只会停止app runnning(仍处于Background状态), 而在iOS7则还会停止app running in the background. 所以现在一些使用到GPS或者实时位置更新的app在被划走之后这些功能就会停止运行, 你不会在后台收到任何通知.

首先, iOS7新增的多任务处理的API分为三大种

  1. Background Fetch : 后台获取, 供进入后台的app的能周期性地更新他的内容.

  2. Remote Notification : 远程通知, 当你发送一个很重要的通知时, 他能够从后台唤醒你的app. 例如即时通讯的消息等

  3. Background Transfer Service : 后台传输服务, 他允许在用户离开你的app后(回到桌面)通过自启动在后台队列中执行上传和下载任务.

后台应用刷新


后台应用刷新能保证每当你的app进入onFocus状态的时候用户看到的都是最新的内容, 而不是他们之前退出时(旧)的内容.

使用用法 :

  • 在info.plist中把Background Fetch这个key添加到UI background modes中.

  • 设置后台获取的minimum fetch interval, 最小时间间隔

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
    {
    
      /*
       * 默认是UIApplicationBackgroundFetchIntervalNever.
       */
      [application setMinimumBackgroundFetchInterval:3600];
    
      return YES;
    }
    
  • 当时间到了的时候, 你的应用程序将(launch/resume)调用以下方法. 你唯一需要做的就是实现这个方法, 发送网络请求, 接收响应数据并刷新UI.

    - (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
    {
          // go to fetch your new content here    
          // go to update UI here
          // 做完所有处理后一定要调用completionHandler block 告诉系统
    }
    

最小时间间隔

需要注意的是, 当你的应用是刚下载好的, 用户还没登陆时, 这个值应为never. 当用户登陆之后, 这个值可以告诉系统, 让系统在适当的时间间隔下启动你的应用并发起网络请求并更新UI(例如更新用户状态信息等). 当然, 如果用户退出登陆了, 你应该设置这个值为never.

例如你设置了5秒钟, 则代表app在退出到后台运行的5秒钟以内是不会调用该API的, 只有在5秒钟之后才有可能去获取数据. 也就是说, 应用在进入后台后的interval这个时间段内是不会被唤醒的.

问题来了, 这有什么用? 我肯定希望我的app任何时候都能自动更新然后每次用户进入我app的时候显示的都是最新的内容啊! 这么想就太自私了, 因为用户手机有电量, 流量等等各种限制. 例如, 抓取某几个地区的天气数据, 这是个很耗流量, 电量且耗服务器资源的操作, 此时你不会想每隔1分钟他就发起一个网络请求吧? 你会倾向于1个小时或者更长的时间去请求, 这能节省资源, 提高用户体验.

需要注意的是, 不应该把delegate方法中的completionHandler当做property存储起来再调用, 而是应该通过方法传递待完成后直接调用. 因为当后台刷新同时出现两次的时候, 第二次的block就会把第一次的block给覆盖掉(假如是用property存储的话), 那意味着第一次的block永远无法被调用. 切记!

当iOS系统中同一时间有多个后台获取任务的时候, 系统就能在一个时间段内处理这些任务, 而不是零零散散地处理, 那会加大电池损耗. 但是一个时间段内的任务太多了也是会增大电量的损耗的.

更为牛逼的是, iOS系统做了如此的优化. 他用一个observer观察用户真实的使用习惯, 例如我每天早上7点钟打开简书看文章, 每天中午12点打开简书, 每天晚上10点打开简书. 那么系统就会记录起这个模式. 之后就会尽可能在我打开app之前就做好这个后台应用刷新的工作.

optimize

如果我们不需要后台应用刷新的服务, 可以自行在设置 -> 通用 -> 后台应用刷新里关掉这个功能. 毕竟有时候我们真的电量不足了, 或是流量不够用了...

远程通知


当我发一个消息给我朋友的时候, 实际上是我先发给苹果的服务器, 然后苹果服务器再下发给我朋友的设备, 然后他才接收到消息/弹窗.

另外, 还能发一个Silent Notification(不带消息的通知), 他会在后台交付然后launch/resume你的app, 并执行一些你自定义的任务.

Silent Notification配置在这里

使用方法 :

  • 在info.plist中把remote-notification这个key添加到UI background modes中.

  • 当你发送一个远程通知之后, app就会被launch/resume

    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
    {
      // do something here
      // remember call completionHandler block when finished work
    }
    

然而, 通知发得太频繁的话, 你的设备和苹果的服务器会限制你的发送频率. 苹果的服务器会先把你的一些通知先存储起来, 过一会再推送给用户.

后台刷新和远程推送的区别

后台刷新 远程推送
内容重要性 有意思但是不太重要 需要立马让用户知道的
频率 非常频繁 偶尔
例子 新闻, 社交, 图片分享 即时信息, 同步内容, 稍后阅读

后台传输服务


iOS7后支持后台上传/下载. iOS会把你的上传/下载任务放在后台传输服务队列中, 当然与此同时你的app将会被唤醒, 以便处理任务执行过程中的任何突发事件, 并保证用户能第一时间知道这些情况.

使用的是NSURLSession而不是NSURLConnection. 他可以用NSURLSessionConfiguration来自定义该session的策略, 例如是否需要缓存, 超时等等. 显然, 他也会launch/resume你的app.

- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler
{
  // do something here
  // remember call completionHandler block when finished work
}

由于后台传输服务是多应用并行的, 所以你要用尽可能少的时间去做UI更新操作(少于一分钟), 同时也要保证CPU使用率不要太高. 用instrument中的Time Profile查看执行时间, 优化让CPU执行时间尽可能少.

一般来说人们会使用这个后台任务API来关闭数据库连接操作或者关闭句柄或者其他系统资源.

数据保护

NSFileProtection

  • completeProtection表示没锁屏的时候数据可正常访问, 锁屏以后数据全部不能访问.
  • None表示有没有锁屏都能正常访问.

在database, SQLite database方面我们一定要用completeProtection以保证安全.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,757评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,478评论 1 289
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,540评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,593评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,903评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,329评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,659评论 2 309
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,383评论 0 195
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,055评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,337评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,864评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,227评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,820评论 3 231
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,999评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,750评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,365评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,260评论 2 258

推荐阅读更多精彩内容