Платформа контактов iOS9 получает идентификатор из вновь сохраненного контакта

Мне нужен идентификатор только что созданного контакта сразу после запроса на сохранение. Вариант использования: в моем приложении пользователь создает новый контакт и дает ему некоторые атрибуты (например, имя, адрес...), после чего он может сохранить контакт. Этот сценарий работает как аспектный. Мой код выглядит так:

    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)
       }
  }

Объект Contact (uiContact) — это всего лишь оболочка CNContact. В завершении закрытия мне нужно вернуть идентификатор, но в этот раз я не имею к ним доступа, потому что он создается системой после процесса записи. Одним из решений может быть получение только что сохраненного CNContact с предикатом

public func unifiedContactsMatchingPredicate(predicate: NSPredicate, keysToFetch keys: [CNKeyDescriptor]) throws -> [CNContact]

но мне это кажется немного нечистым, потому что у этого контакта может быть только имя, и может существовать более одного. Что-то вроде обратного вызова с созданным идентификатором было бы неплохо. Но нет. Есть ли другой способ решить эту проблему?


person Thomas G.    schedule 18.06.2016    source источник


Ответы (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");
    }
}
person Yufei L.    schedule 28.11.2017

Свифт 4

Это способ получить идентификатор контакта при создании контакта

    do {
        try store.execute(saveRequest)
        if contactToAdd.isKeyAvailable(CNContactIdentifierKey) {
            print(contactToAdd.identifier) // here you are getting identifire
        }
    }
    catch {
        print(error)
    }
person Harsh Prajapati    schedule 08.10.2018
comment
Работает также для Swift 5 - person Stephane Paquet; 20.09.2019
comment
Это не работает для меня, так как я обнаружил, что при сохранении контакта в адресной книге Google идентификатор, который я сохранил, кажется, меняется после его сохранения. Досадно, что это означает, что если я добавлю контакт в группу, он исчезнет, ​​когда я снова выберу группу, поскольку ее больше не существует. ОДНАКО вновь созданный контакт теперь находится в адресной книге с другим идентификатором, и я мог бы добавить его в группу. Я в недоумении, почему - person Peter Johnson; 22.05.2021
comment
В то время это работало для меня, на этом этапе я также был без ума от этой функции. Спасибо, что пришли сюда, пожалуйста, дайте свой ответ, как только вы его получите. - person Harsh Prajapati; 23.05.2021