iOS:通信錄(18-01-17更)

来源:https://www.cnblogs.com/leonlincq/archive/2018/01/17/8304249.html
-Advertisement-
Play Games

1、讀取通信錄 1)、9.0以前 2)、9.0以後 2、調用通信錄UI 1)、9.0以前 2)、9.0以後 3、參考 0、寫在前面 plist 需要設置隱私許可權 Privacy - Contacts Usage Description : 請求訪問通訊錄(自定義) 1、讀取通信錄 1)、9.0以前 ...


1、讀取通信錄

  1)、9.0以前:AddressBook

  2)、9.0以後:Contacts

2、調用通信錄UI(不弄)

  1)、9.0以前:AddressBookUI

  2)、9.0以後:ContactsUI

3、參考

 

0、寫在前面

  1)、plist 需要設置 隱私許可權描述

    NSContactsUsageDescription(Privacy - Contacts Usage Description) :請求訪問通訊錄(自定義) 

  2)、一般應用只需要電話就夠了,不過,如果想做 壞事 大數據分析,可能還是要全讀取給後臺吧?

  3)、9.0後的 Contacts 類:

    3-1)、如果請求數據的數組裡沒有該Key,但在 block 判斷有,會奔潰。

    3-2)、請求類型key,有10.0後的,需要註意,做判斷。               

  4)、原生UI不打算弄了,感覺一般都是自定義UI,比如:有註冊的在上面,添加好友按鈕,沒註冊的在下麵,邀請好友按鈕。

  5)、有空再整理成 單例manage。 

 

1、讀取通信錄

  1)、9.0以前

    1-1)、頭文件

#import <AddressBook/AddressBook.h>

    1-2)、判斷是否有許可權

- (void)DetermineAndReadAddressBook
{
    // 判斷是否授權
    ABAuthorizationStatus authorizationStatus = ABAddressBookGetAuthorizationStatus();
    if (authorizationStatus == kABAuthorizationStatusNotDetermined) {
        // 請求授權
        ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, NULL);
        ABAddressBookRequestAccessWithCompletion(addressBookRef, ^(bool granted, CFErrorRef error){
            if (granted) {
                // 授權成功
                [self readAddressBook];
            } else {
                // 授權失敗
                NSLog(@"提示:用戶取消授權,讀取失敗");
            }
        });
    }
    else if (authorizationStatus == kABAuthorizationStatusAuthorized){
        // 授權過
        [self readAddressBook];
    }
    else {
        dispatch_async(dispatch_get_main_queue(), ^{
            // 更新界面
            NSLog(@"提示:應用-通信錄 設置");
        });
    }
}

    1-3)、讀取並保存模型(未做)

- (void)readAddressBook {
    
    // 獲取所有聯繫人
    ABAddressBookRef addressBookRef = ABAddressBookCreate();
    // 獲取所有聯繫人 數據
    CFArrayRef peoples = ABAddressBookCopyArrayOfAllPeople(addressBookRef);
    // 獲取所有聯繫人 個數
    CFIndex peoplesCount = ABAddressBookGetPersonCount(addressBookRef);
    
    for (int i = 0; i < peoplesCount; i++) {
        //獲取聯繫人對象的引用
        ABRecordRef people = CFArrayGetValueAtIndex(peoples, i);
        
        //獲取當前聯繫人名字
        NSString *firstName=(__bridge NSString *)(ABRecordCopyValue(people, kABPersonFirstNameProperty));
        //獲取當前聯繫人姓氏
        NSString *lastName=(__bridge NSString *)(ABRecordCopyValue(people, kABPersonLastNameProperty));
        NSLog(@"--------------------------------------------------");
        NSLog(@"firstName=%@, lastName=%@", firstName, lastName);
        
        //獲取當前聯繫人中間名
        NSString *middleName=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonMiddleNameProperty));
        //獲取當前聯繫人的名字首碼
        NSString *prefix=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonPrefixProperty));
        //獲取當前聯繫人的名字尾碼
        NSString *suffix=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonSuffixProperty));
        //獲取當前聯繫人的昵稱
        NSString *nickName=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonNicknameProperty));
        //獲取當前聯繫人的名字拼音
        NSString *firstNamePhoneic=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonFirstNamePhoneticProperty));
        //獲取當前聯繫人的姓氏拼音
        NSString *lastNamePhoneic=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonLastNamePhoneticProperty));
        //獲取當前聯繫人的中間名拼音
        NSString *middleNamePhoneic=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonMiddleNamePhoneticProperty));
        //獲取當前聯繫人的公司
        NSString *organization=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonOrganizationProperty));
        //獲取當前聯繫人的職位
        NSString *job=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonJobTitleProperty));
        //獲取當前聯繫人的部門
        NSString *department=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonDepartmentProperty));
        
        //獲取當前聯繫人的生日
        NSDate *birthday=(__bridge NSDate*)(ABRecordCopyValue(people, kABPersonBirthdayProperty));
        //獲取當前聯繫人的備註
        NSString *notes=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonNoteProperty));
        
        //獲取當前聯繫人頭像圖片
        NSData *userImage=(__bridge NSData*)(ABPersonCopyImageData(people));
        
        //獲取kind值
        CFNumberRef kindType = ABRecordCopyValue(people, kABPersonKindProperty);
        if (kindType == kABPersonKindOrganization) {
            NSLog(@"公司");
        } else {
            // it's a person, resource, or room
            NSLog(@"個人");
        }
        
        //獲取創建當前聯繫人的時間 註意是NSDate
        NSDate *creatTime=(__bridge NSDate*)(ABRecordCopyValue(people, kABPersonCreationDateProperty));
        //獲取最近修改當前聯繫人的時間
        NSDate *alterTime=(__bridge NSDate*)(ABRecordCopyValue(people, kABPersonModificationDateProperty));
        
        
        
        //獲取當前聯繫人的電話 數組
        NSMutableArray *phoneArray = [[NSMutableArray alloc]init];
        ABMultiValueRef phones = ABRecordCopyValue(people, kABPersonPhoneProperty);
        CFIndex phonesCount = ABMultiValueGetCount(phones);
        for (NSInteger j=0; j<phonesCount; j++) {
            //獲取電話Label
            NSString *phoneLabel = (__bridge NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(phones, j));
            //獲取該Label下的電話值
            NSString *phone = (__bridge NSString *)(ABMultiValueCopyValueAtIndex(phones, j));
            NSLog(@"phone=%@", phone);
            [phoneArray addObject:phone];
        }

        //獲取IM多值
        NSMutableArray *instantMessageArray = [[NSMutableArray alloc]init];
        ABMultiValueRef instantMessages = ABRecordCopyValue(people, kABPersonInstantMessageProperty);
        CFIndex instantMessagesCount = ABMultiValueGetCount(instantMessages);
        for (int j = 1; j < instantMessagesCount; j++)
        {
            //獲取IM Label
            NSString* instantMessageLabel = (__bridge NSString*)ABMultiValueCopyLabelAtIndex(instantMessages, j);
            //獲取IM 的內容
            NSDictionary* instantMessageContent =(__bridge NSDictionary*)ABMultiValueCopyValueAtIndex(instantMessages, j);
            NSString* username = [instantMessageContent valueForKey:(NSString *)kABPersonInstantMessageUsernameKey];
            NSString* service = [instantMessageContent valueForKey:(NSString *)kABPersonInstantMessageServiceKey];
        }
        
        //獲取URL多值
        NSMutableArray *urlArray = [[NSMutableArray alloc]init];
        ABMultiValueRef urls = ABRecordCopyValue(people, kABPersonURLProperty);
        CFIndex urlsCount = ABMultiValueGetCount(urls);
        for (int j = 0; j < urlsCount; j++)
        {
            //獲取電話Label
            NSString * urlLabel = (__bridge NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(urls, j));
            //獲取該Label下的電話值
            NSString * urlContent = (__bridge NSString*)ABMultiValueCopyValueAtIndex(urls,j);
        }
        
        //獲取當前聯繫人的郵箱 註意是數組
        NSMutableArray *emailArray = [[NSMutableArray alloc]init];
        ABMultiValueRef emails= ABRecordCopyValue(people, kABPersonEmailProperty);
        CFIndex emailsCount = ABMultiValueGetCount(emails);
        for (NSInteger j=0; j< emailsCount; j++) {
            //獲取email Label
            NSString* emailLabel = (__bridge NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(emails, j));
            //獲取email值
            NSString *email = (__bridge NSString *)(ABMultiValueCopyValueAtIndex(emails, j));
            NSLog(@"email=%@", email);
            [emailArray addObject:email];
        }
        
        //獲取地址 註意是數組
        NSMutableArray *addressArray = [[NSMutableArray alloc]init];
        ABMultiValueRef addresss = ABRecordCopyValue(people, kABPersonAddressProperty);
        CFIndex addresssCount = ABMultiValueGetCount(addresss);
        for (int j=0; j<addresssCount; j++) {
            // 地址類型
            NSString *addressLabel = (__bridge NSString *)(ABMultiValueCopyLabelAtIndex(addresss, j));
            NSDictionary * personaddress = (__bridge NSDictionary *)(ABMultiValueCopyValueAtIndex(addresss, j));
            // 獲取地址
            NSString* country = [personaddress valueForKey:(NSString *)kABPersonAddressCountryKey];
            NSString* state = [personaddress valueForKey:(NSString *)kABPersonAddressStateKey];
            NSString* city = [personaddress valueForKey:(NSString *)kABPersonAddressCityKey];
            NSString* street = [personaddress valueForKey:(NSString *)kABPersonAddressStreetKey];
            NSString* zip = [personaddress valueForKey:(NSString *)kABPersonAddressZIPKey];
            NSString* coutntrycode = [personaddress valueForKey:(NSString *)kABPersonAddressCountryCodeKey];
            //地址字元串,可以按需求格式化
            NSString *adress = [NSString stringWithFormat:@"國家:%@\n省:%@\n市:%@\n街道:%@\n郵編:%@",country,state,city,street,zip];
        }
        
        //獲取當前聯繫人紀念日
        NSMutableArray *dateArr = [[NSMutableArray alloc]init];
        ABMultiValueRef dates= ABRecordCopyValue(people, kABPersonDateProperty);
        CFIndex datesCount = ABMultiValueGetCount(dates);
        for (NSInteger j=0; j<datesCount; j++) {
            //獲取dates Label
            NSString* dateLabel = (__bridge NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(dates, j));
            //獲取紀念日日期
            NSDate *date =(__bridge NSDate*)(ABMultiValueCopyValueAtIndex(dates, j));
            //獲取紀念日名稱
            NSString *str =(__bridge NSString*)(ABMultiValueCopyLabelAtIndex(dates, j));
            NSDictionary *tempDic = [NSDictionary dictionaryWithObject:date forKey:str];
            [dateArr addObject:tempDic];
        }
    }
}

 

   2)、9.0以後

    2-1)、頭文件

#import <Contacts/Contacts.h>

    2-2)、判斷是否有許可權

- (void)DetermineAndReadAddressBook
{
    // 判斷是否授權
    CNAuthorizationStatus authorizationStatus = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
    
    if (authorizationStatus == CNAuthorizationStatusNotDetermined) {
        CNContactStore *contactStore = [[CNContactStore alloc] init];
        [contactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
            if (granted) {
                // 授權成功
                [self readAddressBook];
            } else {
                // 授權失敗
                NSLog(@"提示:用戶取消授權,讀取失敗");
            }
        }];
    }
    else if (authorizationStatus == CNAuthorizationStatusAuthorized){
        // 授權過
        [self readAddressBook];
    }
    else {
        dispatch_async(dispatch_get_main_queue(), ^{
            // 更新界面
            NSLog(@"提示:應用-通信錄 設置");
        });
    }
}

    2-3)、讀取並保存模型(未做)

- (void)readAddressBook {
    // 獲取指定的欄位,如果這裡不列出,在下麵block讀取,會奔潰。註意,有一個是10.0以後的。
    NSArray *keysToFetch = @[CNContactNamePrefixKey,
                             CNContactGivenNameKey,
                             CNContactMiddleNameKey,
                             CNContactFamilyNameKey,
                             CNContactPreviousFamilyNameKey,
                             CNContactNameSuffixKey,
                             CNContactNicknameKey,
                             CNContactOrganizationNameKey,
                             CNContactDepartmentNameKey,
                             CNContactJobTitleKey,
                             CNContactPhoneticGivenNameKey,
                             CNContactPhoneticMiddleNameKey,
                             CNContactPhoneticFamilyNameKey,
                             CNContactPhoneticOrganizationNameKey,    // 10.0
                             CNContactBirthdayKey,
                             CNContactNonGregorianBirthdayKey,
                             CNContactNoteKey,
                             CNContactImageDataKey,
                             CNContactThumbnailImageDataKey,
                             CNContactImageDataAvailableKey,
                             CNContactTypeKey,
                             CNContactPhoneNumbersKey,
                             CNContactEmailAddressesKey,
                             CNContactPostalAddressesKey,
                             CNContactDatesKey,
                             CNContactUrlAddressesKey,
                             CNContactRelationsKey,
                             CNContactSocialProfilesKey,
                             CNContactInstantMessageAddressesKey];
    
    CNContactFetchRequest *fetchRequest = [[CNContactFetchRequest alloc] initWithKeysToFetch:keysToFetch];
    CNContactStore *contactStore = [[CNContactStore alloc] init];
    [contactStore enumerateContactsWithFetchRequest:fetchRequest error:nil usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) {
        

        // 獲取名字
        NSString *givenName = contact.givenName;
        NSString *familyName = contact.familyName;
        NSLog(@"-------------------------------------------------------");
        NSLog(@"givenName=%@, familyName=%@", givenName, familyName);
        
        // 獲取電話
        NSArray *phoneNumbers = contact.phoneNumbers;
        for (CNLabeledValue *labelValue in phoneNumbers) {
            NSString *label = labelValue.label;
            CNPhoneNumber *phoneNumber = labelValue.value;
            
            NSLog(@"label=%@, phone=%@", label, phoneNumber.stringValue);
        }
        
        // 獲取對方IM
        NSArray *ims = contact.instantMessageAddresses;
        for (CNLabeledValue *labelValue in ims) {
            NSString *label = labelValue.label;
            CNInstantMessageAddress *adds = labelValue.value;
            
            NSLog(@"label=%@, add.username=%@,add.service=%@", label, adds.username , adds.service);
        }
        
        //        *stop = YES;  // 停止迴圈,相當於break;
    }];
}

  

 

 

 
3、參考

《iOS的通訊錄開發》         --千煌89    簡書

《iOS 獲取通訊錄的4種方式詳解》   --vbirdbest   CSDN


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 概述 本篇我們將利用DMA一步一步實現SQL Server 的遷移。幫助大家理解現在的SQL Server與新版本的融合問題,同時需要我們做哪些操作來實現新版本的升級或者遷移。 SQL Server 遷移 一定要有一個準備好的計劃,我下麵列出了所有的遷移過程需要做的工作,如下列表: 步驟列表 序號 ...
  • 最近群里聊起秒殺和限流,我自己沒有做過類似應用,但是工作中遇到過更大的數據和併發。 於是提出了一個簡單的模型: var count = rds.inc(key); if(count > 1000) throw "已搶光!" 藉助Redis單線程模型,它的inc是安全的,確保每次加一,然後返回加一後的 ...
  • 工作中,經常會遇到將某個數據表的所有或大部份欄位讀取出來情況,比如說跨資料庫進行表更新或插入等。假如欄位名一個一個地敲的話,一是效率低,二是會有漏掉的情況。 針對此種情況,處理的方法有很多種,比如新建一個視圖,在裡面錄入SELECT * FROM 表名,系統會自動將星號改成欄位名(SQL SERVE ...
  • 查詢資料庫中的表及列,依資料庫自帶的函數,一條語句就可以搞定: ...
  • sqlserver: with Result as ( select SUM(F_DayValue) AS F_Value,F_ZZ_ttBuildID,F_EnergyItemCode from T_EC_EnergyItemDayResult where F_EnergyItemCode lik... ...
  • 〓資料庫的分類〓 資料庫通常分為層次式資料庫、網路式資料庫和關係式資料庫三種。而不同的資料庫是按不同的數據結構來聯繫和組織的。 而在當今的互聯網中,最常見的資料庫模型主要是兩種,即關係型資料庫和非關係型資料庫。 資料庫分類 〓關係型資料庫介紹〓 1、關係型資料庫的由來 雖然網狀資料庫和層次資料庫已經 ...
  • 【轉】Android總結篇系列:Activity生命周期 Android官方文檔和其他不少資料都對Activity生命周期進行了詳細介紹,在結合資料和項目開發過程中遇到的問題,本文將對Activity生命周期進行一次總結。 Activity是由Activity棧進管理,當來到一個新的Activity ...
  • 尊重勞動成果,轉載請標明出處:http://www.cnblogs.com/tangZH/p/8305063.html 我們在自定義view的時候有時候需要給組件一個背景,而這個背景可能是不規則的,比如一個紅色背景,但是左邊有圓角,右邊沒有,那麼應該怎麼做呢?在這裡我以textView為例。 用xm ...
一周排行
    -Advertisement-
    Play Games
  • 概述:本文代碼示例演示瞭如何在WPF中使用LiveCharts庫創建動態條形圖。通過創建數據模型、ViewModel和在XAML中使用`CartesianChart`控制項,你可以輕鬆實現圖表的數據綁定和動態更新。我將通過清晰的步驟指南包括詳細的中文註釋,幫助你快速理解並應用這一功能。 先上效果: 在 ...
  • openGauss(GaussDB ) openGauss是一款全面友好開放,攜手伙伴共同打造的企業級開源關係型資料庫。openGauss採用木蘭寬鬆許可證v2發行,提供面向多核架構的極致性能、全鏈路的業務、數據安全、基於AI的調優和高效運維的能力。openGauss深度融合華為在資料庫領域多年的研 ...
  • openGauss(GaussDB ) openGauss是一款全面友好開放,攜手伙伴共同打造的企業級開源關係型資料庫。openGauss採用木蘭寬鬆許可證v2發行,提供面向多核架構的極致性能、全鏈路的業務、數據安全、基於AI的調優和高效運維的能力。openGauss深度融合華為在資料庫領域多年的研 ...
  • 概述:本示例演示了在WPF應用程式中實現多語言支持的詳細步驟。通過資源字典和數據綁定,以及使用語言管理器類,應用程式能夠在運行時動態切換語言。這種方法使得多語言支持更加靈活,便於維護,同時提供清晰的代碼結構。 在WPF中實現多語言的一種常見方法是使用資源字典和數據綁定。以下是一個詳細的步驟和示例源代 ...
  • 描述(做一個簡單的記錄): 事件(event)的本質是一個委托;(聲明一個事件: public event TestDelegate eventTest;) 委托(delegate)可以理解為一個符合某種簽名的方法類型;比如:TestDelegate委托的返回數據類型為string,參數為 int和 ...
  • 1、AOT適合場景 Aot適合工具類型的項目使用,優點禁止反編 ,第一次啟動快,業務型項目或者反射多的項目不適合用AOT AOT更新記錄: 實實在在經過實踐的AOT ORM 5.1.4.117 +支持AOT 5.1.4.123 +支持CodeFirst和非同步方法 5.1.4.129-preview1 ...
  • 總說周知,UWP 是運行在沙盒裡面的,所有許可權都有嚴格限制,和沙盒外交互也需要特殊的通道,所以從根本杜絕了 UWP 毒瘤的存在。但是實際上 UWP 只是一個應用模型,本身是沒有什麼許可權管理的,許可權管理全靠 App Container 沙盒控制,如果我們脫離了這個沙盒,UWP 就會放飛自我了。那麼有沒... ...
  • 目錄條款17:讓介面容易被正確使用,不易被誤用(Make interfaces easy to use correctly and hard to use incorrectly)限制類型和值規定能做和不能做的事提供行為一致的介面條款19:設計class猶如設計type(Treat class de ...
  • title: 從零開始:Django項目的創建與配置指南 date: 2024/5/2 18:29:33 updated: 2024/5/2 18:29:33 categories: 後端開發 tags: Django WebDev Python ORM Security Deployment Op ...
  • 1、BOM對象 BOM:Broswer object model,即瀏覽器提供我們開發者在javascript用於操作瀏覽器的對象。 1.1、window對象 視窗方法 // BOM Browser object model 瀏覽器對象模型 // js中最大的一個對象.整個瀏覽器視窗出現的所有東西都 ...