swiftresearchkit

Argument type 'Int' does not conform to expected type 'NSCoding & NSCopying & NSObjectProtocol'


I am new to Swift and was trying some tutorials to learn and polish my knowledge on Swift. I stumbled upon above error in this code which I didn't understand. In case anyone of you have idea, please explain whats wrong here.

    let textChoices =   [
    ORKTextChoice(text: "Create a ResearchKit app", value:0),
    ORKTextChoice(text: "Seek the Holy grail", value:1),
    ORKTextChoice(text: "Find a shrubbery", value:2)
]

I resolved the error by suggestion provided by Xcode and now my code looks like

    let textChoices =   [
    ORKTextChoice(text: "Create a ResearchKit app", value:0 as NSCoding & NSCopying & NSObjectProtocol),
    ORKTextChoice(text: "Seek the Holy grail", value:1 as NSCoding & NSCopying & NSObjectProtocol),
    ORKTextChoice(text: "Find a shrubbery", value:2 as NSCoding & NSCopying & NSObjectProtocol)
]

There is another solution I got from answer. While it works, I am still not clear about the problem and solution. What is the concept I am missing.


Solution

  • As ORKTextChoice's initialiser has an abstract parameter type for value:, Swift will fallback on interpreting the integer literals passed to it as Int – which does not conform to NSCoding, NSCopying or NSObjectProtocol. It's Objective-C counterpart, NSNumber, however does.

    Although, rather than casting to NSCoding & NSCopying & NSObjectProtocol, which would result in a bridge to NSNumber (albeit an indirect and unclear one), you can simply make this bridge directly:

    let textChoices = [
        ORKTextChoice(text: "Create a ResearchKit app", value: 0 as NSNumber),
        ORKTextChoice(text: "Seek the Holy grail", value: 1 as NSNumber),
        ORKTextChoice(text: "Find a shrubbery", value: 2 as NSNumber)
    ]
    

    Your original code would have worked prior to Swift 3, as Swift types were able to be implicitly bridged to their Objective-C counterparts. However, as per SE-0072: Fully eliminate implicit bridging conversions from Swift, this is no longer the case. You need to make the bridge explicit with as.