我正在尝试学习如何使用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
的代码前面,我不知道该写些什么。谁能帮我?还是我整个事情做错了?
答案 0 :(得分:0)
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
传递给呼叫者。
答案 1 :(得分:0)
您的方法是错误的。首先,在调用异步任务之前已经检查了空文本字段。
第二个坏习惯是使包含异步任务的函数throws
在完成块中返回接收到的数据或错误。
这是一个示例,其中Result
结构返回接收的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旧式语法。