user8646151
user8646151

Reputation:

"How to use Codable Protocol for a Networking Layer "

How to resolve this issue.......

Im trying to build a network layer for my app so as I go through the project

I'm getting the error

"Cannot invoke 'decode' with an argument list of type '(Codable, from: Data)'" I think its happening because of error type or a mismatch Help me resolve this issue

enum Type:String {
    case GET
    case POST
    case PUT
    case DELETE
}


func networkRequest(MethodType:Type, url:String, codableType:Codable) {

    guard let getUrl = URL(string: url) else {return}

    if MethodType == Type.GET  {

        URLSession.shared.dataTask(with: getUrl) { (data, response, err) in

            if let urlRes = response as? HTTPURLResponse{

                if 200...300 ~= urlRes.statusCode {

                    guard let data = data else {return}

                    do {
                        let newData = try JSONDecoder().decode(codableType.self, from: data)
                    }
                    catch let jsonerr {
                        print("Error Occured :"+jsonerr.localizedDescription)
                    }
                }


            }
        }.resume()

    }

}

Upvotes: 0

Views: 451

Answers (2)

Sweeper
Sweeper

Reputation: 270840

Generics can solve this problem.

First, introduce a generic type parameter:

func networkRequest<T: Decodable>(MethodType:Type, url:String)
                   ^^^^^^^^^^^^^^

Now you can use T.self for the type to decode:

try JSONDecoder().decode(T.self, from: data)

Also, you might consider adding a completion handler, otherwise the value you fetched will be lost:

func networkRequest<T: Decodable>(MethodType:Type, url:String, completionHandler: (T) -> Void)

Usage:

networkRequest(MethodType: .GET, url: ...) {
    (myStuff: MyType) in
    ...
}

Upvotes: 3

vadian
vadian

Reputation: 285069

JSONDecoder expects a concrete type which conforms to Decodable. A protocol cannot conform to itself.

You could make the method generic

func networkRequest<T : Decodable>(MethodType: Type, url: String, codableType: T.Type) {
...
   let newData = try JSONDecoder().decode(T.self, from: data)

And call it

networkRequest(MethodType: .GET, 
                      url: "https://test.com/api", 
              codableType: News.self)

Upvotes: 1

Related Questions