0.前言
今年有幸和同事一起参加了WWDC2018大会,于是在回来之后,自然而然的需要进行小量的汇报工作和经历分享。我记得在我的分享主题中,着重的介绍了其中我认为比较有用的且最可能需要适配的两个功能Siri Shortcut
和Group Notification
。
在分享之后,iOS12的适配工作也开始了,于是很自然的这个活儿到了我的手里=。= 从现在来看,这真的是一段弥足珍贵且十分感人的过程。终于可以坐下来好好总结一下这段时间的适配工作了。
1.Group Notification
理想很美好,现实很残酷
分组通知讲道理是我个人非常喜欢的一个更新,终于不用再滑那一面一面的通知了,But
很遗憾,我们还是能够通过某种手段来实现不分组一条一条展示的样子。。。在适配的时候,我也曾问过组织,这个分组,是否有限制?或者是否有一个模糊的限制?答案也是含糊的,“推荐”使用你的app中核心的通知分类来进行分组。也就是现在当iOS12
正式出来之后,我们看到的某乎啊等一些的app,我们会惊喜的发现,我擦勒,竟然是:‘One Notification,One Group’
.讲道理内心是拒绝的,但是换个角度思考,显然这也是产品层面的压力导致的钻篓子,打擦边球了。
实现Group Notification
说起实现,客户端本身一般是没有工作量的,更多的是app的push后台来进行相应的开发和适配。原因在于如何分组的机制,是通过增加三个新key
来实现。分别是:
- thread-id 标识分组id,这个字段用来系统识别分组来使用,例如“体育”“娱乐”等
- summary-arg 标识相关者,系统识别来显示通知下方信息条,例如:还有来自“梅西”的通知
- summary-arg-count 标识相关者所关联的通知数量,例如:还有十个来自“梅西”通知
2.Siri Shortcut
Siri更懂手机前的你,手机后是一脸懵逼的我
这个功能大概是CarPlay
支持高德等第三方导航之外收获掌声最多的一个新功能了吧。早前苹果收购了workflow
就或多或少的预感到Siri+捷径
是一条很炫酷的路线。
对于我来说也是第一次接触SiriKit
的相关开发,之前并没有接触过,不过其实并不影响适配任务,大部分反正也都是在摸索,坑是挺多的,但是结果还算满意。
(1)了解Siri Shortcut的整个行为
我们需要去创造一个捷径,那首先我们就要定义这个捷径的含义。
因为这个新功能是让用户能够通过Siri
智能的猜测出下一步的行为并给与提示,或者一句话做完一件曾经需要好几个步骤的事情。而在我需要适配的app内,由于客户端目前的功能已经十分的繁多,因此为一些热门功能,入口又比较深的功能定义捷径就显得很有必要了,而且使用场景也非常的契合。想想一下用户可以通过唤醒Siri
来直接打开某些栏目,或者直接收听音频,岂不是美滋滋。
下图其实是从宏观上描述了一个捷径的整个Create
过程
Create Shortcut所需要的媒介:
- 1.NSUserActivity
- 2.Intents
之前如果有开发过Handoff
功能的同学一定不陌生NSUserActivity
,通过它来实现Shortcut相对来说比较简单,对于那种需要通过打开客户端来完成后续动作和任务的捷径来说很合适。而Intents
苹果推荐的更多的是不需要打开客户端的Action
。我在这次适配的过程中,为了方便统一和维护,在适配的三个捷径的实现方式中,都使用到的是Intents
来实现,因此后文主要介绍这个方式的捷径设计和实现。
(2)定义Intent
创建Intent工程文件:
在下图中可以看到,已经内置了一部分现成的Intent来供我们使用,这次在demo中准备使用Play Media Intent
来实现Siri
唤起客户端音频这个功能。
除了使用Custom System Intent
之外,我们还可以自定义自己需要的纯正Custom Intent
。如图我创建了一个打开弹窗的意图:
到这里,定义Intent客户端文件的工作就完成了,准备好告诉Siri
了。
在demo
中我定义了一个基础模型,来和未来的业解耦SiriShortcutIntentModel
,只包含两个必备的属性:
播放音频的SiriShortcutMediaItemModel
model:
(3)Donate Intent
苹果这里用了一个很生动的词儿Donate
,相当于用户在触发了上文我们定义的意图的时候,我们来告诉Siri
用户触发了这个意图是什么样子的,也就是这个意图的参数是什么,Siri
会根据你的Donate
信息来正确的判断出用户意图,来充分的预测下一次想要进行这个意图的时间,Donate
越充分,这个预测模型就越强壮,当然这里也不用担心用户隐私数据的问题,苹果可反复的在承诺这是一个本地用户模型的创建和模拟。
当然这个Donate
的时机也很重要,用苹果的话叫做真正要告诉Siri
的时候再告诉,不要滥用。虽然“滥用”看上去貌似没有什么致命的或者非法的影响=。=
Demo
中简单的将Donate
时机放在了程序启动的时候。
(3.1)贡献Intent的方法形如:
initWithMediaItems
可以理解专辑内的歌曲们,mediaContainer
理解为专辑名称。
(3.3)然后实现Donate
系统方法:
到这里我们理论上就已经告诉系统用户这个意图了,Siri
就会知道,哦,这个时间,用户播放了XXX歌单里边的XXX歌曲们了。
(4)Handle Intent
贡献上去的Intent
看似是无形的,对于我们开发阶段来说需要大概率的看到自己贡献出去的意图,Siri
会如何的展现给用户,因此这里可以通过下边的设置来达到目的 手机设置
-开发者
中打开如图几个选项:
这么一顿操作之后,就可以在锁屏
或者spotlight
里边轻松的发现我们贡献过的Intent
了,从而快速的联调和开发。
当然这个时候点击播放按钮或者整条的Siri
推荐都是直接打开客户端的,并且是进入到首页什么事儿都不会做的,那是因为还没有去Handle Intent
。这里就需要我们自定义的CustomIntentUI
和CustomIntent
了。
(4.1)新建两个Target:
- CustomIntentUI:负责自定义的Siri反馈UI显示的
- CustomIntent:负责自定义的Intent Handle
(4.2)Custom Intent:
在CustomIntent中,需要实现的是INPlayMediaIntentHandling
协议
当然不同的内置Intent
是需要实现不同的协议的,当我们新建一个Custom Intent
模板自带的就是信息的内置Intent
以及他的协议:
回调返回:
这里使用的是需要在主客户端处理,因为一定的客观原因,实际工作工程暂时还没有sharegroup
的内容,因此请求网络、播放音频等操作,还是要交给主客户端,如果你的app这方面很成熟了,就可以不这么做了。
由于我们需要主客户端来处理Intent
的相应,因此在主客户端的App Delegate
中还需要额外的操作,实现下面的这个代理方法,否则是无法正确处理的:
在这个方法中,我们可以进行INPlayMediaIntent
解析,并进行网络请求来播放最新一期的音频等,最后在回调中记得告诉Siri处理成功与否:
(4.3)Custom Intent UI:
Prepare your view controller for the interaction to handle.
到这里,完整的INPlayMediaIntent
创建和反馈基本上都做好了,剩下的就是自定义的UI了,默认如果我们不新建Custom Intent UI
的话,系统会给一个默认的信息面板给用户一个应用icon+Title+subTitle,组合方式根据Intent
参数来,很灵活。主要的自定义UI的代码写在这里:
生命周期在整个Intent
响应期间,因此会多次调用上面这个方法,我们可以根据给的当前状态来配置相应的UI。状态的获取:interaction.intentHandlingStatus
。最后回调中配置每一次状态的UI高度:
(4.4)Bug Reporter 1:
这里顺带提到了一个已知的问题,已经提交了Radar,编号:44375523,问题描述:
概括来说就是当使用Siri
来唤起UI的时候,会收不到intentHandlingStatusSuccess
状态=。=
这样的问题就是会造成不同场景下Custom UI
反应不一致,截止到目前来看,新的Beta SDK依然没有解决掉这个问题。
3.新组件
这是一个船新控件,绑定Intent
可以直接在点击中出现添加ShortCut
的组件,由于是苹果自己的控件,因此很推荐使用这个按钮。
样式有四种:
demo中有罗列,只管看上去就是下图的样子,第一个没有边框,和背景色白色重叠,最后一个看不到边框是内部的黑色和边框视觉上很难分清:
协议可以做的事情其实就两种:
- present Add Voice ShortcutVC
- present Edit Voice ShortcutVC
(1.3)本地化
在自己工程内本地化文件中相应的添加对应字符串就可以了。苹果给的本地化推荐字符串如下:
(2):INUIAddVoiceShortcutViewController
这个新出的VC和在iPhone-设置-Siri
中添加Shortcut
的页面一致,辅助客户端可以在内部就可以唤起,并直接添加相关的语音捷径,不需要用户再跳去设置页面,这样用户就可以在感兴趣的客户端内容中方便的添加。
这里要注意的是一定要实现Delegate
否则添加完语音,无论是Done
还是Cancel
都会崩溃:
而且这个内置页是不会随着用户的交互自己消失的,需要自己在代理回调中dismiss
掉。
(3):INUIEditVoiceShortcutViewController
编辑VC和添加VC很像,不同的是实现的代理不同,需要注意一下。
我们以点击第二个Add To Siri
按钮为例:
点击添加:
添加完成之后按钮变化:
点击添加过的按钮,出编辑VC:
4.支持Siri Watch Face
这就需要另一个Shortcut
来实现了:INRelevantShortcut
我们在贡献这个Shortcut
的时候可以给系统参考的东西比较丰富了,我们可以创建不同的Provider
,例如地点的、时间的甚至是日常活动的,这个东西理解起来比较抽象,或者说比较机器。
- INDateRelevanceProvider 用户每周四都会买一本体坛周刊,这个周四,就可以作为一个维度来给siri来预测
- INLocationRelevanceProvider 用户每次到北京,都是来出差的,这种case就可以将北京传给系统
- INDailyRoutineRelevanceProvider 这个我觉得是应用场景最多的了一个了,我在工程适配的时候使用的是
INDailyRoutineSituationMorning
注意这里的早中晚啊并不是时区上的早中晚,而是针对这个手机前的人来讲,比如我可能每天十点半才起床,那十点半就是我的INDailyRoutineSituationMorning
我们还可以定制Siri watch face
的样式,这个和Custom Intent UI
很类似,如果我们不设置的话,系统会给我们一个模板来展示。
最后设置到INRelevantShortcutStore
万事大吉:
5.其他比较有用的Tips
(1):获取当前App添加的所有Siri 捷径
INVoiceShortcutCenter
提供了一个方法给我们来获取当前App
一共添加了多少条Siri
语音捷径:
handler
:
我们通过这个方法可以间接的获取我们某一个Intent
的语音捷径条数了,或者判断某一个Intent
是否被用户添加过相关的语音捷径:
(2):本地化
适配版本的前几个版本提交审核前的打包上传这一步做完之后,总是会收到一封邮件,大概意思就是我们所定义的Custom Intent
没有进行本地化,虽然不会影响暂时的打包和提交审核,但是也是不推荐的,需要我们去做:
这玩意研究半天,实验了几次打包才没有了这种邮件警告=。=,具体的做法是在右边编辑面板这里选择本地化按钮:
然后选择你的工程内的主语言:
然后在右边面板内继续勾上工程所需要本地化的语言,比如粤语等,最后我们会看到原来的intentdefinition
文件左边多了一个箭头,可以打开看到增加的本地化语言:
左边我的理解是一个唯一标示吧,右边是相应语言的本地化文字。
(3): Watch新icon的添加
最近的几次提交会收到一封邮件,大致上是说Watch App
缺少watch series4
的icon,我们缺少的是这两个
(4)小插曲:尝试修复Xcode10打包出来的在iOS9.0-9.2崩溃的问题:
核心方法:
ln -s Xcode9的ibtoold路径 Xcode10的ibtoold路径
0.需要同时安装Xcode9和Xcode10.
1.定位到Xcode10 ibtoold 路径下 把这个文件随便改个名字例如
ibtoold.bat
2.Xcode10 ibtoold 路径:/Users/JerryLiu/Downloads/Xcode.app/Contents/Developer/usr/bin/ibtoold
3.Xcode9 ibtoold 路径:/Users/JerryLiu/Downloads/Xcode\2.app/Contents/Developer/usr/bin/ibtoold
4.执行:ln -s Xcode9的ibtoold路径 Xcode10的ibtoold路径
ln -s /Users/JerryLiu/Downloads/Xcode\2.app/Contents/Developer/usr/bin/ibtoold /Users/JerryLiu/Downloads/Xcode.app/Contents/Developer/usr/bin/ibtoold
5.如果代表正确设置了:
6.注意的是,无法将Xcode10 关于iOS12、watchOS5等新SDK的UI(通过storyboard添加的UI:例如nowplayingView)打包成功,需要舍弃。
会报如下错误:
6.小结
其实参与过适配或者,新Feature
调研开发的同学都应该知道这条路就是一条很寂寞的道路,前期资源太少,而恰恰这个时候苹果爸爸那里的工具又不是很稳定,从下面图可以看得出来,iOS12
经历了多少磨难方才和大家见面:
别看Xcode10 才出到beta 6,但是讲道理尽管是到了GM
版本,依然存在问题是不争的事实,甚至是包括致命的iOS9
崩溃问题,要知道在国内,低版本不升级的iOS
系统还是很多的,根本就不可能舍弃这一部分的用户。
另一方面,诸如Siri Shortcut
的新功能的适配仿佛大家都比较滞后,或者说其实很多人遇到了和我一样的问题,只是没有听到过或者查到过,我印象中比较深的是,第二天iOS12
就要释放了,这个时候我却发现了一个bug,并提交了Radar,那这么说,我遇到的已经算比较晚的了,竟然没有被修复或者优化。
以上种种,都不能去忽视Siri
的越来越强大,我也相信随着真正的用户角度的Intent
越来越多,使用Siri
来方便自己生活的人会越来越多,App也会更加的强壮。💪 就这么多吧,应该还会有一些适配的细节忘记了没有说,如果想起来了,再回来补充,也祝大家适配顺利~早日上线!