41 lines
1.5 KiB
Swift
41 lines
1.5 KiB
Swift
import Foundation
|
|
|
|
/// Represents a shared card fetched from CloudKit for display in the App Clip.
|
|
struct SharedCardSnapshot: Sendable {
|
|
let recordName: String
|
|
let vCardData: String
|
|
let displayName: String
|
|
let role: String
|
|
let company: String
|
|
let photoData: Data?
|
|
|
|
init(recordName: String, vCardData: String) {
|
|
self.recordName = recordName
|
|
self.vCardData = vCardData
|
|
|
|
// Parse display fields from vCard
|
|
let lines = vCardData.components(separatedBy: .newlines)
|
|
self.displayName = Self.parseField("FN:", from: lines) ?? "Contact"
|
|
self.role = Self.parseField("TITLE:", from: lines) ?? ""
|
|
self.company = Self.parseField("ORG:", from: lines)?
|
|
.components(separatedBy: ";").first ?? ""
|
|
self.photoData = Self.parsePhoto(from: lines)
|
|
}
|
|
|
|
private static func parseField(_ prefix: String, from lines: [String]) -> String? {
|
|
lines.first { $0.hasPrefix(prefix) }?
|
|
.dropFirst(prefix.count)
|
|
.trimmingCharacters(in: .whitespaces)
|
|
}
|
|
|
|
private static func parsePhoto(from lines: [String]) -> Data? {
|
|
// Find line that starts with PHOTO; and contains base64 data
|
|
guard let photoLine = lines.first(where: { $0.hasPrefix("PHOTO;") }),
|
|
let base64Start = photoLine.range(of: ":")?.upperBound else {
|
|
return nil
|
|
}
|
|
let base64String = String(photoLine[base64Start...])
|
|
return Data(base64Encoded: base64String)
|
|
}
|
|
}
|