0
votes

With my newbie swift skills I'm struggling to figure out the correct swift syntax to get this playground to work. Depending how I try to solve it I either get

Cannot invoke 'encode' with an argument list of type '(Encodable)'

which is similar to what was solved in this question Using JSON Encoder to encode a variable with Codable as type or I get

' (T) -> ()' requires that 'Encodable' conform to 'Encodable'

I'd really appreciate a solution with explanation

EDIT To provide some more context, the pattern I'm trying to implement here is for a middleware router. Depending on the actions made in the app, the router will construct the network request. The intent of the codableParam is to deliver the conforming structure for the use case. All cases would therefore return either nil or a Codable type.

struct unityAuthenticationRequest: Codable {
    var username : String
    var password : String
}

enum test  {
    case volume
    case num2
    case num3

    var codableParam: Encodable? {
        switch self {
        case .volume:
            return unityAuthenticationRequest(username: "uname", password: "pwrods")
        default:
            return nil
        }
    }
}

func saveObject<T:Encodable>(_ object: T) {
    let data = try? JSONEncoder().encode(object)
}

func dx<T: Codable>(fx: T) {
    let datax = try? JSONEncoder().encode(fx)
}

let r = test.volume
saveObject(r.codableParam)
1
What is it that you are trying to achieve? Your example seems quite contrived without an explanation of what is your code supposed to do. You cannot return an Encodable and supply that as input to saveObject, since Encodable cannot be used as a concrete type, which is what the error message actually tells you if you check both errors on the problematic line. - Dávid Pásztor
Edited and added intent as requested - 300baud
One option I was considering was for the codableParam function to morph into codableData - where the encode has been performed within the function - but this seemed like a workaround - 300baud
Now I'm even more confused. If you're trying to create URLRequests, why are you returning Codable? Why would you want to encode a URLRequest into JSON? How do you plan on executing a URLRequest after encoding it to JSON? Btw you should conform to the Swift naming convention, which is UpperCamelCase for type names, so Test and UnityAuthenticationRequest would be appropriate. - Dávid Pásztor
I was using this medium.com/@AladinWay/… as an example - this will show you the broader context. In this example it uses JSONSerialisation, but I wanted to understand if Codable was a better option. - 300baud

1 Answers

0
votes

The error message pretty much tells you what is going on:

Fatal error: Optional<Encodable> does not conform to Encodable
  because Encodable does not conform to itself.
  You must use a concrete type to encode or decode.:
    file /BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-900.0.74.1/src/swift/stdlib/public/core/Codable.swift, line 3960

It is however easy enough to fix, just change your first line like this:

var codableParam: unityAuthenticationRequest? {
    switch self {
    case .volume:
        return unityAuthenticationRequest(username: "uname", password: "pwrods")
    default:
        return nil
    }
}

Now your parameter does have a concrete type and the requirements are satisfied with minimal syntactic changes.

I am still having a hard time figuring out how this type of code might transfer your intentions in the most comprehensible way possible, but we would have to know more about your intentions in order to improve upon it.