首页 > 其他分享 >带你走进灵动岛

带你走进灵动岛

时间:2023-12-05 09:59:02浏览次数:21  
标签:走进 App activity 实时 灵动 Activity 推送

前言

iOS最近几年新特性

iOS14 视频画中画 AppLibrary 桌面小组件 照片隐私加强 应用限免 智能折叠 全新siri悬浮显示
iOS15 FaceTime支持屏幕共享 信息和新增拟我表情 推出专注模式 通知重新设计,图标变得更大 地图公共交通路线置顶,增加时间显示 识别图片上文字信息 支持照片信息和照片上的文字进行搜索
iOS16 iOS 16 锁定界面 锁定界面小组件 锁屏界面的实时活动 iPhone锁定全屏幕音乐播放器 电池百分比出来啦 视频实况文本 快速查询Wi-Fi密码
iOS17 设置您的待机屏幕 优先考虑交互式小部件 定制您的联系海报 创建您自己的贴纸 设置新的 Safari 配置文件 开启反追踪 分享您的 iCloud 钥匙串密码

一、简介

实时活动(Live Activity),是iOS16新增的扩展组件功能,可以在灵动岛和锁定屏幕上显示应用程序的实时数据。用于追踪事件和任务进度实时活动的开始和结束都是离散的,具体画面场景如下:苹果

苹果在 iPhone 14 Pro 及 iPhone 14 Pro MAX 上推出了灵动岛。灵动岛将 iPhone 前置镜头和软件通知结合在一起的全新设计,用出色的交互设计掩盖硬件的缺陷,是一次交互玩法的革新。灵动岛可以通过点按、长按、轻扫来进行交互,最多支持两个应用同时“登岛”。

灵动岛全称 Dynamic Island,作为 iOS 中实时活动(Live Activities)功能的一部分,用来展示需要实时更新的消息。例如外卖配送信息,地图实时导航信息等。灵动岛有 3 种展现形式。

1.1 展现形式

1.1.1 紧凑(Compact)

当系统只有 1 个实时活动的内容时,灵动岛默认使用紧凑模式。紧凑模式下UI由头部(Leading side)和尾部(Trailing side)组成,如图所示。用户可以点击灵动岛打开 App 查看实时活动的内容

1.1.2 最小化(Minimal)

当系统有多个实时活动的内容时,灵动岛自动切换使用最小化模式。最小化模式下由附着的头部(Leading(attached))和分割开的尾部(Trailing(detached))组成,如图所示。和紧凑模式一样,最小化模式也支持用户点击打开 App。

1.1.3扩展(Expanded)

当用户在紧凑或最小化模式轻扫或长按灵动岛时,灵动岛可以切换成扩展模式。用于向用户展示更多信息。扩展模式的 UI

设计尽量保持和紧凑模式一致,用户从紧凑模式切换到扩展模式会有一个平滑的体验。

当我们向 App Store 提交了适配灵动岛的 App 版本时,以上 3 种模式都需要适配。

二、场景限制

2.1样式限制

1、实时活动针对锁定屏幕和灵动岛提供了不同的视图。锁定屏幕可以出现在所有支持 iOS 16 的设备上。而灵动岛在支持设备上,使用以下视图显示实时活动:紧凑前视图、紧凑尾视图、最小视图和扩展视图。

2、当用户触摸灵动岛,且灵动岛中有紧凑或最小视图,同时实时活动更新时,会出现扩展视图。在不支持灵动岛的设备上,扩展视图显示为实时活动更新的横幅。

3、为确保系统可以在每个位置显示 App 的实时活动,开发者必须支持所有视图

建议:同场景多卡片由于样式趋同且折叠,不建议同时创建多卡片

灵动岛页面需要实现的部分有4个:

a、不支持灵动岛的机型 或 锁屏时的 显示

b、紧凑级展示(即左右贴合灵动岛的展示)

c、多Live activity时的展示(即极小视图,左贴合,右分离)

d、扩展视图(长按灵动岛时触发)

备注:还有一个App同时存在的实时活动面板最多只能创建5个,这也是一个场景约束条件。Error requesting delivery Live Activity The operation couldn’t be completed. Maximum number of activities for target already exists

2.2 时间限制

实时活动最多可以保持八小时的活动状态,除非其应用程序或人员在此限制之前结束活动。超过八小时限制后,系统自动结束直播活动,并立即将其移出动态岛。但是,实时活动会保留在锁定屏幕上,直到有人将其删除,或者在系统将其删除之前最多再保留四个小时(以先到者为准)。因此,实时活动在锁定屏幕上保留最多 12 小时。

官方表述:https://developer.apple.com/documentation/activitykit/displaying-live-data-with-live-activities

A Live Activity can be active for up to eight hours unless your app or a person ends it before this limit. After the 8-hour limit, the system automatically ends it. When a Live Activity ends, the system immediately removes it from the Dynamic Island. However, the Live Activity remains on the Lock Screen until a person removes it or for up to four additional hours before the system removes it — whichever comes first. As a result, a Live Activity remains on the Lock Screen for a maximum of twelve hours.

2.3 数据更新

每个实时活动运行在自己的沙盒中,与小组件不同的是,它无法访问网络或接收位置更新。若要更新实时活动的动态数据,少量(不能超过4KB)数据可通过远程推送通知发送,或通过ActivityKit 框架后台活动刷新数据。

ActivityKit 更新和 ActivityKit 推送通知的更新动态数据大小不能超过 4 KB。

2.4 网络限制

a、卡片本身禁止定位以及网络请求,数据刷新依赖本地刷新,实施活动推送刷新,同2)所述;

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

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

2.5 埋点限制

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

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

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

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

三、适配

3.1 UI适配

1、尺寸

目前只有 iPhone 14 Pro 及 iPhone 14 Pro MAX 具有灵动岛功能。在两种机型上,灵动岛的圆角半径都为 44Points,这个数值和前置深感摄像头的半径是一样的。按照前述的 3 种模式,灵动岛的具体参数如下表格所示(表格涉及的数值表示Points)。

机型 屏幕尺寸 紧凑模式(头部) 紧凑模式(尾部) 最小化模式 展开模式
iPhone 14 Pro 393*852 52.33*36.67 52.33*36.67 36.67*36.67 371*(84-160)
iPhone 14 Pro Max 430*932 62.33*36.67 62.33*36.67 36.67*36.67 408*(84-160)

2、颜色

开发者无法更改灵动岛的背景颜色,只能更改文字颜色、素材颜色、灵动岛边框颜色等。UI 适配需要考虑系统的深色模式,必要情况可以使用两套 UI。

3.2开发适配

3.2.1开发框架简介

苹果在 iOS 16.1 正式对外开放了灵动岛适配框架ActivityKit,第三方 App 可以使用这些ActivityKit完成灵动岛适配工作。注意ActivityKit的 API 目前仅适用于 iPhone。灵动岛使用WidgetKitSwiftUI完成 UI 开发工作,ActivityKit在其中扮演创建Activity,请求数据,更新数据,结束Activity的角色。

3.2.2权限管理

灵动岛作为实时活动的一部分,需要实时活动权限才能正常展示。和通知权限,相机权限等类似,实时活动权限需要 App

3.2.3 生命周期

Request

Update

Observe avtivity state

End

import ActivityKit

struct AdventureAttributes: ActivityAttributes {
//不可变
    let hero: EmojiRanger
    /// The associated type that describes the dynamic content of a Live Activity.
    ///
    /// The dynamic data of a Live Activity that's encoded by `ContentState` can't exceed 4KB.
    struct ContentState: Codable & Hashable {
        let currentHealthLevel: Double
        let eventDescription: String
    }
}





let adventure = AdventureAttributes(hero: hero)

let initialState = AdventureAttributes.ContentState(
    currentHealthLevel: hero.healthLevel,
    eventDescription: "Adventure has begun!"
)
let content = ActivityContent(state: initialState, staleDate: nil, relevanceScore: 0.0)

let activity = try Activity.request(
    attributes: adventure,
    content: content,
    pushType: nil
)





let heroName = activity.attributes.hero.name               
let contentState = AdventureAttributes.ContentState(
    currentHealthLevel: hero.healthLevel,
    eventDescription: "\(heroName) has taken a critical hit!"
)

var alertConfig = AlertConfiguration(
    title: "\(heroName) has taken a critical hit!",
    body: "Open the app and use a potion to heal \(heroName)",
    sound: .default
)  
     
activity.update(
    ActivityContent<AdventureAttributes.ContentState>(
        state: contentState,
        staleDate: nil
    ),
    alertConfiguration: alertConfig
)





// Observe activity state asynchronously
func observeActivity(activity: Activity<AdventureAttributes>) {
    Task {
        for await activityState in activity.activityStateUpdates {
            if activityState == .dismissed {
                self.cleanUpDismissedActivity()
            }
        }
    }
}

// Observe activity state synchronously
let activityState = activity.activityState
if activityState == .dismissed {
    self.cleanUpDismissedActivity()
}





let hero = activity.attributes.hero

let finalContent = AdventureAttributes.ContentState(
    currentHealthLevel: hero.healthLevel,
    eventDescription: "Adventure over! \(hero.name) has defeated the boss! Congrats!"
)

let dismissalPolicy: ActivityUIDismissalPolicy = .default

activity.end(
    ActivityContent(state: finalContent, staleDate: nil),
    dismissalPolicy: dismissalPolicy)
}

3.2.4UI



import WidgetKit
import SwiftUI

@main
struct EmojiRangersWidgetBundle: WidgetBundle {
    var body: some Widget {
        EmojiRangerWidget()
        LeaderboardWidget()
        AdventureActivityConfiguration()
    }
}





struct AdventureActivityConfiguration: Widget {
    var body: some WidgetConfiguration {
        ActivityConfiguration(for: AdventureAttributes.self) { context in
            // ...
            // Create the view that appears on the Lock Screen and as a
            // banner on the Home Screen of devices that don't support the
            // Dynamic Island.
        } dynamicIsland: { context in
 // Create the views that appear in the Dynamic Island.
            DynamicIsland {
                // Create the expanded view.
                // Leading region
                

                // Expanded region
                

                // Bottom region
                 
            } compactLeading: {
                // Create the compact leading view.
                // ...
            } compactTrailing: {
                // Create the compact trailing view.
                // ...
            } minimal: {
                // Create the minimal view.
                // ...
            }
        }
    }
}





四、远程通知更新数据

实时活动也支持远程推送更新,根据文档以下9点要求实现(avtivity远程推送每小时有通知预算(数量未明确),超出后系统将关闭通知)

1、确保启动activity时[request(attributes:contentState:pushType:)传入pushType参数(.token);

2、获取启动后的activity的推送令牌pushToken,传给服务端用来推送更新activity;(实时活动的pushToken不是消息通知的token,这个是独立出来的)

3、服务端推送的更新内容字段需要和ActivityAttributes的ContentState中定义的动态数据字段对应;

4、设置推送的报头apns-push-type的值为liveactivity;

5、设置推送的报头apns-topic的值为.push-type.liveactivity;

6、正确的推送对应的内容和状态;

7、使用pushTokenUpdates监听pushToken变化,如有变化,就令牌失效,需要将新的令牌传给服务器;

8、当Activity结束时,服务器端的pushToken将失效;

{
    "aps": {
        "timestamp": 1685952000,
        "event": "update",
        "content-state": {
            "currentHealthLevel": 0.0,
            "eventDescription": "Power Panda has been knocked down!"
        },
        "alert": {
            "title": "Power Panda is knocked down!",
            "body": "Use a potion to heal Power Panda!",
            "sound": "default"
        }
    }
}





注意:

1、不用为推送提供声音 , 如果推送延迟,在activity结束后收到时将被忽略,avtivity每小时有通知预算(数量未明确),超出后系统将关闭通知;

2、实时活动的pushToken不是消息通知的token,这个token上报到JDPush服务,需要单独管理和归类。

备注:

  1. 灵动岛的实时信息要有明确的开始和结束时间点

  2. 当一个实时信息持续超过 8 小时,系统会从灵动岛移除这个 App 的信息

  3. 当一个实时活动结束时,灵动岛上的展示信息也会立即被系统移除

  4. 避免在灵动岛上显示广告,毕竟引起用户反感可以被直接关闭

  5. App 要能够响应灵动岛的点击信息,跳转到 App 中的正确子页面,而不是停留在 App 的首页

运用场景

1、需在屏幕驻留的文字、图像为主的信息:如地图导航、airdrop 传输情况等;

2、后台进行的音频类:如接电话、放音乐、录音、倒计时等;

3、即时交互反馈:如充电、静音、人脸识别等。超过这三类信息后,桌面可能会变得杂乱无章

参考文章

ActivityKit官方文档

https://developer.apple.com/videos/play/wwdc2023/10194

https://developer.apple.com/videos/play/wwdc2023/10184

https://www.jianshu.com/p/f410eba6c392

https://www.bilibili.com/read/cv18549307/

作者:京东零售 李艳敏

来源:京东云开发者社区 转载请注明来源

标签:走进,App,activity,实时,灵动,Activity,推送
From: https://www.cnblogs.com/Jcloud/p/17876535.html

相关文章

  • 走进Java
    day1走进Java对于新手零基础的我想对自己说:​对于零基础的人学习Java这件事来说其实任何困难都不怕,比如总有人会问英语不好/理解慢/现在学晚不晚,其实持之以恒才是最关键的!没有坚持,一切学习都是白谈。​坚持的重要性不止在学习Java这条路上尤为关键,在其他方面的学习也是一样......
  • 鲸鸿动能广告联盟走进厦门,与开发者共道商业化新增长
    11月24日,以“聚势增长,合作共赢”为主题的鲸鸿动能广告联盟城市沙龙·厦门站顺利举行,这也是今年鲸鸿动能开发者城市沙龙系列的第二站。从流量运营、产品创新到广告体验,鲸鸿动能团队与开发者真诚分享,一起见证平台的飞速发展,共同探索流量商业化变现的当下和未来。截至目前,已经有600......
  • 苹果史上最大号平板要来了!iPad Pro 14.1外观出炉:首次用上灵动岛
    从去年6月份开始,就不断有消息称苹果在规划iPadPro14.1英寸超大屏版本。根据爆料人MajinBuOfficial的最新新消息,苹果将会在明年推出这款史上最大号iPad。同时还公布了新机渲染图,整体设计语言与iPhone15Pro高度一致,正面是灵动岛屏幕,背部则是三摄系统,图上展示的配色也与手机相......
  • RTOS中的“大事记”:事件组带你走进并发的奇妙世界!
    引言:嘿,RTOS的小伙伴们!你是不是有时候觉得任务之间的沟通有点麻烦,像是在用古老的通信方式?今天我们要介绍的主角是“事件组”——就像是任务之间的私密通信手段,让你的RTOS应用更加轻松愉快!在这次的“大事记”中,我们将探索事件组的神奇之处,揭开它与任务之间的联系!背景:在RTOS的大舞台......
  • 撒贝宁走进折叠宇宙:从折手机到折电视,玩转场景需求
    如果说过去几年折叠产品是少数人的玩具,那么今年,一个全民热捧的折叠宇宙正在形成。去年9月,央视名嘴撒贝宁拿着折叠手机,一屏看台本,一屏看新闻,掀起高端用户“折叠”潮流。今年,撒老师把可折叠激光电视“卷”进“新家”,从想用大屏激光电视看台本,到赏画、观影、娱乐,演绎出新时代人群对电......
  • 百家国企走进云投集团,探索世界500强数智化转型之路
    为深入推进国资国企数智化进程,加快世界一流企业建设,11月9日,由用友网络科技股份有限公司(简称:用友)与云南省投资控股集团有限公司(简称:云投集团)联合主办的“数智赋能国资创新——走进云投集团暨国资国企数智化转型创新论坛”成功举办!用友网络董事长兼CEO王文京,云投集团党委书记、董事......
  • 华润啤酒走进用友,数智化赋能酒业新世界
    11月8日,华润啤酒董事会主席侯孝海、华润啤酒首席财务官赵伟、华润啤酒智数部总监郭华、华润啤酒营运中心总经理曹志民等一行莅临用友产业园(北京)参观交流。用友网络董事长兼CEO王文京、用友网络高级副总裁吴平、用友网络助理总裁黄伟、用友网络BIP产品管理部总经理李惠苹、用友网络......
  • 华秋带您走进新一代产业园电子电路主题展
    一、主题背景介绍工信部、财政部近日联合印发《电子信息制造业2023—2024年稳增长行动方案》(简称《方案》),提出2023-2024年,计算机、通信和其他电子设备制造业增加值平均增速5%左右,电子信息制造业规模以上企业营业收入突破24万亿元。为贯彻落实《方案》精神,深圳新一代产业园积极组......
  • 走进网络安全
    今天分享我之前读《网络安全人才实战能力白皮书》2022年版本的整理思维导图,主要分4个方面:网络安全产业人才状况分析网络安全人才攻防实战能力分析网络安全人才攻防实战能力评价分析网络安全攻防实战经验分析我们走进哪个行业有必要了解行业情况,未来发展,值得花点时间了解。......
  • 东莞有许多家庭在这年选择了走进婚姻的殿堂
    婚姻是社会生活中的重要组成部分,而离婚则反映了家庭关系的变迁。根据广郡通数据平台提供的数据,2021年东莞的结婚登记对数为431对,离婚登记对数为264对。本文将探讨这些数字背后的趋势和影响,以及它们对社会和家庭的意义。结婚登记对数的增加通常反映了一定程度上的家庭稳定和社会......