带你走进灵动岛

这篇具有很好参考价值的文章主要介绍了带你走进灵动岛。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

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/

作者:京东零售 李艳敏

来源:京东云开发者社区 转载请注明来源文章来源地址https://www.toymoban.com/news/detail-748479.html

到了这里,关于带你走进灵动岛的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vLive带你走进虚拟直播世界

    虚拟直播是什么? 虚拟直播是基于5G+实时渲染技术,在绿幕环境下拍摄画面,通过实时抠像、渲染与合成,再推流到直播平台的一种直播技术。尽管这种技术早已被影视工业所采用,但在全民化进程中却是困难重重,面临着克服相关技术难题。该技术的应用需要具备专业导演

    2023年04月20日
    浏览(31)
  • APISpace 带你一起走进西湖美景

    俗话说:“上有天堂,下有苏杭”。 “欲把西湖比西子,浓妆艳抹总相宜” 今天我就带大家走进杭州的西湖美景。自古以来,文人歌者面对西湖美景留下千古绝句,还以西湖为背景书写了一段段动人的爱情传说。 天生自带浪漫色彩的西湖如何画?是苏堤,是断桥,是岸边细

    2024年02月09日
    浏览(31)
  • 带你走进JAVA的世界|用心感受JAVA

    作者主页:paper jie的博客 本文作者:大家好,我是paper jie,感谢你阅读本文,欢迎一建三连哦。 本文录入于《JAVASE语法系列》专栏,本专栏是针对于大学生,编程小白精心打造的。笔者用重金(时间和精力)打造,将javaSE基础知识一网打尽,希望可以帮到读者们哦。 其他专栏

    2024年02月15日
    浏览(30)
  • 详解C++类&对象(上篇),带你走进C++

    目录 一,面向对象面向过程的认识(简单了解即可,逐步认识) 二, 类 2.1 类的引入  2.2 类的定义 1. struct  2. class  类的两种定义方式: 2.3 封装类的访问限定符  1. 封装概念 2. 类的访问限定符  2. 4 类的作用域 2. 5 类对象模型 1. 计算类大小 2. 类对象的存储方式 2.6  结构体

    2024年02月05日
    浏览(27)
  • 【C++ • STL】一文带你走进string

    ヾ(๑╹◡╹)ノ\\\" 人总要为过去的懒惰而付出代价 ヾ(๑╹◡╹)ノ\\\" STL (standard template libaray- 标准模板库 ):是C++标准库的 重要组成部分 ,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。 STL六大组件 开源的:linux、git、STL、mysql、安卓……【开源会发

    2024年02月09日
    浏览(29)
  • 一文带你走进软路由和 OpenWrt 系统

    先说说硬路由,顾名思义就是 通过专用硬件电路实现的路由器 。大家家里用的路由器(比如 TP-LINK、华为、水星等)基本都是硬路由,它们内部的硬件电路是专门为数据包转发和通信功能量身定制的,跑的固件程序也是厂商专门开发的,都不能通用。 软路由就是 通过软件系

    2024年02月09日
    浏览(35)
  • NodeJs 最近各版本特性汇总

    (预测未来最好的方法就是把它创造出来——尼葛洛庞帝) 官方链接 github链接 V8链接 Node.js发布于2009年5月,由Ryan Dahl开发,是一个基于Chrome V8引擎的JavaScript运行环境,使用了一个事件驱动、非阻塞式I/O模型, [1] 让JavaScript 运行在服务端的开发平台,它让JavaScript成为与PHP、

    2024年02月09日
    浏览(32)
  • 【C++杂货铺】一文带你走进RBTree

    红黑树是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是 Red 或 Black。通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出两倍,这句话换个意思就是:红黑树中最长路径不超过最短路径的 2 倍

    2024年02月08日
    浏览(32)
  • 一篇文章带你走进Java(保姆级)

    手打不易,希望对各位还在徘徊学什么语言的有帮助!!java不会让你失望!! Java是一种优秀的程序设计语言,它具有令人赏心悦目的语法和易于理解的语义。 Java还是有一系列计算机软件和规范形成的技术体系,这个技术体系提供了完整的用于软件开发和跨平台部署的支持

    2024年02月15日
    浏览(42)
  • 带你走进Java字符串的小世界

    目录 一. String 1. 什么是String 2. String常用构造器 3. 字符串的判断 4. 字符串的获取 5. 字符串的转换 6. 字符串比较和替换 7. 字符串的切割 二. StringBuffer与StringBuilder 2.1 关于StringBuffer 2.1.1 定义 2.1.2 构造方法 2.2 关于StringBuffer 三. StringJoiner的使用 四. 关于常量池的面试 🐼 个人

    2023年04月08日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包