2
votes

So, I'm trying to achieve this:

Have a protocol with associatedtype who will handle json parsing into his extension. The associatedtype must conform to Decodable:

protocol MyProtocol {
  associatedtype ResponseType: Decodable
  func handleResponse(data: Data) -> ResponseType
}

What I'm want to do is to set a default type for responseType into my extension and then, if needed, override that type into the class, or struct conformance. Something like this.

extension MyProtocol {
  typealias ResponseType = MyDefaultDecodableType

  func handleResponse(data: Data) -> ResponseType { ... }
}

class MyObject: MyProtocol {
  typealias ResponseType = AnotherDecodableType
}

Problem is I'm getting an error like this inside MyObject:

error: type 'MyObject' does not conform to protocol 'MyProtocol'
class MyObject: MyProtocol {
      ^
note: multiple matching types named 'ResponseType'
    associatedtype ResponseType: Decodable
                   ^
note: possibly intended match
  typealias ResponseType = AnotherDecodableType
            ^
note: possibly intended match
    public typealias ResponseType = MyDefaultDecodableType

I don't know if it's possible to achieve what I'm trying or I'm approaching the wrong way. Anyone can give me some light?

Thanks.

1
How does your MyDefaultDecodableType and AnotherDecodableType look ?Sandeep
AnotherDecodableType and MyDefaultDecodableType is confirming Decodable protocol ?Prashant Tukadiya
Thanks you accepting answer i am glad that it helps you :) Have a nice dayPrashant Tukadiya

1 Answers

0
votes

I have created the same code. There are some facts that need to be understood here.

extension MyProtocol {
    typealias ResponseType = MyDefaultDecodableType
    
    func handleResponse(data: Data) -> ResponseType {
        
        return try! JSONDecoder().decode(MyDefaultDecodableType.self, from: data)
        
    }
}

Conceptually, there are no generic protocols in Swift. But by using typealias we can declare a required alias for another type.

Your extension doesn't need to define typealias ResponseType = MyDefaultDecodableType as it is going to provide some default implementation using MyDefaultDecodableType, so it is useless.

So your extension would be something like this

extension MyProtocol {
  //  typealias ResponseType = MyDefaultDecodableType // NO NEED FOR IT
    
    func handleResponse(data: Data) -> MyDefaultDecodableType {
        print("Test \(self)")
        return try! JSONDecoder().decode(MyDefaultDecodableType.self, from: data)
        
    }
}

Now you can define

class MyObject:MyProtocol {
    typealias ResponseType = AnotherDecodableType
    
    func handleResponse(data: Data) -> ResponseType {
        print("Test \(self)")

        return try! JSONDecoder().decode(AnotherDecodableType.self, from: data)
        
    }
    
}
class MyObject2:MyProtocol {
   
    
}

Without any errors

Now if you use

MyObject().handleResponse(data:data)
MyObject2().handleResponse(data:data2)

You will get

test __lldb_expr_44.MyObject

test __lldb_expr_44.MyObject2