CNContact Frame work not fetching all contacts(iCloud,Gmail) - ios

Settings>Contacts>Default Account selected as iCloud and saved a new contact.Then changed Default Account as gmail. CNContactStore not fetching the new saved contact.
CNContactStore *store = [[CNContactStore alloc] init];
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted == YES)
{
NSArray *keys = #[CNContactFamilyNameKey, CNContactGivenNameKey, CNContactPhoneNumbersKey, CNContactImageDataKey,CNContactEmailAddressesKey];
NSArray * contactContainerArray = [store containersMatchingPredicate:nil error:nil];
for(CNContainer * container in contactContainerArray) {
NSPredicate *predicate = [CNContact predicateForContactsInContainerWithIdentifier:container.identifier];
NSError *error;
NSArray *cnContacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:keys error:&error];
}

If you simply wish to get all unified contacts (Contacts in different accounts that represent the same person may be automatically linked together. Linked contacts are displayed in macOS and iOS apps as unified contacts) the best solution would be below one
-(void)fetchContacts
{
CNContactStore *store = [[CNContactStore alloc] init];
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted == YES)
{
//keys with fetching properties
NSArray *keys = #[CNContactFamilyNameKey, CNContactGivenNameKey, CNContactPhoneNumbersKey, CNContactImageDataKey,CNContactEmailAddressesKey];
NSString *containerId = store.defaultContainerIdentifier;
NSArray * contactContainerArray = [store containersMatchingPredicate:nil error:nil];
CNContactFetchRequest * fetchRequest = [[CNContactFetchRequest alloc]initWithKeysToFetch:keys];
[store enumerateContactsWithFetchRequest:fetchRequest error:nil usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) {
}];
}
}

Related

On creating VCard not getting contact image and notes in iOS

Fetching contact list using CNContactStore and converting complete contact list to VCard, all are coming fine except i am not getting contact image and notes.
NSMutableArray *contactsArray=[[NSMutableArray alloc] init];
CNContactStore *store = [[CNContactStore alloc] init];
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (!granted) {
dispatch_async(dispatch_get_main_queue(), ^{
});
return;
}
NSMutableArray *contacts = [NSMutableArray array];
NSError *fetchError;
CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:#[[CNContactVCardSerialization descriptorForRequiredKeys], [CNContactFormatter descriptorForRequiredKeysForStyle:CNContactFormatterStyleFullName]]];
BOOL success = [store enumerateContactsWithFetchRequest:request error:&fetchError usingBlock:^(CNContact *contact, BOOL *stop) {
[contacts addObject:contact];
}];
if (!success) {
NSLog(#"error = %#", fetchError);
}
for (CNContact *contact in contacts) {
CNContact *contact1 = contact.mutableCopy;
[contactsArray addObject:contact1];
}
NSData *vcardString =[CNContactVCardSerialization dataWithContacts:contactsArray error:&error];
vcardStr = [[NSString alloc] initWithData:vcardString encoding:NSUTF8StringEncoding];
NSLog(#"vcardStr = %#",vcardStr);
}];
Contact Profile images from CNContact
if (granted == YES) {
NSArray *keys = #[CNContactFamilyNameKey, CNContactGivenNameKey, CNContactPhoneNumbersKey, CNContactImageDataKey];
NSString *containerId = store.defaultContainerIdentifier;
NSPredicate *predicate = [CNContact predicateForContactsInContainerWithIdentifier:containerId];
NSError *error;
NSArray *Contacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:keys error:&error];
if (error)
{
//error
}
else
{
for (CNContact *contact in Contacts)
{
UIImage *contactProfileImage;
if (contact.imageDataAvailable)
{
UIImage * image = [UIImage imageWithData:contact.imageData];
contactProfileImage = image;
}
else
{
contactProfileImage = [UIImage imageNamed:#"icon.png"];
}
}

Contact Framework is fatching only few contacts

I am using Contacts Framework to grab all Contacts from my iPhone to my application. But it is fetching only few contacts. This is the code I have used this code:
//ios 9+
CNContactStore *store = [[CNContactStore alloc] init];
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted == YES) {
NSArray *keys = #[CNContactGivenNameKey,CNContactFamilyNameKey,CNContactPhoneNumbersKey,CNLabelPhoneNumberMobile,CNLabelPhoneNumberMain,CNContactImageDataKey,CNContactIdentifierKey];
NSString *containerId = store.defaultContainerIdentifier;
NSPredicate *predicate = [CNContact predicateForContactsInContainerWithIdentifier:containerId];
NSError *error;
NSArray *cnContacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:keys error:&error];
}
try this:
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted == YES) {
NSArray *keys = #[CNContactGivenNameKey,CNContactFamilyNameKey,CNContactPhoneNumbersKey,CNLabelPhoneNumberMobile,CNLabelPhoneNumberMain,CNContactImageDataKey,CNContactIdentifierKey];
NSError *error;
NSArray *allContainer = [store containersMatchingPredicate:nil error:&error];
for (CNContainer *container in allContainer) {
NSPredicate *predicate = [CNContact predicateForContactsInContainerWithIdentifier:container.identifier];
NSArray *result = [store unifiedContactsMatchingPredicate:predicate keysToFetch:keys error:&error];
[aryAllContacts addObject:result];
}
}
}];

iOS Objective-C: CNContactStore unifiedContactsMatchingPredicate is extremely slow on some cases. What could be the cause for the latency?

CNEntityType entityType = CNEntityTypeContacts;
NSMutableArray* allContacts = [[NSMutableArray alloc] init];
CNContactStore * contactStore = [[CNContactStore alloc] init];
NSArray *keys = #[CNContactFamilyNameKey, CNContactMiddleNameKey, CNContactGivenNameKey, CNContactOrganizationNameKey,
CNContactNicknameKey, CNContactPhoneNumbersKey, CNContactImageDataKey];
NSError *error;
if ([CNContactStore authorizationStatusForEntityType:entityType] == CNAuthorizationStatusNotDetermined)
{
[contactStore requestAccessForEntityType:entityType completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted) {
NSArray* allContainers = [contactStore containersMatchingPredicate:nil error:&error];
for (CNContainer* container in allContainers)
{
NSPredicate *predicate = [CNContact predicateForContactsInContainerWithIdentifier:container.identifier];
NSArray* cnContacts = [contactStore unifiedContactsMatchingPredicate:predicate keysToFetch:keys error:&error];
if (error) {
NSLog(#"error fetching contacts %#", error);
} else {
for (CNContact *contact in cnContacts) {
[allContacts addObject:contact];
}
}
}
}
}];
It seems on some phones the performance of unifiedContactsMatchingPredicate can be extremely slow while on others it is pretty fast. What may be the cause of the performance discrepancy? As far as I can tell the contacts on different phones aren't stored that differently, is there something else that could be the cause?

I have fetched the contact using cncontacts and able to display them on console screen, but not on table view

How to display contact in table view?
I have fetched the contacts via CNContactStore iOS 9.
- (void) getContacts {
CNContactStore *store = [[CNContactStore alloc] init];
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted == YES) {
//keys with fetching properties
NSArray *keys = #[CNContactFamilyNameKey, CNContactGivenNameKey, CNContactPhoneNumbersKey,CNContactImageDataKey];
NSString *containerId = store.defaultContainerIdentifier;
NSPredicate *predicate = [CNContact predicateForContactsInContainerWithIdentifier:containerId];
NSError *error;
NSArray *cnContactsarray = [store unifiedContactsMatchingPredicate:predicate keysToFetch:keys error:&error];
if (error) {
NSLog(#"error fetching contacts %#", error);
}
else {
for (CNContact *contact in cnContactsarray) {
//store all the contacts as per your requirement
NSLog(#"Name : %#",contact.givenName);
NSLog(#"Id : %#",contact.identifier);//the contact id which you want
[_ContactsCN addObject:contact];
}
}
NSLog(#"array %#",_ContactsCN);
}
}];
}
Any help will be appreciated.
You need to reload data on main thread when your fetch contact from CNContact is complete
to run on main thread
dispatch_async(dispatch_get_main_queue(), ^{// reload your table here
});

Customize ContactPicker UI in iOS 9

How do I customize the UI of the CNContactPickerViewController?
I want to alter the colors, fonts, and text - similar to how snapchat has done?
Currently - my CNContactPickerViewController looks exactly like Apple's native contacts app.
First get contacts from address book and pass them into an NSArray:
CNContactStore *store = [[CNContactStore alloc] init];
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
NSMutableArray *contacts = [NSMutableArray array];
NSError *fetchError;
CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:#[CNContactIdentifierKey, [CNContactFormatter descriptorForRequiredKeysForStyle:CNContactFormatterStyleFullName]]];
BOOL success = [store enumerateContactsWithFetchRequest:request error:&fetchError usingBlock:^(CNContact *contact, BOOL *stop) {
[contacts addObject:contact];
}];
if (!success) {
NSLog(#"error = %#", fetchError);
}
}];
Then simply use the NSArray in a UITableView and from there you can customize the font, colors, etc.

Resources