Swift-JSONDecoder-将类类型作为参数传递,以使用通用方法对模型进行解码

问题描述 投票:0回答:1

[这里,我们遇到一种使用“ JSONDecoder”解析模型类的问题。

让我分享您在本示例中所做的以及我面临的问题:

  • 有一个通过Codable派生的模型协议。
  • 一个结构模型和一个类GenericExample
  • GenericExample类具有以下内容:
    • 共享实例
    • typeContainer,它是协议的类型
  • 还有两个方法staticClassParsingdynamicClassParsing,其中一个参数为dynamicType
  • 最后,一个通用方法返回已解析的数据模型。

用于解析模型的调用方法:

GenericExample.shared.dynamicClassParsing(Numbers.self,data:“ [\ r \ n {\”一个\“:\” 1 \“},\ r \ n {\”两个\“:\” 2 \“ } \ r \ n]“)

编译时错误:

无法推断出通用参数'T'

在这里发生

returnModelType:typeContainer.self

**更多详细信息,请通过以下代码:**

protocol BaseMapModel : Codable { }
struct Numbers: BaseMapModel {
    var one: String?
    var two: String?
}
class GenericExample: NSObject {

    static let shared = GenericExample()

    var typeContainer : BaseMapModel.Type?

    private override init() {
        super.init()
    }
}
extension GenericExample {

    // Static Class Parsing passed through the conversion
    func staticClassParsing() {
        let dataJson = "[\r\n{\"one\": \"1\"},\r\n{\"two\":\"2\"}\r\n]"
        convertTypeContainer(data: Data(dataJson.utf8), returnModelType: Numbers.self) { (mappedResult) in
            print(mappedResult?.one ?? "")
            print(mappedResult?.two ?? "")
        }
    }

    // Dynamic Class Parsing can't passed through the conversion
    // Error:- Generic parameter 'T' could not be inferred
    // Error Parameter:- in "returnModelType: typeContainer.self"
    func dynamicClassParsing(_ dynamicType: BaseMapModel.Type, data:String) {
        typeContainer = dynamicType.self
        convertTypeContainer(data: Data(data.utf8), returnModelType: typeContainer.self) { (mappedResult) in
            print(mappedResult?.one ?? "")
            print(mappedResult?.two ?? "")
        }
    }
}
extension GenericExample {

    private func convertTypeContainer<T : BaseMapModel>(data:Data, returnModelType: T.Type, completion: ((_ result:T?)->Void)) {

        guard let responseModel = try? JSONDecoder().decode(returnModelType.self, from: data) else {
            completion(nil)
            return
        }
        completion(responseModel)
    }
}
ios swift generics swift-protocols jsondecoder
1个回答
0
投票

typeContainer必须为具体类型,不能为协议。并且完成处理程序毫无意义,因为JSONDecoder是同步工作的。

要使用泛型解码JSON,必须使用类似的方法,强烈建议您也处理解码错误

struct Numbers: Decodable {
    var one: String?
    var two: String?
}

class GenericExample: NSObject {
    static let shared = GenericExample()
}

extension GenericExample {
    func dynamicClassParsing<T : Decodable>(_ dynamicType: T.Type, data:String) -> T? {
        return try? JSONDecoder().decode(T.self, from: Data(data.utf8))
    }
}

let dataJson = "[{\"one\": \"1\"},{\"two\":\"2\"}]"
let result = GenericExample.shared.dynamicClassParsing([Numbers].self, data: dataJson)
switch result {
    case .success(let numbers): print(numbers)
    case .failure(let error): print(error)
}
© www.soinside.com 2019 - 2024. All rights reserved.