I have more than 6000 contacts in my iPad and fetch all contacts as well as store in core data and I have already implemented this functionality in my app but its taking too much time for fetch and load data so Is there any way to fetch, store data asynchronously or other way.
So Please give me suggestions or any idea for solve my issue.
Thanks in advance.
//Code for synchronize contacts
- (void)synchronizeContacts
{
if (self.syncStatus)
{
//Loading and showing the activity indicator view
[NSThread detachNewThreadSelector:@selector(showActivityIndicator:)
toTarget:self
withObject:@"Synchronizing contacts..."];
}
if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined)
{
// Request authorization to Address Book
ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, NULL);
ABAddressBookRequestAccessWithCompletion(addressBookRef, ^(bool granted, CFErrorRef error)
{
// First time access has been granted, add the contact
NSLog(@"First time access has been granted, add the contact");
[self synchronizeContactsFromContacts];
});
}
else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized)
{
// The user has previously given access, add the contact
NSLog(@"The user has previously given access, add the contact");
[self synchronizeContactsFromContacts];
}
else {
// The user has previously denied access
// Send an alert telling user to change privacy setting in settings app
NSLog(@"The user has previously denied access");
}
}
-(void)synchronizeContactsFromContacts
{
NSMutableArray *phoneContactsArray = [[NSMutableArray alloc]init];
NSMutableArray *allDeviceContacts=[[NSMutableArray alloc]init];
// Do whatever you want here.
ABAddressBookRef iphoneAddress = ABAddressBookCreate();
//read all sources
CFArrayRef sourcesArray = ABAddressBookCopyArrayOfAllSources(iphoneAddress);
for (CFIndex i = 0; i < CFArrayGetCount(sourcesArray); i++)
{
ABRecordRef iphoneSource = (ABRecordRef)CFArrayGetValueAtIndex(sourcesArray, i);
NSArray *allPersons = (NSArray *)ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(iphoneAddress, iphoneSource, kABPersonSortByFirstName);
[allDeviceContacts addObjectsFromArray:allPersons];
//read all persons
for(int nameIndex=0; nameIndex<[allPersons count]; nameIndex++)
{
ABRecordRef person = [allPersons objectAtIndex:nameIndex];
//person modification date
CFDateRef lastModifyDate = ABRecordCopyValue(person, kABPersonModificationDateProperty);
NSDate *lastSyncDate = [[PFCoreDataController sharedCoreDataController] getLastContactSynchedDate];
if(lastSyncDate)
{
NSTimeInterval timeInterval = [lastSyncDate timeIntervalSinceDate: (NSDate*)lastModifyDate] * -1000.0;
if(timeInterval <= 0) //skip if this conatct is not modified
{
if(lastModifyDate)
CFRelease(lastModifyDate);
continue;
}
}
if(lastModifyDate)
CFRelease(lastModifyDate);
NSString *nullValue = @"";
NSNumber *zeroValue = [NSNumber numberWithInt:0];
NSMutableDictionary *companyAddress = [NSMutableDictionary dictionaryWithObjectsAndKeys:
zeroValue, @"personUId",
zeroValue, KEYCONTACTS_CONTACTID,
zeroValue, KEYCONTACTS_ID,
nullValue, KEYCONTACTS_NAME,
nullValue, KEYCONTACTS_LAST_NAME,
nullValue, KEYCONTACTS_STREET,
nullValue, KEYCONTACTS_CITY,
nullValue, KEYCONTACTS_STATE,
nullValue, KEYCONTACTS_ZIP,
nullValue, KEYCONTACTS_COUNTRY,
nullValue, KEYCONTACTS_PHONE,
nullValue, KEYCONTACTS_EMAIL,
nullValue, @"company_Name",
nullValue, @"website",
nullValue, @"mobile",
nil];
NSString *fName = @"";
//NSString *mName = @"";
NSString *lName = @"";
// NSString *profileName = @"";
NSString *profileCompanyText = @"";
//get name
fName=(NSString*)ABRecordCopyValue(person, kABPersonFirstNameProperty);
//mName=(NSString*)ABRecordCopyValue(person, kABPersonMiddleNameProperty);
lName=(NSString*)ABRecordCopyValue(person, kABPersonLastNameProperty);
//profileName = [self concatnateContactName:fName middleName:mName andLastName:lName];
[companyAddress setValue:fName forKey:KEYCONTACTS_NAME];
[companyAddress setValue:lName forKey:KEYCONTACTS_LAST_NAME];
[fName release];
//[mName release];
[lName release];
[companyAddress setValue:[NSNumber numberWithInt:ABRecordGetRecordID(person)] forKey:@"personUId"];
//NSLog(@"%d",ABRecordGetRecordID(person));
//for mapping org name to comp name
CFTypeRef profileCompany = ABRecordCopyValue(person,kABPersonOrganizationProperty );
if(profileCompany)
{
profileCompanyText = (NSString*)profileCompany;
[companyAddress setValue:profileCompanyText forKey:@"company_Name"];
CFRelease(profileCompany);
}
//get email id
ABMutableMultiValueRef multiValue = nil;
if(multiValue)
{
CFRelease(multiValue);
multiValue =nil;
}
multiValue = ABRecordCopyValue(person, kABPersonEmailProperty);
if(ABMultiValueGetCount(multiValue) > 0)
{
CFDictionaryRef dict = ABMultiValueCopyValueAtIndex(multiValue, 0);
[companyAddress setValue:(NSString*)dict forKey:KEYCONTACTS_EMAIL];
CFRelease(dict);
}
if(multiValue)
{
CFRelease(multiValue);
multiValue =nil;
}
//get URL
multiValue = ABRecordCopyValue(person, kABPersonURLProperty);
if(ABMultiValueGetCount(multiValue) > 0)
{
CFDictionaryRef dict = ABMultiValueCopyValueAtIndex(multiValue, 0);
[companyAddress setValue:(NSString*)dict forKey:@"website"];
CFRelease(dict);
}
if(multiValue)
{
CFRelease(multiValue);
multiValue =nil;
}
//to get address from iphone contacts
multiValue = ABRecordCopyValue(person, kABPersonAddressProperty);
if(ABMultiValueGetCount(multiValue) > 0)
{
CFDictionaryRef dict = ABMultiValueCopyValueAtIndex(multiValue, 0);
CFStringRef street = CFDictionaryGetValue(dict, kABPersonAddressStreetKey);
CFStringRef city = CFDictionaryGetValue(dict, kABPersonAddressCityKey);
CFStringRef state = CFDictionaryGetValue(dict, kABPersonAddressStateKey);
CFStringRef zip = CFDictionaryGetValue(dict, kABPersonAddressZIPKey);
CFStringRef country = CFDictionaryGetValue(dict, kABPersonAddressCountryKey);
CFRelease(dict);
[companyAddress setValue:(NSString*)street forKey:KEYCONTACTS_STREET];
[companyAddress setValue:(NSString*)city forKey:KEYCONTACTS_CITY];
[companyAddress setValue:(NSString*)state forKey:KEYCONTACTS_STATE];
[companyAddress setValue:(NSString*)zip forKey:KEYCONTACTS_ZIP];
[companyAddress setValue:(NSString*)country forKey:KEYCONTACTS_COUNTRY];
}
if(multiValue)
{
CFRelease(multiValue);
multiValue =nil;
}
//get contact number
multiValue = ABRecordCopyValue(person, kABPersonPhoneProperty);
CFStringRef phoneNumber;
NSString* mobileLabel;
if(ABMultiValueGetCount(multiValue) > 0)
{
for(CFIndex i = 0; i < ABMultiValueGetCount(multiValue); i++)
{
mobileLabel = (NSString*)ABMultiValueCopyLabelAtIndex(multiValue, i);
if([mobileLabel isEqualToString:@"_$!<Mobile>!$_"]) {
phoneNumber = ABMultiValueCopyValueAtIndex(multiValue, i);
[companyAddress setValue:(NSString*)phoneNumber forKey:@"mobile"];
//NSLog(@"1=%@",phoneNumber);
CFRelease(phoneNumber);
}
else if([mobileLabel isEqualToString:@"_$!<Work>!$_"]) {
phoneNumber = ABMultiValueCopyValueAtIndex(multiValue, i);
[companyAddress setValue:(NSString*)phoneNumber forKey:KEYCONTACTS_PHONE];
//NSLog(@"2=%@",phoneNumber);
CFRelease(phoneNumber);
}
[mobileLabel release];
}
}
if(multiValue)
{
CFRelease(multiValue);
multiValue =nil;
}
[phoneContactsArray addObject:companyAddress];
}
[allPersons release];
}
CFRelease(sourcesArray);
CFRelease(iphoneAddress);
iphoneAddress=nil;
//delete key contact from app(deleated from native app)
BOOL deleteStatus=YES;
NSArray *allKeyContactArray=[[NSArray alloc]initWithArray:[[PFCoreDataController sharedCoreDataController]getAllSyncContacts]];
for(int m=0;m<[allKeyContactArray count];m++){
int devKeyContactId=[[[allKeyContactArray objectAtIndex:m]devConatctId]intValue];
deleteStatus=YES;
for(int n=0;n<[allDeviceContacts count];n++)
{
ABRecordRef person = [allDeviceContacts objectAtIndex:n];
int personId=ABRecordGetRecordID(person);
if(personId==devKeyContactId)
{
deleteStatus=NO;
break;
}
}
if(deleteStatus==YES)
{
//delete key contact
NSString *deviceId=[NSString stringWithFormat:@"%d",devKeyContactId];
NSArray *syncContactArray=[[NSArray alloc]initWithArray:[[PFCoreDataController sharedCoreDataController]getSyncContactsDetailsByDevId:deviceId]];
if([syncContactArray count]>0)
{
int contactId=[[[syncContactArray objectAtIndex:0]appContactId]intValue];
[[PFCoreDataController sharedCoreDataController]deleteSyncContacts:contactId];
[[PFCoreDataController sharedCoreDataController]deleteKeyContact:contactId];
}
[syncContactArray release];
}
}
[allKeyContactArray release];
//delete company from app(deleated from native app)
//deleteStatus=YES;
NSArray *allCompanyArray=[[NSArray alloc]initWithArray:[[PFCoreDataController sharedCoreDataController]getAllSyncCompanies]];
for(int m=0;m<[allCompanyArray count];m++)
{
int devKeyContactId=[[[allCompanyArray objectAtIndex:m]devCompanyId]intValue];
deleteStatus=YES;
for(int n=0;n<[allDeviceContacts count];n++)
{
ABRecordRef person = [allDeviceContacts objectAtIndex:n];
int personId=ABRecordGetRecordID(person);
if(personId==devKeyContactId)
{
deleteStatus=NO;
break;
}
}
if(deleteStatus==YES)
{
//delete contact
NSString *deviceId=[NSString stringWithFormat:@"%d",devKeyContactId];
NSArray *syncCompanyArray=[[NSArray alloc]initWithArray:[[PFCoreDataController sharedCoreDataController]getSyncCompanyDetailsByDevId:deviceId]];
if([syncCompanyArray count]>0)
{
int companyId=[[[syncCompanyArray objectAtIndex:0] appCompanyId]intValue];
NSString *companyName = nil;
NSArray *companyArray=[[NSArray alloc]initWithArray:[[PFCoreDataController sharedCoreDataController]getContactUsingContactId:companyId]];
if([companyArray count] > 0)
{
Contacts *tempContact=[companyArray objectAtIndex:0];
companyName=[NSString stringWithFormat:@"%@",tempContact.companyName];
}
[companyArray release];
//delete company
[[PFCoreDataController sharedCoreDataController]deleteSyncCompanyByAppId:companyId];
[[PFCoreDataController sharedCoreDataController]deleteCompanyById:companyId];
//check this company has key contact then create company to app
NSArray *keyContactOfCompany=[[NSArray alloc]initWithArray:[[PFCoreDataController sharedCoreDataController]getKeyContactsFromContact:[NSNumber numberWithInt:companyId] searchKey:@"*"]];
if([keyContactOfCompany count]>0){
NSString *nullValue = @"";
NSNumber *zeroValue = [NSNumber numberWithInt:0];
NSDictionary *company = [NSMutableDictionary dictionaryWithObjectsAndKeys:
zeroValue, CONTACTS_ID,
nullValue, CONTACTS_COMPANYNAME,
nullValue, CONTACTS_STREET,
nullValue, CONTACTS_STATE,
nullValue, CONTACTS_CITY,
nullValue, CONTACTS_ZIP,
nullValue, CONTACTS_COUNTRY,
nullValue, CONTACTS_PHONE,
nullValue, CONTACTS_WEBSITE,
nil];
[company setValue:companyName forKey:CONTACTS_COMPANYNAME];
[company setValue:[NSNumber numberWithInt:companyId] forKey:CONTACTS_ID];
[[PFCoreDataController sharedCoreDataController]addNewCompanyToApp:company];
}
[keyContactOfCompany release];
}
[syncCompanyArray release];
}
}
[allCompanyArray release];
[allDeviceContacts release];
//sort the objects(due to get company first)
NSString *descriptor = KEYCONTACTS_NAME;
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:descriptor ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray = [phoneContactsArray sortedArrayUsingDescriptors:sortDescriptors];
[phoneContactsArray removeAllObjects];
[phoneContactsArray addObjectsFromArray:sortedArray];
[sortDescriptor release];
//keep old company references
NSArray *syncContacts=[[NSArray alloc]initWithArray:[[PFCoreDataController sharedCoreDataController]getAllSyncCompanyDetails]];
for(int k=0;k<[syncContacts count];k++)
{
NSMutableDictionary *syncCompany = [[NSMutableDictionary alloc]init];
[syncCompany setValue:[[syncContacts objectAtIndex:k]appCompanyId] forKey:@"appId"];
[syncCompany setValue:[[syncContacts objectAtIndex:k]devCompanyId] forKey:@"devId"];
[oldSyncCompanies addObject:syncCompany];
[syncCompany release];
}
[syncContacts release];
//delete all key contacts
//[[PFCoreDataController sharedCoreDataController]deleteAllKeyContacts];
//[[PFCoreDataController sharedCoreDataController]deleteAllSyncContacts];
//delete all contacts
//[[PFCoreDataController sharedCoreDataController]deleteAllCompany];
//[[PFCoreDataController sharedCoreDataController]deleteAllSyncCompany];
//delete modified key contact from app
for(int p=0;p<[phoneContactsArray count];p++)
{
NSString *deviceId=[NSString stringWithFormat:@"%d",[[[phoneContactsArray objectAtIndex:p]valueForKey:@"personUId"]intValue]];
NSArray *syncContactArray=[[NSArray alloc]initWithArray:[[PFCoreDataController sharedCoreDataController]getSyncContactsDetailsByDevId:deviceId]];
if([syncContactArray count]>0)
{
int contactId=[[[syncContactArray objectAtIndex:0]appContactId]intValue];
[[PFCoreDataController sharedCoreDataController]deleteSyncContacts:contactId];
[[PFCoreDataController sharedCoreDataController]deleteKeyContact:contactId];
}
[syncContactArray release];
}
//delete modified company from app
for(int p=0;p<[phoneContactsArray count];p++)
{
NSString *deviceId=[NSString stringWithFormat:@"%d",[[[phoneContactsArray objectAtIndex:p]valueForKey:@"personUId"]intValue]];
NSArray *syncCompanyArray=[[NSArray alloc]initWithArray:[[PFCoreDataController sharedCoreDataController]getSyncCompanyDetailsByDevId:deviceId]];
if([syncCompanyArray count]>0)
{
int companyId=[[[syncCompanyArray objectAtIndex:0] appCompanyId]intValue];
[[PFCoreDataController sharedCoreDataController]deleteSyncCompanyByAppId:companyId];
[[PFCoreDataController sharedCoreDataController]deleteCompanyById:companyId];
}
[syncCompanyArray release];
}
//----------------> phone to app Synchornization <----------------//
for(int n=0;n<[phoneContactsArray count];n++)
{
NSMutableDictionary *phoneContact = [phoneContactsArray objectAtIndex:n];
NSString *companyName = (NSString*)[phoneContact valueForKey:@"company_Name"];
NSString *personName = (NSString*)[phoneContact valueForKey:KEYCONTACTS_NAME];
if(!(companyName == NULL) && !([companyName isEqualToString:@""]) && !([trimmedText(companyName) length] == 0))
{
if(!(personName == NULL) && !([personName isEqualToString:@""]) && !([trimmedText(personName) length] == 0))
{
NSArray *allCompanyArray=[[NSArray alloc]initWithArray:[[PFCoreDataController sharedCoreDataController] searchContact:companyName]];
//add key contact to existing company
if([allCompanyArray count]!=0)
{
for(Contacts *appContact in allCompanyArray)
{
NSInteger newContactId = [PFCommon getNewKeyContactId];
[phoneContact setValue:appContact.contactId forKey:KEYCONTACTS_CONTACTID];
[phoneContact setValue:[NSNumber numberWithInt:newContactId] forKey:KEYCONTACTS_ID];
[[PFCoreDataController sharedCoreDataController]addKeyContact:phoneContact];
[[PFCoreDataController sharedCoreDataController]addSynchedContacts:newContactId:[NSString stringWithFormat:@"%d",[[phoneContact valueForKey:@"personUId"] intValue]]];
}
}
//create company and add key contact
else
{
[self createNewCompany:phoneContact];
NSArray *aCompany=[[NSArray alloc]initWithArray:[[PFCoreDataController sharedCoreDataController] searchContact:companyName]];
if([aCompany count]>0)
{
Contacts *newContact= [aCompany objectAtIndex:0];
NSNumber *contactId=newContact.contactId;
NSInteger newKeyContactId = [PFCommon getNewKeyContactId];
[phoneContact setValue:contactId forKey:KEYCONTACTS_CONTACTID];
[phoneContact setValue:[NSNumber numberWithInt:newKeyContactId] forKey:KEYCONTACTS_ID];
[[PFCoreDataController sharedCoreDataController]addKeyContact:phoneContact];
[[PFCoreDataController sharedCoreDataController]addSynchedContacts:newKeyContactId:[NSString stringWithFormat:@"%d",[[phoneContact valueForKey:@"personUId"] intValue]]];
}
[aCompany release];
}
[allCompanyArray release];
}
else{
NSArray *allCompanyArray=[[NSArray alloc]initWithArray:[[PFCoreDataController sharedCoreDataController] searchContact:companyName]];
//check company existing if existing discard this contact
if([allCompanyArray count]!=0)
{}
//create only a company
else
{
[self createNewCompany:phoneContact];
}
[allCompanyArray release];
}
}
//if company field is null
else
{
NSArray *uncategoryCompany=[[NSArray alloc]initWithArray:[[PFCoreDataController sharedCoreDataController] searchContact:@"Uncategorized"]];
if([uncategoryCompany count]>0)
{}
else
{
[self createNewCompany:phoneContact];
[uncategoryCompany release];
uncategoryCompany=[[NSArray alloc]initWithArray:[[PFCoreDataController sharedCoreDataController] searchContact:@"Uncategorized"]];
}
//add new uncategorized key contacts
NSInteger newContactId = [PFCommon getNewKeyContactId];
[phoneContact setValue:(id)[[uncategoryCompany objectAtIndex:0]contactId] forKey:KEYCONTACTS_CONTACTID];
[phoneContact setValue:[NSNumber numberWithInt:newContactId] forKey:KEYCONTACTS_ID];
[[PFCoreDataController sharedCoreDataController]addKeyContact:phoneContact];
[[PFCoreDataController sharedCoreDataController]addSynchedContacts:newContactId:[NSString stringWithFormat:@"%d",[[phoneContact valueForKey:@"personUId"] intValue]]];
[uncategoryCompany release];
}
}
[phoneContactsArray release];
phoneContactsArray = nil;
//adds the last synched contact date
[[PFCoreDataController sharedCoreDataController] addLastContactSynchedDate:[PFCommon getContactSyncId] :[NSDate date]];
[PFCommon setContactSyncStatus:YES];
[self performSelector:@selector(hideActivityIndicatorView) withObject:nil afterDelay:1.0f];
}
- (void)createNewCompany:(NSMutableDictionary*)aCompany
{ NSString *nullValue = @""; NSNumber *zeroValue = [NSNumber numberWithInt:0];
NSDictionary *company = [NSMutableDictionary dictionaryWithObjectsAndKeys:
zeroValue, CONTACTS_ID,
nullValue, CONTACTS_COMPANYNAME,
nullValue, CONTACTS_STREET,
nullValue, CONTACTS_STATE,
nullValue, CONTACTS_CITY,
nullValue, CONTACTS_ZIP,
nullValue, CONTACTS_COUNTRY,
nullValue, CONTACTS_PHONE,
nullValue, CONTACTS_WEBSITE,
nil];
NSString *companyName = (NSString*)[aCompany valueForKey:@"company_Name"];
NSString * streetName = (NSString*)[aCompany valueForKey:@"street"];
NSLog(@"companyName %@",companyName);
//check the company is already added then keep old id
NSInteger contactId=-1;
for(int i=0;i<[oldSyncCompanies count];i++)
{
NSMutableDictionary *tempDict=[oldSyncCompanies objectAtIndex:i];
int oldDevId=[[tempDict valueForKey:@"devId"]intValue];
int newDevId=[[aCompany valueForKey:@"personUId"]intValue];
if(oldDevId==newDevId)
contactId=[[tempDict valueForKey:@"appId"] intValue];
}
if(contactId==-1)
contactId=[PFCommon getNewContactId];
if((companyName == NULL) || ([companyName isEqualToString:@""]) || ([trimmedText(companyName) length] == 0))
{
[company setValue:@"Uncategorized" forKey:CONTACTS_COMPANYNAME];
[company setValue:[NSNumber numberWithInt:-1] forKey:CONTACTS_ID];
contactId=-1;
}
else
{
[company setValue:[aCompany valueForKey:@"company_Name"] forKey:CONTACTS_COMPANYNAME];
[company setValue:[NSNumber numberWithInt:contactId] forKey:CONTACTS_ID];
//we added due to display company details/address Nikunj
[company setValue:[aCompany valueForKey:KEYCONTACTS_STREET] forKey:CONTACTS_STREET];
[company setValue:[aCompany valueForKey:KEYCONTACTS_CITY] forKey:CONTACTS_CITY];
[company setValue:[aCompany valueForKey:KEYCONTACTS_STATE] forKey:CONTACTS_STATE];
[company setValue:[aCompany valueForKey:KEYCONTACTS_ZIP] forKey:CONTACTS_ZIP];
[company setValue:[aCompany valueForKey:KEYCONTACTS_COUNTRY] forKey:CONTACTS_COUNTRY];
[company setValue:[aCompany valueForKey:KEYCONTACTS_PHONE] forKey:CONTACTS_PHONE];
[company setValue:[aCompany valueForKey:@"website"] forKey:CONTACTS_WEBSITE];
NSString *personName = (NSString*)[aCompany valueForKey:KEYCONTACTS_NAME];
//NSLog(@"personName %@",personName);
if((personName == NULL) || ([personName isEqualToString:@""]) || ([trimmedText(personName) length] == 0))
{
[company setValue:[aCompany valueForKey:KEYCONTACTS_STREET] forKey:CONTACTS_STREET];
[company setValue:[aCompany valueForKey:KEYCONTACTS_CITY] forKey:CONTACTS_CITY];
[company setValue:[aCompany valueForKey:KEYCONTACTS_STATE] forKey:CONTACTS_STATE];
[company setValue:[aCompany valueForKey:KEYCONTACTS_ZIP] forKey:CONTACTS_ZIP];
[company setValue:[aCompany valueForKey:KEYCONTACTS_COUNTRY] forKey:CONTACTS_COUNTRY];
[company setValue:[aCompany valueForKey:KEYCONTACTS_PHONE] forKey:CONTACTS_PHONE];
[company setValue:[aCompany valueForKey:@"website"] forKey:CONTACTS_WEBSITE];
}
}
[[PFCoreDataController sharedCoreDataController]addSynchedCompany:contactId:[NSString stringWithFormat:@"%d",[[aCompany valueForKey:@"personUId"] intValue]]];
[[PFCoreDataController sharedCoreDataController]addNewCompanyToApp:company];
}