作为我正在创建的应用程序的一部分,我实现了一个运行跟踪功能。我有大部分代码,但我有一段代码几乎执行得太快,我需要在下一段代码执行之前从newRun.php脚本回复,这是由于它返回一个ID我要求执行下一段代码。
@IBAction func stopRun(_ sender: Any)
{
startButton.isHidden=false
stopButton.isHidden=true
saveRun()
}
上面是运行saveRun的代码部分。在此按钮上单击我希望它在'run_history'表中创建新记录。只有这个已经完成,然后我想让它用newRun.php
脚本返回的run_id创建新记录,其中包括运行的所有经度和纬度。
private func saveRun()
{
首先执行。
let request = NSMutableURLRequest(url: NSURL(string: "../newRun.php")! as URL)
request.httpMethod = "POST"
let postString = "id=\(MainMenuViewController.myVariables.user_id)"
request.httpBody = postString.data(using: String.Encoding.utf8)
let task = URLSession.shared.dataTask(with: request as URLRequest)
{
data, response, error in
if error != nil
{
print("error=\(String(describing: error))")
return
}
print("response = \(String(describing: response))")
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
MainMenuViewController.myVariables.new_run_id = responseString! as String
print ("Run ID =\(MainMenuViewController.myVariables.new_run_id))")
}
task.resume()
第二次被执行。
for location in self.locationList
{
var timestamp = location.timestamp
var latitude:String = String(format:"%f", location.coordinate.latitude)
var longitude:String = String(format:"%f", location.coordinate.longitude)
print("Timestamp is \(timestamp)")
print("latitude is \(latitude)")
print("longitude is \(longitude)")
let requestGps = NSMutableURLRequest(url: NSURL(string: "../newRunGps.php")! as URL)
requestGps.httpMethod = "POST"
let postStringGps = "id=\(MainMenuViewController.myVariables.new_run_id)&lng=\(longitude)&lat=\(latitude)&time=\(timestamp)"
requestGps.httpBody = postStringGps.data(using: String.Encoding.utf8)
let taskGps = URLSession.shared.dataTask(with: requestGps as URLRequest)
{
dataGps, responseGps, errorGps in
if errorGps != nil
{
print("error=\(String(describing: errorGps))")
return
}
print("response = \(String(describing: responseGps))")
let responseStringGps = NSString(data: dataGps!, encoding: String.Encoding.utf8.rawValue)
print ("responseString =\(responseStringGps!))")
}
taskGps.resume()
}
}
我见过DispatchQueue和DispatchGroup的提及,但我不确定如果有人可以帮我解决这个问题,我会如何在我的代码中使用这些?
答案 0 :(得分:0)
您可以尝试这样的事情:
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(4), execute: {
for vc in (self.navigationController?.viewControllers ?? []) {
if vc is DashboardViewController {
self.navigationController?.popToViewController(vc, animated: true)
break
}
}
})
答案 1 :(得分:0)
你也可以使用"推迟"
{
defer {
//code run after below defer
}
defer{
// code run first
}
}
但请记住,这个推迟会在范围结束前执行
答案 2 :(得分:0)
这里的问题是MainMenuViewController.myVariables.new_run_id
是在异步方法的回调中设置的,这意味着DispatchQueue
或defer
将在这里为您提供帮助。
处理它的最简单方法是将for
循环放在回调本身内。因此,将始终确保在执行调用后仅执行:
let request = NSMutableURLRequest(url: NSURL(string: "../newRun.php")! as URL)
request.httpMethod = "POST"
let postString = "id=\(MainMenuViewController.myVariables.user_id)"
request.httpBody = postString.data(using: String.Encoding.utf8)
let task = URLSession.shared.dataTask(with: request as URLRequest)
{
data, response, error in
if error != nil
{
print("error=\(String(describing: error))")
return
}
print("response = \(String(describing: response))")
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
MainMenuViewController.myVariables.new_run_id = responseString! as String
print ("Run ID =\(MainMenuViewController.myVariables.new_run_id))")
// here run the for loop
for location in self.locationList {
// TODO: rest of the for loop code
}
}
task.resume()
如果您对UI做任何事情(将文本设置为UILabel等),请确保在主线程上排队代码(在您的情况下,您似乎只是将数据发送到服务器,因此您不需要需要处理那个)。