Swift 獲取聯(lián)系人信息

Swift 獲取聯(lián)系人信息

如今很多開(kāi)發(fā)者都開(kāi)始嘗試使用Swift進(jìn)行開(kāi)發(fā),而且獲取手機(jī)通訊錄作為開(kāi)發(fā)常見(jiàn)的需求
作為一個(gè)新的開(kāi)發(fā)者,如果我們開(kāi)發(fā)的應(yīng)用需求不是特別高,只要求是iOS9以上,
那么恭喜你,基本上你寫(xiě)的很少,
你可以選擇Contacts框架,這個(gè)框架是在iOS9才出來(lái)的@available(iOS 9.0, *)
直接上代碼
首先在需要的類中

import Contacts

然后就可以使用這個(gè)框架了
首先lazy一個(gè)contactStore的對(duì)象

lazy var myContactStore: CNContactStore = {
        let cn:CNContactStore = CNContactStore()
        return cn
    }()

首先是檢測(cè)權(quán)限,如果沒(méi)有授權(quán)就要申請(qǐng)權(quán)限,有權(quán)限則直接獲取通訊錄,沒(méi)有權(quán)限可以選擇彈窗是否需要重新開(kāi)啟權(quán)限

func checkContactStoreAuth(){
        switch CNContactStore.authorizationStatus(for: .contacts) {
        case .notDetermined:
            print("未授權(quán)")
            requestContactStoreAuthorization(myContactStore)
        case .authorized:
            print("已授權(quán)")
            readContactsFromContactStore(myContactStore)
        case .denied, .restricted:
            print("無(wú)權(quán)限")
        //可以選擇彈窗到系統(tǒng)設(shè)置中去開(kāi)啟
        default: break
        }
    }

請(qǐng)求權(quán)限

func requestContactStoreAuthorization(_ contactStore:CNContactStore) {
        contactStore.requestAccess(for: .contacts, completionHandler: {[weak self] (granted, error) in
            if granted {
                print("已授權(quán)")
                self?.readContactsFromContactStore(contactStore)
            }
        })
    }

讀取通訊錄

func readContactsFromContactStore(_ contactStore:CNContactStore) {
        guard CNContactStore.authorizationStatus(for: .contacts) == .authorized else {
            return
        }
        
        let keys = [CNContactFamilyNameKey,CNContactGivenNameKey,CNContactPhoneNumbersKey]
        
        let fetch = CNContactFetchRequest(keysToFetch: keys as [CNKeyDescriptor])
        do {
            try contactStore.enumerateContacts(with: fetch, usingBlock: { (contact, stop) in
                //姓名
                let name = "\(contact.familyName)\(contact.givenName)"
                print(name)
                //電話
                for labeledValue in contact.phoneNumbers {
                    let phoneNumber = (labeledValue.value as CNPhoneNumber).stringValue
                    print(phoneNumber)
                }
            })
        } catch let error as NSError {
            print(error)
        }
    }

OK 以上就是iOS9以上的獲取方式
對(duì)于iOS9以下的話就沒(méi)有那么方便了
我們只能使用iOS早期的一個(gè)AddressBook框架了
一樣的 首先import AddressBook
然后加載一個(gè)通訊錄對(duì)象

private lazy var myAddressBook: ABAddressBook = {
        var error:Unmanaged<CFError>?
        let ab: ABAddressBook = ABAddressBookCreateWithOptions(nil, nil).takeRetainedValue()
        return ab;
    }()

注意這里之所以使用lazy加載,是因?yàn)檎{(diào)用ABAddressBookCreateWithOptions進(jìn)行ABAddressBookCreateWithOptions的初始化需要設(shè)置為一個(gè)lazy變量,否則在用戶拒絕授權(quán)的情況下,程序?qū)?huì)崩潰。因?yàn)锳BAddressBookCreateWithOptions(nil, nil)得到的值為nil
所以這里一定要注意

之后也大致是同樣的方式
檢測(cè)權(quán)限

func checkAddressBookAuth() {
        switch ABAddressBookGetAuthorizationStatus() {
        case .notDetermined:
            print("未授權(quán)")
            requestAddressBookAuthorization(myAddressBook)
        case .authorized:
            print("已授權(quán)")
            readContactsFromAddressBook(myAddressBook)
        case .denied, .restricted:
            print("無(wú)權(quán)限")
            //可以選擇彈窗到系統(tǒng)設(shè)置中去開(kāi)啟
        }
    }

申請(qǐng)權(quán)限

func requestAddressBookAuthorization(_ addressBook:ABAddressBook) {
        ABAddressBookRequestAccessWithCompletion(addressBook, {[weak self] (granted, error) in
            if granted {
                print("已授權(quán)")
                self?.readContactsFromAddressBook(addressBook)
            }
        })
    }

讀取通訊錄

func readContactsFromAddressBook(_ addressBook:ABAddressBook) {
        guard ABAddressBookGetAuthorizationStatus() == .authorized else {
            return
        }
        
        let allContacts = ABAddressBookCopyArrayOfAllPeople(addressBook).takeRetainedValue() as Array
        for record in allContacts {
            let currentContact: ABRecord = record
            let name = ABRecordCopyCompositeName(currentContact).takeRetainedValue() as String
            print(name)
            
            let currentContactPhones: ABMultiValue = ABRecordCopyValue(currentContact, kABPersonPhoneProperty).takeRetainedValue() as ABMultiValue
            for i in 0..<ABMultiValueGetCount(currentContactPhones){
                let phoneNumber = ABMultiValueCopyValueAtIndex(currentContactPhones, i).takeRetainedValue() as! String
                print(phoneNumber)
            }
        }
    }

至于如何判斷采用哪一個(gè)框架

if #available(iOS 9.0, *) {
                checkContactStoreAuth()
        }else {
                checkAddressBookAuth()
        }

當(dāng)然,你還要這樣做


這里寫(xiě)圖片描述

需要在info.plist中添加允許訪問(wèn)通訊錄的權(quán)限,否則iOS10以上的系統(tǒng)也會(huì)導(dǎo)致崩潰

OK 至此,通訊錄大家應(yīng)該都能夠獲取到了

這是我的模擬器運(yùn)行的結(jié)果


這里寫(xiě)圖片描述

附上DEMO地址:https://github.com/spicyShrimp/XLXContact

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容