I am following along the tutorial at https://www.youtube.com/watch?v=AUOoalBwxos
However, the ActivityKit API used to start and end the live activity have been deprecated in iOS 16.2.
I have figured out how to update the start method to the new API by replacing activity = try? Activity<TimeTrackingAttributes>.request(attributes: attributes, contentState: state, pushType: nil)
with:
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)")
}
However, I am having trouble ending the live activity started with the new API. With the old, deprecated API, I could start and end my live activity. But when I use the old end API, I get the message end(using:dismissalPolicy:)' was deprecated in iOS 16.2: Use end(content:dismissalPolicy:) instead
. The old ‘end’ API does not end the activity started with the new 'start' API.
Would anyone be able to offer some advice for how to end a live activity with the new ActivityKit API in iOS 16.2?
Documentation for the new API: https://developer.apple.com/documentation/activitykit/activity/end(_:dismissalpolicy:)
Documentation for the old API: https://developer.apple.com/documentation/activitykit/activity/end(using:dismissalpolicy:)
The full code for 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")
}
}
}
}
The full code for TimeTrackingAttributes:
import Foundation
import ActivityKit
struct TimeTrackingAttributes: ActivityAttributes {
public typealias TimeTrackingStatus = ContentState
public struct ContentState: Codable, Hashable {
var startTime: Date
}
}