[英]Swift - JSONDecoder - passing class Type as parameter to decode model using generic method
讓我與您分享我在此示例中所做的工作以及我遇到的問題:
解析模型的調用方法:
GenericExample.shared.dynamicClassParsing(Numbers.self,data: "[\\r\\n{\\"one\\": \\"1\\"},\\r\\n{\\"two\\":\\"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)
}
}
typeContainer
必須是具體類型,不能是協議。 並且完成處理程序毫無意義,因為JSONDecoder
是同步工作的。
要使用泛型解碼 JSON,您必須使用類似這樣的方法,強烈建議同時處理 Decoding 錯誤
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) -> Result<T,Error> {
return Result { 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)
}
首先感謝大家的支持。 是的,我想發布我的問題的答案。
class BaseMapModel : Codable { }
class Numbers: BaseMapModel {
var one: String?
var two: String?
enum CodingKeys: String, CodingKey {
case one = "one"
case two = "two"
}
// Decoding
required init(from decoder: Decoder) throws {
let response = try decoder.container(keyedBy: CodingKeys.self)
one = try? response.decode(String.self, forKey: .one)
two = try? response.decode(String.self, forKey: .two)
let superDecoder = try response.superDecoder()
try super.init(from: superDecoder)
}
}
class GenericExample: NSObject {
static let shared = GenericExample()
var defaultTypeContainer : Numbers.Type!
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 passed through the conversion
func dynamicClassParsing(_ dynamicType: BaseMapModel.Type, data:String) {
typeContainer = dynamicType.self
convertTypeContainer(data: Data(data.utf8), returnModelType: (typeContainer ?? defaultTypeContainer).self) { (mappedResult) in
print((mappedResult as? Numbers)?.one ?? "")
print((mappedResult as? Numbers)?.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)
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.