iOS:通信錄(完成)(18-01-18更)

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

1、讀取通信錄 1)、9.0以前:AddressBook 2)、9.0以後:Contacts 2、調用通信錄UI(不弄) 1)、9.0以前:AddressBookUI 2)、9.0以後:ContactsUI 3、參考 0、寫在前面 1)、plist 需要設置 隱私許可權描述 NSContactsUsa ...


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
更多相關文章
  • ReactiveCocoa常見類 1. RAC中最核心的類RACSiganl: RACSiganl:信號類,一般表示將來有數據傳遞,只要有數據改變,信號內部接收到數據,就會馬上發出數據 解析: 信號類(RACSiganl),只是表示當數據改變時,信號內部會發出數據,它本身不具備發送信號的能力,而是交 ...
  • 後端開發:1、高級java軟體架構師實戰培訓視頻教程2、大型SpringMVC,Mybatis,Redis,Solr,Nginx,SSM分散式電商項目視頻教程3、Spark Streaming實時流處理項目實戰4、Java校招面試 Google面試官親授5、Java開發企業級許可權管理系統6、Java ...
  • 1.顯示當前運行的全部模擬器: adb devices2.啟動ADB adb start-server3.停止ADB adb kill-server4.安裝應用程式: adb install -r [apk文件]-l #鎖定該程式-r #重新安裝該程式,保存數據-s #安裝在SD卡內,而不是設備內部 ...
  • 本文主要轉載自:Objective-C-Coding-Guidelines-In-Chinese Objective-C編碼規範,內容來自蘋果、谷歌的文檔翻譯,自己的編碼經驗和對其它資料的總結。 一 概要 Objective-C是一門面向對象的動態編程語言,主要用於編寫iOS和Mac應用程式。關於O ...
  • 1 網路請求的安全方案 1.1 https請求,最好有安全交互平臺。 1.2 對重要的參數請求進行加密(推薦AES,ERSA加密)。 1.3 伺服器返回數據時,對重要數據進行加密。 1.4 不要把密鑰寫到代碼里。可以先通過非對稱加密的介面獲取密鑰,然後再在後面的介面通信中用這個密鑰進行加密。 1.5 ...
  • 一、運行的效果圖 1、剛開始的效果 2、運行結束後的效果 二、準備工作 1、準備一個html文件導入到oc工程中 2、jiaohu.html文件的原始內容 3、從oc語言中操作.html文件---增刪改查 1).查詢操作 2).刪除操作 3).更改操作 4).插入操作 //插入操作1 //插入操作2 ...
  • 開發過程中出現了通過自定義設置打開熱點後手機搜索不到熱點的問題。 後來通過觀看 /data/misc/wifi 目錄下的 hostapd.conf 文件,發現是 ...
  • speed-tools 是一款基於代理模式的動態部署apk熱更新框架、插件化開發框架; ...
一周排行
    -Advertisement-
    Play Games
  • 基於.NET Framework 4.8 開發的深度學習模型部署測試平臺,提供了YOLO框架的主流系列模型,包括YOLOv8~v9,以及其系列下的Det、Seg、Pose、Obb、Cls等應用場景,同時支持圖像與視頻檢測。模型部署引擎使用的是OpenVINO™、TensorRT、ONNX runti... ...
  • 十年沉澱,重啟開發之路 十年前,我沉浸在開發的海洋中,每日與代碼為伍,與演算法共舞。那時的我,滿懷激情,對技術的追求近乎狂熱。然而,隨著歲月的流逝,生活的忙碌逐漸占據了我的大部分時間,讓我無暇顧及技術的沉澱與積累。 十年間,我經歷了職業生涯的起伏和變遷。從初出茅廬的菜鳥到逐漸嶄露頭角的開發者,我見證了 ...
  • C# 是一種簡單、現代、面向對象和類型安全的編程語言。.NET 是由 Microsoft 創建的開發平臺,平臺包含了語言規範、工具、運行,支持開發各種應用,如Web、移動、桌面等。.NET框架有多個實現,如.NET Framework、.NET Core(及後續的.NET 5+版本),以及社區版本M... ...
  • 前言 本文介紹瞭如何使用三菱提供的MX Component插件實現對三菱PLC軟元件數據的讀寫,記錄了使用電腦模擬,模擬PLC,直至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1. PLC開發編程環境GX Works2,GX Works2下載鏈接 https:// ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • 1、jQuery介紹 jQuery是什麼 jQuery是一個快速、簡潔的JavaScript框架,是繼Prototype之後又一個優秀的JavaScript代碼庫(或JavaScript框架)。jQuery設計的宗旨是“write Less,Do More”,即倡導寫更少的代碼,做更多的事情。它封裝 ...
  • 前言 之前的文章把js引擎(aardio封裝庫) 微軟開源的js引擎(ChakraCore))寫好了,這篇文章整點js代碼來測一下bug。測試網站:https://fanyi.youdao.com/index.html#/ 逆向思路 逆向思路可以看有道翻譯js逆向(MD5加密,AES加密)附完整源碼 ...
  • 引言 現代的操作系統(Windows,Linux,Mac OS)等都可以同時打開多個軟體(任務),這些軟體在我們的感知上是同時運行的,例如我們可以一邊瀏覽網頁,一邊聽音樂。而CPU執行代碼同一時間只能執行一條,但即使我們的電腦是單核CPU也可以同時運行多個任務,如下圖所示,這是因為我們的 CPU 的 ...
  • 掌握使用Python進行文本英文統計的基本方法,並瞭解如何進一步優化和擴展這些方法,以應對更複雜的文本分析任務。 ...
  • 背景 Redis多數據源常見的場景: 分區數據處理:當數據量增長時,單個Redis實例可能無法處理所有的數據。通過使用多個Redis數據源,可以將數據分區存儲在不同的實例中,使得數據處理更加高效。 多租戶應用程式:對於多租戶應用程式,每個租戶可以擁有自己的Redis數據源,以確保數據隔離和安全性。 ...