iOS7 多任务管理

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

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


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

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

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

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

iOS7之后, 建议使用NSURLSession.

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

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

iOS7 多任务管理_第1张图片
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之前就做好这个后台应用刷新的工作.

iOS7 多任务管理_第2张图片
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以保证安全.

你可能感兴趣的:(iOS7 多任务管理)