5

Any ideas why some CNContacts come back with EMPTY Phone Numbers?

I keep getting output like this:

"phoneNumbers=(not fetched), emailAddresses=(not fetched),"

So for example, when I'm fetching Contacts from the Simulator's built-in Contacts App, I get mixed results: "John Appleseed" does return with its Phone Numbers, but "Kate Bell" does not - even though she clearly has phone numbers. Its quite strange cause I'm definitely using CNContactPhoneNumbersKey in my fetch request.

Here's my code:

let fetchKeys = [ CNContactEmailAddressesKey, CNContactPhoneNumbersKey, 
                  CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName) ]
let contactFetchRequest = CNContactFetchRequest(keysToFetch: fetchKeys)

do { 
   try self.contactsStore.enumerateContactsWithFetchRequest(contactFetchRequest) {                     
   fetchedContact, stop in
         print("fetched Contact is: \n\(fetchedContact.description)")
   }
}

As I mentioned, the output reveals that sometimes the fetched Contact comes back with Phone Numbers, and sometimes it does not. Same for emails: sometimes they're returned, sometimes not.

This happens both in the Simulator and when I run this on my iPhone.

Any idea what might be happening here?

Sirab33
  • 1,247
  • 3
  • 12
  • 27

2 Answers2

0

When phone numbers are added in the contacts app, they sometimes miss a label (e.g. "home" or "phone" ...) If the label is null, the numbers aren't displayed. A workaround would be to explicitly set a default label for the ones missing. A simple example:

for phoneNumber in contact.phoneNumbers {
        guard let phone = phoneNumber.value as? CNPhoneNumber
            else { continue }

        let phoneLabel = phoneNumber.label == nil ? "DefaultLabel" : phoneNumber.label!

        phoneNumbers.append((phone.stringValue,phoneLabel))
    }
0

You should add below lines to info.plist.

 <key>NSContactsUsageDescription</key>
<string>$(PRODUCT_NAME) contact use</string>

And when the time the user will access to contacts in your app for present the alert for permission you should call some method for doing it like :

- (void)checkPermissionForCNContacts
{
    switch ([CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts])
    {
        case CNAuthorizationStatusNotDetermined:
        {
            [[[CNContactStore alloc] init] requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
                if (granted == YES)
                  [self METHOD_NAME_FOR_OPENING_THE_CONTACT_LIST];
            }];
        }
            break;
        case CNAuthorizationStatusRestricted:
        case CNAuthorizationStatusDenied:
            // Show custom alert
            break;
        case CNAuthorizationStatusAuthorized:
           [self METHOD_NAME_FOR_OPENING_THE_CONTACT_LIST];
            break;
    }
}

The method code I took from: Programmatically Request Access to Contacts

This will ask the user for permissions for Contacts list.

Community
  • 1
  • 1
Almog_0
  • 422
  • 4
  • 11