Created
December 8, 2022 22:15
-
-
Save mergesort/cf57ddc44e7b469973e889a11b2d26a9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public final class LiveActivitiesController<Model: Identifiable & Equatable & Codable, ModelActivity: ActivityAttributes & Identifiable>: ObservableObject { | |
var activityFromModel: (Model) -> ModelActivity | |
var contentStateFromModel: (Model) -> ModelActivity.ContentState | |
public init(activityFromModel: @escaping (Model) -> ModelActivity, contentStateFromModel: @escaping (Model) -> ModelActivity.ContentState) { | |
self.activityFromModel = activityFromModel | |
self.contentStateFromModel = contentStateFromModel | |
} | |
public func activityIsActive(_ model: Model) -> Bool { | |
return self.allActivities.map(\.attributes.id).contains(where: { $0 == self.activityFromModel(model).id }) | |
} | |
public func startActivity(_ model: Model) async throws { | |
do { | |
_ = try Activity.request( | |
attributes: self.activityFromModel(model), | |
contentState: self.contentStateFromModel(model) | |
) | |
} catch { | |
print(error) | |
} | |
} | |
public func updateActivity(_ reminder: Model) async { | |
let state = contentStateFromModel(reminder) | |
await self.activityMatching(reminder)?.update(using: state) | |
} | |
public func endActivity(_ reminder: Model) async { | |
await self.activityMatching(reminder)?.end(dismissalPolicy: .immediate) | |
} | |
} | |
private extension LiveActivitiesController { | |
var allActivities: [Activity<ModelActivity>] { | |
return Activity<ModelActivity>.activities | |
} | |
func activityMatching(_ model: Model) async -> Activity<ModelActivity>? { | |
self.allActivities.first(where: { $0.attributes.id == self.activityFromModel(model).id }) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Create a Reminder Model | |
public struct Reminder: Identifiable, Equatable, Codable { | |
public let id: UUID | |
public var createdAt: Date | |
public var updatedAt: Date | |
public var creator: String | |
public var title: String | |
public var hexColor: String | |
public var description: String | |
public var isArchived: Bool | |
} | |
// Create a Reminder live acitivy model | |
public struct ReminderActivity: ActivityAttributes, Identifiable { | |
// Static properties for your activity that cannot change after initialization | |
public var id: UUID | |
public init(id: UUID) { | |
self.id = id | |
} | |
public struct ContentState: Codable, Hashable { | |
// Dynamic (state changing) properties about your activity, cannot be more than 4kb per property | |
public var title: String | |
public var description: String | |
public var hexColor: String | |
public init(title: String, description: String, hexColor: String) { | |
self.title = title | |
self.description = description | |
self.hexColor = hexColor | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// The view for your live activity | |
struct ReminderLockScreenLiveActivityView: View { | |
let context: ActivityViewContext<ReminderActivity> | |
var body: some View { | |
VStack(alignment: .leading, spacing: 4.0) { | |
Text(context.state.title) | |
.lineLimit(3) | |
.bold() | |
.font(.title2) | |
Text(context.state.description) | |
.font(.title3) | |
Spacer() | |
} | |
.multilineTextAlignment(.leading) | |
.padding(16.0) | |
.frame(maxWidth: .infinity, alignment: .leading) | |
.background(Color(hex: context.state.hexColor)) | |
.foregroundColor(Color.white) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@StateObject private var liveActivitiesController = LiveActivitiesController<Reminder, ReminderActivity>( | |
activityFromModel: { reminder in | |
ReminderActivity(id: reminder.id) | |
}, | |
contentStateFromModel: { reminder in | |
ReminderActivity.ContentState(title: reminder.title, description: reminder.description ?? "", hexColor: reminder.hexColor) | |
} | |
) | |
// Check a live activity is active | |
if self.liveActivitiesController.activityIsActive(reminder) { | |
// End a live activity | |
await liveActivitiesController.endActivity(reminder) | |
} else { | |
// Start a new live activity | |
try await liveActivitiesController.startActivity(reminder) | |
} | |
// Update a live activity with new data | |
await liveActivitiesController.updateActivity(reminder) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment