您的位置:首页 > 移动开发 > Swift

swift3下通讯录的开发

2017-02-09 11:18 239 查看

swift3下通讯录的开发

1:封装一个通讯录Manager:

iOS9之后,通讯录用CNContactStore实现;iOS9之前使用ABAddressBook。


读取通讯录的流程:

检测授权;

没有权限申请权限;

得到权限读取通讯录消息。

2:开始封装AddressBookManger单例:

基本信息设置与实现:

iOS10之后需要在plist文件中添加访问权限:key:Privacy - Contacts Usage Description value:contactsDesciption。

mannager单例实现:

/// 单例
class var sharedInstance: YSAddressBookManager{
struct Static {
static var instance : YSAddressBookManager = YSAddressBookManager()
}
return Static.instance
}


分别创建一个CNContactStore和ABAddressBook的属性:

//注意调用ABAddressBookCreateWithOptions进行ABAddressBookCreateWithOptions的初始化需要设置为一个lazy变量,否则在用户拒绝授权的情况下,程序将会崩溃。因为ABAddressBookCreateWithOptions(nil, nil)得到的值为nil。
lazy var addressBook:ABAddressBook = {
var emptyDictionary: CFDictionary?
var errorRef: Unmanaged<CFError>?
let ab:ABAddressBook = ABAddressBookCreateWithOptions(emptyDictionary, &errorRef).takeRetainedValue()
return ab
}()

@available(iOS 9.0, *)
lazy var contact:CNContactStore = CNContactStore()

//获取当前系统版本号
lazy var current_iOS_Version:Float = {
return UIDevice.current.systemVersion.floatValue
}()

var originalAddressData:[AddressBookObj] = [] //用于存放通讯录里的原始有效数据


创建一个对外的权限授权状态:

//@objc如果是在OC和swift3混编的工程里,OC的类需要使用到AddressBookAuthorizationStatus枚举,则加上@objc,这样就可以在OC类里也使用,否则无需@objc标注
@objc enum AddressBookAuthorizationStatus:Int {
case deniedOrRestricted = 1
case authorized = 2
case notDeterMined = 3
}


授权:

检测授权情况

//检测授权情况
func cheackAddressBookAuthorizationStatus()->AddressBookAuthorizationStatus {

if #available(iOS 9, *) {
switch CNContactStore.authorizationStatus(for: .contacts) {
case .denied,.restricted:
return .deniedOrRestricted
case .authorized:
return .authorized
case .notDetermined:
return .notDeterMined
}
}else{
switch ABAddressBookGetAuthorizationStatus() {
case .denied,.restricted: //访问限制或者拒绝 弹出设置对话框
return .deniedOrRestricted
case .authorized://已授权,加载数据
return .authorized
case .notDetermined://从未进行过授权操作、请求授权
return .notDeterMined
}
}
}


请求授权

//请求授权
func requestAddressBookAccess(_ success:@escaping ((_ granted:Bool )->Void)) {
if #available(iOS 9, *){
self.contact.requestAccess(for: .contacts, completionHandler: { (granted, error) in
if !granted {
success(false)
}else{
success(true)
}
})
}else{
ABAddressBookRequestAccessWithCompletion(self.addressBook) {(granted, error) in
if !granted {
success(false)
}else{
success(true)
}
}
}
}


读取通讯录信息:

1://谓词表达式判断手机号码是否有效
func validateMobile(_ phoneNum:String)-> Bool {
if phoneNum.characters.count != 11 || phoneNum.characters.count == 0 {
return false
}
let mobile =  "^1[3|4|5|7|8][0-9]\\d{8}$"
let regexMobile = NSPredicate(format: "SELF MATCHES %@",mobile)
let isValid:Bool = regexMobile.evaluate(with: phoneNum)
if !isValid {
return false
}
return true
}


2://有的手机系统读取到的手机号都有'-',所以去除'-'
func removeUnuseChar(str:String) -> String {
var tmpStr = str
for char in tmpStr.characters {
if char == "-" {
let range = tmpStr.range(of: "-")
tmpStr.removeSubrange(range!)
}
}
return tmpStr
}


3:

func readRecords() -> [AddressBookObj] //原始有效数据
{
self.originalAddressData.removeAll()
if #available(iOS 9, *){

let keysToFetch = [CNContactFormatter.descriptorForRequiredKeys(for: CNContactFormatterStyle.fullName),CNContactPhoneNumbersKey] as [Any]

try! self.contact.enumerateContacts(with: CNContactFetchRequest(keysToFetch: keysToFetch as! [CNKeyDescriptor]), usingBlock: {[weak self] (contact, pointer) in
var phone = ""
if contact.phoneNumbers.count > 0 {
let phoneNum = contact.phoneNumbers.first

guard let phoneNumber = phoneNum?.value else {
return
}

let phoneString = phoneNumber.stringValue

let result = self?.removeUnuseChar(str: phoneString)

if self!.validateMobile(result!) {
phone = result!
}

if phone != "" {
let obj:AddressBookObj = AddressBookObj()
obj.phone = phone
let name:String = String(format: "%@%@", contact.givenName,contact.familyName)
obj.name = name
self?.originalAddressData.append(obj)
print("CNContact:\(name):\(phone)")
}
}
})
return originalAddressData
}else{

let peoples = ABAddressBookCopyArrayOfAllPeople(self.addressBook).takeRetainedValue() as [ABRecord]

for people: ABRecord in peoples {
var firstName = ""
var lastName = ""
var phone = ""

if let firstNameUnmanaged = ABRecordCopyValue(people, kABPersonLastNameProperty) {
firstName = firstNameUnmanaged.takeRetainedValue() as? String ?? ""
}
if let lastNameUnmanaged = ABRecordCopyValue(people, kABPersonFirstNameProperty) {
lastName = lastNameUnmanaged.takeRetainedValue() as? String ?? ""
}

let phoneNums: ABMultiValue = ABRecordCopyValue(people, kABPersonPhoneProperty).takeRetainedValue() as ABMultiValue

for index in 0..<ABMultiValueGetCount(phoneNums){
let label = ABMultiValueCopyValueAtIndex(phoneNums, index).takeRetainedValue() as! String

let result = self.removeUnuseChar(str: label)

if self.validateMobile(result) {
phone = result
break
}

}

if phone != "" {
let obj:AddressBookObj = AddressBookObj()
obj.phone = phone
let name:String = String(format: "%@%@", lastName,firstName)
obj.name = name
self.originalAddressData.append(obj)
print("ABAddressBook:\(name):\(phone)")
}

}
return originalAddressData
}
}


联系人数据的排序与使用:

//数据处理:排序、传给后端,更新UI
func updateOroginalData(){
//得出27个索引
let collation = UILocalizedIndexedCollation.current()
let sectionTitles = collation.sectionTitles.count
//self.sectionTitleArr存放section数组
self.sectionTitleArr = NSMutableArray(array: collation.sectionTitles)
//初始化27个空数组 self.dataArrays存放numberOfRowsInSection
var i = 0
while i<sectionTitles {
let arr = NSMutableArray()
self.dataArrays.add(arr)
i += 1
}
for obj in self.originalAddressData {
if obj.name != "" {
let sectionNum = collation.section(for: obj, collationStringSelector: #selector(obj.nameMethod))
let array:NSMutableArray = self.dataArrays[sectionNum] as! NSMutableArray
array.add(obj)
}
}

//对每个section中的数组按name排序
for i in 0..<self.dataArrays.count {
let arr:NSMutableArray = self.dataArrays[i] as! NSMutableArray
let sortArr = collation.sortedArray(from: arr as [AnyObject], collationStringSelector: #selector(getter: xxClass.name))
arr.removeAllObjects()
arr.addObjects(from: sortArr)
}

//去掉无数据的数组
let tmpArrA = NSMutableArray()
let tmpArrB = NSMutableArray()

for i in 0..<self.dataArrays.count {
let arr = self.dataArrays[i]
if (arr as AnyObject).count == 0 {
tmpArrA.add(self.sectionTitleArr[i])
tmpArrB.add(self.dataArrays[i])
}
}

for i in 0..<tmpArrA.count {
self.sectionTitleArr.remove(tmpArrA[i])
self.dataArrays.remove(tmpArrB[i])
}

tableView.reloadData()
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息