美文网首页
Contact.framework联系人相关操作

Contact.framework联系人相关操作

作者: Future_3e45 | 来源:发表于2019-08-01 16:16 被阅读0次

//

//  ViewController.swift

//  ContactClean

//

//  Created by zhangzb on 2019/7/31.

//  Copyright © 2019 zhangzb. All rights reserved.

//

/*

1、引入Contacts框架

2、检查授权状态

3、获取联系人

4、展示、增删改查操作

5、info.plist增加字段

*/

import UIKit

// 引入Contacts框架

import Contacts

class ViewController: UIViewController {

    // 所有联系人都是CNContact类型的数据,所以直接使用系统的CNContact实体类

    var contacts = [CNContact]()

    @IBOutlet var tableView: UITableView!

    override func viewDidLoad() {

        super.viewDidLoad()

        // 检查状态

        if self.checkAuthStatus() {

            // 如果已授权,那么直接拉取数据

            self.requestAllContacts()

        }

    }

    /// 检查授权状态,true已授权,false未授权

    func checkAuthStatus() -> Bool {

        weak var weakSelf = self

        // 获取授权状态

        switch CNContactStore.authorizationStatus(for: .contacts) {

        // 不允许,没有权限

        case .denied:

            let alertController = UIAlertController(title: "未授权", message: "您关闭了App访问通讯录的权限,请先去开启后重试", preferredStyle: .alert)

            alertController.addAction(UIAlertAction(title: "去开启", style: .default, handler: { (_) in

                weakSelf?.goToSetting()

            }))

            alertController.addAction(UIAlertAction(title: "取消", style: .cancel, handler: { (_) in

            }))

            self.present(alertController, animated: true, completion: nil)

        // 未授权,restricted(因为一些原因没有授权)

        case .notDetermined, .restricted:

            // 申请授权

            CNContactStore().requestAccess(for: .contacts) { (success, error) in

                if success, error == nil {

                    let alertController = UIAlertController(title: "成功", message: "授权成功", preferredStyle: .alert)

                    alertController.addAction(UIAlertAction(title: "确定", style: .default, handler: { (_) in

                        // 由于会优先返回false,所以第一次授权弹窗时不会刷新数据,在授权成功之后需要重新调用刷新方法

                        weakSelf?.requestAllContacts()

                    }))

                    weakSelf?.present(alertController, animated: true, completion: nil)

                } else {

                    let alertController = UIAlertController(title: "错误", message: "授权失败", preferredStyle: .alert)

                    alertController.addAction(UIAlertAction(title: "确定", style: .cancel, handler: { (_) in

                    }))

                    weakSelf?.present(alertController, animated: true, completion: nil)

                }

            }

        // 已允许

        case .authorized:

            print("Authorized")

            return true

        // CNAuthorizationStatus 可能会在将来添加状态,所以Apple要求写@unknown default状态,试试注掉会报警告

        // Switch covers known cases, but 'CNAuthorizationStatus' may have additional unknown values, possibly added in future versions

        @unknown default:

            let alertController = UIAlertController(title: "错误", message: "授权失败", preferredStyle: .alert)

            alertController.addAction(UIAlertAction(title: "确定", style: .cancel, handler: { (_) in

            }))

            weakSelf?.present(alertController, animated: true, completion: nil)

        }

        // 只有在允许的情况下才返回true

        return false

    }

    /// 刷新数据

    func requestAllContacts() {

        self.contacts.removeAll()

        weak var weakSelf = self

        let contactStore = CNContactStore()

        do {

            // 此处列举需要获取的联系人数据的key,eg. CNContactGivenNameKey

            try contactStore.enumerateContacts(with: CNContactFetchRequest(keysToFetch: [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey] as [CNKeyDescriptor])) { (contact, stop) in

                weakSelf?.contacts.append(contact)

            }

            self.tableView.reloadData()

        } catch {

            print(error)

        }

    }

    // 跳转设置页面

    func goToSetting() {

        if let settingUrl = URL(string: UIApplication.openSettingsURLString), UIApplication.shared.canOpenURL(settingUrl) {

            UIApplication.shared.open(settingUrl)

        }

    }

    // 增加一个

    @IBAction func addOne() {

        // 创建一个新的contact

        let contact = CNMutableContact()

        contact.givenName = "aaaaa\(arc4random_uniform(100))"

        contact.familyName = "bb\(arc4random_uniform(100))"

        var phones = [CNLabeledValue<CNPhoneNumber>]()

        for _ in 0...arc4random_uniform(5) {

            let phoneValue = CNLabeledValue(label: "手机", value: CNPhoneNumber(stringValue: "130000\(arc4random_uniform(99999))"))

            phones.append(phoneValue)

        }

        contact.phoneNumbers = phones

        // 创建保存saveRequest

        let saveRequest = CNSaveRequest()

        saveRequest.add(contact, toContainerWithIdentifier: nil)

        self.excute(saveRequest: saveRequest)

    }

    // 删

    func deleteOne(contact: CNContact) {

        // 创建删除saveRequest

        let saveRequest = CNSaveRequest()

        saveRequest.delete(contact.mutableCopy() as! CNMutableContact)

        self.excute(saveRequest: saveRequest)

    }

    // 改

    func updateOne(contact: CNContact) {

        // 修改对应的联系人信息

        let mutableContact = contact.mutableCopy() as! CNMutableContact

        mutableContact.givenName = "aaaaa\(arc4random_uniform(100))"

        mutableContact.familyName = "bb\(arc4random_uniform(100))"

        var phones = [CNLabeledValue<CNPhoneNumber>]()

        for _ in 0...arc4random_uniform(5) {

            let phoneValue = CNLabeledValue(label: "手机", value: CNPhoneNumber(stringValue: "130000\(arc4random_uniform(99999))"))

            phones.append(phoneValue)

        }

        mutableContact.phoneNumbers = phones

        // 创建修改saveRequest

        let saveRequest = CNSaveRequest()

        saveRequest.update(mutableContact)

        self.excute(saveRequest: saveRequest)

    }

    // 执行request

    func excute(saveRequest: CNSaveRequest) {

        do {

            try CNContactStore().execute(saveRequest)

            print("保存成功")

            self.requestAllContacts()

        } catch {

            print(error)

        }

    }

}

// 联系人cell

class CCContactCell: UITableViewCell {

    /// 姓名

    @IBOutlet var nameLabel: UILabel!

    /// 手机号码

    @IBOutlet var phoneLabel: UILabel!

    func updateUI(contact: CNContact) {

        self.nameLabel.text = contact.givenName + contact.familyName

        var phones = [String]()

        for phone in contact.phoneNumbers {

            phones.append(phone.value.stringValue)

        }

        self.phoneLabel.text = phones.joined(separator: ",")

    }

}

extension ViewController: UITableViewDataSource, UITableViewDelegate {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return self.contacts.count

    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        var cell = tableView.dequeueReusableCell(withIdentifier: "ContactCell") as? CCContactCell

        if cell == nil {

            cell = CCContactCell(style: .default, reuseIdentifier: "ContactCell")

        }

        cell?.updateUI(contact: self.contacts[indexPath.row])

        return cell ?? CCContactCell()

    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        // 点击cell时更新联系人的信息

        self.updateOne(contact: self.contacts[indexPath.row])

    }

    func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {

        return .delete

    }

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {

        // 删除联系人的信息

        self.deleteOne(contact: self.contacts[indexPath.row])

    }

}

最后,别忘了在项目info.plist中添加NSContactsUsageDescription

相关文章

网友评论

      本文标题:Contact.framework联系人相关操作

      本文链接:https://www.haomeiwen.com/subject/ichcdctx.html