40

My iOS application checks the contacts from time to time and imports a new one to its own database.

I checked that contact and it already exists by the identifier field, that is usually filled by UUID:

CNContactStore *store = [CNContactStore new];
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError *error) {
    if (granted) {
        NSArray *keys = @[CNContactNamePrefixKey,
                          CNContactGivenNameKey,
                          CNContactMiddleNameKey,
                          CNContactFamilyNameKey,
                          CNContactInstantMessageAddressesKey];
        NSString *containerId = store.defaultContainerIdentifier;
        NSPredicate *predicate = [CNContact predicateForContactsInContainerWithIdentifier:containerId];
        NSArray *cnContacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:keys error:&err];
        for (CNContact *contact in cnContacts) {
            ...
            NSString *contactId = [contact identifier];
            [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"uuid == %@", contactId]];

        ...

    }

Sometimes, the identifier excepts UUID that contains the :ABPerson string (eg 9326A125-3C0A-494F-9E50-BBFCF1140EF0:ABPerson), and such contact appears only one time. Next time, the same contact appears, but with another UUID and without the :ABPerson string.

So, my contacts importer considers that they are 2 different contacts and saves them 2 times.

What is the :ABPerson string in CNContact identifier?
I know about AddressBook framework with ABPerson class, but I'm using the Contacts framework to work with device contacts, why is the :ABPerson string appearing here?
Can I just filter or check this string in the identifier for preventing contacts duplicates?
Are there other strings that may be contained in CNContact identifiers?

General Failure
  • 2,421
  • 4
  • 23
  • 49
  • 1
    Have you used enumeratecontactswithfetchrequest For getting Contacts ? – Sagar Shirbhate Dec 29 '16 at 13:18
  • No, I'm using `unifiedContactsMatchingPredicate:predicate:` method. I'm updated my code, so you can look this. – General Failure Dec 30 '16 at 04:31
  • 2
    If you use Google account in Address Book then after saving to AddressBook google changes contact identifier to self identifier without ":APBerson". In first moment it just removes :ABPerson, but after relaunch it changes contact identifier to another GUID. On other contacts providers it may be other rules of mutating card identifiers, so better do not use contact identifier at all. – poGUIst Apr 11 '17 at 15:10
  • @poGUIst: how can we manage to update such contacts? Pls advice. – Suresh Durishetti Oct 26 '17 at 08:44
  • 1
    @[suresh-durishetti](https://stackoverflow.com/users/1717292/suresh-durishetti), I manage contacts using their phone numbers that also has `UUID` and unlike contacts does not change them between application sessions – General Failure Oct 26 '17 at 09:16
  • @GeneralFailure I tried your approach but getting different identifier for all parameter(phone,email,postal). Can you help to share ur code? – Suresh Durishetti Oct 26 '17 at 10:55
  • Apple Docs (https://developer.apple.com/documentation/contacts/cncontact/1403103-identifier) state "An identifier can be persisted between the app launches." – fivewood Mar 08 '18 at 18:01
  • 1
    Did you found an answer to this issue? – Diogo Antunes Mar 22 '18 at 14:36
  • The Contacts framework is the successor to AddressBook, so even though they have differently-named constants, the *value* for the constant is often the same for back compatibility, since you can have older apps modifying the same database. But, that doesn't really answer your question as to why sometimes the suffix is there, and sometimes not. – Carl Lindberg Mar 23 '21 at 00:06

1 Answers1

0

Looks like :ABPerson is added when sharing a contact from the Contacts application. By the way, be careful because a shared contact may have a different ID even on a same device.

chepiok
  • 193
  • 12