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. python调用c++传递数组
  2. 背包九讲之五(二维费用的背包问题)
  3. HTTP 错误 500.21 - Internal Server Error 处理程序“PageHandlerFactory-ISAPI-4.0_32bit”在其模块...
  4. MVC3实现多个按钮提交
  5. API接口设计之RESTful软件架构风格
  6. 一个网站的诞生- MagicDict未来予想図1 [水平分割数据表的构想]
  7. 6.Jenkins 权威指南 --- 高级构建
  8. 如何将MyEclipse开发的项目导入到Eclipse中运行
  9. 9、从命令行运行postman脚本及生成测试报告
  10. c语言中 临时变量的作用,C语言 临时变量不能作为函数的返回值?
  11. DSP28335学习——系统初始化
  12. DNF脚本完整源码编辑可用
  13. MYSQL统计收益排名
  14. Vision-and-Language Navigation: Interpreting visually-grounded navigation instructions in real env
  15. 联想拯救者u盘安装linux系统,联想拯救者Y7000 U盘装系统win8教程
  16. Codeforces Round 701 Multiples and Power Differences
  17. python建模库介绍:pandas与建模代码的结合,使用Patsy创建模型描述
  18. (附源码)pringboot餐饮点餐系统 毕业设计301749
  19. 火狐浏览器无法启动java_打开火狐浏览器出现错误
  20. 星际穿越-网易python(简单数学公式)

热门文章

  1. java弹球游戏代码_Java实现简单的弹球游戏
  2. 创意点亮产业未来,百度超级链XuperChain应用案例征集
  3. 在模板字符串中条件判断和遍历
  4. 云楚煌8600升降器
  5. 蓝牙耳机连接windows后断连关机
  6. 大作业,但是图片不会传
  7. YOLOv5s的模型训练与使用(纯小白入门)
  8. cpp程序设计学习与实验系统(c语言程序设计软件) 注册码,cpp程序设计学习与实验系统...
  9. 如何制作微信群群发软件
  10. CentOS搭建GitLab服务器