The usual way to return a value from an asynchronous action (such as using URLSession
to query a URL
) is to provide a completion handler. Something like this:
func getData(completion: (User?) -> Void) {
let url = URL(string: "https://jsonplaceholder.typicode.com/users")!
URLSession.shared.dataTask(with: url) { data, _, _ in
if let data = data {
do {
let result = try JSONDecoder().decode([User].self, from: data)
completion(result[0])
} catch {
completion(nil)
}
}
}.resume()
}
And you would call it like this:
@IBAction func check(_ sender: NSButton) {
getData { user in
//user is a User?, so either a valid User or nil
//do whatever you want with it
}
}
Even better would be to supply a Result
type to the completion handler:
enum MyErrorType: Error {
case invalidUser
//and any other errors you might receive
}
func getData(completion: (Result<User, MyErrorType>) -> Void) {
let url = URL(string: "https://jsonplaceholder.typicode.com/users")!
URLSession.shared.dataTask(with: url) { data, _, _ in
if let data = data {
do {
let result = try JSONDecoder().decode([User].self, from: data)
completion(.success(result[0]))
} catch {
completion(.failure(.invalidUser))
}
}
}.resume()
}
@IBAction func check(_ sender: NSButton) {
getData { result in
switch result {
case .success(let user):
//do whatever you want with the user data
case .failure(let error):
//handle the error
}
}
}