我正在尝试运行url请求以在选择某个表行之后获取JSON文件,基于该行与URL请求一起发送唯一ID并生成不同的JSON。这是我的准备世界
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
var divisionScene = segue.destinationViewController as! DivisionViewController
// Pass the selected object to the new view controller.
if let indexPath = tableView.indexPathForSelectedRow() {
let arrayIndex = indexPath.row
//println("Index: \(arrayIndex)")
torneoIDTransfer = torneos[arrayIndex].torneoID
//println("\(torneoIDTransfer)")
//check second url with second request type same token
//sets url to string using token
let tercerURL = NSURL(string: "http://api.zione.mx/get.json.asp?tr=3&tkn=\(tkn)&tor=\(torneoIDTransfer)")
//initializes request
let request = NSURLRequest(URL: tercerURL!)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.currentQueue()) { response, jsonDataRequest3, error in
let dataRequest3 = jsonDataRequest3
//takes data, saves it as json
let tercerJSON = JSON(data: jsonDataRequest3)
//checks to see that contents != nil, meaning the JSON file was found
if tercerJSON != nil {
//checks amount of tournaments available in order to generate table.
let divisionCount = tercerJSON["lista-divisiones"].count
//sets global variable numero de torneos
numeroDeDivisiones = divisionCount
//for loop to go insert into Torneo nuevo each ID and name by using count from above
for var index = 0; index < divisionCount; ++index {
var divisionID = Int(tercerJSON["lista-divisiones" ][index]["DivisionID"].number!)
var nomDivision = tercerJSON["lista-divisiones"][index]["nomDivision"].string
//println("\(divisionID)")
//println("\(nomDivision)")
var divisionNuevo = listaDivisiones(divisionID: divisionID, nomDivision: nomDivision!)
divisiones.append(divisionNuevo)
numeroDeDivisiones = 10
print("WHO IS FIRST")
}
}
print("\(divisiones[0].nomDivision)")
}
}
}
我通过从表格单元格拖动到新视图控制器来创建我的赛格威。但是,当我单击表格单元格时,转换会在请求有机会完成之前立即发生转换,因此不会显示任何数据。
答案 0 :(得分:1)
“在请求有机会完成之前,转换立即发生”。
当然它确实如此,这正是异步意味着什么。你提到它是异步的,你必须对这意味着什么有误解。解释您认为这意味着什么以及您对代码的期望,以便您可以更好地接受我们的教育。
当您调用sendAsynchronousRequest()时,请将您的程序视为分支为两个(实际上这实际上是有效的)。一部分是您的原始代码,它将继续执行,即您的prepareFoSegue代码将继续执行。 同时,并行地,OS将执行请求,并且当请求完成时,将传递您传递给sendAsynchronousRequest()的块中的代码。因此,您的prepareForSeque()函数将在收到Json之前完成。
但除此之外,你不应该试图或希望或者希望在segue过渡之前获取JSon - 这样做会停止你的ui。假设sendAsynchronousRequest()是sendSynchronousRequest()而且需要10秒才能完成,你认为应用程序在运行时会产生什么后果?
您应该在GUI准备好显示之前长时间获取数据,或者如果不可能,请立即显示没有数据的GUI,然后在数据到达时更新它。
答案 1 :(得分:1)
在用户选择表格行之前很久,在后台获取和处理数据是理想的。如果这是不可能的,那么我建议您让目标视图控制器执行URL请求。 URL请求是异步发生的,因此在取消分配源视图控制器之前,它永远不会有机会完成。
在源视图控制器中,修改prepareForSegue
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var divisionScene = segue.destinationViewController as! DivisionViewController
if let indexPath = tableView.indexPathForSelectedRow() {
let arrayIndex = indexPath.row
torneoIDTransfer = torneos[arrayIndex].torneoID
let tercerURL = NSURL(string: "http://api.zione.mx/get.json.asp?tr=3&tkn=\(tkn)&tor=\(torneoIDTransfer)")
divisionScene.fetchDataAtURL(tercerURL)
}
}
您需要在目标视图控制器中定义一个方法来处理提取。
func fetchDataAtURL(URL: NSURL) {
let request = NSURLRequest(URL: tercerURL!)
NSURLConnection.sendAsynchronousRequest( // ... your fetching logic here
}
一旦数据到达,您还需要一些逻辑来显示数据。我建议将它放入你的请求的完成回调中(或者更确切地说,让回调触发显示更新)。如果您的divisionScene
是tableView,则可以调用reloadData
(更新数据源后)。如果没有,您将需要一些其他方式来更新UI。如果要更新UI,请确保dispatch
到该部分的主队列。
这样做至少会将URL加载责任传递给目标视图控制器,这至少会在数据最终到达时为止。