[iOS] iOS6 iOS7 訪問和使用系統通訊錄

導入AddressBook和AddressBookUI框架

iOS 6之前,可以通過如下方法獲得通訊錄

ABAddressBookRef addressBook = ABAddressBookCreate();  

不過在iOS 6之後,這個方法被廢棄,可以使用下面的方法獲得通訊錄。
AB_EXTERN ABAddressBookRef ABAddressBookCreateWithOptions(CFDictionaryRef options, CFErrorRef* error) __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_6_0);  

而且在ios6之後,每個App要訪問通訊錄都應該得到用戶的授權:
//系統定義的block
typedef void(^ABAddressBookRequestAccessCompletionHandler)(bool granted, CFErrorRef error);  
//獲取授權的方法,其中第二個參數是上面定義的block
AB_EXTERN void ABAddressBookRequestAccessWithCompletion(ABAddressBookRef addressBook,  ABAddressBookRequestAccessCompletionHandler completion) __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_6_0);  
代碼如下:


-(void)getAddress
{
    //typedef CFTypeRef ABAddressBookRef;
    //typedef const void * CFTypeRef;
    //指向常量的指針
    ABAddressBookRef addressBook = nil;
    //判斷當前系統的版本
    if ([[UIDevice currentDevice].systemVersion floatValue] >= 6.0)
    {
        //如果不小於6.0,使用對應的api獲取通訊錄,注意,必須先請求用戶的同意,如果未獲得同意或者用戶未操作,此通訊錄的內容爲空
        addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
//等待同意後向下執行
//爲了保證用戶同意後在進行操作,此時使用多線程的信號量機制,創建信號量,信號量的資源數0表示沒有資源,調用dispatch_semaphore_wait會立即等待。若對此處不理解,請參看GCD信號量同步相關內容。
        dispatch_semaphore_t sema = dispatch_semaphore_create(0);
//發出訪問通訊錄的請求
        ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error){
            //如果用戶同意,纔會執行此block裏面的方法
            //此方法發送一個信號,增加一個資源數
            dispatch_semaphore_signal(sema);});
        //如果之前的block沒有執行,則sema的資源數爲零,程序將被阻塞
        //當用戶選擇同意,block的方法被執行, sema資源數爲1;
        dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
        dispatch_release(sema);
    }//如果系統是6.0之前的系統,不需要獲得同意,直接訪問
else{  addressBook = ABAddressBookCreate(); 
}
    //通訊錄信息已獲得,開始取出
    CFArrayRef results = ABAddressBookCopyArrayOfAllPeople(addressBook);
    //聯繫人條目數(使用long而不使用int是爲了兼容64位)
    long peopleCount = CFArrayGetCount(results);
    for (int i=0; i<peopleCount; i++)
    {
        ABRecordRef record = CFArrayGetValueAtIndex(results, i);
        NSString *firstName,*lastName;

        firstName = nil;
        lastName= nil;

        CFTypeRef tmp = NULL;
        //firstName
        tmp = ABRecordCopyValue(record, kABPersonFirstNameProperty);
        if (tmp) {
            firstName = [NSString stringWithString:tmp];
            CFRelease(tmp);tmp = NULL;
        }
        //lastName
        tmp = ABRecordCopyValue(record, kABPersonLastNameProperty);
    if (tmp){
        lastName= [NSString stringWithString:tmp];
        CFRelease(tmp);
        tmp = NULL;
    }
        //取得完整名字(與上面firstName、lastName無關)
      CFStringRef  fullName=ABRecordCopyCompositeName(record);
        NSLog(@"%@",(NSString*)fullName);
    // 讀取電話,不只一個
        ABMultiValueRef phones = ABRecordCopyValue(record, kABPersonPhoneProperty);
    long phoneCount = ABMultiValueGetCount(phones);
    for (int j=0; j<phoneCount; j++) {
        // label
        CFStringRef lable = ABMultiValueCopyLabelAtIndex(phones, j);
        // phone number
        CFStringRef number = ABMultiValueCopyValueAtIndex(phones, j);
        // localize label
        CFStringRef local = ABAddressBookCopyLocalizedLabel(lable);
        //此處可使用一個自定義的model類來存儲姓名和電話信息。我在這裏就直接輸出了。
        NSLog(@"number%@" ,(NSString *)number);
        if (local)CFRelease(local);
        if (lable) CFRelease(lable);
        if (number)CFRelease(number);
    }
        if (phones) CFRelease(phones);
        record = NULL;
    }
    if (results)CFRelease(results);
results = nil;if (addressBook)CFRelease(addressBook);
addressBook = NULL;
}


請求訪問通訊錄,只有第一次會彈出警示框詢問用戶。可通過以下方法判斷狀態來提醒用戶

//系統定義的枚舉類型
typedef CF_ENUM(CFIndex, ABAuthorizationStatus) {

kABAuthorizationStatusNotDetermined = 0,

kABAuthorizationStatusRestricted,

kABAuthorizationStatusDenied,

kABAuthorizationStatusAuthorized 

};  AB_EXTERN ABAuthorizationStatus ABAddressBookGetAuthorizationStatus(void) __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_6_0);  
//獲得狀態,根據狀態判斷
 ABAuthorizationStatus statu=ABAddressBookGetAuthorizationStatus();



以上內容 iphone4 ios7.1.1真機測試通過。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章