swift3下通讯录的开发
Posted Shayne_win
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了swift3下通讯录的开发相关的知识,希望对你有一定的参考价值。
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]\\\\d8$" 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()
以上是关于swift3下通讯录的开发的主要内容,如果未能解决你的问题,请参考以下文章