用Generics解析Swift 5中的JSON-本地文件与URL



我有下面两个函数,用来帮助解析Swift中的JSON。第一个函数可以很好地处理我抛出的任何JSON

第二种方法是让我感到不适,但我无法解决问题。我基本上想做与第一个函数相同的事情,但我的数据来自URLSession,而不是本地文件。

你知道我在这里做错了什么吗?我得到一个奇怪的编译器错误,void函数中意外的非void返回值,但签名完全相同。

import Foundation
import SwiftUI

// Populates Model from local files
public func loadFromJson<T: Decodable>(_ filename: String) -> T {
let data: Data

guard let path = Bundle.main.path(forResource: filename, ofType: "json")

else{
fatalError("(filename) not found.")
}
do {
let file = URL(fileURLWithPath: path)
data = try Data(contentsOf: file)
} catch {
fatalError("Could not load (filename): (error)")
}

do{
return try JSONDecoder().decode(T.self, from: data)
} catch {
fatalError("Unable to parse (filename): (error)")
}
}
// Populates Model from REST endpoint
public func loadFromJsonFromURL<T: Decodable>(_ urlString: String) -> T {
let data: Data

let url = URL(string: urlString)!
let task = URLSession.shared.dataTask(with: url) { data, response, error in

if let error = error {
fatalError("Error: (error.localizedDescription)")
}


guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
fatalError("Error: invalid HTTP response code")
}

guard let data = data else {
fatalError("Error: missing response data")
}
do {
return try JSONDecoder().decode(T.self, from: data)
}
catch {
print("Error: (error.localizedDescription)")
}
}
task.resume()

}

dataTask(with: completionHandler:)异步方法。因此,直到收到响应后调用completionHandler时,方法loadFromJsonFromURL(_:_:)已经返回。

在收到API的响应后,需要使用closure将数据传递回。

public func loadFromJsonFromURL<T: Decodable>(_ urlString: String, _ handler: @escaping ((T?)->())) {
if let url = URL(string: urlString) {
let task = URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error {
fatalError("Error: (error.localizedDescription)")
}
guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
fatalError("Error: invalid HTTP response code")
}
guard let data = data else {
fatalError("Error: missing response data")
}
do {
let value = try JSONDecoder().decode(T.self, from: data)
handler(value)
}
catch {
print("Error: (error.localizedDescription)")
handler(nil)
}
}
task.resume()
}
}

相关内容

  • 没有找到相关文章

最新更新