iOS9 Contacts Framework从新保存的联系人获取标识符

Tho*_* G. 5 ios swift cncontact cncontactstore contacts-framework

我在保存请求后直接需要新创建的联系人的标识符.用例:在我的应用程序中,用户创建一个新联系人并为他们提供一些属性(例如姓名,地址......),之后他可以保存联系人.此方案正如预期的那样工作.我的代码看起来像这样:

    func createContact(uiContact: Contact, withImage image:UIImage?, completion: String -> Void)
    {    
       let contactToSave = uiContact.mapToCNContact(CNContact()) as! Cnmutablecontawctlet
       if let newImage = image
       {
          contactToSave.imageData = UIImageJPEGRepresentation(newImage, 1.0)
       }
       request           = CNSaveRequest()
       request.addContact(contactToSave, toContainerWithIdentifier: nil)
       do
       {
          try self.contactStore.executeSaveRequest(request)
          print("Successfully saved the CNContact")
          completion(contactToSave.identifier)
       }
       catch let error
       {
         print("CNContact saving faild: \(error)")
         completion(nil)
       }
  }
Run Code Online (Sandbox Code Playgroud)

Contact Object(uiContact)只是CNContact的包装器.在闭包完成时,我需要返回标识符,但此时我无权访问它们,因为他是在写入过程之后由系统创建的.一种解决方案可能是使用谓词获取新保存的CNContact

public func unifiedContactsMatchingPredicate(predicate: NSPredicate, keysToFetch keys: [CNKeyDescriptor]) throws -> [CNContact]
Run Code Online (Sandbox Code Playgroud)

但在我看来,这似乎有点不洁,因为这种接触可能只有一个名称,而且可能存在多个名称.像创建标识符的回调之类的东西会很好.但事实并非如此.还有其他方法可以解决这个问题吗?

小智 2

这可能有点晚了,但以防万一有人需要这个。

通过使用最新的 SDK(iOS 11),我可以通过以下方式获取标识符:

NSError *error = nil;

saveReq = [[CNSaveRequest alloc] init];
[saveReq addContact:cnContact toContainerWithIdentifier:containerIdentifier];

if (![contactStore executeSaveRequest:saveReq error:&error]) {
    NSLog(@"Failed to save, error: %@", error.localizedDescription);
}
else
{
    if ([cnContact isKeyAvailable:CNContactIdentifierKey]) {
        NSLog(@"identifier for new contact is: %@", cnContact.identifier);
        // this works for me everytime
    } else {
        NSLog(@"CNContact identifier still isn't available after saving to address book");
    }
}
Run Code Online (Sandbox Code Playgroud)