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, displayName: String? = nil, role: String? = nil, company: String? = nil, photoData: Data? = nil ) { self.recordName = recordName self.vCardData = vCardData // Parse display fields from vCard let lines = vCardData.components(separatedBy: .newlines) let parsedDisplayName = Self.parseField("FN:", from: lines) ?? "Contact" let parsedRole = Self.parseField("TITLE:", from: lines) ?? "" let parsedCompany = Self.parseField("ORG:", from: lines)? .components(separatedBy: ";").first ?? "" let parsedPhotoData = Self.parsePhoto(from: lines) let cleanedDisplayName = displayName?.trimmingCharacters(in: .whitespacesAndNewlines) ?? "" self.displayName = cleanedDisplayName.isEmpty ? parsedDisplayName : cleanedDisplayName self.role = role ?? parsedRole self.company = company ?? parsedCompany self.photoData = photoData ?? parsedPhotoData } 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) } }