获取 iOS 上所有联系人的列表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3747844/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get a list of all contacts on iOS
提问by Chiron
I want to get a list of all contacts of an iPhone.
我想获取 iPhone 的所有联系人列表。
I checked Address Book
reference, I may missed something but I didn't see it provides a method to get a list of contacts.
我检查了Address Book
参考资料,我可能错过了一些东西,但我没有看到它提供了一种获取联系人列表的方法。
回答by Rob
In my original answer, at the end of this answer, I show how to retrieve contacts in iOS versions prior to 9.0 in a manner that addresses some of the problems entailed by other answers here.
在我的原始答案中,在本答案的末尾,我展示了如何在 9.0 之前的 iOS 版本中检索联系人,以解决此处其他答案所带来的一些问题。
But, if only supporting iOS 9 and later, one should use the Contacts
framework, avoiding some of the annoying bridging issues entailed when using the older AddressBook
framework.
但是,如果只支持 iOS 9 及更高版本,则应该使用该Contacts
框架,避免使用旧AddressBook
框架时出现的一些烦人的桥接问题。
So, in iOS 9, you'd use the Contacts
framework:
因此,在 iOS 9 中,您将使用该Contacts
框架:
@import Contacts;
You also need to update your Info.plist
, adding a NSContactsUsageDescription
to explain why your app requires access to contacts.
您还需要更新您的Info.plist
,添加一个NSContactsUsageDescription
来解释为什么您的应用需要访问联系人。
And then do something like follows:
然后执行如下操作:
CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
if (status == CNAuthorizationStatusDenied || status == CNAuthorizationStatusRestricted) {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Access to contacts." message:@"This app requires access to contacts because ..." preferredStyle:UIAlertControllerStyleActionSheet];
[alert addAction:[UIAlertAction actionWithTitle:@"Go to Settings" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString] options:@{} completionHandler:nil];
}]];
[alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]];
[self presentViewController:alert animated:TRUE completion:nil];
return;
}
CNContactStore *store = [[CNContactStore alloc] init];
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
// make sure the user granted us access
if (!granted) {
dispatch_async(dispatch_get_main_queue(), ^{
// user didn't grant access;
// so, again, tell user here why app needs permissions in order to do it's job;
// this is dispatched to the main queue because this request could be running on background thread
});
return;
}
// build array of contacts
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);
}
// you can now do something with the list of contacts, for example, to show the names
CNContactFormatter *formatter = [[CNContactFormatter alloc] init];
for (CNContact *contact in contacts) {
NSString *string = [formatter stringFromContact:contact];
NSLog(@"contact = %@", string);
}
}];
Below is my answer applicable if supporting iOS versions prior to iOS 9.0.
如果支持 iOS 9.0 之前的 iOS 版本,以下是我的回答。
--
——
A couple of reactions to not only your question, but also many of the answers provided here (which either fail to request permission, don't handle ABAddressBookCreateWithOptions
errors properly, or leak):
对您的问题以及此处提供的许多答案的一些反应(要么未请求许可,未ABAddressBookCreateWithOptions
正确处理错误,要么泄漏):
Obviously, import the
AddressBook
framework:#import <AddressBook/AddressBook.h>
or
@import AddressBook;
You must request permission for the app to access the contacts. For example:
ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus(); if (status == kABAuthorizationStatusDenied || status == kABAuthorizationStatusRestricted) { // if you got here, user had previously denied/revoked permission for your // app to access the contacts and all you can do is handle this gracefully, // perhaps telling the user that they have to go to settings to grant access // to contacts [[[UIAlertView alloc] initWithTitle:nil message:@"This app requires access to your contacts to function properly. Please visit to the \"Privacy\" section in the iPhone Settings app." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show]; return; } CFErrorRef error = NULL; ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error); if (!addressBook) { NSLog(@"ABAddressBookCreateWithOptions error: %@", CFBridgingRelease(error)); return; } ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) { if (error) { NSLog(@"ABAddressBookRequestAccessWithCompletion error: %@", CFBridgingRelease(error)); } if (granted) { // if they gave you permission, then just carry on [self listPeopleInAddressBook:addressBook]; } else { // however, if they didn't give you permission, handle it gracefully, for example... dispatch_async(dispatch_get_main_queue(), ^{ // BTW, this is not on the main thread, so dispatch UI updates back to the main queue [[[UIAlertView alloc] initWithTitle:nil message:@"This app requires access to your contacts to function properly. Please visit to the \"Privacy\" section in the iPhone Settings app." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show]; }); } CFRelease(addressBook); });
Note that above, I have not used the pattern suggested by others:
CFErrorRef *error = NULL; ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);
That is not correct. As you'll see above, you want:
CFErrorRef error = NULL; ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
The former pattern will not capture the error correctly, whereas the latter will. If
error
was notNULL
, don't forget toCFRelease
it (or transfer ownership to ARC like I did) or else you'll leak that object.To iterate through the contacts, you want to:
- (void)listPeopleInAddressBook:(ABAddressBookRef)addressBook { NSArray *allPeople = CFBridgingRelease(ABAddressBookCopyArrayOfAllPeople(addressBook)); NSInteger numberOfPeople = [allPeople count]; for (NSInteger i = 0; i < numberOfPeople; i++) { ABRecordRef person = (__bridge ABRecordRef)allPeople[i]; NSString *firstName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonFirstNameProperty)); NSString *lastName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonLastNameProperty)); NSLog(@"Name:%@ %@", firstName, lastName); ABMultiValueRef phoneNumbers = ABRecordCopyValue(person, kABPersonPhoneProperty); CFIndex numberOfPhoneNumbers = ABMultiValueGetCount(phoneNumbers); for (CFIndex j = 0; j < numberOfPhoneNumbers; j++) { NSString *phoneNumber = CFBridgingRelease(ABMultiValueCopyValueAtIndex(phoneNumbers, j)); NSLog(@" phone:%@", phoneNumber); } CFRelease(phoneNumbers); NSLog(@"============================================="); } }
I want to draw your attention to a fairly key detail, namely the "Create Rule":
Core Foundation functions have names that indicate when you own a returned object:
Object-creation functions that have “
Create
” embedded in the name;Object-duplication functions that have “
Copy
” embedded in the name.
If you own an object, it is your responsibility to relinquish ownership (using CFRelease) when you have finished with it.
This means that you bear responsibility for releasing any object returned by any Core Foundation function with
Create
orCopy
in the name. You can either callCFRelease
explicitly (as I did above withaddressBook
andphoneNumbers
) or, for objects that support toll-free bridging, you can transfer ownership to ARC with__bridge_transfer
orCFBridgingRelease
(as I did above withallPeople
,lastName
,firstName
, andphoneNumber
).The static analyzer (press shift+command+Bin Xcode or choose "Analyze" from the "Product" menu) can identify many situations in which you neglected to observe this "Create Rule" and failed to release the appropriate objects. So, whenever writing Core Foundation code like this, always run it through the static analyzer to make sure you don't have any obvious leaks.
显然,导入
AddressBook
框架:#import <AddressBook/AddressBook.h>
或者
@import AddressBook;
您必须请求应用程序访问联系人的权限。例如:
ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus(); if (status == kABAuthorizationStatusDenied || status == kABAuthorizationStatusRestricted) { // if you got here, user had previously denied/revoked permission for your // app to access the contacts and all you can do is handle this gracefully, // perhaps telling the user that they have to go to settings to grant access // to contacts [[[UIAlertView alloc] initWithTitle:nil message:@"This app requires access to your contacts to function properly. Please visit to the \"Privacy\" section in the iPhone Settings app." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show]; return; } CFErrorRef error = NULL; ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error); if (!addressBook) { NSLog(@"ABAddressBookCreateWithOptions error: %@", CFBridgingRelease(error)); return; } ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) { if (error) { NSLog(@"ABAddressBookRequestAccessWithCompletion error: %@", CFBridgingRelease(error)); } if (granted) { // if they gave you permission, then just carry on [self listPeopleInAddressBook:addressBook]; } else { // however, if they didn't give you permission, handle it gracefully, for example... dispatch_async(dispatch_get_main_queue(), ^{ // BTW, this is not on the main thread, so dispatch UI updates back to the main queue [[[UIAlertView alloc] initWithTitle:nil message:@"This app requires access to your contacts to function properly. Please visit to the \"Privacy\" section in the iPhone Settings app." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show]; }); } CFRelease(addressBook); });
请注意,上面,我没有使用其他人建议的模式:
CFErrorRef *error = NULL; ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);
那是不正确的。正如你在上面看到的,你想要:
CFErrorRef error = NULL; ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
前一种模式不会正确捕获错误,而后者会。如果
error
不是NULL
,请不要忘记CFRelease
它(或像我一样将所有权转让给 ARC),否则您将泄漏该对象。要遍历联系人,您需要:
- (void)listPeopleInAddressBook:(ABAddressBookRef)addressBook { NSArray *allPeople = CFBridgingRelease(ABAddressBookCopyArrayOfAllPeople(addressBook)); NSInteger numberOfPeople = [allPeople count]; for (NSInteger i = 0; i < numberOfPeople; i++) { ABRecordRef person = (__bridge ABRecordRef)allPeople[i]; NSString *firstName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonFirstNameProperty)); NSString *lastName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonLastNameProperty)); NSLog(@"Name:%@ %@", firstName, lastName); ABMultiValueRef phoneNumbers = ABRecordCopyValue(person, kABPersonPhoneProperty); CFIndex numberOfPhoneNumbers = ABMultiValueGetCount(phoneNumbers); for (CFIndex j = 0; j < numberOfPhoneNumbers; j++) { NSString *phoneNumber = CFBridgingRelease(ABMultiValueCopyValueAtIndex(phoneNumbers, j)); NSLog(@" phone:%@", phoneNumber); } CFRelease(phoneNumbers); NSLog(@"============================================="); } }
我想提请您注意一个相当关键的细节,即“创建规则”:
Core Foundation 函数的名称指示您何时拥有返回的对象:
Create
名称中嵌入了“ ”的对象创建函数;Copy
名称中嵌入了“ ”的对象复制函数。
如果您拥有一个对象,您有责任在完成后放弃所有权(使用 CFRelease)。
这意味着您有责任释放任何 Core Foundation 函数返回的任何带有
Create
或Copy
在名称中的对象。您可以拨打CFRelease
明确的(像我一样上面addressBook
和phoneNumbers
),或者对于对象支持免费桥接,可以将所有权转让给电弧__bridge_transfer
或CFBridgingRelease
(如我上面做了allPeople
,lastName
,firstName
,和phoneNumber
)。静态分析器(在 Xcode 中按shift+ command+B或从“产品”菜单中选择“分析”)可以识别许多您忽略遵守此“创建规则”而未能释放相应对象的情况。因此,每当编写这样的 Core Foundation 代码时,请始终通过静态分析器运行它以确保您没有任何明显的泄漏。
回答by martin clayton
Perhaps ABPerson
function ABAddressBookCopyArrayOfAllPeoplemight do?
也许ABPerson
函数ABAddressBookCopyArrayOfAllPeople可以做?
示例:
ABAddressBookRef addressBook = ABAddressBookCreate( );
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople( addressBook );
CFIndex nPeople = ABAddressBookGetPersonCount( addressBook );
for ( int i = 0; i < nPeople; i++ )
{
ABRecordRef ref = CFArrayGetValueAtIndex( allPeople, i );
...
}
回答by Denis Kutlubaev
Use this code to display all names + lastnames + phonenumbers (iOS 6). Works on simulator too:
使用此代码显示所有姓名 + 姓氏 + 电话号码 (iOS 6)。也适用于模拟器:
CFErrorRef *error = NULL;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex numberOfPeople = ABAddressBookGetPersonCount(addressBook);
for(int i = 0; i < numberOfPeople; i++) {
ABRecordRef person = CFArrayGetValueAtIndex( allPeople, i );
NSString *firstName = (__bridge NSString *)(ABRecordCopyValue(person, kABPersonFirstNameProperty));
NSString *lastName = (__bridge NSString *)(ABRecordCopyValue(person, kABPersonLastNameProperty));
NSLog(@"Name:%@ %@", firstName, lastName);
ABMultiValueRef phoneNumbers = ABRecordCopyValue(person, kABPersonPhoneProperty);
for (CFIndex i = 0; i < ABMultiValueGetCount(phoneNumbers); i++) {
NSString *phoneNumber = (__bridge_transfer NSString *) ABMultiValueCopyValueAtIndex(phoneNumbers, i);
NSLog(@"phone:%@", phoneNumber);
}
NSLog(@"=============================================");
}
回答by Hector204
Make sure you have the proper import
确保您有正确的导入
#import <AddressBook/AddressBook.h>
Then you can get a CFArray object with all contacts using
然后你可以得到一个包含所有联系人的 CFArray 对象使用
CFArrayRef ABAddressBookCopyArrayOfAllPeople (ABAddressBookRef addressBook);
回答by danielM
In iOS 6, make sure you use ABAddressBookCreateWithOptions
, which is the updated version of ABAddressBookCreate
在 iOS 6 中,请确保使用ABAddressBookCreateWithOptions
,这是更新版本ABAddressBookCreate
CFErrorRef * error = NULL;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex numberOfPeople = ABAddressBookGetPersonCount(addressBook);
for(int i = 0; i < numberOfPeople; i++){
ABRecordRef person = CFArrayGetValueAtIndex( allPeople, i );
// More code here
}
回答by Hossam Ghareeb
Updatefor iOS 9.0
. Apple has deprecated AddressBook
and now they have added Contacts
framework:
更新了iOS 9.0
。Apple 已弃用AddressBook
,现在他们添加了Contacts
框架:
Add CNContactStore
property and define it like this:
添加CNContactStore
属性并像这样定义它:
self.contactsStrore = [[CNContactStore alloc] init];
Then add these methods to read all contacts:
然后添加这些方法来读取所有联系人:
-(void)checkContactsAccess{
[self requestContactsAccessWithHandler:^(BOOL grandted) {
if (grandted) {
CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:@[CNContactFamilyNameKey, CNContactGivenNameKey, CNContactNamePrefixKey, CNContactMiddleNameKey, CNContactPhoneNumbersKey]];
[self.contactsStrore enumerateContactsWithFetchRequest:request error:nil usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) {
NSLog(@"%@", contact.familyName);
NSLog(@"%@", contact.givenName);
NSLog(@"%@", contact.namePrefix);
NSLog(@"%@", contact.middleName);
NSLog(@"%@", contact.phoneNumbers);
NSLog(@"=============================================");
}];
}
}];
}
-(void)requestContactsAccessWithHandler:(void (^)(BOOL grandted))handler{
switch ([CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts]) {
case CNAuthorizationStatusAuthorized:
handler(YES);
break;
case CNAuthorizationStatusDenied:
case CNAuthorizationStatusNotDetermined:{
[self.contactsStrore requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
handler(granted);
}];
break;
}
case CNAuthorizationStatusRestricted:
handler(NO);
break;
}
}
Before iOS 9.0 => Use AddressBook
framework.
You have to check for access and request access to User contacts first:
iOS 9.0 之前 => 使用AddressBook
框架。您必须首先检查访问权限并请求访问用户联系人:
// Prompt the user for access to their Address Book data
-(void)requestAddressBookAccess
{
YourViewController * __weak weakSelf = self;
ABAddressBookRequestAccessWithCompletion(self.addressBook, ^(bool granted, CFErrorRef error)
{
if (granted)
{
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf accessGrantedForAddressBook];
});
}
});
}
-(void)checkAddressBookAccess
{
switch (ABAddressBookGetAuthorizationStatus())
{
// Update our UI if the user has granted access to their Contacts
case kABAuthorizationStatusAuthorized:
[self accessGrantedForAddressBook];
break;
// Prompt the user for access to Contacts if there is no definitive answer
case kABAuthorizationStatusNotDetermined :
[self requestAddressBookAccess];
break;
// Display a message if the user has denied or restricted access to Contacts
case kABAuthorizationStatusDenied:
case kABAuthorizationStatusRestricted:
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Privacy Warning"
message:@"Permission was not granted for Contacts."
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}
break;
default:
break;
}
}
回答by Roozbeh Zabihollahi
Thanks to mahesh and wzbozon, the following code worked for me:
感谢 mahesh 和 wzbozon,以下代码对我有用:
CFErrorRef * error = NULL;
addressBook = ABAddressBookCreateWithOptions(NULL, error);
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error)
{
if (granted)
{
dispatch_async(dispatch_get_main_queue(), ^{
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex numberOfPeople = ABAddressBookGetPersonCount(addressBook);
for(int i = 0; i < numberOfPeople; i++){
ABRecordRef person = CFArrayGetValueAtIndex( allPeople, i );
NSString *firstName = (__bridge NSString *)(ABRecordCopyValue(person, kABPersonFirstNameProperty));
NSString *lastName = (__bridge NSString *)(ABRecordCopyValue(person, kABPersonLastNameProperty));
NSLog(@"Name:%@ %@", firstName, lastName);
ABMultiValueRef phoneNumbers = ABRecordCopyValue(person, kABPersonPhoneProperty);
NSMutableArray *numbers = [NSMutableArray array];
for (CFIndex i = 0; i < ABMultiValueGetCount(phoneNumbers); i++) {
NSString *phoneNumber = (__bridge_transfer NSString *) ABMultiValueCopyValueAtIndex(phoneNumbers, i);
[numbers addObject:phoneNumber];
}
NSMutableDictionary *contact = [NSMutableDictionary dictionary];
[contact setObject:name forKey:@"name"];
[contact setObject:numbers forKey:@"numbers"];
[all_contacts addObject:contact];
}
});
}
});
回答by Bojan Bozovic
Swift version:
迅捷版:
override func viewDidLoad() {
super.viewDidLoad()
var error: Unmanaged<CFErrorRef>?
var addressBook: ABAddressBook = ABAddressBookCreateWithOptions(nil, &error).takeRetainedValue()
if ABAddressBookGetAuthorizationStatus() == ABAuthorizationStatus.NotDetermined {
ABAddressBookRequestAccessWithCompletion(addressBook, {
(granted:Bool, error:CFErrorRef!) -> Void in
self.populateFrom(addressBook: addressBook)
})
}
else if ABAddressBookGetAuthorizationStatus() == ABAuthorizationStatus.Authorized {
self.populateFrom(addressBook: addressBook)
}
}
func populateFrom(#addressBook:ABAddressBook){
let allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook).takeRetainedValue()
let nPeople = ABAddressBookGetPersonCount(addressBook)
for index in 0..<nPeople{
let person: ABRecordRef = Unmanaged<ABRecordRef>.fromOpaque(COpaquePointer(CFArrayGetValueAtIndex(allPeople, index))).takeUnretainedValue()
let firstName: String = ABRecordCopyValue(person, kABPersonFirstNameProperty).takeUnretainedValue() as? String
println("\(firstName.debugDescription)")
}
}
回答by vaughan
Check out https://github.com/heardrwt/RHAddressBook(254 stars 01/2014).
查看https://github.com/heardrwt/RHAddressBook(254颗星 01/2014)。
Provides an ObjC wrapper for AddressBook with much simpler API.
使用更简单的 API 为 AddressBook 提供 ObjC 包装器。
回答by KumarS
This works for ios 7 and ios 8 , i hope its help you.............
这适用于 ios 7 和 ios 8,我希望它对你有帮助.......
NSMutableArray *result = [[NSMutableArray alloc] init];
CFErrorRef *error = nil;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);
__block BOOL accessGranted = NO;
if (ABAddressBookRequestAccessWithCompletion != NULL){
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
accessGranted = granted;
dispatch_semaphore_signal(sema);
});
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
}
else{
accessGranted = YES;
}
if (accessGranted){
// If the app is authorized to access the first time then add the contact
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex numberOfPeople = ABAddressBookGetPersonCount(addressBook);
for (int i=0; i<numberOfPeople; i++){
CFStringRef phone;
ABRecordRef person = CFArrayGetValueAtIndex(allPeople, i);
CFStringRef firstName = ABRecordCopyValue(person, kABPersonFirstNameProperty);
CFStringRef lastName = ABRecordCopyValue(person, kABPersonLastNameProperty);
NSString *userName = @"NoName";
userName = [NSString stringWithFormat:@"%@ %@", firstName, lastName];
userName = [userName stringByReplacingOccurrencesOfString:@"(null)" withString:@""];
ABMutableMultiValueRef phoneNumbers = ABRecordCopyValue(person, kABPersonPhoneProperty);
CFIndex phoneNumberCount = ABMultiValueGetCount( phoneNumbers );
phone = nil;
for ( CFIndex ind= 0; ind<phoneNumberCount; ind++ ){
CFStringRef phoneNumberLabel = ABMultiValueCopyLabelAtIndex( phoneNumbers, ind);
CFStringRef phoneNumberValue = ABMultiValueCopyValueAtIndex( phoneNumbers, ind);
// converts "_$!<Work>!$_" to "work" and "_$!<Mobile>!$_" to "mobile"
// Find the ones you want here
if (phoneNumberLabel != nil){
NSStringCompareOptions compareOptions = NSCaseInsensitiveSearch;
if(CFStringCompare(phoneNumberLabel, CFSTR("mobile"),compareOptions)){
phone = phoneNumberValue;
}
phone = phoneNumberValue;
NSStringCompareOptions compareOptionss = NSCaseInsensitiveSearch;
if(!CFStringCompare(phone, CFSTR("1-800-MY-APPLE"),compareOptionss)){
continue;
}
NSMutableArray *theKeys = [NSMutableArray arrayWithObjects:@"name", @"small_name",@"phone", @"checked", nil];
NSMutableArray *theObjects = [NSMutableArray arrayWithObjects:userName, [userName lowercaseString],phone, @"NO", nil];
NSMutableDictionary *theDict = [NSMutableDictionary dictionaryWithObjects:theObjects forKeys:theKeys];
if (![[functions formatNumber:(__bridge NSString *)(phone)] isEqualToString:[[NSUserDefaults standardUserDefaults]valueForKey:@"phoneNumber"]]){
[result addObject:theDict];
}
}
}
}
}
//sort array
NSSortDescriptor * descriptor = [[NSSortDescriptor alloc] initWithKey:@"small_name"
ascending:YES]; // 1
NSArray * sortedArray = [result sortedArrayUsingDescriptors:[NSArray arrayWithObject:descriptor]];