3

I have a JSON parsing class like so

class JSONParser: NSObject {
    let newJSONDecoder : JSONDecoder
    let data : Data

    init(decoder: JSONDecoder, data: Data, model:  ) {
        self.newJSONDecoder = JSONDecoder()
        self.data = data
    }
}

The goal is to have the model parameter be a class that can take in any data and any model and create an object and return it to the calling class instance. EG below

let jsonParser = JSONParser(myDecoder, data, struct)
let parsedArray = jsonParser.createJSONArray()

Can I pass in a struct to the JSONParser init method of type struct and not of type struct "class" name (eg ModelStruct)?

Eventually, the struct parameter should get used in this function

try newJSONDecoder.decode(model.self, from:data!), so the second issue is how to get it into that function - won't work if printed as a String.

3
  • Do you want to pass specific struct or generic? Commented Sep 4, 2018 at 5:08
  • generic struct - basically to parse JSON since I did not use a class. Goal is to make dependencies know in initialization. Commented Sep 4, 2018 at 5:09
  • Why can't you just use JSONDecoder? Commented Sep 4, 2018 at 5:39

2 Answers 2

4

You can do something like below:

class JSONParser: NSObject {
    let newJSONDecoder : JSONDecoder
    let data : Data

    init<T: Codable>(data: Data, model: T.Type) {
        self.newJSONDecoder = JSONDecoder()
        do {
        let result = try self.newJSONDecoder.decode(model.self, from: data)
        print(result)
        } catch let err {
            print(err.localizedDescription)
        }
        self.data = data
    }
}

Your model struct:

struct TestModel: Codable {
    let name: String
    let age: Int
}

How you call init:

let str = """
        {"name": "Robert", "age" : 35}
        """

    let data = str.data(using: .utf8)
    let jsonParser = JSONParser(data: data!, model: TestModel.self)
Sign up to request clarification or add additional context in comments.

2 Comments

I think this will work. Could you add an explanation for <T: Codable> part of the code?
@noobsmcgoobs <T: Codable> define type of model. Here model must be type of Codable.
0

Here is how I pass generic Codable struct as a parameter and also return it via completion handler as parameter, allGeneric :

func getAccordingToWebServiceFlag<T:Decodable>(flagSender: WebServicesFlagSenders,codableStruct: T.Type ,completionHandler: @escaping ( _ publicDataResponseModel:T?,_ flagSender: WebServicesFlagSenders) -> Void) {

excuteServerOperation(nil, imageData: nil, url:ServerAPIServant.webServiceFullURL(webServicesFlagSenders: flagSender), way: .get, flagSender: flagSender,completionHandler: { (result, flagSender) in
    AppDelegate().printStringBy_ispha(string: "  \(flagSender) Hmmm 🤔 \(result)")
    do {
        let jsonData = try JSONSerialization.data(withJSONObject:  result , options: .prettyPrinted)
        let decodableResponse = try! JSONDecoder().decode(codableStruct, from: jsonData)

        HelpingMethods.printCustomObjectBy_ispha(anyObject: decodableResponse as AnyObject)
        completionHandler(decodableResponse,flagSender)
    } catch let error {
        HelpingMethods.printStringBy_ispha(string: "😞 Codable failure with error = \(error.localizedDescription)")
         completionHandler(nil,flagSender)
    }


}
)}

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.