iOS灵动岛开发实践

背景

这篇文章主要做一个引导,以及开发过程中遇到的疑难点进行讲述。具体的实操部分网上已经很多文章,可以去找找。

开发灵动岛必看官方文档:

  1. 灵动岛设计开发规范 ,这篇文档你们UI和产品会需要,你也需要看一下,讲述了灵动岛的尺寸、样式等。《Live Activities
  2. 灵动岛开发指导 ,这篇文章主要讲解灵动岛的相关接口使用,开发必看。《Displaying live data with Live Activities

问题点

1、灵动岛和实时活动如何实现动画?

目前灵动岛和实时活动还不支持自定义动画,如果自己写了动画,会被系统强制屏蔽。但iOS17开始,可以使用时序曲线实现一些线性的动画效果,具体可以去了解一下。

2、如何屏蔽或者修改系统自带的模糊淡入和淡出的动画效果?

可以使用控件的转场动画.contentTransition()接口,对内容动画进行调整。注意.transition()和.contentTransition()方法的区别,.transition()方法是针对整个控件的转场动画,如果只是控件内容发生改变,不会有什么效果的;.contentTransition()是对内容的转场动画,比如更新Text的内容,就用到它。.identity屏蔽系统动画,还有其他枚举,可以调整动画显示的类型。

scss 复制代码
//屏蔽系统自带的动画淡入淡出效果
Text(context.state.time)
    .multilineTextAlignment(.center)
    .foregroundColor(context.state.color)
    .font(.system(size: 14).weight(.semibold))
    .padding(.trailing, 7)
    .contentTransition(.identity)
3、如何在灵动岛或者实时活动添加按钮?

iOS17及以上才支持添加按钮点击事件,在此之前添加按钮到灵动岛或者实时活动页上,点击按钮时,点击事件是不生效的,会直接打开App。

4、灵动岛/实时活动如何和主App进行通讯,传递事件或者数据?

灵动岛/实时活动和主App进行通讯,分为两个方向的数据传递:主App-->灵动岛灵动岛-->主App 。 讲这个前,首先我们要清楚一个前提:当主App被杀掉时(没运行的时候),灵动岛和实时活动仍然是可以展示和更新的,而灵动岛和实时活动作为一个小组件,并不知道主App的生命周期。因此灵动岛-->主App同步发送数据或事件这条链路是行不通的。 那问题来了,我们要怎么实现数据传递呢?无法同步实现,我们可以异步实现是不?

  • 主App-->灵动岛

这个链路就比较容易实现,苹果提供了相关的接口:

swift 复制代码
    /// 显示灵动岛和实时活动
    @objc public func show(title:String, time:String, islandIcon:String, islandColor:String, content:String, isRecording: Bool) {
        let attributes = CCityWidgetAttributes(title: title)
        let contentState = CCityWidgetAttributes.ContentState(time: time, islandIcon: islandIcon, islandColor: islandColor, content: content, isRecording: isRecording)
        do {
            activity = try Activity<CCityWidgetAttributes>.request(attributes: attributes, contentState: contentState, pushType: nil)
        } catch {
            print(error.localizedDescription)
        }
    }
    
    /// 更新灵动岛内容
    @objc public func update(time:String, islandIcon:String, islandColor:String, content:String, isRecording: Bool) {
        let contentState = CCityWidgetAttributes.ContentState(time: time, islandIcon: islandIcon, islandColor:islandColor, content: content, isRecording: isRecording)
        Task {
            await self.activity?.update(using: contentState)
        }
    }
    
    /// 结束灵动岛显示
    @objc public func end() {
        Task {
            for activity in Activity<CCityWidgetAttributes>.activities{
                await activity.end(dismissalPolicy: .immediate)
            }
        }
    }
swift 复制代码
@available(iOS 16.1, *)
struct CCityWidgetAttributes: ActivityAttributes {

    public struct ContentState: Codable, Hashable {
        // 动态属性,可以在update方法中更新的属性,需要一直更新的内容,可以放到ContentState中。
        var time: String
        var islandIcon: String
        var islandColor: String
        var content: String
        var isRecording: Bool
        
        var color: Color {
            return Color(hexString: islandColor)
        }
    }
    // 静态属性,只有在show的时候才会更新的属性,不变的属性放在这里
    var title: String
}
  • 灵动岛-->主App

这个链路目前苹果并没有提供直接同步传递数据的方式,因此是不支持这个链路的数据通讯的。但是我们可以使用共享沙盒目录进行数据传递,即当用户点击灵动岛或者实时活动中的按钮时,将状态或者数据保存到共享沙盒中,然后当唤起主App时,主App读取沙盒中的数据,实现数据传递。相关逻辑可以参考《APP Extension 与 APP之间的数据共享》。

当然网上还有其他方案,比如通过本地socket进行数据发送来实现通讯,大致思路就是小组件和主App,作为socket的两端,相互发送数据来实现通讯,但是那样太重,没这必要。至于其他方式基本都被苹果禁用掉了,苹果也拒绝使用其他非常规手段,建议不用徒劳了。

4. 其他一些开发过程中遇到的问题。
  • 连续同步update灵动岛,数据只会更新一次,苹果内部接口应该对灵动岛的更新有一定的时间限制,因此建议将数据缓存一次性进行更新。
  • 当锁屏时(真正的锁屏,即没有解锁脸部识别),实时活动的更新频率会降低,比如几秒钟才会更新一次(哪怕你代码是每秒钟都调update接口),且更新动画也会被屏蔽,苹果应该是为了省电吧。
相关推荐
struggle202516 小时前
Ollmao (OH-luh-毛程序包及源码) 是一款原生 SwiftUI 应用程序,它与 Ollama 集成,可在 Mac 上本地运行强大的 AI 模型
ios·swiftui·swift
货拉拉技术1 个月前
货拉拉用户端SwiftUI踩坑之旅
ios·swiftui·swift
ZacJi1 个月前
巧用 allowsHitTesting 自定义 SignInWithAppleButton
ios·swiftui·swift
刘争Stanley1 个月前
SwiftUI 是如何改变 iOS 开发游戏规则的?
ios·swiftui·swift
1024小神1 个月前
在swiftui中使用Alamofire发送请求获取github仓库里的txt文件内容并解析
ios·github·swiftui
大熊猫侯佩1 个月前
SwiftUI 撸码常见错误 2 例漫谈
swiftui·xcode·tag·tabview·preview·coredata·fetchrequest
东坡肘子2 个月前
肘子的 Swift 周报 #063|异种肾脏移植取得突破
swiftui·swift·apple
恋猫de小郭2 个月前
什么?Flutter 可能会被 SwiftUI/ArkUI 化?全新的 Flutter Roadmap
flutter·ios·swiftui
靴子学长2 个月前
iOS + watchOS Tourism App(含源码可简单复现)
mysql·ios·swiftui
hxx2212 个月前
iOS swift开发系列--如何给swiftui内容视图添加背景图片显示
ios·swiftui·swift