当我请求网络服务时,我想获得一些数据或完成一些工作。但是当我使用URLSession.dataTask
方法执行此操作时,我的var始终会重置。为什么呢?
当我在func checkToken()
中设置断点时,var iftokened
为true
,因为responseStatus是" 200"。但当它返回func viewDidLoad()
时,var iftokened
将被重置。当我打印它时,它是false
。为什么?如何解决?
import UIKit
import Foundation
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
checkToken()
print(iftokened)
}
var iftokened = false
func checkToken() {
fetchToken { [weak self] (responseStatus) in
if responseStatus == "200" {
self?.iftokened = true
} else {
self?.iftokened = false
}
}
}
let session: URLSession = {
let config = URLSessionConfiguration.default
return URLSession(configuration: config)
}()
func fetchToken(completion: @escaping (String) -> Void) {
let urlString = "http://www.google.com"
let url = URL(string: urlString)
let request = URLRequest(url: url!)
let task = session.dataTask(with: request) {
(data, response, error) in
completion("200")
}
task.resume()
}
}
答案 0 :(得分:0)
您正在尝试的是异步,因为会话在主线程以外的单独线程中运行,因此在调用url控件时会传递给下一行,即打印假的变量尚未更改的print语句响应呼叫完成
func checkToken() {
fetchToken { [weak self] (responseStatus) in
if responseStatus == "200" {
self?.iftokened = true
} else {
self?.iftokened = false
}
print(iftokened)
/// start using iftokened here
}
}
答案 1 :(得分:0)
尝试这种方式获取当前令牌状态
override func viewDidLoad() {
super.viewDidLoad()
checkToken(completion: { [weak self] response in
self?.iftokened = response
print(self?.iftokened ?? false)
})
}
var iftokened = false
func checkToken(completion: @escaping (Bool) -> Void){
fetchToken { (responseStatus) in
if responseStatus == "200" {
completion(true)
} else {
completion(false)
}
}
}
答案 2 :(得分:-1)
您需要使用semophore
发出同步请求func fetchToken(completion: @escaping (String) -> Void) {
let semaphore = DispatchSemaphore(value: 0)
let urlString = "http://www.google.com"
let url = URL(string: urlString)
let request = URLRequest(url: url!)
let task = self.session.dataTask(with: request) {
(data, response, error) in
completion("200")
semaphore.signal()
}
task.resume()
semaphore.wait(timeout: .distantFuture)
}
但您的代码也有其他问题:
您应该在请求完成时从服务器获取响应状态,而不是在回调时使用完成(“200”)
if let response = response as? HTTPURLResponse {
completion(response.statusCode)
}