问题
I am following a tutorial on REST API calls with Swift and Codable. I cannot compile the following although I was careful when I typed all of it. Can anyone tell me what's wrong? Also, can anyone point me to a better tutorial? The error is:
Catch block is unreachable
and also
cannot find json in scope
import UIKit
import Foundation
struct Example: Codable {
let userId: Int
let id: Int
let title: String
let completed: Bool
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
func getJson(completion: @escaping (Example)-> ()) {
let urlString = "https://jsonplaceholder.typicode.com/todos/1"
if let url = URL(string: urlString) {
URLSession.shared.dataTask(with: url) {data, res, err in
if let data = data {
let decoder = JSONDecoder()
do {
let json: Example = try! decoder.decode(Example.self, from: data)
completion(json)
}catch let error {
print(error.localizedDescription)
}
}
}.resume()
}
}
getJson() { (json) in
print(json.id)
}
}
回答1:
Instead of "do catch", you can use "guard let"
func getJson(completion: @escaping (Example)-> ()) {
let urlString = "https://jsonplaceholder.typicode.com/todos/1"
if let url = URL(string: urlString) {
URLSession.shared.dataTask(with: url) {data, res, err in
guard let data = data else {return print("error with data")}
let decoder = JSONDecoder()
guard let json: Example = try? decoder.decode(Example.self, from: data) else {return print("error with json")}
completion(json)
}.resume()
}
}
This does NOT handle errors, so my solution is just to an answer to your question, not a general solution for every similar cases.
回答2:
struct Example: Decodable {
let userId: Int
let id: Int
let title: String
let completed: Bool
}
struct APIRequest {
var resourceURL: URL
let urlString = "https://jsonplaceholder.typicode.com/todos/1"
init() {
resourceURL = URL(string: urlString)!
}
//create method to get decode the json
func requestAPIInfo(completion: @escaping(Result<Example, Error>) -> Void) {
let dataTask = URLSession.shared.dataTask(with: resourceURL) { (data, response, error) in
guard error == nil else {
print (error!.localizedDescription)
print ("stuck in data task")
return
}
let decoder = JSONDecoder()
do {
let jsonData = try decoder.decode(Example.self, from: data!)
completion(.success(jsonData))
}
catch {
print ("an error in catch")
print (error)
}
}
dataTask.resume()
}
}
class ViewController: UIViewController {
let apiRequest = APIRequest()
override func viewDidLoad() {
super.viewDidLoad()
apiRequest.requestAPIInfo { (apiResult) in
print (apiResult)
}
}
}
来源:https://stackoverflow.com/questions/65876500/swift-rest-api-call-example-using-codable