我的 iPad 中有超过 6000 个联系人,并获取所有联系人并存储在核心数据中,我已经在我的应用程序中实现了这个功能,但是它花费了太多时间来获取和加载数据,所以有什么方法可以获取、存储数据异步或其他方式。
所以请给我建议或任何想法来解决我的问题。
提前致谢。
//同步联系人的代码
- (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];
}