Как добавить настраиваемое скрытое поле в мобильные контакты ios с помощью CNMutableContact?

Я хочу добавить одно настраиваемое скрытое поле в мобильные контакты iOS из моего приложения.

Можно ли добавить новое скрытое поле со значением в мобильных контактах iOS? Будет ли CNMutableContact разрешать мне добавлять новое настраиваемое свойство?

Ответ 1

Короткий ответ печально - нет, это невозможно.

Долгий ответ: CNMutableContact является подклассом CNContact, который поставляется со следующим открытым интерфейсом.

open class CNContact : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
    open var identifier: String { get }
    open var contactType: CNContactType { get }
    open var namePrefix: String { get }
    open var givenName: String { get }
    open var middleName: String { get }
    open var familyName: String { get }
    open var previousFamilyName: String { get }
    open var nameSuffix: String { get }
    open var nickname: String { get }
    open var organizationName: String { get }
    open var departmentName: String { get }
    open var jobTitle: String { get }
    open var phoneticGivenName: String { get }
    open var phoneticMiddleName: String { get }
    open var phoneticFamilyName: String { get }
    open var phoneticOrganizationName: String { get }
    open var note: String { get }
    open var imageData: Data? { get }
    open var thumbnailImageData: Data? { get }
    open var imageDataAvailable: Bool { get }
    open var phoneNumbers: [CNLabeledValue<CNPhoneNumber>] { get }
    open var emailAddresses: [CNLabeledValue<NSString>] { get }
    open var postalAddresses: [CNLabeledValue<CNPostalAddress>] { get }
    open var urlAddresses: [CNLabeledValue<NSString>] { get }
    open var contactRelations: [CNLabeledValue<CNContactRelation>] { get }
    open var socialProfiles: [CNLabeledValue<CNSocialProfile>] { get }
    open var instantMessageAddresses: [CNLabeledValue<CNInstantMessageAddress>] { get }
    open var birthday: DateComponents? { get }
    open var nonGregorianBirthday: DateComponents? { get }
    open var dates: [CNLabeledValue<NSDateComponents>] { get }
    /* [...] functions */
}

Единственное необходимое различие между двумя типами (что делает его изменчивым) состоит в том, что кроме свойства identifier свойства CNMutableContact не указываются как get-only. При более внимательном рассмотрении вы можете теперь видеть, что нет никаких возможностей для пользовательских свойств объектов Contact. Подкласс CNMutableContact, как я сделал в следующем примере, приведет к тому, что nilError и CNContactStore не сохранят наш пользовательский контакт.

func saveCustomContact() {
    let contactStore = CNContactStore()
    let contact = MyContact()

    contact.givenName = "John"
    contact.familyName = "Doe"
    contact.test = "Hello World"

    do {
        let saveRequest = CNSaveRequest()
        saveRequest.add(contact, toContainerWithIdentifier: nil)
        try contactStore.execute(saveRequest)
    } catch {
        print(error)
    }
}

func retrieveCustomContact() {
    DispatchQueue.global().async {
        let keysToFetch = [CNContactFormatter.descriptorForRequiredKeys(for: .fullName),CNContactPhoneNumbersKey] as [Any]
        let fetchRequest = CNContactFetchRequest( keysToFetch: keysToFetch as! [CNKeyDescriptor])
        CNContact.localizedString(forKey: CNLabelPhoneNumberiPhone)

        fetchRequest.mutableObjects = false
        fetchRequest.unifyResults = true
        fetchRequest.sortOrder = .userDefault

        do {
            try CNContactStore().enumerateContacts(with: fetchRequest) { (contact, stop) -> Void in
                guard let contact = contact as? MyContact else { print("damn - it not working!"); return }
                print(contact.test)
            }
        } catch {
            print(error)
        }
    }
}

open class MyContact: CNMutableContact {
    open var test: String?
}

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