Reputation: 13846
Wrote this simple getJson
wrapper:
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
}
But I get this error about my completionHandler
:
Invalid conversion from throwing function of type '(_, _, _) throws -> ()' to non-throwing function type '(Data?, URLResponse?, Error?) -> Void'
On a related note, this is 3 layers of if
statements, can they be flattened?
Upvotes: 0
Views: 663
Reputation: 17882
Your code has quite a lot of problems apart from the throwing issue. Like you noticed, the many nested ifs make it hard to read, but mainly, it returns your obj
variable before waiting for the asynchronous network call and thus wouldn't produce the results you're expecting.
Here's how I would start rewriting it.
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
}
}
Upvotes: 3
Reputation: 221
Your completion handler uses a try keyword that throws an exception when it fails. That's why you get an error. Completion handler expects a non throwing method as the message error says.
You need to catch the error by using :
do {
obj = try decoder.decode(T.self, from: json)
} catch {
print("error") // Write here what you want to do if decoder fails.
}
Upvotes: 0