swift 在新的iOS 16.2 ActivityKit API中结束Live Activity

wgx48brx  于 2023-10-15  发布在  Swift
关注(0)|答案(2)|浏览(146)

我沿着教程在https://www.youtube.com/watch?v=AUOoalBwxos
但是,用于启动和结束实时Activity的ActivityKit API已在iOS 16.2中弃用。
我已经弄清楚了如何将start方法更新为新的API,方法是将activity = try? Activity<TimeTrackingAttributes>.request(attributes: attributes, contentState: state, pushType: nil)替换为:

let activityContent = ActivityContent(state: state, staleDate: Calendar.current.date(byAdding: .hour, value: 3, to: Date())!)

do {
    let myActivity = try Activity<TimeTrackingAttributes>.request(attributes: attributes, content: activityContent, pushType: nil)
    print("Requested MyActivity live activity. ID: \(myActivity.id)")
} catch let error {
    print("Error requesting live activity: \(error.localizedDescription)")
}

但是,我在结束使用新API启动的活动时遇到了问题。使用旧的、过时的API,我可以开始和结束我的活动。但是当我使用旧端API时,我得到消息end(using:dismissalPolicy:)' was deprecated in iOS 16.2: Use end(content:dismissalPolicy:) instead。旧的“end”API不会结束使用新的“start”API启动的Activity。
有人能提供一些建议,如何结束一个活的活动与新的ActivityKit API在iOS 16.2?
新API的文档:https://developer.apple.com/documentation/activitykit/activity/end(_:dismissalpolicy:)
旧API的文档:https://developer.apple.com/documentation/activitykit/activity/end(using:dismissalpolicy:)
ContentView的完整代码:

import SwiftUI
import ActivityKit

struct ContentView: View {
    @State private var isTrackingTime: Bool = false
    
    @State private var startTime: Date? = nil
    
    @State private var activity: Activity<TimeTrackingAttributes>? = nil;
    
    var body: some View {
        NavigationView {
            VStack {
                if let startTime {
                    Text(startTime, style: .relative)
                }
                
                Button {
                    isTrackingTime.toggle()
                    
                    if isTrackingTime {
                        startTime = .now
                        
                        // start the live activity
                        let attributes = TimeTrackingAttributes()
                        guard let startTime else { return }
                        let state = TimeTrackingAttributes.ContentState(startTime: startTime)
                        
                        activity = try? Activity<TimeTrackingAttributes>.request(attributes: attributes, contentState: state, pushType: nil)
                        
                        // TODO: how to match the new 'start' API to the new 'end' API ?
//                        let activityContent = ActivityContent(state: state, staleDate: Calendar.current.date(byAdding: .hour, value: 3, to: Date())!)
//                        do {
//                            let myActivity = try Activity<TimeTrackingAttributes>.request(attributes: attributes, content: activityContent, pushType: nil)
//                            print("Requested MyActivity live activity. ID: \(myActivity.id)")
//                        } catch let error {
//                            print("Error requesting live activity: \(error.localizedDescription)")
//                        }
                    } else {
                        // end the live activity
                        guard let startTime else { return }
                        let state = TimeTrackingAttributes.ContentState(startTime: startTime)
                        
                        // TODO: how to match the new 'end' API to the new 'start' API ?
                        Task {
                             await activity?.end(using: state, dismissalPolicy: .immediate)
                        }
                        
                        self.startTime = nil
                    }
                } label: {
                    Text(isTrackingTime ? "STOP" : "START")
                        .fontWeight(.light)
                        .foregroundColor(.white)
                        .frame(width: 200, height: 200)
                        .background(Circle().fill(isTrackingTime ? .red : .green))
                }
                .navigationTitle("Basic Time Tracker")
            }
        }
    }
}

TimeTrackingAttributes的完整代码:

import Foundation
import ActivityKit

struct TimeTrackingAttributes: ActivityAttributes {
    public typealias TimeTrackingStatus = ContentState
    
    public struct ContentState: Codable, Hashable {
        var startTime: Date
    }
}
cwtwac6a

cwtwac6a1#

它为我工作:

func stopLiveActivity() {
    let state = TimeTrackingAttributes.TimeTrackingStatus(endTime: .now) 

    Task {
        let content = ActivityContent(state: state, staleDate: .now)
        await activity?.end(content, dismissalPolicy: .immediate)
    }
}

这段代码通过使用staleDate创建内容来立即结束Activity:.now和dismissalPolicy:.易熔矿

62lalag4

62lalag42#

非常确定它需要内容的原因是活动的“过时日期”也更新为最终值。希望这对我有帮助,这种方式对我来说非常有效,我也会在这里提到一件事:

  • 如果您使用“.after(date:)”的解除策略结束Activity,Activity的动态岛部分将立即删除,即使锁屏/通知视图将保留到解除日期。
let state = TimeTrackingAttributes.ContentState(startTime: startTime)

Task {
   await activity?.end(ActivityContent(state: state, staleDate: someDate, dismissalPolicy: .immediate))
 }

相关问题