ios - 打印结果后执行 Alamofire 请求
问题描述
我正在制作一个关于在网站上使用 API 的应用程序。这是一个火车时刻表应用程序。我在将数据从一个 ViewController 发送到另一个时遇到了麻烦。问题是为什么我创建的全局变量 (trainNo) 在执行代码“self.trainNo.append(data2.intValue)”和“prepare(...)”时没有传递给另一个 VC。我使用 print 语句进行调试。我发现当按下按钮时,首先执行Alamofire请求语句中的打印语句“print(self.trainNo)”,然后执行Alamofire请求中的“print(self.trainNo)”。我不知道为什么会这样。
我尝试在不同的地方使用 print 语句。
@IBAction func buttonPressed(_ sender: Any) {
APIUrl = "https://ptx.transportdata.tw/MOTC/v2/Rail/TRA/DailyTimetable/OD/"+"\(startStationNo)"+"/to/"+"\(endStationNo)"+"/"+"\(selectedDate)"+"?$top=30&$format=JSON&$orderby=OriginStopTime/ArrivalTime"
let request = setUpUrl(APIUrl: APIUrl)
print("\(APIUrl)")
Alamofire.request(request).responseJSON { response in
do{
let json: JSON = try JSON(data: response.data!)
if let result = json.array {
for data in result {
let data2 = data["DailyTrainInfo"]["TrainNo"]
self.trainNo.append(data2.intValue)
print(self.trainNo)
}
}
else{
print("ERROR in data2")
}
}
catch{
print("ERROR in json \(error)")
}
}
print(self.trainNo)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.destination is TimeTableController {
let vc = segue.destination as? TimeTableController
vc?.trainNo = self.trainNo
print(self.trainNo)
}
}
我预计 trainNo 的值将被更改并传递给另一个 VC。但它没有用。
实际结果:
[] //这个是按钮中的“print(self.trainNo)”
[] //这个是prepare中的“print(self.trainNo)”
[101] ...... [101, 3147, 371, 3157, 3167, 1] // 这些是 Alamofire 中的“print(self.trainNo)”循环
这意味着 Alamofire 请求和循环在 print 语句之后执行,我不知道发生了什么。
解决方案
因为请求是异步的,所以需要self.performSegue(withIdentifier
在回调里面使用
@IBAction func buttonPressed(_ sender: Any) {
APIUrl = "https://ptx.transportdata.tw/MOTC/v2/Rail/TRA/DailyTimetable/OD/"+"\(startStationNo)"+"/to/"+"\(endStationNo)"+"/"+"\(selectedDate)"+"?$top=30&$format=JSON&$orderby=OriginStopTime/ArrivalTime"
let request = setUpUrl(APIUrl: APIUrl)
print("\(APIUrl)")
Alamofire.request(request).responseJSON { response in
do{
let json: JSON = try JSON(data: response.data!)
if let result = json.array {
for data in result {
let data2 = data["DailyTrainInfo"]["TrainNo"]
self.trainNo.append(data2.intValue)
print(self.trainNo)
}
// this will trigger the segue
self.performSegue(withIdentifier: "segueName", sender: nil)
}
else{
print("ERROR in data2")
}
}
catch{
print("ERROR in json \(error)")
}
}
print(self.trainNo)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.destination is TimeTableController {
let vc = segue.destination as? TimeTableController
vc?.trainNo = self.trainNo
print(self.trainNo)
}
}
并将segue的源连接到vc本身而不是按钮,顺便说一句,您可能需要在请求之前显示活动指示器作为一个好的UX,所以用户期望这是一个网络操作
推荐阅读
- flutter - Flutter如何在构建小部件之外使用上下文?
- android - 出现软键盘时如何避免只有BottomNavbar向上推
- google-app-engine - 错误:(gcloud.app.deploy)错误响应:[5] 无法在全局作业中获取云区域
- css - 有没有办法将填充或 boxshadow 添加到 css 圆锥渐变部分
- java - 心率查询返回空集
- python - AttributeError:从 Windows Server 使用 Paramiko 连接时,模块“paramiko.win_pageant”没有属性“can_talk_to_agent”
- unity3d - ARKit 跟踪能否与 Vuforia 的区域目标一样有效?
- sql - 使用 IIF() 替换 SELECT 语句中的空值
- postgresql - 将 execute$$ 替换为 plpgsql 格式
- json - 调用 Ruby,Rspec 错误时,应用程序是否返回 JSON?