Search code examples
iosswiftswift3

How do I use swift generic Decodable protocol in generic functions


I would like to write a generic function which parses the result and return in success block of closure or sends back error in failure block.

I'm getting error like this 'Generic parameter 'T' could not be inferred'.

Here is my sample code.

let jsonString = """
{
"id": 1,
"msg": "Sample msg"
}
"""

struct Post: Codable {
    var id: String?
    var msg: String?
}

enum PostError: Error {
    case empty
}


func fetch<T:Decodable>(_ completion: @escaping (Result<T?, PostError>) -> Void)  {

        do {
            let data = Data(jsonString.utf8)
            let post = try JSONDecoder().decode(T.self, from: data)
            completion(.success(post))
        }
        catch {
            completion(.failure(.empty))
        }
    }


fetch { res in
        switch res {
        case .success( let p):
            print(p.description)

        case .failure(let error):
            print(error)
        }
    }

Here is the error I'm getting.

I'm getting error like this.


Solution

  • You can accept the generic type as a parameter, like so:

    func fetchObject<T:Decodable>(ofType type: T.Type, _ completion: @escaping (Result<T, PostError>) -> Void)  {
       do {
          let data = Data(jsonString.utf8)
          let post = try JSONDecoder().decode(type, from: data)
          completion(.success(post))
       }
       catch {
          completion(.failure(.empty))
       }
    }
    

    Usage:

    fetchObject(ofType: Post.self) { res in
       switch res {
           case .success(let post):
              print(post.description)
           case .failure(let error):
              print(error)
       }
    }