7

最近我从旧的 ABAddressBook 框架切换到了新的 CNContacts。在我的项目中,我将本地联系人与我自己的核心数据联系人同步。为此,我使用联系人标识符和电话标识符来同步电话号码。

但是我观察到有趣的事情,当我尝试编辑联系人时,我将这行代码称为

func getContact() -> CNContact? {
        let contactStore = CNContactStore()
        guard let contactRecord = try? contactStore.unifiedContact(withIdentifier: "8222B6F1-DE99-4099-82A4-47EAB9206A94:ABPerson", keysToFetch: [CNContactViewController.descriptorForRequiredKeys()]) else {
            return nil
        }
        return contactRecord
    }

@IBAction func showContact() {

        let contactViewController = CNContactViewController(forNewContact: self.getContact())
        contactViewController.delegate = self
        contactViewController.title = "New Contact"

        let navigationController = UINavigationController(rootViewController: contactViewController)
        navigationController.navigationBar.isTranslucent = false
        self.present(navigationController, animated: true, completion: nil)
    }

func contactViewController(_ viewController: CNContactViewController, didCompleteWith contact: CNContact?) {
        let newContact = self.getContact()
        viewController.dismiss(animated: false, completion: nil)
    }

这真的很简单。但是如果我在 CNContactViewController 中编辑用户照片,电话标识符将会改变,即使我没有在这个控制器中编辑电话号码。电话标识符可以像这样轻松打印:

po newContact?.phoneNumbers.first?.identifier

这真的打乱了我的同步,因为用户可能只是改变照片,但电话号码的标识符会改变,我无法知道发生了什么。如果我编辑一些其他数据,比如人名、公司等,这个标识符不会改变......即使我将手机编辑为其他值,它也会保持不变。但由于某种原因,改变照片完全搞砸了。

有没有其他人观察到这一点?

这是示例项目的链接以测试此https://drive.google.com/file/d/0B9ngBRq15jSuZTBYNVJCaVJ5WGc/view?usp=sharing

编辑:我在真机上测试了这个

4

2 回答 2

3

我在 iPhone 8 模拟器上尝试了您的示例项目,但似乎无法重现该问题。这是我设置初始联系人照片后的输出:

(lldb) po newContact?.phoneNumbers.first?.identifier
▿ Optional<String>
  - some : "E5D4EDC2-B6FC-4E86-9AF0-F6B78BAF41E5"

(lldb) po oldContact?.phoneNumbers.first?.identifier
▿ Optional<String>
  - some : "E5D4EDC2-B6FC-4E86-9AF0-F6B78BAF41E5"

在我再次点击按钮并将另一张照片设置为联系人照片后:

(lldb) po oldContact?.phoneNumbers.first?.identifier
▿ Optional<String>
  - some : "E5D4EDC2-B6FC-4E86-9AF0-F6B78BAF41E5"

(lldb) po newContact?.phoneNumbers.first?.identifier
▿ Optional<String>
  - some : "E5D4EDC2-B6FC-4E86-9AF0-F6B78BAF41E5"

这些在我看来都一样。我对您的项目所做的唯一一件事就是将 getContact() 中的查找更改为我自己的联系人数据库中存在的标识符。

于 2017-10-04T02:34:32.727 回答
2

我上传了一个如何创建新联系人以及如何编辑它的示例

https://drive.google.com/file/d/0B7OUqtQ1nSxjb3lFTFA5WnlGdFk/view?usp=sharing

为了创建我正在使用的新联系人:

        let newContact = CNMutableContact()
        newContact.givenName = "Jhonny"
        newContact.nickname = "Jhonny"
        newContact.familyName = "My Family"
        newContact.phoneNumbers.append(CNLabeledValue(label: "Home", value: CNPhoneNumber(stringValue: "555-123-4567")))

        let contactViewController = CNContactViewController(forNewContact: newContact)
        contactViewController.delegate = self
        contactViewController.title = "New Contact"
        let navigationController = UINavigationController(rootViewController: contactViewController)
        self.present(navigationController, animated: true, completion: nil)

注意这一行

let contactViewController = CNContactViewController(forNewContact: newContact)

编辑我正在使用的联系人:

        let contactViewController = CNContactViewController(for: contactRecord)
        contactViewController.delegate = self
        contactViewController.title = "Edit Contact"
        let navigationController = UINavigationController(rootViewController: contactViewController)
        self.present(navigationController, animated: true, completion: nil)

再次,注意这一行

let contactViewController = CNContactViewController(for: contactRecord)

我相信问题是调用CNContactViewController的方式。创建和编辑的构造函数是不同的。在演示中,您将在控制台日志中看到电话号码标识符保持不变,即使您编辑照片或其他任何内容。

于 2017-10-04T02:43:33.883 回答