Search code examples
swiftcncontact

Getting CNLabeledValue error "'NSCopying & NSSecureCoding' cannot be in Xcode 10.2 not in Xcode 10.1


var currentContact = CNLabeledValue<NSCopying & NSSecureCoding>()

I want to create a variable which will store the value from the contact which can be either a phone number or an email address

var currentContact = CNLabeledValue<NSCopying & 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
}

Here i am trying to display the contact number or email address available in a no name type contact inside the cell of a tableview, but I'm getting error on declaration of var currenctContact

The error message: "'NSCopying & NSSecureCoding' cannot be used as a type conforming to protocol 'NSSecureCoding' because 'NSSecureCoding' has static requirements".


Solution

  • LabeledValue is a generic. Two different LabeledValue types (that is, the same generic resolved in two different ways, CNLabeledValue<NSString> and CNLabeledValue<CNPhoneNumber>) are different types and cannot be stored in a common property. This is no different from the fact that [Int] and [String] are two different types even though they are both arrays.

    The only way you can store two different LabeledValue types in a single property is to type that property as AnyObject. Thus, this works:

    var currentContact : AnyObject? = nil
    
    let phoneNumber = CNPhoneNumber(stringValue: "1234567890")
    let labelled = CNLabeledValue(label: "yoho", value: phoneNumber)
    currentContact = labelled
    
    let email = CNLabeledValue(label: "hoha", value: "[email protected]" as NSString)
    currentContact = email
    

    However, I don’t recommend doing that. Instead, since all you really need is a string, make your currentContact a labeled value wrapping an NSString:

    var currentContact : CNLabeledValue<NSString>? = nil
    

    You can store an email CNLabeledValue directly into that. For a phone number, form a new labeled value from the phone number’s string value:

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