原创Blog,转载请注明出处
http://blog.csdn.net/hello_hwc?viewmode=list
我的stackoverflow

前言:在iOS 9之前,一直使用AddressBook这个framework来访问用户通讯录。但是在iOS 9中,AddressBook被废弃了,转而使用Contacts Framework。

文档

  • Contacts Framework
  • Contacts UI 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

  1. 让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)
// 昵称,在中文条件下

最后

欢迎关注我的CSDN博客,在我每个月都会更新10篇左右的iOS 文章,源码都是Swift的。

Swift iOS 9通讯录访问的更多相关文章

  1. Swift iOS 9通讯录访问

    viewmode=list我的stackoverflow前言:在iOS9之前,一直使用AddressBook这个framework来访问用户通讯录。

  2. [Swift] Enum 好用, Enum 可以更易用

    只需要写少量的几行声明:如下.选中,右键,选择"Services|generate_enum"然后如下代码就自动生成了:怎么样?当然还有其他选项可以使用.如果你有其他需要麻烦告诉我.当然有PR最好了.最后来张动图感受一下:代码在:OSCGitGithub

  3. swift – 交换机:枚举交换机问题:不是int的成员

    我在Swift中编写了我的第一个项目,由于某种原因,我无法找出为什么我的枚举和开关不工作属性开关我得到的错误是枚举大小写“viewmodeFavourite”不是“Int!”类型的成员所以我改为这个,因为它不是一个Int!forStoryboard)然后我得到枚举大小写模式不能匹配非枚举类型“Int”的值你必须将contactviewmode声明为Contactviewmode而不是Int。如果您真的希望它是Int,那么您必须通过将变量与枚举情况的rawValue属性进行比较来更改交换机中的大小写:但除非

  4. android – ContactsContract.CommonDataKinds.StructuredName的问题

    在查询联系人数据时,我得到了大部分工作.我正在与Structuredname和Organization战斗.他们不适合我.如果您不介意,请查看代码.它是手工制作的,并且删除了大量错误检查,以使其尽可能小地发布在此处.“不工作”的评论是对我不起作用的部分.两个前导if()是onActivityResult的一部分,我在联系人选择结束时收到数据.通过以下方式拨打电话:提前谢谢了HJW解决方法你的情况是错的.用于Structuredname:

  5. 如何在我的Android程序中访问联系人

    我正在制作短信应用程序并希望在我的Android应用程序中访问联系人.我想访问联系人,就像他们在实际联系人列表中的位置一样.选择后,我需要返回我的活动,我可以向该人发送短信.或者是否可以访问存储联系人的数据库?我的代码如下所示:我的LogCat看起来像这样:谁能帮我?解决方法使用此代码选择联系人:

  6. 如何避免在Android上的onCreate上重新创建视图?

    如何避免重新创建列表?

  7. 启动时Android应用程序崩溃:ContactsFragment中的SQLite NullPointerException

    我正在集成数据库来保存和存储以后要检索的基本联系信息.但是,我的应用程序现在在启动时崩溃,所以我甚至无法验证是否正在创建表等.数据库处理程序代码:logcat说问题是sqliteDatabasedb=this.getWriteableDatabase();这也是我违规的Contactsfragment:最后,这是ContactsDB类:非常感谢任何帮助–我认为问题在于我的Context为null.

  8. 在android中获取联系人非常慢

    我编写了一个代码来从联系人中获取联系人姓名,电话号码和图像,并将其显示在android的listview中.它工作正常,但需要更多时间来加载.我曾尝试在代码的某些部分使用多线程.但加载时间并未减少.这是onCreate()方法:以下是获取联系人的代码:这里,listview的setAdapter()函数在将所有联系人提取到ArrayList之后正在工作.有没有人知道如何在获取联系人期间显示联系人?

  9. 如何获取Android中联系人的所有详细信息

    给定联系人ID,我可以通过对每个字段进行不同的查询来获取各种联系人详细信息.但有没有一种方法可以通过单个查询获取与此联系人ID相关的所有详细信息?解决方法不得不改变ContentProviders上的一些教程,因为它引用了弃用的类,这可能会有所帮助.

  10. android – 如何使用一个查询搜索带地址的联系人(FORMATTED_ADDRESS)?

    我尝试对用户联系人实施实时搜索,我想获取每个匹配联系人的姓名,缩略图和地址(如果有).用户键入时正在运行实时搜索.所以他输入了ma并将获得’martin’,’matthews’……

随机推荐

  1. Swift UITextField,UITextView,UISegmentedControl,UISwitch

    下面我们通过一个demo来简单的实现下这些控件的功能.首先,我们拖将这几个控件拖到storyboard,并关联上相应的属性和动作.如图:关联上属性和动作后,看看实现的代码:

  2. swift UISlider,UIStepper

    我们用两个label来显示slider和stepper的值.再用张图片来显示改变stepper值的效果.首先,这三个控件需要全局变量声明如下然后,我们对所有的控件做个简单的布局:最后,当slider的值改变时,我们用一个label来显示值的变化,同样,用另一个label来显示stepper值的变化,并改变图片的大小:实现效果如下:

  3. preferredFontForTextStyle字体设置之更改

    即:

  4. Swift没有异常处理,遇到功能性错误怎么办?

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  5. 字典实战和UIKit初探

    ios中数组和字典的应用Applicationschedule类别子项类别名称优先级数据包contactsentertainment接触UIKit学习用Swift调用CocoaTouchimportUIKitletcolors=[]varbackView=UIView(frame:CGRectMake(0.0,0.0,320.0,CGFloat(colors.count*50)))backView

  6. swift语言IOS8开发战记21 Core Data2

    上一话中我们简单地介绍了一些coredata的基本知识,这一话我们通过编程来实现coredata的使用。还记得我们在coredata中定义的那个Model么,上面这段代码会加载这个Model。定义完方法之后,我们对coredata的准备都已经完成了。最后强调一点,coredata并不是数据库,它只是一个框架,协助我们进行数据库操作,它并不关心我们把数据存到哪里。

  7. swift语言IOS8开发战记22 Core Data3

    上一话我们定义了与coredata有关的变量和方法,做足了准备工作,这一话我们来试试能不能成功。首先打开上一话中生成的Info类,在其中引用头文件的地方添加一个@objc,不然后面会报错,我也不知道为什么。

  8. swift实战小程序1天气预报

    在有一定swift基础的情况下,让我们来做一些小程序练练手,今天来试试做一个简单地天气预报。然后在btnpressed方法中依旧增加loadWeather方法.在loadWeather方法中加上信息的显示语句:运行一下看看效果,如图:虽然显示出来了,但是我们的text是可编辑状态的,在storyboard中勾选Editable,再次运行:大功告成,而且现在每次单击按钮,就会重新请求天气情况,大家也来试试吧。

  9. 【iOS学习01】swift ? and !  的学习

    如果不初始化就会报错。

  10. swift语言IOS8开发战记23 Core Data4

    接着我们需要把我们的Rest类变成一个被coredata管理的类,点开Rest类,作如下修改:关键字@NSManaged的作用是与实体中对应的属性通信,BinaryData对应的类型是NSData,CoreData没有布尔属性,只能用0和1来区分。进行如下操作,输入类名:建立好之后因为我们之前写的代码有些地方并不适用于coredata,所以编译器会报错,现在来一一解决。

返回
顶部