1

I have tried to keep my question very simple. I have been struggling whole day to make it work but no luck. I have two protocols. Decodable and Requestable.

protocol Decodable { }
struct D: Decodable { }

protocol Requestable {
    associatedtype Model
}

extension Requestable {
    func returnValue() {
        Utils.doSomething(Model)
    }
}

And a class Utils

class Utils {
    static func doSomething<T>(param: T) {
        print("Default")
    }

    static func doSomething<T: Decodable>(param: T) {
        print("Decodable")
    }

    static func doSomething<T: Decodable>(param: [T]) {
        print("Decodable Array")
    }
}

I create a struct R implementing Requestable and give the type alias Model to String

struct R: Requestable {
    typealias Model = String
}

When i run the R().returnValue() function, It prints Default. As Expected.

I create a struct R2 implementing Requestable and give the type alias Model to D which is implementing Decodable

struct R2: Requestable {
    typealias Model = D
}

When i run the R2().returnValue() function, It prints Default. but i was expecting it would print Decodable because the Model D conforms to Decodable.

I create a struct R3 implementing Requestable and give the type alias Model to [D] where the element of array is implementing Decodable

struct R3: Requestable {
    typealias Model = [D]
}

When i run the R3().returnValue() function, It prints Default. but i was expecting it would print Decodable Array because the Model D conforms to Decodable.

Any kind of help appreciated.

UPDATE

Using AnyRequestable and checking in runtime will not work in this case because in real code the Generic is the return value and could not be checked dynamically.

In real code functions signatures are like

public static func ResponseSerializer<M>() -> ResponseSerializer<M, NSError> {}
public static func ResponseSerializer<M: Decodable>() -> ResponseSerializer<M, NSError> {}
public static func ResponseSerializer<M: Decodable>() -> ResponseSerializer<[M], NSError> {}

1 Answer 1

3

This is the expected result. You forgot to declare the Decodable conformance for your Model associated type. This should fix it:

protocol Requestable {
    associatedtype Model: Decodable
}

Edit: Reading your comments, I now understand your problem. The thing is, what you're asking of requires the runtime, there is no way to statically achieve it:

class Utils {
    static func doSomething<T>(param: T) {
        if let param = param as? Decodable {
            print("Decodable")
        } else {
            print("Default")
        }
    }
}

Think about it; when you are compiling your code, in the scope of returnValue, the compiler only knows that Model is an associated type and nothing else. Either you explicitly declare the conformance Decodable, or the compiler assumes the default case, which is just <T>.

Sign up to request clarification or add additional context in comments.

4 Comments

My Bad. I added a normal case also. And the Model could be [Decodable] too.
Appreciate your help. I got the same reply here. stackoverflow.com/questions/35431712/…. But there is no way to check in the runtime. I am struggling since so many days in this.
@RahulKatariya: You, my friend, are in luck. Because I have invented just the technique you need to solve your kind of problem. Meet OpaqueSwift.
I have been playing a lot with TypeErasures too. I will give it a try. cuz the real code is always much more complex. Thanks a lot.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.