从 IBAction 调用的 dispatchqueue.main.async 中跳过了 Https 请求
Posted
技术标签:
【中文标题】从 IBAction 调用的 dispatchqueue.main.async 中跳过了 Https 请求【英文标题】:Https Request skipped in dispatchqueue.main.async called from IBAction 【发布时间】:2021-02-14 02:16:43 【问题描述】:从 IBAction 调用时,会跳过获取 json 和解码的请求!但如果它是在 viewDidLoad 中制作的,它就可以工作。谁能启发我并帮助我如何解决这个问题?提前谢谢!
class LoginViewController:UIViewController
@IBOutlet weak var login_id_field: UITextField!
@IBOutlet weak var login_pw_field: UITextField!
var loginData = [LoginData]()
var storeData = [StoreData]()
So below part in viewDidLoad() is working fine,
override func viewDidLoad()
super.viewDidLoad()
self.hideKeyboardWhenTappedAround()
let param2 = ["login": self.login_id_field.text!]
let url2 = "http://dev.purejoin.com/PJPI/login.php"
print("HI")
DispatchQueue.main.async
let headers: HTTPHeaders = [
"Accept": "text/html",
"Content-Type" : "application/x-www-form-urlencoded"
]
AF.request(url2, method: .post, parameters: param2, encoding: URLEncoding.httpBody, headers: headers).responseString response in
#if DEBUG
let request = response.request
NSLog("Request: \(request!.httpMethod!) - \(request!.url!.absoluteString)\n\(request!.httpBody.map body in String(data: body, encoding: .utf8) ?? "" ?? "")")
switch response.result
case .success(let value):
print("Response with content \(value)")
case .failure(let error):
print("Response with error: \(error as NSError): \(response.data ?? Data())")
#endif
但是下面的这里不起作用。 Dispatchqueue.main.async
刚刚被跳过?至少看起来是这样的。
@IBAction func login_button(_ sender: Any)
//Check for email field that is too short or just didn't get any input
if (self.login_id_field.text!.count < 7 )
let alert = UIAlertController(title: "Invalid Email", message: "Please Check Your Email", preferredStyle: .alert)
let ok = UIAlertAction (title: "OK", style: UIAlertAction.Style.cancel, handler: nil)
alert.addAction(ok)
self.present(alert, animated: true, completion: nil)
//query
else
let param2 = ["login": self.login_id_field.text!]
let url2 = "http://dev.purejoin.com/PJPI/login.php"
print("HI")
DispatchQueue.main.async
let headers: HTTPHeaders = [
"Accept": "text/html",
"Content-Type" : "application/x-www-form-urlencoded"
]
AF.request(url2, method: .post, parameters: param2, encoding: URLEncoding.httpBody, headers: headers).responseString response in #if DEBUG
let request = response.request
NSLog("Request: \(request!.httpMethod!) - \(request!.url!.absoluteString)\n\(request!.httpBody.map body in String(data: body, encoding: .utf8) ?? "" ?? "")")
switch response.result
case .success(let value):
print("Response with content \(value)")
case .failure(let error):
print("Response with error: \(error as NSError): \(response.data ?? Data())")
#endif
//MD5
let md5 = MD5(self.login_pw_field.text!)
print (self.loginData)
if (md5 == String(self.loginData[0].user_password))
//OPEN SEGUE
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyBoard.instantiateViewController(withIdentifier: "selectStore") as! SelectStoreViewController
self.present(vc, animated: true, completion: nil)
else
let alert = UIAlertController(title: "Wrong Password", message: "Please Check Your Password", preferredStyle: .alert)
let ok = UIAlertAction (title: "OK", style: UIAlertAction.Style.cancel, handler: nil)
alert.addAction(ok)
self.present(alert, animated: true, completion: nil)
【问题讨论】:
首先:永远不要在DispatchQueue.main
上运行任何网络请求;将它直接放在 viewDidLoad 或任何 IBAction 中也是一个非常糟糕的设计。但是你也可以在几个地方放置断点(例如在 DispatchQueue 中,看看它是否到达那里
那你建议我把 dispatchqueue.main 放在哪里?
【参考方案1】:
像DispatchQueue.main.async
enqueue 这样的异步调用在队列上工作,然后继续执行,无需等待完成。有多种方法可以解决这个问题,但幸运的是您不需要其中任何一种:您无需致电 DispatchQueue.main.async
。
相反,只需发出您的网络请求,Alamofire 就会回调主队列(默认情况下)以执行您的响应处理程序的内容(在本例中为 responseString
)。从表面上看,您需要将网络调用之后的逻辑移动到您的响应处理程序中,因为它取决于网络调用的结果。
【讨论】:
以上是关于从 IBAction 调用的 dispatchqueue.main.async 中跳过了 Https 请求的主要内容,如果未能解决你的问题,请参考以下文章
当从同一个组件调用时,两个 IBAction 触发的顺序是啥?
从 NSTimer 函数调用 UIButton @IBAction [关闭]
从 IBAction 调用的 dispatchqueue.main.async 中跳过了 Https 请求