62 lines
2.0 KiB
Swift
62 lines
2.0 KiB
Swift
import CloudKit
|
|
|
|
/// Service for fetching shared cards from CloudKit public database.
|
|
struct ClipCloudKitService: Sendable {
|
|
private let database: CKDatabase
|
|
|
|
init(containerID: String = ClipIdentifiers.cloudKitContainerIdentifier) {
|
|
self.database = CKContainer(identifier: containerID).publicCloudDatabase
|
|
}
|
|
|
|
/// Fetches a shared card from CloudKit by record name.
|
|
/// - Parameter recordName: The UUID string identifying the record.
|
|
/// - Returns: A snapshot of the shared card data.
|
|
func fetchSharedCard(recordName: String) async throws -> SharedCardSnapshot {
|
|
let recordID = CKRecord.ID(recordName: recordName)
|
|
|
|
let record: CKRecord
|
|
do {
|
|
record = try await database.record(for: recordID)
|
|
} catch {
|
|
throw ClipError.fetchFailed
|
|
}
|
|
|
|
guard let vCardData = record["vCardData"] as? String else {
|
|
throw ClipError.invalidRecord
|
|
}
|
|
|
|
if let expiresAt = record["expiresAt"] as? Date, expiresAt < .now {
|
|
throw ClipError.expired
|
|
}
|
|
|
|
let displayName = record["displayName"] as? String
|
|
let role = record["role"] as? String
|
|
let company = record["company"] as? String
|
|
let photoData = dataFromPhotoAsset(record["photoAsset"] as? CKAsset)
|
|
|
|
return SharedCardSnapshot(
|
|
recordName: recordName,
|
|
vCardData: vCardData,
|
|
displayName: displayName,
|
|
role: role,
|
|
company: company,
|
|
photoData: photoData
|
|
)
|
|
}
|
|
|
|
/// Deletes a shared card from CloudKit after it is saved to Contacts.
|
|
func deleteSharedCard(recordName: String) async throws {
|
|
let recordID = CKRecord.ID(recordName: recordName)
|
|
do {
|
|
_ = try await database.deleteRecord(withID: recordID)
|
|
} catch {
|
|
throw ClipError.deleteFailed
|
|
}
|
|
}
|
|
|
|
private func dataFromPhotoAsset(_ asset: CKAsset?) -> Data? {
|
|
guard let fileURL = asset?.fileURL else { return nil }
|
|
return try? Data(contentsOf: fileURL)
|
|
}
|
|
}
|