http://benbeng.leanote.com/post/Handoff%E7%BC%96%E7%A8%8B%E6%8C%87%E5%8D%97-part1

关于Handoff

Handoff是iOS 8 和 OS X v10.10中引入的功能,可以让同一个用户在多台设备间传递项目。

Handoff能让用户从一台设备开始一个项目,然后切换至其他设备继续进行,这一切都是无缝的,每台设备都无需重新配置。例如,用户正在Mac上的Safari浏览一片长文章,随后他可以切换到附近一台已使用相同Apple ID 登入iCloud的iOS设备上,在这台iOS设备上的Safiri中继续浏览相同的网页,页面滚动的位置和原设备上的一样。

Apple的应用,比如Safari、邮件、地图、联系人、备忘录、日历和提醒事项,在iOS8 和 OS X v10.10中使用公共API来实现Handoff功能。第三方开发者也可以使用相同的API来在应用中实现Handoff,这些应用需要有同一个Team ID。此类应用必须通过App Store发布或者使用注册开发者签名。

Handoff交互

传递用户的活动包括3个阶段:

  • 为用户在你的app中的每一个活动创建一个user activity 对象。
  • 定期使用用户的最新信息更新user activity 对象。
  • 当用户请求时,在不同的设备上继续用户的活动。

基于文件的app(也就是基于NSDocument或者UIDocument子类的app)为Handoff的这3个阶段提供了内建支持。响应者对象(NSResponder和UIResponder的子类)为更新user activity和管理当前状态提供了内建支持。你的app可以直接创建、更新和继续user activity,特别是在app delegate中。

Handoff主要是依赖Foundation中的一个类NSUserActivity,该类支持UIKit和AppKit中的一小部分API。app将用户活动的信息封装在NSUserActivity对象中,这些activity就用来在其他设备上继续活动。特定user activity的Handoff需要最开始的应用把活动的NSUserActivity对象指定为当前activity,保存相关信息,然后把数据发给另一台设备。Handoff只在设备间传递能描述用户活动的必要信息,而大规模的数据同步则由iCloud来处理。

在“另一台”设备上,会通知用户有一项活动可以继续。如果用户选择继续该活动,系统会启动合适的app,并提供activity中的数据。user activity只能在与原app有相同Team ID 并且支持这种activity类型的app中继续。在app的Infp.plist中的NSUserActivityTypes键下可以设置支持的activity类型。所以,“另一台”设备选择启动哪个app是基于:目标Team ID,起始的NSUserActivity对象的activity type 属性,还可能包括activity对象的title属性。“另一台”设备上的app可以根据user activity对象中userInfo字典的内容来配置UI界面和状态,以实现用户活动的无缝切换。

另外,如果继续一个activity需要更多的数据,不能使用第一种传输机制来高效传输,那么resuming app可以让起始app的user activity对象在应用间打开流来传输更多数据。例如,用户正在写一封含有图片的电子邮件,那么最好的方法就是流来把这些数据传输到另一台设备上。更多信息参见Using Continuation Streams。

iOS和OS X中基于文件的app已自动支持Handoff,详见Supporting a User Activity in Document-Based Apps(本文内)。

User Activity对象

NSUserActivity对象封装了特定设备、特定应用中用户活动的状态,它是Handoff机制中主要的对象。起始app为每个它支持传递给另一台设备的用户活动创建一个user activity 对象。例如,网页浏览器会为每一个正在浏览网页的标签页或者窗口创建一个user activity 对象。但是只有在前台的标签页或者窗口对应的activity 对象才是当前有效的,只有当前有效的activity才能用于继续用户活动(continuation好难翻译。。。。。。。。)。

NSUserActivity对象通过它的activityType和title属性来区分。NSUserActivity的userInfo字典里有状态数据,它还有一个叫needsSave的脏标志(dirty flag)来支持delegete的延迟更新状态。NSUserActivity的方法addUserInfoEntriesFromDictionary:允许delegate和其他委托(clients)把状态数据合并到userInfo字典里。

更多信息参见NSUserActivity Class Reference。

User Activity Delegate

User activity delegate是一个遵从NSUserActivityDelegate协议的对象。它通常是app中顶层对象,比如view controller 或者app delegate。delegate管理着activity与app的交互。

NSUserActivity的delegate属性就是user activity delegate,负责更新NSUserActivity对象userInfo字典中的数据,以便它可以传递给另一台设备。当系统需要activity更新时,比如活动要在另一台设备上继续之前,系统会调用delegate的userActivityWillSave:方法。你可以实现这个回调来更新对象中承载数据的属性,例如userInfo、title等。一旦系统调用这个方法,它会把needsSave重置为NO。如果userInfo或者其他承载数据的属性又发生变化的话,把这个值改为YES。

另一方面,除了实现上面所说的delegate的userActivityWillSave:方法之外,你还可以让UIKit或者AppKit自动管理user activity。通过设置响应者对象的userActivity属性,并且实现响应者的updateUserActivityState:回调,app就会选择自动管理user activity,详见Managing a User Activity With Responders(本文内)。选择一个合适你的实现方法。(This arrangement is preferred if it works for your user activity.)

更多信息参见NSUserActivityDelegate Protocol Reference。

App框架支持

UIKit和AppKit在document、responder和app delegate中为Handoff提供了支持。尽管不同平台之间有一些细小的差别,但是允许app保存和恢复user activity的基本机制是相同的,API也是相同的。

在基于文件的app中支持User Activity

如果你在app的Info.plist里为每个CFBundleDocumentTypes入口添加一个NSUbiquitousDocumentUserActivityType键值对,这样iOS和OS X中基于文件的app就自动自动支持Handoff了。如果有这个键的话,NSDocument和UIDocument就会为特定文件类型的基于iCloud的文件,自动创建NSUserActivity对象。NSUbiquitousDocumentUserActivityType的值是一个字符串,表示NSUserActivity对象的activity type。也就是说,你为基于文件的app所支持的文件类型都提供了一个activity type。多个文件类型可以有同一个activity type。NSDocument和UIDocument会自动把fileURL属性放到activity对象userInfo字典的NSUserActivityDocumentURLKey键下。

在OS X中,如果app delegate方法application:continueUserActivity:restorationHandler:返回NO,或者没有实现,那么AppKit可以自动恢复用上面方式创建的NSUserActivity对象。在这种情况,文件会使用NSDocumentController的方法openDocumentWithContentsOfURL:display:completionHandler: 来打开,并且会收到一条restoreUserActivityState: 消息。

更多信息参见Adopting Handoff in Document-Based Apps、NSDocument Class Reference 和 UIDocument Class Reference。

用响应者来管理user activity

如果你把user activity设置为一个响应者对象的userActivity属性,UIKit 和 AppKit就可以管理user activity。当响应者知道activity的状态是已修改(dirty)时,它必须要把activity对象的needsSave属性置为YES。系统会在合适时机自动保存NSUserActivity对象,首先会通过回调updateUserActivityState:给响应者一个机会来更新activity的状态。你的响应者子类必须重写updateUserActivityState:方法来给user activity对象添加状态数据。如果多个响应者共用一个NSUserActivity对象,当系统更新user activity对象时,它们都会收到updateUserActivityState:回调。在更新回调发送之前,activity对象的userInfo字典会被清空。

在OS X中,NSUserActivity对象由AppKit管理,并与响应者相关联。根据main window 和响应者链,activity对象会自动变为当前有效,也就是在文件的window变为main window时。但是在iOS中,NSUserActivity对象由UIKit管理,你必须显式调用becomeCurrent或者当app进入前台时,给在视图层级中的UIViewController对象设置文件的NSUserActivity对象。

响应者可以把它的userActivity属性置为nil来断开与activity的关联。当一个由app框架管理的NSUserActivity对象没有关联的响应者和文件时,它就自动无效了。

更多信息参见Adopting Handoff in Responders、 NSResponder Class Reference 和UIResponder Class Reference。

使用app delegate来继续activity

在一个不是基于文件的app中,app delegate就是继续user activity的主要入口。当用户选择要继续一个activity时,Handoff会启动合适的app,然后给app delegate发送一条application:willContinueUserActivityWithType:消息。app让用户知道activity马上就可以继续。同时,当app delegate收到 application:continueUserActivity:restorationHandler: 消息时,NSUserActivity 对象会传递过来。你应该实现这个方法,通过user activity对象来恢复activity,配置app的界面。

application:continueUserActivity:restorationHandler:消息包括一个恢复处理block,如果你的app使用其他的响应者或者文件对象来恢复user activity,那你可以调用这个block。创建这些对象(如果已经有的话就不用创建了),传入block的NSarray参数中。系统会给每个对象发送一条restoreUserActivityState:消息,并传入user activity对象。每个对象可以用activity的userInfo数据来恢复。关于恢复处理block的更多信息,参见NSApplicationDelegate Protocol Reference中的application:continueUserActivity:restorationHandler: 方法。

如果你没有实现application:continueUserActivity:restorationHandler:方法或者返回NO,并且你的app是基于文件的,AppKit可以自动恢复activity,这在Supporting User Activity in Document-Based Apps中有描述。更多信息参见Continuing an Activity。

(第一部分完)

iOS Handoff编程指南相关推荐

  1. IOS并发编程指南:Dispatch Queue任务执行与Dispatch Source

    导读: 本文为读<Concurrency Programming Guide>笔记第三篇,在对OS X和iOS应用开发中实现任务异步执行的技术.注意事项.Operation与Dispatc ...

  2. iOS并发编程指南(3)

    Dispatch Sources 现代系统通常提供异步接口,允许应用向系统提交请求,然后在系统处理请求时应用可以继续处理自己的事情.Grand Central Dispatch正是基于这个基本行为而设 ...

  3. iOS VoiceOver编程指南

    前言 VoiceOver是苹果"读屏"技术的名称,属于辅助功能的一部分.VoiceOver可以读出屏幕上的信息,以帮助盲人进行人机交互. 这项技术在苹果的各个系统中都可以看到,OS ...

  4. iOS并发编程指南之同步

    1.gcd fmdb使用了gcd,它是通过 建立系列化的G-C-D队列 从多线程同时调用调用方法,GCD也会按它接收的块的顺序来执行. fmdb使用的是dispatch_sync,多线程调用a ser ...

  5. iOS开发:Core Animation编程指南

    关于Core Animation Core Animation是iOS与OS X平台上负责图形渲染与动画的基础设施.Core Animation可以动画视图和其他的可视元素.Core Animatio ...

  6. CoreAnimation编程指南(九)图层布局

    NSView提供了经典的"stuts and springs"模式,用于视图调整大小的时候把关联到它父图层的视图重新调整位置.图层支持该模式,而且Mac OS X上面的核心动画提供 ...

  7. [ISUX转译]iOS 8人机界面指南(一):UI设计基础

    糖箔糊2014.09.23 文章索引 1.1 为iOS而设计(Designing for iOS) 1.1.1 以内容为核心(Defer to Content) 1.1.2 保证清晰度(Provide ...

  8. iOS 8人机界面指南(一):UI设计基础

    [ISUX转译]iOS 8人机界面指南(一):UI设计基础 看看新闻网>看引擎>Tencent 1.1 为iOS而设计(Designing for iOS) iOS 的革新关键词如下: 遵 ...

  9. 《iOS编程指南》——导读

    本节书摘来自异步社区<iOS编程指南>一书中的目录,作者 [美]Alasdair Allan,更多章节内容可以访问云栖社区"异步社区"公众号查看 目 录 第 1 章 为 ...

最新文章

  1. jquery_jquery插件、jqueryUI使用方法、自定义jquery插件(一个插件其实就是一个功能)...
  2. Git代码管理常用命令操作
  3. VTK:PolyData之ColorCellsWithRGB
  4. 3. CMake 系列 - 分模块编译安装项目
  5. jsapi.php必须传openid,【微信统一支付】发起支付, returnCode != SUCCESS, returnMsg = JSAPI支付必须传openid...
  6. [JavaWeb-JavaScript]JavaScript_Function函数(方法)对象
  7. 程序员面试金典 - 面试题 17.09. 第 k 个数(set优先队列/DP)
  8. hihocoder234周 计算不包含黑点的矩形个数
  9. “使用 iNalyzer 分析应用程序的类结构”
  10. 行连接和列连接的区别
  11. Visual Studio 常用快捷键(一)
  12. Docker-mysql 安装
  13. 什么是相关性以及为什么需要初始化它?
  14. 【三维激光扫描】第四章:点云数据处理
  15. IPAM 开源IP地址管理系统部署
  16. 更换苹果推送服务证书Apple Push Services Certificate
  17. java swing企业人事管理系统 java swing mysql实现的企业人事管理系统源码和导入文档(1013)
  18. < span >标签的使用
  19. 阿里面试:“说一下从 url 输入到返回请求的过程”
  20. AndroidManifest.xml 最全详解(转载)

热门文章

  1. 即时通讯软件协议选择
  2. 2017全国计算机二级office考试时间,2017年全国计算机二级MS Office高级应用考试大纲...
  3. 谭浩强C程序设计第五版课后答案视频+代码讲解完整版(合集)持续跟新中~~~
  4. 真我手机会用鸿蒙系统吗,鸿蒙操作系统面世 华为称“把不可能变为可能”
  5. GBase 8c 函数和操作符 - HLL函数和操作符 之 聚合函数
  6. 企业智能组网——企业分支间网络互联高效解决方案
  7. 小容 app android,小容app
  8. Boost库学习笔记(4)—— Signals2
  9. SSM毕设项目基于线上考试系统t90ic(java+VUE+Mybatis+Maven+Mysql)
  10. 呼叫中心服务器类型,呼叫中心的多种分类