JKSwiftExtension,測試用例在 JKContactsKitViewController 里面
目錄:
- 1、簡介和CNKeyDescriptor的key介紹
- 2襟铭、通訊錄的基本使用
- 獲取授權狀態(tài)
- 查詢出所有通訊錄信息
- 添加新聯(lián)系人
- 更新聯(lián)系人
- 刪除聯(lián)系人
一、簡介和CNKeyDescriptor的key介紹
1.1粥惧、在 iOS9.0 之前, 我們只能通過 AddressBook 框架來獲取通訊錄聯(lián)系人信息抛腕。但 AddressBook framework 語法很奇怪,同時也十分難用啰劲。所以蘋果從 iOS9.0 開始推出的全新的聯(lián)系人框架 Contacts FrameWork 作為替代,同時將原來的 AddressBook 給廢棄掉板丽。
-
1.2呈枉、Contacts FrameWork 同樣包含兩種訪問通訊錄的方式:
- ContactsUI.framework 框架 : 通過系統(tǒng)提供的通訊錄交互界面來訪問(替代原先的 AddressBookUI.framework)
- Contacts.framework 框架 : 沒有界面,通過代碼來獲取所有聯(lián)系人信息(替代原先的 AddressBook.framework)
由于蘋果安全策略更新埃碱,在使用 Xcode8 開發(fā)時猖辫,需要在 Info.plist 配置請求通訊錄的相關描述字段(
Privacy - Contacts Usage Description
) -
1.3、CNKeyDescriptor的key介紹
// 標識符 @available(iOS 9.0, *) public let CNContactIdentifierKey: String // 姓名前綴 @available(iOS 9.0, *) public let CNContactNamePrefixKey: String // 姓名 @available(iOS 9.0, *) public let CNContactGivenNameKey: String // 中間名 @available(iOS 9.0, *) public let CNContactMiddleNameKey: String // 姓氏 @available(iOS 9.0, *) public let CNContactFamilyNameKey: String // 之前的姓氏(ex:國外的女士) @available(iOS 9.0, *) public let CNContactPreviousFamilyNameKey: String // 姓名后綴 @available(iOS 9.0, *) public let CNContactNameSuffixKey: String // 昵稱 @available(iOS 9.0, *) public let CNContactNicknameKey: String // 公司(組織) @available(iOS 9.0, *) public let CNContactOrganizationNameKey: String // 部門 @available(iOS 9.0, *) public let CNContactDepartmentNameKey: String // 職位 @available(iOS 9.0, *) public let CNContactJobTitleKey: String // 名字的拼音或音標 @available(iOS 9.0, *) public let CNContactPhoneticGivenNameKey: String // 中間名的拼音或音標 @available(iOS 9.0, *) public let CNContactPhoneticMiddleNameKey: String // 形式的拼音或音標 @available(iOS 9.0, *) public let CNContactPhoneticFamilyNameKey: String // 公司(組織)的拼音或音標(iOS10 才開始存在的呢) @available(iOS 10.0, *) public let CNContactPhoneticOrganizationNameKey: String // 生日 @available(iOS 9.0, *) public let CNContactBirthdayKey: String // 農(nóng)歷 @available(iOS 9.0, *) public let CNContactNonGregorianBirthdayKey: String // 備注 @available(iOS 9.0, *) public let CNContactNoteKey: String // 頭像 @available(iOS 9.0, *) public let CNContactImageDataKey: String // 頭像的縮略圖 @available(iOS 9.0, *) public let CNContactThumbnailImageDataKey: String // 頭像是否可用 @available(iOS 9.0, *) public let CNContactImageDataAvailableKey: String // 類型 @available(iOS 9.0, *) public let CNContactTypeKey: String // 電話號碼 @available(iOS 9.0, *) public let CNContactPhoneNumbersKey: String // 郵箱地址 @available(iOS 9.0, *) public let CNContactEmailAddressesKey: String // 住址 @available(iOS 9.0, *) public let CNContactPostalAddressesKey: String // 其他日期 @available(iOS 9.0, *) public let CNContactDatesKey: String // url地址 @available(iOS 9.0, *) public let CNContactUrlAddressesKey: String // 關聯(lián)人 @available(iOS 9.0, *) public let CNContactRelationsKey: String // 社交 @available(iOS 9.0, *) public let CNContactSocialProfilesKey: String // 即時通信 @available(iOS 9.0, *) public let CNContactInstantMessageAddressesKey: String
二砚殿、通訊錄的基本使用
-
2.1啃憎、獲取授權狀態(tài)
// MARK: 1.1、獲取授權狀態(tài) /// 獲取授權狀態(tài) /// - Returns: 授權狀態(tài) static func authorizationStatus() -> CNAuthorizationStatus { // 獲取授權狀態(tài) return CNContactStore.authorizationStatus(for: .contacts) }
-
2.2似炎、查詢出所有通訊錄信息
// MARK: 1.2辛萍、獲取通訊錄的信息 /// 獲取通訊錄的信息 /// - Parameter keys: 獲取Fetch,并且指定之后要獲取聯(lián)系人中的什么屬性 /// - completion: 結果閉包 static func selectContactsData(keys: [String] = [CNContactFamilyNameKey, CNContactGivenNameKey, CNContactOrganizationNameKey, CNContactPhoneNumbersKey, CNContactNicknameKey], completion: @escaping (([CNContact], Error?) -> Void)) { // 創(chuàng)建通訊錄對象 let store = CNContactStore() store.requestAccess(for: .contacts) {(granted, error) in if (granted) && (error == nil) { // 創(chuàng)建請求對象 需要傳入一個(keysToFetch: [CNKeyDescriptor]) 包含'CNKeyDescriptor'類型的數(shù)組 let request = CNContactFetchRequest(keysToFetch: keys as [CNKeyDescriptor]) do { var contacts: [CNContact] = [] // 需要傳入一個CNContactFetchRequest try store.enumerateContacts(with: request, usingBlock: {(contact : CNContact, stop : UnsafeMutablePointer) -> Void in contacts.append(contact) }) completion(contacts, nil) } catch { completion([], nil) } } else { completion([], error) } } }
-
2.3、添加新聯(lián)系人
// MARK: 1.3羡藐、添加新聯(lián)系人 /// 添加新聯(lián)系人 /// - Parameters: /// - contact: 聯(lián)系人的信息 /// - completion: 結果閉包 static func addContactItem(contact: CNMutableContact, completion: @escaping ((Bool, Error?) -> Void)) { // 創(chuàng)建通訊錄對象 let store = CNContactStore() store.requestAccess(for: .contacts) {(granted, error) in if (granted) && (error == nil) { // 添加聯(lián)系人請求 let saveRequest = CNSaveRequest() saveRequest.add(contact, toContainerWithIdentifier: nil) do { // 寫入聯(lián)系人 try store.execute(saveRequest) completion(true, nil) } catch { completion(true, error) } } else { completion(false, error) } } }
-
2.4贩毕、更新聯(lián)系人
// MARK: 1.4、更新聯(lián)系人 /// 更新聯(lián)系人 /// - Parameters: /// - identifier: 唯一標識符 /// - familyName: 姓氏 /// - givenName: 名字 /// - phoneNumbers: 手機號碼數(shù)組 /// - keys: key /// - completion: 結果閉包 static func updateContactItem(identifier: String, familyName: String, givenName: String, phoneNumbers: [CNLabeledValue<CNPhoneNumber>], keys: [String] = [CNContactFamilyNameKey, CNContactGivenNameKey, CNContactOrganizationNameKey, CNContactPhoneNumbersKey, CNContactNicknameKey], completion: @escaping ((Bool, Error?) -> Void)) { // 創(chuàng)建通訊錄對象 let store = CNContactStore() store.requestAccess(for: .contacts) {(granted, error) in if (granted) && (error == nil) { guard let itemContact = try? store.unifiedContact(withIdentifier: identifier, keysToFetch: keys as [CNKeyDescriptor]) else { return } let mutableContact = itemContact.mutableCopy() as! CNMutableContact mutableContact.familyName = familyName mutableContact.givenName = givenName mutableContact.phoneNumbers = phoneNumbers // 修改聯(lián)系人請求 let request = CNSaveRequest() request.update(mutableContact) do { // 修改聯(lián)系人 try store.execute(request) completion(true, error) } catch { completion(false, error) } } else { completion(false, error) } } }
-
2.5仆嗦、刪除聯(lián)系人
// MARK: 1.5辉阶、刪除聯(lián)系人 /// 刪除聯(lián)系人 /// - Parameters: /// - identifier: 唯一標識符 /// - keys: key /// - completion: 結果閉包 static func deleteContactItem(identifier: String, keys: [String] = [CNContactFamilyNameKey, CNContactGivenNameKey, CNContactOrganizationNameKey, CNContactPhoneNumbersKey, CNContactNicknameKey], completion: @escaping ((Bool, Error?) -> Void)) { // 創(chuàng)建通訊錄對象 let store = CNContactStore() store.requestAccess(for: .contacts) {(granted, error) in if (granted) && (error == nil) { guard let itemContact = try? store.unifiedContact(withIdentifier: identifier, keysToFetch: keys as [CNKeyDescriptor]) else { return } let mutableContact = itemContact.mutableCopy() as! CNMutableContact // 刪除聯(lián)系人請求 let request = CNSaveRequest() request.delete(mutableContact) do { // 執(zhí)行操作 try store.execute(request) completion(true, error) } catch { completion(false, error) } } else { completion(false, error) } } }