BusinessCard/BusinessCardClip/State/ClipCardStore.swift

57 lines
1.5 KiB
Swift

import Foundation
/// State management for the App Clip card display and save flow.
@MainActor
@Observable
final class ClipCardStore {
enum State {
case loading
case loaded(SharedCardSnapshot)
case saved
case error(String)
}
private let cloudKit: ClipCloudKitService
private let contactSave: ContactSaveService
var state: State = .loading
/// The currently loaded card snapshot, if any.
var snapshot: SharedCardSnapshot? {
if case .loaded(let snap) = state { return snap }
return nil
}
init(
cloudKit: ClipCloudKitService = ClipCloudKitService(),
contactSave: ContactSaveService = ContactSaveService()
) {
self.cloudKit = cloudKit
self.contactSave = contactSave
}
/// Loads a shared card from CloudKit.
/// - Parameter recordName: The record name (UUID) to fetch.
func load(recordName: String) async {
state = .loading
do {
let snapshot = try await cloudKit.fetchSharedCard(recordName: recordName)
state = .loaded(snapshot)
} catch {
state = .error(error.localizedDescription)
}
}
/// Saves the currently loaded card to Contacts.
func saveToContacts() async {
guard let snapshot else { return }
do {
try await contactSave.saveContact(vCardData: snapshot.vCardData)
state = .saved
} catch {
state = .error(error.localizedDescription)
}
}
}