naqi
naqi

Reputation: 151

CNContact(s) created locally are not synced to iCloud account

Recently some of our users were complaining about contacts not syncing to their iCloud account. It was working in iOS 8 and mysteriously stopped in one of the updates in iOS 9. With iOS 10 around the corner I thought it might be linked to deprecation of AddressBook.framework to Contacts.framework. However, even moving to new Contacts.framework it didn't fix the problem.

There are no error logs on console of the device and neither of the frameworks generate any errors when contacts are being created/updated on the device.

Contacts are visible and available on the device just not syncing to iCloud and other devices attached to the iCloud account.

Upvotes: 2

Views: 167

Answers (2)

rajesh
rajesh

Reputation: 1

CNContact(s) created locally are not synced to Third party application.

I have crated contacts in iphone contacts page.Those contacts are not synching inside my application.I have used below method to fetch contacs from my contacts framework.

There are no error logs on console of the device and neither of the frameworks generate any errors when contacts are being created/updated on the device.

Contacts are visible and available on the device just not syncing to my app.I have given permission to my application to access my contacts.

@available(iOS 10.0, *)
func retrieveContacts(_ completion: (_ success: Bool, _ contacts: [ContactEntry]?) -> Void) {
    var contacts = [ContactEntry]()
    do {
        let contactsFetchRequest = CNContactFetchRequest(keysToFetch: [CNContactGivenNameKey as CNKeyDescriptor, CNContactFamilyNameKey as CNKeyDescriptor, CNContactImageDataKey as CNKeyDescriptor, CNContactImageDataAvailableKey as CNKeyDescriptor, CNContactPhoneNumbersKey as CNKeyDescriptor, CNContactEmailAddressesKey as CNKeyDescriptor])
        try contactStore.enumerateContacts(with: contactsFetchRequest, usingBlock: { (cnContact, error) in
            if let contact = ContactEntry(cnContact: cnContact) {
                contacts.append(contact)
                print(contact,contacts.count)
            }
        })
        completion(true, contacts)
    } catch {
        completion(false, nil)
    }
    
    let keysToFetch = [CNContactFormatter.descriptorForRequiredKeys(for: .fullName),CNContactPhoneNumbersKey] as [Any]
    let fetchRequest = CNContactFetchRequest( keysToFetch: keysToFetch as! [CNKeyDescriptor])
    var contacts1 = [CNContact]()
    
    if #available(iOS 10.0, *) {
        fetchRequest.mutableObjects = false
    } else {
        // Fallback on earlier versions
    }
    fetchRequest.unifyResults = true
    fetchRequest.sortOrder = .userDefault
    
    let contactStoreID = CNContactStore().defaultContainerIdentifier()
    print("\(contactStoreID)")
    
    
    do {
        
        try CNContactStore().enumerateContacts(with: fetchRequest) { (contact, stop) -> Void in
            
                contacts1.append(contact)
            print(contact)
        }
    } catch let e as NSError {
        print(e.localizedDescription)
    }

Upvotes: 0

naqi
naqi

Reputation: 151

After a lot of debugging what I was able to isolate the issue to imageData property. Contacts which had imageData populated were not synced and the few which had no images were synced. This lead me to look at the code for imageData. Turns out I had been using UIImagePNGRepresentation to convert UIImage to NSData for imageData. Moving to UIImageJPEGRepresentation fixed the issue. The day was saved and iCloud accounts are synced.

Thank you Apple for not documenting this change. (it might be the image size even that is not documented)

Upvotes: 5

Related Questions