原创Blog,转载请注明出处
http://blog.csdn.net/hello_hwc?viewmode=list
我的stackoverflow
前言:在iOS 9之前,一直使用AddressBook这个framework来访问用户通讯录。但是在iOS 9中,AddressBook被废弃了,转而使用Contacts Framework。
文档
Demo效果
请求访问权限
相关类
CNContactStore(线程安全)
CNContactStore代表了实际设备上存储,通过这个类可以
- 检查当前的通讯录访问权限
- 请求访问通讯录权限
- fetch通讯录内容(支持按条件fetch,和core data 类似)
- 保存到通讯录
CNContact(线程安全)
表示通讯录中一位联系人的Model类,和NSDictionary类似,他有一个子类是可变的CNMutableContact
示例代码
保存一个store对象,Demo中采用单例
注意,Swift中单例这么写是线程安全的
- class ContactsStore{
- static let sharedStore = CNContactStore()
- }
请求权限
- let authStatus = CNContactStore.authorizationStatusForEntityType(CNEntityType.Contacts)
- let authStatus = ContactsStore.sharedStore.authorizationStatusForEntityType(CNEntityType.Contacts)
- if authStatus == CNAuthorizationStatus.Denied || authStatus == CNAuthorizationStatus.NotDetermined{
- self.contactsStore.requestAccessForEntityType(CNEntityType.Contacts,completionHandler: { (result,error) -> Void in
- if result == false{
- let alert = UIAlertController(title: "警告",message: "请在设置中允许通讯录访问,否则App无法正常使用",preferredStyle: UIAlertControllerStyle.Alert)
- alert.addAction(UIAlertAction(title: "确定",style: UIAlertActionStyle.Cancel,handler: nil))
- self.presentViewController(alert,animated: true,completion: nil)
- }
- })
- }
调用系统的ContactsPickerViewController
- 让ViewController实现CNContactPickerDelegate协议
实现如下方法,处理选中的结果
- func contactPicker(picker: CNContactPickerViewController,didSelectContact contact: CNContact) {
- if let phoneNumber = contact.phoneNumbers.first?.value as? CNPhoneNumber{
- self.textfield.text = phoneNumber.stringValue
- }
- }
然后,模态展示
- let contactsVC = CNContactPickerViewController()
- contactsVC.delegate = self;
- presentViewController(contactsVC,animated:true,completion: nil)
查询全部通讯录
注意,要先指明需要fetch的属性,
因为enumerateContactsWithFetchRequest
这个函数会抛出异常,所以要用do-try-catch包括起来
- let keys = [CNContactGivenNameKey,CNContactPhoneNumbersKey,CNContactThumbnailImageDataKey]
- let fetchAllRequest = CNContactFetchRequest(keysToFetch:keys)
- do{
- try ContactsStore.sharedStore.enumerateContactsWithFetchRequest(fetchAllRequest) { (contact,pointer) -> Void in
- self.contacts.append(contact)
- }
- }catch{
-
- }
条件查询
条件查询在示例工程中未列出,按照如下步骤查询
使用如下CNContact方法创建NSPredicate对象
- + predicateForContactsMatchingName:
- + predicateForContactsWithIdentifiers:
- ...
使用CNContactStore的
来查询
- unifiedContactsMatchingPredicate:keysToFetch:error:
添加
摘自Swift2.1文档
- 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)
本地化/格式化
几个常用的类
- CNContactFormatter
- CNPostalAddressFormatter
- CNContact.localizedStringForKey
- CNLabeledValue.localizedStringForLabel
举例
从Contact中拼接出全名
- let fullName = CNContactFormatter.stringFromContact(contact,style: .FullName)
- print(fullName)
- // John Appleseed
邮政地址
- let postalString = CNPostalAddressFormatter.stringFromPostalAddress(homeAddress)
- print(postalString)
- // 1 Infinite Loop
- // Cupertino
- // CA
- // 95014
对通讯录的内置Key获取
- let displayName = CNContact.localizedStringForKey(CNContactNicknameKey)
- print(displayName)
- // 昵称,在中文条件下