iOS16 基于ObjectiveC的实时活动以及灵动岛

iOS16.1系统开始正式支持实时活动,更新Xcode为最新的14.1版本,(跟着官方文档步骤)开始着手开发
官方文档https://developer.apple.com/documentation/activitykit/displaying-live-data-with-live-activities
前情提要:项目是OC项目,且这次实时活动没有用到远程推送

1.新建OC项目,Info-Plist文件加入Bool类型的权限key值为:Supports Live Activities value为:YES
2.如果项目之前有过小组件,则不需要再创建新的Widget-Extension,直接在@main WidgetBundle里面添加要创建的Live-Activity组件即可(我们在后面添加)
3.(我是OC项目)在主项目里面新建一个Attributes.swift项目
Attributes

官方文档有详细讲解,以我的为例

import Foundation
import ActivityKit

//我自己的Widget类
struct ZKWidgetAttributes: ActivityAttributes {
    public typealias ZKWidgetState = ContentState
    //可变参数(动态参数)
    public struct ContentState: Codable, Hashable {
        //参数,当前的监测时间
        var monitorTime: ClosedRange<Date>
        var sleepProgress :Float 
    }
    var sleepGoal: Double
}

//定义一个Manager类(单例)
@available(iOS 16.1, *)
public class ZkActivityManager : NSObject{
    
    var timer: Timer?
    
    var sleepTime: Int = 0
    var progress: Float = 0.0
    
    static let defaultManager: ZkActivityManager = ZkActivityManager()
    
    @objc public class func defaultManage() -> ZkActivityManager
    {
        return ZkActivityManager.defaultManager
    }
    
    //开启一个实时活动
    @objc public func startActivity(sleepGoal:Int){
        self.startTimer()
        
        let attributes = ZKWidgetAttributes(sleepGoal: Double(sleepGoal))
        
        let initialConetntState = ZKWidgetAttributes.ZKWidgetState(monitorTime: Date()...Date().addingTimeInterval(12 * 60 * 60 ),sleepProgress: Float(self.progress))
        
        do {
            let activity = try Activity<ZKWidgetAttributes>.request(attributes: attributes, contentState: initialConetntState, pushType: nil)
            print("Requested a pizza delivery Live Activity \(activity.id)")
        } catch (let error) {
            print("Error requesting pizza delivery Live Activity \(error.localizedDescription)")
        }
        
    }
    //更新一个实时活动
    @objc public func updateActivity (){
        Task {
            let updateStatus = ZKWidgetAttributes.ZKWidgetState(monitorTime: Date()...Date().addingTimeInterval(0.2 * 60),sleepProgress:Float(self.progress))
            for activity in Activity<ZKWidgetAttributes>.activities{
                await activity.update(using: updateStatus)
            }
        }
    }
   
  //结束一个实时活动
    @objc public func stopActivity (){
        
        Task {
            for activity in Activity<ZKWidgetAttributes>.activities{
                await activity.end(dismissalPolicy: .immediate)
            }
        }
        self.cancelTimer()
    }
  //是否支持实施活动(开关是否打开)
    @objc public func isOpenLiveActivity ()-> Bool {
        if !ActivityAuthorizationInfo().areActivitiesEnabled {
            return false
        }
        return true
    }
    //获取实施活动列表
    @objc public func getLiveActivityList () async{
        for await activity in Activity<ZKWidgetAttributes>.activityUpdates {
            print("Pizza delivery details: \(activity.attributes)")
        }
    }
    
    //开启定时器
    @objc public func startTimer() {
        timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(recordTime), userInfo: nil, repeats: true)
        if let curTimer : Timer = timer {
            RunLoop.main.add(curTimer, forMode: .common)
        }
    }
    
    @objc func recordTime(){
        sleepTime += 1
        self.progress = Float(sleepTime) / 480.0 / 60
        print("开始计时:\(self.sleepTime)")
        print("目前进度:\(self.progress)")
    }
    deinit {
        cancelTimer()
    }
    func cancelTimer() {
        timer?.invalidate()
        timer = nil
    }
}

tips 需要在Widget里用到我们在主工程的Attributes,需要在Attributes.swift文件右边的Target Membership里面,勾上WidgetExtension,以确保组件也可以用到该文件

4.创建Widget

里面包括锁屏界面的Widget以及灵动岛的Widget,这块就自己用SWiftUI进行布局即可
//当然我们也可以通过不同的Attributes开启不同的实时活动,传入不同参数,刻画不同的Widget样式

5.上截图
锁屏界面实时活动
灵动岛实时活动
放到最后

1.自己心中有个疑虑,如果实时活动锁屏组件上有个类似于圆环进度条,如何做到实时刷新(没有remote-push)),本人想法是,主项目有个计时器,然后调用updateActivity方法,但是可能会导致大量耗电,不是一个好的方法。
Text有一个(timerInterval: ClosedRange<Date>, pauseTime: Date? = nil, countsDown: Bool = true, showsHours: Bool = true)方法,可以动画的进行倒计时,也就是Apple官方给的披萨外卖demo。

就先到这,后期有啥再更新!
Github地址https://github.com/Superman-Frank/liveActivity

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,744评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,505评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,105评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,242评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,269评论 6 389
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,215评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,096评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,939评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,354评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,573评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,745评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,448评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,048评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,683评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,838评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,776评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,652评论 2 354

推荐阅读更多精彩内容