盒马 iOS Live Activity &“灵动岛”配送场景实践

本文涉及的产品
视频直播,500GB 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 盒马 iOS Live Activity &“灵动岛”配送场景实践

苹果在 WWDC22 中,提出了实时活动(Live Activity)的概念,以便于用户在锁屏查看一些应用实时活动的更新,这与盒马的配送场景十分贴合。因此,我们将 Live Activity & “灵动岛” 特性第一时间落地到盒马 30 分钟配送场景,并作为第一批适配实时活动的 iOS 应用,获得 App Store Today 推荐。

目前,盒马 App 适配“灵动岛”的最新 5.51.1 版本已正式上线,欢迎大家升级体验。在适配过程中,盒马 App 也在端侧踩过很多“坑”,特此汇总为实战经验分享给大家,欢迎交流。

落地效果

image.png

快速落地时间线

  • 6月16日,根据WWDC相关内容提前调研;
  • 8月16日,开始基于官方文档和beta版做demo;
  • 9月8日,登上Apple中国区官网;
  • 9月15日,iOS 16.1 beta开放,开始正式的需求流程;
  • 10月19日,iOS 16.1 RC上线,开始打包以及回归测验;
  • 10月20日,提交审核;
  • 10月22日,审核通过上架;
  • 10月25日,App Store Today推荐。

image.png

客户端技术方案

Live Activity&灵动岛简介

在介绍盒马最终落地技术方案之前,先给大家简单介绍一下Live Activity&灵动岛技术调研得出的一些关键信息及其比较适用的场景。

场景限制及建议

  1. 最多持续8小时,使用场景需要考虑,8小时之后无法再刷新(目前实际还可以,但是以官方文档为准,自行限制),12小时后强制消失(因此跨天场景不考虑)
  2. 创建时,需要app在前台主动创建,没启动应用的时候不能自己出现(与特定业务绑定,比如下单后显示)
  3. 卡片本身禁止定位以及网络请求,少量(4KB)数据可通过通知发送,或通过后台活动刷新数据
  4. 同场景多卡片由于样式趋同且折叠,不建议同时创建多卡片

灵动岛适配必要性

  • 与锁屏Live Activity共享数据,在支持灵动岛的机型下,用户在非锁屏页面时,信息的更新会以灵动岛的形式展示更新
  • Live Activity创建后,灵动岛就可以进行点击响应了,如果不适配的话,点击灵动岛会自动进入主程序,并且长按会变成一个没有任何信息的黑块
  • 盒马iPhone14 Pro以及 Pro Max用户占比逐渐升高

整体方案流程图

image.png

注意事项:

  • Live Activity有一个独立的权限,并且是不需要请求同意的,默认开启
  • 用户必须保持开始通知权限,才能通过通知刷新,后台活动不需要
  • 必须在应用处于前台时启动,相当于要主动触发
  • 数据更新时,系统自动适配动画,不需要自己额外添加动画(添加了也会被忽略)
  • 不支持在其中显示gif图片和网络图片
  • 可以设置响应页面,比如点击不同控件跳到不同页面,和widget类似

技术难点及策略

基于上述流程方案,我们在实际落地过程中也遇到一些问题,下面是核心问题和应对策略。

实时更新 - 通知刷新数据

更新方式有2种:

  1. 通过本地update方式在后台刷新数据,比如蓝牙、后台活动等。此方式要求主App进程必须存在,进程一旦杀掉就无法更新;
  2. 通过通知刷新的实时活动,需要通知为Token-Based,并且对请求的参数做新的扩展。此方式比较灵活,无需主App进程存在,更新及时,因此我们采用此方式。

监听并上报token

使用通知刷新的方式需要获取实时活动独立的pushToken,对比在Swift中通过Http请求的方式上报,这里考虑用block的方式,将Swift中的token丢回给主工程,由主工程负责上传token。

图片传入 - 非本地化图片

技术限制

因为Live Activity内部禁用网络图片,传统的服务端传图片URL的方式无法满足实际使用,但是希望传入订单图片来个性化地表达并且区分不同订单。

解决方案

iOS 16 beta版时可以通过创建时将图片转为Data格式传入卡片,但是iOS16.1该方案仅限传入4KB左右的图片(API限制),因此暂时不考虑非本地图片方案,采用内置图片方式实现。

机型适配 - 获取屏幕宽度问题

技术限制

iOS 16 beta版时,尝试使用UIScreen.main.bounds.width获取屏幕宽度,该方法在模拟器上可以正确获取,但是在真机上,得到值为0,导致无法进行适配。

解决方案

考虑在创建Live Activity时,直接从主工程将屏幕宽度作为起始属性传入其中,验证发现可行。

过渡动画 - 系统限制

Live Activity限制了自定义动画,在数据刷新时,系统自行进行过渡,这也导致了过渡时会出现一些问题。

卡片大小变化过渡问题及解决方案

如果通过设置整个View的.background,在变更整体Live Activity大小的时候,一开始会先把之后的区域框定,但是超出的部分颜色与自定义的背景是不一致的。

改之前(渐变背景为.background设置),有明显不同色的情况。

改之后(渐变背景为单独图层),变化时不再有颜色区别。

进度条长度变化过渡问题及解决方案

实际应用发现,通过mask实现的进度条,如果进度条变长,并没有过渡效果,而是直接跳到最终位置,因此考虑相反的进度条,就可以实现过渡效果。

埋点分析 - 点击跳转

由于默认情况点击是回主程序,而并不是固定页面,因此有必要自定义widgetUrl(如用于回到订单页面),也可以通过Link实现分区域的跳转,Link和widgetUrl共存时,点击Link区域会响应Link,因此两者同时使用即可。

技术限制

无法在widget内部直接添加埋点,并且灵动岛收起时,仅支持添加同一个widgetUrl,对于收起状态添加Link并没有响应。

解决方案

因为点击直接跳转到主App,因此考虑将埋点参数加入URL参数即可,主App解析时埋点。但是无法记录包括用户查看、用户关闭(关闭卡片 继续发送推送也没有报错 因此无法判断)等行为的埋点。

对于灵动岛的区分,实际测试发现,在展开模式下,可以加入Link并且可以正常响应,这与官方文档中的描述一致。

版本适配 - 与小镇widget共存

盒马App本来上线有小镇Widget,iOS 14即可支持,而Live Activity需要iOS 16.1,因此需要对两者做版本适配。

技术限制

  • Xcode 14beta不支持在Bundle内部区分版本,只能重新创建一个扩展;
  • Xcode 14.1支持在同一个widget Extension内部区分版本。但beta版发现使用了该方法,会导致两个widget都不出现,不使用则都可以正常使用,确认是当前版本bug。

解决方案

后置系统版本判断,在LiveActivityWidget内部去限制版本,成功使二者同时展现。

触发场景 - 前置判断

权限限制

系统版本:

  • 不支持iOS 16.1以下

没有权限:

  • 通知权限
  • 实时活动权限

前置权限限制判断,不满足以上条件时,不尝试创建Live Activity。

时间限制

送达时间超过8小时的场景不创建,因为创建后8小时就无法再刷新

异常场景

  • 已经存在了很多卡片,达到上限,创建时失败(返回创建结果,失败不进行后续推送)
  • 用户关闭卡片,应用无法感知(继续推送,也不会再显示)

触发提醒 - 疲劳度控制

锁屏提醒

实时活动的刷新支持静默刷新和提醒刷新,这就需要考虑用户疲劳度,并且灵动岛的展开提醒会比普通的通知屏占比更大,更容易影响到用户。

带有alert字段的通知会触发锁屏的亮起以及声音,在主屏幕时会展示灵动岛,不带有alert字段的通知,会静默更新,锁屏时不会亮起,息屏显示时也不会有动画过渡,直接显示后续进度。

特殊情况

事件类型为END的通知,即使带了alert,也不会触发提醒。如果需要的话,可以在此时发一条update。

对于不支持灵动岛的机型,添加alert字段,会在主屏幕中触发锁屏Live Activity样式的横幅通知,目前该横屏会常驻显示,但屏幕有新的任何用户点击都会直接被收起。

扩展能力 - 字段解析

技术限制

为了保证通知能正常解析,通知payload字段必须保证包含客户端定义的字段,若新版本加了新字段,服务端下发了新字段,老版本不会受到影响也可以正常解析。

原因:原生的解析方式,将通知中的JSON解析为对象,但是对于字段缺少的JSON,解析会失败,这时候无法成功刷新。

解决方案

考虑外部传入JSONString,内部进行单独解析,注意不要解析为对象,不然还是没法处理字段缺少的情况,直接解析为字典,字典内部再对各个属性判断,并将空的属性置为空值,widget内部再对应进行调整显示。

这样方式可以使各业务端只要传自己需要用到的字段即可,不必再传入空值。

相关文章
|
7月前
|
缓存 编解码 测试技术
基于iOS平台的高效图片处理技术实践
【4月更文挑战第7天】 在移动应用开发领域,图片处理是一个常见且要求高性能的功能模块。特别是在iOS平台上,由于其封闭的生态系统和用户对流畅体验的高期待,开发者需采用高效的图片处理技术以满足应用的性能需求。本文将探讨一种针对iOS平台优化的图片处理流程,涉及图像加载、缓存策略、异步处理以及图形渲染等关键技术点,旨在为iOS应用提供一个低内存消耗、高效率的图片处理解决方案。
|
1月前
|
安全 Swift iOS开发
Swift 与 UIKit 在 iOS 应用界面开发中的关键技术和实践方法
本文深入探讨了 Swift 与 UIKit 在 iOS 应用界面开发中的关键技术和实践方法。Swift 以其简洁、高效和类型安全的特点,结合 UIKit 丰富的组件和功能,为开发者提供了强大的工具。文章从 Swift 的语法优势、类型安全、编程模型以及与 UIKit 的集成,到 UIKit 的主要组件和功能,再到构建界面的实践技巧和实际案例分析,全面介绍了如何利用这些技术创建高质量的用户界面。
29 2
|
3月前
|
安全 Android开发 数据安全/隐私保护
探索安卓与iOS的安全性差异:技术深度分析与实践建议
本文旨在深入探讨并比较Android和iOS两大移动操作系统在安全性方面的不同之处。通过详细的技术分析,揭示两者在架构设计、权限管理、应用生态及更新机制等方面的安全特性。同时,针对这些差异提出针对性的实践建议,旨在为开发者和用户提供增强移动设备安全性的参考。
151 3
|
4月前
|
开发工具 数据安全/隐私保护 iOS开发
探索iOS应用开发的核心理念与实践
【8月更文挑战第23天】在数字时代的浪潮中,iOS应用开发不仅仅是技术的堆砌,更是一场关于创新、用户体验和持续改进的旅程。本文将深入探讨iOS应用开发的核心理念,从设计哲学到开发工具的选择,再到市场趋势的适应,旨在为开发者提供一条清晰的路径,帮助他们在不断变化的技术世界中保持竞争力和创新力。
|
7月前
|
API iOS开发 智能硬件
在iOS应用中使用实时活动与灵动岛
iOS16系统引入了实时活动与灵动岛相关的API。实时活动API能够让用户在桌面直接浏览到应用程序所提供的实时性较高的信息,例如比赛的比分信息,外卖的配送进度信息,票务信息等。在支持灵动岛的设备上,实时活动配合灵动岛,更是能带给用户沉浸式的信息获取体验,在某些特定应用场景下非常有用。
411 8
|
5月前
|
移动开发 开发工具 Android开发
探索安卓与iOS开发的差异:平台特性与编程实践
【7月更文挑战第8天】在移动开发的广阔天地中,安卓和iOS这两大操作系统各自占据着半壁江山。它们在用户界面设计、系统架构及开发工具上展现出截然不同的特色。本文将深入探讨这两个平台在技术实现和开发生态上的关键差异,并分享一些实用的开发技巧,旨在为跨平台开发者提供有价值的见解和建议。
|
6月前
|
安全 IDE Android开发
探索Android与iOS开发的差异:平台特性与编程实践
【6月更文挑战第17天】在移动应用开发的广阔天地中,Android和iOS两大平台各自占据半壁江山。它们在用户群体、系统架构以及开发环境上的差异,为开发者带来了不同的挑战和机遇。本文深入探讨了这两个平台在技术实现、界面设计、性能优化等方面的主要区别,并提供了实用的开发建议,旨在帮助开发者更好地理解各自平台的特性,从而创造出更加优秀的移动应用。
|
7月前
|
iOS开发 开发者 UED
iOS 中的并发编程:GCD 与 Operation 的对比与实践
【4月更文挑战第23天】 在iOS开发中,为了提高应用的性能和响应能力,理解并合理运用并发编程是至关重要的。本文将深入探讨两种主要的并发模式:Grand Central Dispatch (GCD) 和 NSOperation。我们将比较它们的优势和局限性,并通过代码示例演示如何在实际场景中应用这两种技术来优化应用性能。文章旨在为开发者提供一个清晰的指南,以便在选择适合自己项目的并发工具时做出明智的决策。
|
7月前
|
安全 开发工具 Swift
ios-class-guard - iOS代码混淆与加固实践
ios-class-guard - iOS代码混淆与加固实践
108 0
|
安全 开发工具 Swift
 ios-class-guard - iOS代码混淆与加固实践
然后在作者的回答中也有提到,PreEmptive Protection for iOS - Rename (or PPiOS-Rename),使用相同的原理,但是它将使用 iPhoneSimulator 支持 iPhoneOS SDK,但是经测试,该工具只能用于纯 OC 项目,并不支持 OC 与 Swift 混编的项目
下一篇
DataWorks