问题描述
我的数据模型有不同的结构。 当我想用 JsonDecoder().decode 解析数据时,我需要在 .decoder(SomeType.self,from: data)
中设置一个 .Type.self我想写一个支持函数,可以分别返回正确的类型。 像这样的东西 但我不知道怎么...
func check<T>(string: String) -> T
if string == "something" {
return Something.type
}
func parseJSON(from data: Data,with address: String)-> Codable? {
let type = check(string: address)
let decoder = JSONDecoder()
do {
let decodedData = try decoder.decode(type.self,from: data)
return decodedData
} catch let error {
print(error)
return nil
}
}
当我编写下面的代码时,一切正常。但我总是不得不一遍又一遍地编写几乎没有区别的 parseJSON func
func fetch(from adress: String) {
guard let url = URL(string: adress) else {print("can't get URL from current urlAdress"); return}
let json = makeHttpBody(from: adress)
let jsonData = try? JSONSerialization.data(withJSONObject: json)
var request = URLRequest(url: url,cachePolicy: .useProtocolCachePolicy)
request.httpMethod = K.post
request.setValue(K.contentType,forHTTPHeaderField:K.applicationjson)
request.timeoutInterval = Double.infinity
request.httpBody = jsonData
let session = URLSession(configuration: .default)
let task = session.dataTask(with: request) { (data,responce,error) in
if error != nil {
print(error!.localizedDescription)
}
if let safeData = data {
if adress == K.balanceUrl {
if let parsedData = self.parseJsonBalance(from: safeData) {
self.delegate?.didUpdateData(with: self,with: parsedData)
}
} else if adress == K.projectsUrl {
if let parsedData = self.parseJsonProject(from: safeData) {
self.delegate?.didUpdateData(with: self,with: parsedData)
}
}
}
}
task.resume()
}
func makeHttpBody(from StringData: String) -> [String: Any] {
switch StringData {
case K.balanceUrl:
return K.authorization
case K.projectsUrl:
return K.projects
default:
return ["none" : "none"]
}
}
解决方法
您的方法行不通,您必须使用限制为 Decodable
的泛型类型。在运行时检查字符串不是一个好习惯。
这是您代码的简化版本,错误已移交给调用方
func parseJSON<T : Decodable>(from data: Data) throws -> T {
return try JSONDecoder().decode(T.self,from: data)
}
然后就可以写了(返回类型一定要注解)
let result : [Foo] = try parseJSON(from: data)
或者如果你想在函数中指定类型
func parseJSON<T : Decodable>(from data: Data,type : T.Type) throws -> T {
return try JSONDecoder().decode(T.self,from: data)
}
let result = try parseJSON(from: data,type: [Foo].self)