2017-09-29 55 views
7

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

编辑:我测试了这个真实的手机

回答

2

我想你的示例项目在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()中的查找更改为存在于我自己的联系人数据库中的标识符。

+0

尝试多次这样做,但在真实的手机上。添加照片,然后保存,删除照片然后保存,再次添加照片,并确定它会改变 – MegaManX

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的方式。构造函数对于创建和编辑而言是不同的。 在演示中,您将在控制台日志中看到即使您编辑照片或其他任何内容,电话号码标识仍保持不变。

+0

我试过你的项目,并经过多次编辑 - 添加照片/删除照片,我设法得到不同的标识符:**** contact givenName :的Jhonny 接触昵称:0F386257-4071-4CC2-A2BE-18048F0F8F87:ABPerson 电话号码标识符:D2F8B6D5-A2AC-4194-96F9-F915294E6445 ***接触给定名称:的Jhonny 接触昵称:0F386257-4071-4CC2-A2BE- 18048F0F8F87:ABPerson 电话号码标识:DB940E27-3ADC-42A2-8EB3-9DA7B0A7D6F4 – MegaManX

+0

@MegaManX我试过你说的()删除照片),你是对的,电话标识符会改变。我在iOS 10和11中测试了它,它仍在发生。我可以问你用什么标识符?也许还有另一种方法来实现你所需要的。 – carlos21

+0

我正在使用它们与我的本地数据库进行同步,因为电话号码不是唯一的,例如,用户的联系人帐号中可以有相同的号码。 – MegaManX