0

I has the follow code implemented to work with Argo framework, has been working until the Xcode 11.2.1 update. when I updated my Xcode Version the follow error appears:

Binary operator '<^>' cannot be applied to operands of type '(()) -> VoiceMailNumberResponse' and 'Decoded<_?>'

Here's my code:

struct VoiceMailNumberResponse{
    var name: String?
    var value: String?
}

extension VoiceMailNumberResponse: Argo.Decodable {
    static func decode(_ json: JSON) -> Decoded<VoiceMailNumberResponse> {
        let voiceMailNumberResponse = curry(VoiceMailNumberResponse.init)
        return voiceMailNumberResponse
            <^> json <|?  "name"
            <*> json <|?  "value"
    }
}

Error appears on line: "<^> json <|? "name"

In addition I'm using Argo, Curry and Runes for parsing JSON.

Hamid Yusifli
  • 9,688
  • 2
  • 24
  • 48
Mervin
  • 3
  • 1

1 Answers1

1

Note: This answer is based only off your code sample and has not been tested.

As both the properties of VoiceMailNumberResponse are optional then Xcode 10.1/Swift 4.2 (the version tested with) produces two init methods:

init()
init(name: String?, value: String?)

If neither, or just one, property is an optional only the second init is produced. From the question it appears Xcode 11.2.1/Swift 5.1 behaves the same way.

The type in the error message:

(()) -> VoiceMailNumberResponse

indicates that the compiler has selected the init() to pass to curry, while the code expects the init(name: String?, value: String?) to be passed.

As the code apparently worked with some previous Xcode/Swift this would appear to be a change in behaviour.

This could be a change to, or "feature" of, the language and/or compiler. You can probably work around it by explicitly specifying which init to use by including the parameter names, e.g. something like:

...
let voiceMailNumberResponse = curry(VoiceMailNumberResponse.init(name:value:))
...

That said it would be best to figure out if:

  • this is a language/compiler change, and therefore Argo, Curry and Runes might need updating which you should report (the version history indicates there have been ambiguities addressed before);

  • a "feature", in which case you should head over to feedbackassistant.apple.com and file a bug report; or

  • something else

You might also want to look at using Swift's Decodable, introduced in Xcode 9, to decode the JSON as an alternative to using these third-party packages.

HTH

CRD
  • 52,522
  • 5
  • 70
  • 86
  • 1
    Instead of selecting `init` via intermediate variable and manual type declaration, you can also specify `init` in full form with all selectors: `curry(VoiceMailNumberResponse.init(name:value:))` – user28434'mstep Nov 18 '19 at 09:59
  • 1
    @user28434 – Good catch! Should have remembered that, I'll edit the answer. – CRD Nov 18 '19 at 17:34