8.9 C
New York
Monday, March 10, 2025

ios – Tips on how to Decide if a Contact is Saved in iCloud, Google, or One other Account in Swift?


I’m utilizing CNContactStore to fetch contacts from an iOS system. Whereas retrieving contacts, I need to examine whether or not every contact is saved in iCloud, Google, Yahoo, or one other account. Nevertheless, I’m solely getting generic container names like “Card” or “Deal with Guide” as an alternative of the particular account names.

Right here is my present code:

func fetchContacts(completion: @escaping ([ContactModel]) -> Void) {
    let retailer = CNContactStore()
    
    DispatchQueue.world(qos: .userInitiated).async {
        let keys: [CNKeyDescriptor] = [
            CNContactIdentifierKey as CNKeyDescriptor,
            CNContactGivenNameKey as CNKeyDescriptor,
            CNContactFamilyNameKey as CNKeyDescriptor,
            CNContactPhoneNumbersKey as CNKeyDescriptor
        ]
        
        var contacts = [ContactModel]()
        
        do {
            // Fetch all containers (iCloud, Google, Outlook, and many others.)
            let containers = attempt retailer.containers(matching: nil)
            
            for container in containers {
                let request = CNContactFetchRequest(keysToFetch: keys)
                request.predicate = CNContact.predicateForContactsInContainer(withIdentifier: container.identifier)
                
                attempt retailer.enumerateContacts(with: request) { (contact, _) in
                    let fullName = "(contact.givenName) (contact.familyName)"
                    let phoneNumbers = contact.phoneNumbers.map { $0.worth.stringValue }
                    
                    // Checking container kind
                    print("Container Identify: (container.identify), Sort: (container.kind.rawValue)")

                    // Trying to map account kind
                    let accountName: String
                    change container.kind {
                    case .cardDAV:
                        accountName = container.identify.comprises("iCloud") ? "iCloud" : "Google/Yahoo (CardDAV)"
                    case .trade:
                        accountName = "Outlook/Alternate"
                    case .native:
                        accountName = "System Contacts"
                    default:
                        accountName = container.identify
                    }
                    
                    let contactModel = ContactModel(contact: contact, accountName: accountName)
                    contacts.append(contactModel)
                }
            }
            
            DispatchQueue.principal.async {
                completion(contacts)
            }
        } catch {
            print("Did not fetch contacts: (error)")
        }
    }
}

Utilizing CNContainer.identify → Returns “Card” or “Deal with Guide”, not “iCloud”, “Google”, and many others.

How can I precisely decide whether or not a contact belongs to iCloud, Google, Yahoo, or one other account?

current result

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles