Получение ошибки CNLabeledValue «‘NSCopying

#swift #cncontact

#swift #cncontact

Вопрос:

 var currentContact = CNLabeledValue<NSCopying amp; NSSecureCoding>()
  

Я хочу создать переменную, в которой будет храниться значение от контакта, которое может быть либо номером телефона, либо адресом электронной почты

 var currentContact = CNLabeledValue<NSCopying amp; NSSecureCoding>()
currentContact = self.itemsInAcontact[section][0] as! CNLabeledValue


if ((currentContact.value as? CNPhoneNumber) != nil){
    phoneNumber = currentContact.value as! CNPhoneNumber

    if let y = phoneNumber?.value(forKey: "initialCountryCode"){
        cell.nameLabel!.text = "(phoneNumber!.value(forKey: "initialCountryCode") as! String)(phoneNumber!.stringValue)"
    }else{
        cell.nameLabel!.text = "(phoneNumber!.stringValue)"
    }
}else{
    cell.nameLabel!.text = currentContact.value as! String
}
  

Здесь я пытаюсь отобразить контактный номер или адрес электронной почты, доступные в контакте без имени, внутри ячейки tableview, но я получаю сообщение об ошибке при объявлении var currenctContact

Сообщение об ошибке: «‘NSCopying amp; NSSecureCoding’ не может использоваться как тип, соответствующий протоколу ‘NSSecureCoding’, поскольку ‘NSSecureCoding’ имеет статические требования».

Комментарии:

1. Вам необходимо предоставить полное сообщение об ошибке, которое «‘NSCopying amp; NSSecureCoding’ не может использоваться как тип, соответствующий протоколу ‘NSSecureCoding’, поскольку ‘NSSecureCoding’ имеет статические требования».

Ответ №1:

LabeledValue является общим. Два разных типа LabeledValue (то есть один и тот же общий тип, разрешенный двумя разными способами, CNLabeledValue<NSString> и CNLabeledValue<CNPhoneNumber> ) являются разными типами и не могут быть сохранены в общем свойстве. Это ничем не отличается от того факта, что [Int] и [String] являются двумя разными типами, даже если они оба являются массивами.

Единственный способ сохранить два разных типа LabeledValue в одном свойстве — ввести это свойство как AnyObject . Таким образом, это работает:

 var currentContact : AnyObject? = nil

let phoneNumber = CNPhoneNumber(stringValue: "1234567890")
let labelled = CNLabeledValue(label: "yoho", value: phoneNumber)
currentContact = labelled

let email = CNLabeledValue(label: "hoha", value: "mickey@mouse.com" as NSString)
currentContact = email
  

Однако я не рекомендую этого делать. Вместо этого, поскольку все, что вам действительно нужно, это строка, сделайте свое currentContact помеченное значение, заключающее в себя NSString:

 var currentContact : CNLabeledValue<NSString>? = nil
  

Вы можете сохранить электронное сообщение CNLabeledValue непосредственно в нем. Для номера телефона сформируйте новое помеченное значение из строкового значения номера телефона:

 currentContact = CNLabeledValue(
    label:phone.label, value:phone.value.stringValue as NSString)
  

Комментарии:

1. на самом деле здесь я должен различать 1) <Home>! $_, value=anna-haro@mac.com > из 2) <Main>!$_, значение=<CNPhoneNumber: 0x600003d2d040: stringValue= (415) 555-3695, initialCountryCode= (null)>> и представлять соответствующим образом, если я сохраняю строку в своей модели, она отлично работает для электронных писем, но не для телефонных номеров

2. Мой ответ остается в силе. Вы не можете хранить два разных типа в одной переменной. Если вам нужно хранить электронные письма и номера телефонов, это как минимум две переменные, а не только одна.

3. Вы можете преобразовать номер телефона в CNLabeledValue<NSString> . Это дает ему общий тип со значением, помеченным электронной почтой, и вы можете сохранить любой из них в одном и том же свойстве. Я отредактировал, чтобы продемонстрировать.

Ответ №2:

Похоже, Apple что-то изменила в NSSecureCoding в XCode 10.2, но я пока не смог найти никаких подробностей.

Итак, на данный момент вам следует перейти с NSCopying amp; NSSecureCoding на NSString

 var currentContact = CNLabeledValue<NSString>()
  

Комментарии:

1. на самом деле здесь я могу получить либо: 1) <Home>! $_, value=anna-haro@mac.com > или 2) <Main>!$_, value=<CNPhoneNumber: 0x600003d2d040: stringValue=(415) 555-3695, initialCountryCode= (null)>> если я использую предложенное вами изменение, я могу корректно получать значения электронной почты, но в случае значения CNPhoneNumber происходит сбой