1

I'm currently parsing JSON like this

struct ExampleStruct : Codable {
     init() {

     }
     // implementation
}

if let jsonData = jsonString.data(using: .utf8) {
    do {
        let decoder = JSONDecoder()
        let object =  try decoder.decode(ExampleStruct.self, from: jsonData)
    } catch {
        print("Coding error - \(error)")
    }
}

This works fine, however I've been trying to learn about Generics over the weekend. I'm trying to write a method which I pass in a Codable struct type and a string of JSON which returns the object of type I want back.

I've tried the following :-

func getType<T>(_ anyType: T.Type, from jsonString:String) -> T? {

if let jsonData = jsonString.data(using: .utf8) {
    do {
        let decoder = JSONDecoder()
        let object =  try decoder.decode(anyType, from: jsonData)//Errors here
        return object as? T
        return nil
    } catch {
        print("Coding error - \(error)")
       return nil
    }
  }
return nil
}

and then when I want to do the above

 if let exampleStruct:ExampleStruct = getType(type(of: ExampleStruct()), from: jsonString) {
  print(exampleStruct)
 }

However on the let = object line I get the following errors

Cannot convert value of type 'T' (generic parameter of global function 'getType(:from:)') to expected argument type 'T' (generic parameter of instance method 'decode(:from:)')

and

In argument type 'T.Type', 'T' does not conform to expected type 'Decodable'

As I said I've just been trying to learn about generics this weekend but I've clearly hit a block in my understanding. Is there a fix for this, indeed is what I'm trying to do even possible or a good idea?

1 Answer 1

7

First of all it's highly recommended to hand over an error of a throwing function to the caller.
Second of all Data created from an UTF8 string can never fail.

You have to constrain the generic type to Decodable, it's not needed to pass the type as extra parameter.

Your function can be reduced to

func getType<T : Decodable>(from jsonString:String) throws -> T {
    let jsonData = Data(jsonString.utf8)
    return try JSONDecoder().decode(T.self, from: jsonData)
}
Sign up to request clarification or add additional context in comments.

Comments

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.