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];
}
}
}];
Related
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"];
}
}
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) {
}];
}
}
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?
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
});
Currently I am using this code snippet to fetch contact from iPhone
CNContactStore *store = [[CNContactStore alloc] init];
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted == YES) {
//keys with fetching properties
NSArray *keys = #[CNContactGivenNameKey,CNContactFamilyNameKey, CNContactPhoneNumbersKey, CNContactImageDataKey];
[[CNContactsUserDefaults sharedDefaults] sortOrder];
NSString *containerId = store.defaultContainerIdentifier;
//NSComparator hg= [CNContact comparatorForNameSortOrder:CNContactSortOrderGivenName];
NSPredicate *predicate = [CNContact predicateForContactsInContainerWithIdentifier:containerId];
NSError *error;
NSArray *cnContacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:keys error:&error];
NSSortDescriptor *sortDescriptor;
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"givenName"
ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray = [cnContacts sortedArrayUsingDescriptors:sortDescriptors];
}];
but here i am only getting contacts from iCloud.
how can i get contact from Facebook, gmail, or any other cloud?
please help regard this.
I spent 2 days for this issue but didn't get any solution.
Then done that with one patch. This is worked for me.
if ([container.name isEqualToString:#"Card"]) {
NSLog(#"iCloud");
}else if ([container.name isEqualToString:#"Address Book"]){
NSLog(#"google");
}else if ([container.name isEqualToString:#"Contacts"]){
NSLog(#"Yahoo");
}else{
NSLog(#"Other");
}
You have to fetch all containers for contacts and fetch contact from individual container and merge them.
// Get all containers of contacts like icloud contacts , gmail contacts and show all data
NSArray *allContainers = [store containersMatchingPredicate:nil error:nil];
for (CNContainer *container in allContainers) {
// create predicate using cncontactstore identifier
NSPredicate *predicate = [CNContact predicateForContactsInContainerWithIdentifier:container.identifier];
// get array of contact using predicate
NSArray *arrContacts = [[[CNContactStore alloc] init] unifiedContactsMatchingPredicate:predicate keysToFetch:keysToFetch error:nil];
}