iOS9 Contacts Framework簡介

這個全新的聯系人框架,簡單易用,使用它可以很容易地查找、創建和更新聯系人信息,而且這個framework對thred-safe、read-only usage方面進行了優化。iOS和OS X平臺都可用,用來代替之前的AddressBook framework。
翻譯自官方文檔Contacts Framework Reference

聯系人對象

CNContact表示一條聯系人記錄,包含聯系人的name、image、phone numbers.
這個類像NSDictionary一樣;擁有一個可變的子類CNMutableContact,你可以使用它修改聯系人屬性。而這些屬性可以擁有多個值,例如phone numbers或者email addresses,這些就是一組CNLabeledValue對象的數組。這個labeled value對象是線程安全的,由不可變labels和values的元組組成。Contacts framework提供一些預先定義的labels,你也可以創建自定義的labels。

創建一個聯系人:

import Contacts
 
// Creating a mutable object to add to the contact
let contact = CNMutableContact()
 
contact.imageData = NSData() // The profile picture as a NSData object
 
contact.givenName = "John"
contact.familyName = "Appleseed"
 
let homeEmail = CNLabeledValue(label:CNLabelHome, value:"john@example.com")
let workEmail = CNLabeledValue(label:CNLabelWork, value:"j.appleseed@icloud.com")
contact.emailAddresses = [homeEmail, workEmail]
 
contact.phoneNumbers = [CNLabeledValue(
    label:CNLabelPhoneNumberiPhone,
    value:CNPhoneNumber(stringValue:"(408) 555-0126"))]
 
let homeAddress = CNMutablePostalAddress()
homeAddress.street = "1 Infinite Loop"
homeAddress.city = "Cupertino"
homeAddress.state = "CA"
homeAddress.postalCode = "95014"
contact.postalAddresses = [CNLabeledValue(label:CNLabelHome, value:homeAddress)]
 
let birthday = NSDateComponents()
birthday.day = 1
birthday.month = 4
birthday.year = 1988  // You can omit the year value for a yearless birthday
contact.birthday = birthday
 
// Saving the newly created contact
let store = CNContactStore()
let saveRequest = CNSaveRequest()
saveRequest.addContact(contact, toContainerWithIdentifier:nil)
try store.executeSaveRequest(saveRequest)

格式和本地化

Contacts framework可以幫助你格式和本地化聯系人信息。例如,你可以準確無誤地格式一個聯系人name(使用CNContactFormatter),或者格式一個國際郵政地址(使用CNPostalAddressFormatter)

格式聯系人name和郵政地址

// Formatting contact name
let fullName = CNContactFormatter.stringFromContact(contact, style: .FullName)
print(fullName)
// John Appleseed
 
// Formatting postal address
let postalString = CNPostalAddressFormatter.stringFromPostalAddress(homeAddress)
print(postalString)
// 1 Infinite Loop
// Cupertino
// CA
// 95014

你可以通過設備當前的本地設置本地化展示對象的names屬性和預先設定的labels。
CNContact類包含localizedStringForKey:方法,它可以通過key值獲取本地化的譯本。而CNLabeledValue類包含localizedStringForLabel:方法,它可以通過預先設定的labels獲取本地化的label,從而獲取相應的信息。

本地化的name:

// device locale is Spanish
let displayName = CNContact.localizedStringForKey(CNContactNicknameKey)
print(displayName)
// alias
 
let displayLabel = CNLabeledValue.localizedStringForLabel(CNLabelHome)
print(displayLabel)
// casa

獲取聯系人

你可以使用聯系人倉庫(CNContactStore),也就是用戶聯系人的數據庫來獲取聯系人。聯系人數據庫的方法是同步的,這就需要你在后臺線程使用它們。而后在主線程中返回獲取到的結果。

Contacts framework提供幾種方法檢索聯系人,包括predicates和keysToFetch

通過predicates獲取聯系人:

let predicate: NSPredicate = CNContact.predicateForContactsMatchingName("Appleseed")

通過KeysToFetch獲取聯系人:

let keysToFetch = [CNContactGivenNameKey,CNContactFamilyNameKey]

如何獲取聯系人:

let store = CNContactStore()
let contacts = try store.unifiedContactsMatchingPredicate(CNContact.predicateForContactsMatchingName("Appleseed"), keysToFetch:[CNContactGivenNameKey, CNContactFamilyNameKey])

Contacts framework也可以在獲取到的聯系人上執行操作,例如格式聯系人name。每次執行操作都需要特定的keys來保證其準確無誤。這些keys是特定的key描述對象,包含在keysToFetch之內。

通過key值描述獲取聯系人:

let keysToFetch = [CNContactEmailAddressesKey, CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName)]

隱私

用戶可以允許或者拒絕訪問聯系人數據。其中為了避免APP UI的主線程獲取,你要么使用異步方法[CNContactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:],要么派遣你的CNContactStore內存到后臺線程。

局部聯系人

一個局部聯系人僅僅只有一些從聯系人數據庫獲取來的屬性值。所有獲取到的聯系人對象都是局部聯系人。如果你使用一個沒有獲取到的屬性值,將會拋出異常。如果你不確定keys在聯系人中是否被獲取到,在使用它們之前最好先檢查其可用性。你可以使用isKeyAvailable:去檢查單個聯系人key的可用性,也可以使用areKeysAvailable:去檢查多個keys。如果檢查的keys不可用就需要重新獲取。

使用isKeyAvailable檢查key的可用性:

// Checking if phone number is available for the given contact.
if (contact.isKeyAvailable(CNContactPhoneNumbersKey)) {
    print("\(contact.phoneNumbers)")
} else {
    //Refetch the keys
    let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey]
    let refetchedContact = try store.unifiedContactWithIdentifier(contact.identifier, keysToFetch: keysToFetch)
    print("\(refetchedContact.phoneNumbers)")
}

整合聯系人

每一個獲取的整合聯系人(CNContact)對象都有它自己獨一無二的標識符,它與其他一連串聯系人的標識符都不同。重新獲取一個整合的聯系人應該通過它的標識符來完成。

保存聯系人

CNSaveRequest類可以實現保存操作而且允許批量修改多個聯系人和分組。
注意:不要在save request中使用正在執行保存的對象,因為它可能已經被修改。

保存一個新的聯系人:

// Creating a new contact
let newContact = CNMutableContact()
newContact.givenName = "John"
newContact.familyName = "Appleseed"
 
// Saving contact
let saveRequest = CNSaveRequest()
saveRequest.addContact(newContact, toContainerWithIdentifier:nil)
try store.executeSaveRequest(saveRequest)

保存一個修改的聯系人:

let mutableContact = contact.mutableCopy() as! CNMutableContact
let newEmail = CNLabeledValue(label: CNLabelHome, value: "john@example.com")
mutableContact.emailAddresses.append(newEmail)
 
let saveRequest = CNSaveRequest()
saveRequest.updateContact(mutableContact)
try store.executeSaveRequest(saveRequest)

聯系人被改變通知

在save執行成功之后,聯系人數據庫提交一個CNContactStoreDidChangeNotification通知到通知者中心。如果你緩存了所有的聯系人對象,你需要重新獲取它們,要么使用它們的標識符,要么通過最初獲取的predicates來重新獲取,而且你需要釋放掉緩存的對象。注意緩存的對象是舊的但不一定是無效的。

容器和群組

用戶可以同步本地設備的聯系人和服務器的聯系人。每個賬戶至少有一個聯系人容器,一個聯系人也只能出現在一個容器里面。

一系列聯系人組成的群組在一個容器里面。不是所有賬戶都支持群組,一些賬戶可能支持子群。一個iCloud賬戶只有一個容器,它可以有很多群組但沒有子群。

類組成

  • CNContact:表示一個聯系人,包含聯系人的name、image、phone numbers,不可變;
  • CNMutableContact:CNContact的子類,表示具有可變屬性的聯系人;
  • CNContactFetchRequest:用于獲取聯系人;
  • CNContactProperty:關于聯系人的property的類,含有contact、key、value、label以及identifier;
  • CNContactRelation:表示一個聯系人與另一個關系的不可變值對象;
  • CNContactStore:聯系人倉庫,可以獲取、保存聯系人,與群組、容器有關;
  • CNContactVCardSerialization:提供vCard表示給定的一系列的聯系人;
  • CNContactsUserDefaults:聯系人user defaults使用過的properties;
  • CNContainer:聯系人容器,不可變;
  • CNGroup:聯系人群組,不可變;
  • CNMutableGroup:CNGroup的子類,表示可變的聯系人群組;
  • CNInstantMessageAddress:表示一個當前消息地址;
  • CNLabeledValue:聯合一個label的聯系人屬性值;
  • CNPhoneNumber:表示一個聯系人的phone number;
  • CNPostalAddress:表示一個聯系人的郵政地址;
  • CNMutablePostalAddress:CNPostalAddress的子類,表示可變的聯系人郵政地址;
  • CNSaveRequest:表示一個聯系人保存操作請求;
  • CNSocialProfile:表示社會簡況;
  • CNContactFormatter:NSFormatter的子類,定義不同的聯系人格式風格;
  • CNPostalAddressFormatter:聯系人郵政地址格式;

擴展

如果想了解更多關于Contacts Framwork的信息,推薦觀看WWDC2015大會上的視頻Introducing the Contacts Framework for iOS and OS X

初始iOS9中新的聯系人框架:

  • 檢查應用是否準許訪問聯系人,并且如何請求授權。
  • 使用三種不同的方式檢索聯系人。其中一種方式將會涉及 Picker View Controller 的使用。
  • 訪問檢索到的聯系人屬性,并調整為適當的顯示格式。
  • 使用默認的 Contacts UI 來實現選擇、查看以及編輯聯系人。
  • 創建一個新的聯系人
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,245評論 4 61
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,372評論 25 708
  • 方法一.使用Qt自帶的windeployqt.exe 打包工具方法二.使用下面鏈接的打包工具鏈接:http://p...
    Noefl閱讀 286評論 0 0
  • 六天的新疆之旅即將結束了 在這里我們走過了天池 走過了那拉提 走過了巴音布魯克 最美的風景還是在那拉提 一望無際的...
    親愛的琉小璃閱讀 186評論 0 1
  • 這個世界很繁華, 小鎮沒有樹, 鳥兒沒有家。
    美人驢兒閱讀 219評論 3 3