一、布景
在 iOS16 上,苹果推出了实时活动 ( Live Activities ) 。实时活动能够出现在用户锁屏界面,并可实时展现用户关怀的一些中心信息。由于运用长途推送通道更新实时活动不需求主 app 坚持敞开,并且比较小组件需求用户手动添加到桌面这个门槛,实时活动功用是默许敞开的,所以这一机制保证了信息的触达概率会远高于小组件。
笔者认为,实时活动是一种更高档的推送形态,对比传统的推送,实时活动显得灵活许多。传统推进在用户接收并读取到内容的瞬间信息就失效了,假如想要为用户供给继续更新的信息需求依赖一条接一条的推送才能够完结,这无论从本钱仍是用户体会上,都是难以承受的。而实时活动则会在继续期间,无干扰的坚持着信息的更新,并且又会在适宜的机遇自行消失,因此用户体会极佳。
作为一家在线旅行产品渠道,咱们一直追求为用户供给极致的用户体会,在本年的上半年,咱们上线了依据实时活动开发的实时出行信息展现功用,用户能够在出行全周期内,经过锁屏或许灵动岛看到最新实时的出行信息。
依据线上计算,项目五月份上线至今,敞开实时活动的用户当中有一半用户已与该功用产生了交互,80%+的用户体会到了愈加快捷的出行信息展现。在用户体会提高方面,以上被覆盖到的用户会更及时地了解自己的出行进度及细节;在品牌提高方面,依据合适的场景对客户端各项新技能进行继续的接入,表现了咱们对用户出行体会的提高的尽力与考虑,一起也会大大添加用户对Qunar品牌的技能能力和服务的承受度与认可度。另外,现阶段实时活动项目首要覆盖了航班与火车的出行场景,标明着依据实时活动的出行信息实时展现的基础设施已搭建完结,后续还可低本钱接入船票、汽车票、景点门票等更多的事务线场景,为整个Qunar的产品生态供给助力。
本文旨在介绍实时活动的特性机制以及分享接入过程中的详细每一步细节,信任读完这篇文章,读者也能够对实时活动的适用场景有初步的了解,并顺畅地完结实时活动的接入,来为 APP 用户的体会带来巨大提高。
二、实时活动介绍
下面简略介绍一下 Live Acitivity 的原理和机制。在 iOS 16.0 版本的 SDK 中,苹果引入了实时活动功用, 它支撑用户在锁屏界面检查一些应用实时活动的更新。然后在后续的 iOS 16.1 SDK 中,实时活动支撑了灵动岛机型的展现,除了上述的锁屏界面,具有灵动岛的机型还会额外支撑灵动岛款式。
主 APP 会经过苹果供给的 ActivityKit SDK,来发动一个 Live Activity 实例,在发动时,能够经过 ActivityAttributes 对象进行初始化参数的传递,实时活动继续期间,还能够经过相似办法在主 APP 端触发实时活动的数据更新。一起,经过相关的设置,实时活动还能够脱离主 APP 的依赖,只经过苹果的推送服务(APNS)即可进行后续的数据更新。
不过这儿还需求额外说明一下,或许是苹果为了兼顾功耗与用户体会,实时活动仍是会存在以下的一些约束。
- Live Activities 小组件出现在锁屏之后会存在 8 小时,8 小时后实时活动会进入结束状况,不再接收数据更新。灵动岛会消失,可是锁屏卡片会在锁屏上再存在 4 小时。
- 实时活动无法自主进行网络请求和方位更新,数据刷新需求依赖主 APP 或 PUSH。
- 每一次更新的数据不能超过 4KB。
- 动画会被系统过滤,例如 withAnimation(::) 等 Api 是无法收效的。
- 每一个 App 能够敞开多个 Live Activities ,每个设备能够一起敞开多个 App 的Live Activities ,一个用户同一时刻或许会抵达一个上限而敞开失败,因此在敞开、更新、结束每一个 Activities 时,检查功用是否可用以及是否操作成功非常的重要。
三、实时活动与iOS14 Widget的一些对比
在之前的 iOS 14 上,苹果还推出过桌面小组件的功用,与实时活动比较,它们之间是有一些相似之处的,比方都是一个脱离主 APP 独立运行的功用,经过一个卡片来展现一些中心信息。可是仔细比较的话,它们仍是存在一些差异,这些差异也决定了它们适用于不同的运用场景,期望读者经过这些对比对实时活动的运用场景有更明晰的了解。
四、需求介绍
此次咱们需求上线的功用是,当用户在出行周期内,可经过实时活动检查出行的中心信息,以火车票事务为例,用户在发车前可经过锁屏或许灵动岛,实时检查检票口信息、正晚点信息、列车状况,在旅程中可检查行将抵达站点,到站后假如需求中转则可检查中转信息,然后完结出行全周期的信息展现。
这个需求描绘起来比较简略,可是触及细节的话会遇到以下的一些问题:
1.用户何时应该展现实时活动?
2.最新的行程数据怎么保证实时更新至实时活动?
3.PUSH 通道怎么下发给指定用户他所需求的信息?
4.实时活动怎么完结及时封闭?
带着这些问题,咱们对整个需求的完结进行了以下的规划。
五、方案规划
首要,咱们梳理出了整个需求中的人物及相关责任,来完结整个事务的完结。
- 订单中心,经过订单中心咱们能够获取到用户与出行产品的绑定联系,然后决定向指定用户推送指定的行程信息。
- 各事务线,需求监控各个行程所属事务的信息,如机票需求重视航变信息,登机口信息,火车票需求监控检票口、登车时刻等。
- 触达渠道相关事务,各个事务线(如机票、火车票)会在适宜的机遇经过 QMQ 音讯行列向触达渠道同步最新出行信息,由触达渠道来进行最新出行信息的下发。
- 客户端,在主 APP 侧,需求发动/更新/封闭实时活动组件,获取 pushToken 并向后端同步;在实时活动组件侧,需求接收到数据后进行相应信息的展现。
- PUSH 通道,需求向触达渠道供给下发实时活动类型的 PUSH 数据的能力,以支撑实时活动组件不依赖主 APP 来坚持信息更新。
功用层级如下图所示:
实时活动发动后,开发者能够获取到当前实施活动的实例 id ,经过该实例能够获取当前展现的数据及实时活动的运行状况等信息,推迟数百 ms 后,能够收到用来针对该实时活动进行推送更新的 push toke n,这儿有个细节,由于服务端是经过用户 id 而不是 push tokon 来进行的最新行程信息的下发,所以需求客户端在获取到 push token 之后进行一次用户 id + push token 的绑定联系同步,这样后续假如有行程数据的更新,会经过用户ID获取到当前可用的 PushToken,然后完结 Push 数据的下发。
六、实时活动接入完结
接下来说一下客户端的接入实时活动的详细细节,这个部分我放了一些详细的代码,期望能够经过借助对代码中各个 API 以及参数的说明,让读者对接入的流程有更直观的了解。
发动实时活动
在主 APP 代码中,引入 ActivityKit ,为了传递初始化数据及后续更新数据,咱们需求首要界说一个数据模型类,继承自 ActivityAttributes 。
另外在发动实时活动前,最好要做一下实时活动权限的判别,避免后续无含义的逻辑。
经过调用 ActivityKit 中的 request(attributes: contentState: pushType:) 办法,能够发动实时活动,接下来咱们逐一解释一下各个参数的含义。
- attributes 是实时活动的初始值,后续不行更新。
- contentState 是可刷新数据的实例,实时活动发动后,后续可经过相关 API 传入新的ContentState 实例来进行实时活动内容的更新。
- pushType 是指定实时活动是否经过长途推送通知接收其动态内容的更新,传入PushType.token会支撑长途推送更新,传入 nil 则只能接收 APP 触发的内容更新。
更新实时活动
实时活动发动后,假如想要实时更新展现内容,有以下两个途径:
1.主 APP 在前台经过 update(using:) API 将封装最新的信息 ContentState 实例传递给实时活动,然后触发实时活动的数据更新,或许主 APP 具有后台权限也可在后台时运用此 API 进行内容更新,可是 iOS 对后台权限约束较多,只在导航、音乐这种场景下才会开放给开发者,大部分 APP 不适用此情况。参阅代码如下:
封闭实时活动
假如想要封闭实时活动,有以下两种办法:
1.主 APP 调用 end(dismissalPolicy:) 办法封闭指定的实时活动实例,这儿能够经过封闭策略参数来操控是当即移除仍是指定时刻后移除,假如挑选默许选项,系统会在 4 小时后进行实时活动的移除。可参阅以下代码:
实时活动推送装备
假如实时活动确定要接入推送能力,以下是需求咱们做的:
-
保证 APP 的推送证书是依据 token 的认证办法 (Token-Based) ,假如现有的认证办法是依据证书的,则需求推送事务来改形成 Token-Based 的。
-
客户端获取实时活动的 PushToken。需求留意的是,推送时运用的 Token 并非App 发动时经过 UIApplication 注册时所取得的 Device Token,而是实时活动发动之后,经过监听实时活动的实例回调(pushTokenUpdates)来获取到的。客户端获取到 PushToken 之后,需求将 PushToken 同步给服务器,这样后续假如有新的信息需求下发,服务器经过该 PushToken 来进行推送操作即可。
七、开发过程中的一些问题与考虑
数据中心形式
由于实时活动是无法自己进行网络请求的,UI 展现的数据来自主 APP 或许推送数据,所以能够把实时活动理解为一个时刻点数据流截面的展现。咱们发现,由于不必关怀数据的上下文,咱们能够经过保护一个数据中心并让一切的 UI 组件同享一份数据来用于 UI 展现。
详细的做法是,咱们在收到数据并供给锁屏卡片及灵动岛的回调中,完结数据解析并将接收到的数据同步到数据中心内,这样的一个好处是一切的 UI 组件在代码中不必再额外声明初始化的入参,直接拜访数据中心获取同享数据即可。
一起,由于苹果的实时活动 API 规划,当接收到数据更新时,必须要返回一个有用的视图用来烘托至锁屏页面及灵动岛,那假如这个数据是无效的怎么办?运用数据中心的形式则有用的避免了这个问题,当数据无效时,由于咱们还保存有上一个有用的数据,所以能够舍弃掉此次无效数据,并用上次有用数据来做兜底处理即可。
UI规划标准要求
依据官方文档说明,实时活动锁屏卡片宽度固定,高度在 84 到 160 像素之间依据内容高度调整;灵动岛拓宽视图与锁屏卡片宽高相似,可是规划时需求规避开灵动岛硬件区域。另外在实际开发中发现,灵动岛拓宽视图会在左、右、底部方向存在约 13 像素的边线区域,规划时也需求留意避开。在投入开发前,最好提前与规划同学对相关的标准进行沟通,避免出现无法完结的问题。
各个形态的详细细节可参阅下图:
卡片消失时刻的操控
在规划之初,咱们计划在实时活动发动时就设置一个封闭的时刻,抵达指定时刻点后会主动移除。可是在调研中发现,现在实时活动并未供给相似的 API,这样会导致一旦发动实时活动后,假如用户封闭了 APP ,实时活动将无法操控它的封闭时刻。终究咱们运用了 PUSH 能力来更新数据,在适宜的机遇触达渠道服务会下发 end 类型的 PUSH 数据来封闭实时活动。
实时活动推送的模拟
在开发过程中,需求经过 PUSH 来测试触发数据更新,假如没有联调环境的话,能够本地经过脚本工具来进行模拟推送的下发,以下是咱们运用的脚本部分内容,供咱们参阅:
怎么进行实时活动代码的断点调试
开发中,假如遇到需求断点调试实时活动来进行问题定位的情况,能够依照如下流程进行:
1.模拟器或许真机发动主 APP ,在 XCode 中的 Debug 菜单中找到相应实时活动的Extention Target 的进程进行 Attach
跳转处理
在 WidgetKit 中,经过 widgetURL(_ url: URL?) API 能够进行点击跳转链接的绑定,假如直接绑定跳转的落地页,会不便于实时活动的跳转的计算与监控,因此咱们对一切的跳转链接进行了二次包装,经过统一格式的 Scheme 进行收口后再进行真正落地页的跳转。
用户点击实时活动调起客户端后,会走到统一分发的逻辑,在这儿咱们处理数据埋点、页面重置(避免用户重复点击实时活动导致页面栈里堆叠多个相同的页面)、落地页 scheme 复原等相关事务逻辑。
八、结语
以上便是 Qunar 大客户端接入实时活动过程中的一些规划、接入细节及相关考虑,现在已经有许多 APP 已经陆续接入了实时活动的功用,假如在适宜的场景中,用户在运用咱们的服务时突然发现这个小小的功用,能展现他此刻正重视的内容,无疑会为产品增色不少,也能在一众竞品中脱颖而出。期望本文能为热爱技能、信任技能的你带来一些启示和帮助,咱们也会为带给用户极致的出行体会,不断探索。
以上便是本次分享的一切内容,最后为咱们带来一个内推信息,欢迎优秀的你参加驼厂~
【内推链接】:app.mokahr.com/recommendat…