Swift 可以放入 `if let` 块吗?
Swift can throw in `if let` blocks?
编写了这个简单的 getJson
包装器:
func getJson<T>(path: String) -> T? {
let url = URL(string: path)
let session = URLSession.shared
var obj: T?
if let usableUrl = url {
let task = session.dataTask(with: usableUrl,
completionHandler: { (data, response, error) in // # <-- this line
if let data = data {
if let stringData = String(
data: data, encoding: String.Encoding.utf8) {
let decoder = JSONDecoder()
obj = try decoder.decode(T.self, from: json)
}
}
})
task.resume()
}
return obj
}
但是我收到关于我的 completionHandler
:
的错误
Invalid conversion from throwing function of type '(_, _, _) throws -> ()' to non-throwing function type '(Data?, URLResponse?, Error?) -> Void'
相关说明,这是3层的if
语句,它们可以被压平吗?
您的完成处理程序使用 try 关键字,该关键字在失败时抛出异常。这就是你得到错误的原因。如消息错误所述,完成处理程序需要一个非抛出方法。
您需要使用 :
来捕获错误
do {
obj = try decoder.decode(T.self, from: json)
} catch {
print("error") // Write here what you want to do if decoder fails.
}
除了抛出问题,你的代码还有很多问题。正如您所注意到的,许多嵌套的 if 使其难以阅读,但主要是,它 returns 您的 obj
变量在等待异步网络调用之前,因此不会产生您期望的结果。
下面是我将如何开始重写它。
func getJson<T: Decodable>(path: String, completion: @escaping (T?) -> () ) {
guard let url = URL(string: path) else {
return
}
let session = URLSession.shared
let task = session.dataTask(with: url) { (data, response, error) in
if let data = data {
do {
let obj = try JSONDecoder().decode(T.self, from: data)
completion(obj)
} catch {
completion(nil)
}
}
}
task.resume()
}
// usage example:
struct Foo: Decodable {
let bar: Int
}
getJson(path: "http://example.com") { (obj: Foo?) in
if let foo = obj {
// processs data
} else {
// an error occurred
}
}
编写了这个简单的 getJson
包装器:
func getJson<T>(path: String) -> T? {
let url = URL(string: path)
let session = URLSession.shared
var obj: T?
if let usableUrl = url {
let task = session.dataTask(with: usableUrl,
completionHandler: { (data, response, error) in // # <-- this line
if let data = data {
if let stringData = String(
data: data, encoding: String.Encoding.utf8) {
let decoder = JSONDecoder()
obj = try decoder.decode(T.self, from: json)
}
}
})
task.resume()
}
return obj
}
但是我收到关于我的 completionHandler
:
Invalid conversion from throwing function of type '(_, _, _) throws -> ()' to non-throwing function type '(Data?, URLResponse?, Error?) -> Void'
相关说明,这是3层的if
语句,它们可以被压平吗?
您的完成处理程序使用 try 关键字,该关键字在失败时抛出异常。这就是你得到错误的原因。如消息错误所述,完成处理程序需要一个非抛出方法。
您需要使用 :
来捕获错误do {
obj = try decoder.decode(T.self, from: json)
} catch {
print("error") // Write here what you want to do if decoder fails.
}
除了抛出问题,你的代码还有很多问题。正如您所注意到的,许多嵌套的 if 使其难以阅读,但主要是,它 returns 您的 obj
变量在等待异步网络调用之前,因此不会产生您期望的结果。
下面是我将如何开始重写它。
func getJson<T: Decodable>(path: String, completion: @escaping (T?) -> () ) {
guard let url = URL(string: path) else {
return
}
let session = URLSession.shared
let task = session.dataTask(with: url) { (data, response, error) in
if let data = data {
do {
let obj = try JSONDecoder().decode(T.self, from: data)
completion(obj)
} catch {
completion(nil)
}
}
}
task.resume()
}
// usage example:
struct Foo: Decodable {
let bar: Int
}
getJson(path: "http://example.com") { (obj: Foo?) in
if let foo = obj {
// processs data
} else {
// an error occurred
}
}