如何在 URLSession 中调用 completionBlock
How to call completionBlock in URLSession
我正在尝试学习如何使用 Rest API。我想先使用 Github API 从 iPhone 登录。
这是我的模型(还没有完成):
mutating func gettingAceess(completionBlock: @escaping (_ data : Data?, _ response : URLResponse?, _ error : Error?) -> Void ) throws {
guard username != "", password != "" else {
throw loginError.emptyUsernameOrPassword
}
let loginString = "\(self.username):\(self.password)"
let resourceUrl = "https://\(loginString)@api.github.com"
guard let loggingUrl = URL(string: resourceUrl) else {fatalError()}
let logging = URLSession.shared.dataTask(with: loggingUrl) { (data, response, error) in
if error != nil {
print("\(String(describing: error))")
}
}
logging.resume()
}
在控制器中,我希望当用户点击登录按钮时,应该调用获取访问权限的功能。
@IBAction func pressLoginBtn(_ sender: UIButton) {
if let username = usernameInput.text, let password = passwordInput.text {
var logginInformation = LogginReguest(username: username, password: password)
do {
try logginInformation.gettingAceess(completionBlock: ...)
} catch {
}
在try
的代码前面,不知道该写什么。谁能帮我?还是我整件事都做错了?
do {
// if completion block is last argument; you can use trailing syntax
try logginInformation.gettingAceess() { (data, response, error) in
// as your completion block have this signature
// completionBlock: @escaping (_ data : Data?, _ response : URLResponse?, _ error : Error?) -> Void)
}
} catch {
您还需要更新 gettingAceess
方法。
let logging = URLSession.shared.dataTask(with: loggingUrl) { (data, response, error) in
if error != nil {
print("\(String(describing: error))")
}
// This line passes this completion block to caller who can read it
completion(data, response, error)
}
上面的详细信息是如何让完成块在您的示例中工作。建议不要直接传递 URLSession
完成块;而是处理它。
enum NKError: Error {
case networkError
}
func gettingAceess(completionBlock: @escaping (Result<[String: Any], NKError>) -> Void ) {
let logging = URLSession.shared.dataTask(with: loggingUrl) { (data, response, error) in
if error != nil {
print("\(String(describing: error))")
completion(.failure(NKError.networkError))
}
// Now I can check for status or data
if let data = data {
// parse the result and then return
if let json = try JSONSerialization.jsonObject(with: data) as? [String: Any] {
completion(.success(json))
}
}
}
}
在这种情况下,我试图将 error
或 json
传递给调用者。
你的做法是错误的。首先在调用异步任务之前检查空文本字段。
其次,在完成块 return 中创建包含异步任务的函数 throws
接收数据或错误是不好的做法。
这是一个示例,其中 Result
结构 return 将收到的 Data
作为字符串或错误。
mutating func gettingAccess(completionBlock: @escaping (Result<String,Error>) -> Void)
{
let loginString = "\(self.username):\(self.password)"
let resourceUrl = "https://\(loginString)@api.github.com"
guard let loggingUrl = URL(string: resourceUrl) else {fatalError()}
let logging = URLSession.shared.dataTask(with: loggingUrl) { (data, _, error) in
if let error = error {
completion(.failure(error))
} else {
let string = String(data: data!, encoding: .utf8)!
completion(.success(string))
}
}
logging.resume()
}
@IBAction func pressLoginBtn(_ sender: UIButton) {
guard usernameInput.hasText, passwordInput.hasText else {
// show an alert
return
}
let logginInformation = LogginReguest(username: usernameInput.text!, password: passwordInput.text!)
logginInformation.gettingAccess { result in
switch result {
case .success(let string): print(string)
case .failure(let error): print(error)
}
}
}
旁注:
请寻找当代教程。带有参数标签和下划线的语法 (_ data : Data?, _ response : URLResponse?, _ error : Error?)
是 Swift 2 旧语法。
我正在尝试学习如何使用 Rest API。我想先使用 Github API 从 iPhone 登录。
这是我的模型(还没有完成):
mutating func gettingAceess(completionBlock: @escaping (_ data : Data?, _ response : URLResponse?, _ error : Error?) -> Void ) throws {
guard username != "", password != "" else {
throw loginError.emptyUsernameOrPassword
}
let loginString = "\(self.username):\(self.password)"
let resourceUrl = "https://\(loginString)@api.github.com"
guard let loggingUrl = URL(string: resourceUrl) else {fatalError()}
let logging = URLSession.shared.dataTask(with: loggingUrl) { (data, response, error) in
if error != nil {
print("\(String(describing: error))")
}
}
logging.resume()
}
在控制器中,我希望当用户点击登录按钮时,应该调用获取访问权限的功能。
@IBAction func pressLoginBtn(_ sender: UIButton) {
if let username = usernameInput.text, let password = passwordInput.text {
var logginInformation = LogginReguest(username: username, password: password)
do {
try logginInformation.gettingAceess(completionBlock: ...)
} catch {
}
在try
的代码前面,不知道该写什么。谁能帮我?还是我整件事都做错了?
do {
// if completion block is last argument; you can use trailing syntax
try logginInformation.gettingAceess() { (data, response, error) in
// as your completion block have this signature
// completionBlock: @escaping (_ data : Data?, _ response : URLResponse?, _ error : Error?) -> Void)
}
} catch {
您还需要更新 gettingAceess
方法。
let logging = URLSession.shared.dataTask(with: loggingUrl) { (data, response, error) in
if error != nil {
print("\(String(describing: error))")
}
// This line passes this completion block to caller who can read it
completion(data, response, error)
}
上面的详细信息是如何让完成块在您的示例中工作。建议不要直接传递 URLSession
完成块;而是处理它。
enum NKError: Error {
case networkError
}
func gettingAceess(completionBlock: @escaping (Result<[String: Any], NKError>) -> Void ) {
let logging = URLSession.shared.dataTask(with: loggingUrl) { (data, response, error) in
if error != nil {
print("\(String(describing: error))")
completion(.failure(NKError.networkError))
}
// Now I can check for status or data
if let data = data {
// parse the result and then return
if let json = try JSONSerialization.jsonObject(with: data) as? [String: Any] {
completion(.success(json))
}
}
}
}
在这种情况下,我试图将 error
或 json
传递给调用者。
你的做法是错误的。首先在调用异步任务之前检查空文本字段。
其次,在完成块 return 中创建包含异步任务的函数 throws
接收数据或错误是不好的做法。
这是一个示例,其中 Result
结构 return 将收到的 Data
作为字符串或错误。
mutating func gettingAccess(completionBlock: @escaping (Result<String,Error>) -> Void)
{
let loginString = "\(self.username):\(self.password)"
let resourceUrl = "https://\(loginString)@api.github.com"
guard let loggingUrl = URL(string: resourceUrl) else {fatalError()}
let logging = URLSession.shared.dataTask(with: loggingUrl) { (data, _, error) in
if let error = error {
completion(.failure(error))
} else {
let string = String(data: data!, encoding: .utf8)!
completion(.success(string))
}
}
logging.resume()
}
@IBAction func pressLoginBtn(_ sender: UIButton) {
guard usernameInput.hasText, passwordInput.hasText else {
// show an alert
return
}
let logginInformation = LogginReguest(username: usernameInput.text!, password: passwordInput.text!)
logginInformation.gettingAccess { result in
switch result {
case .success(let string): print(string)
case .failure(let error): print(error)
}
}
}
旁注:
请寻找当代教程。带有参数标签和下划线的语法 (_ data : Data?, _ response : URLResponse?, _ error : Error?)
是 Swift 2 旧语法。