视图控制器之间的差异传递数据
我试图在我的第一个ViewController和我的SecondViewController之间传递数据。我有两个变量在ViewController的顶部被初始化为空。然后我解析JSON数据并将这两个变量的值设置为解析的临时JSON变量。然后在prepareforSegue函数中,让SecondViewController的变量等于我的第一个ViewController中的前两个变量。由于某些原因,传递的变量只在空变量时传递变量。我不知道如果我做任何意义,但这里是我的代码:视图控制器之间的差异传递数据
class ViewController: UIViewController {
var stockSymbol = String()
var stockPrice = String()
@IBOutlet weak var textField: UITextField!
@IBAction func buttonPressed(sender: AnyObject) {
let requestURL: NSURL = NSURL(string: "https://finance.yahoo.com/webservice/v1/symbols/\(textField.text!)/quote?format=json")!
let urlRequest: NSMutableURLRequest = NSMutableURLRequest(URL: requestURL)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(urlRequest) {
(data, response, error) -> Void in
let httpResponse = response as! NSHTTPURLResponse
let statusCode = httpResponse.statusCode
if (statusCode == 200) {
print("Everyone is fine, file downloaded successfully.")
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options:.AllowFragments)
if let resources = json["list"]?!["resources"] as? [[String:AnyObject]] {
if let fields = resources[0]["resource"]?["fields"] as? [String:String], price = fields["price"], symbol = fields["symbol"] {
self.stockSymbol = symbol
self.stockPrice = price
print(self.stockSymbol, self.stockPrice)
}
}
} catch {
print("Error with Json: \(error)")
//end catch
}
} //end if status code == 200
} //end task
task.resume()
}
override func viewDidLoad() {
super.viewDidLoad()
//var test:String
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "searchResults") {
print("working \(self.stockPrice)")
let secondVC = segue.destinationViewController as! SecondViewController;
secondVC.passedSymbol = self.stockSymbol
secondVC.passedPrice = self.stockPrice
print(secondVC.passedSymbol)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
基本上我想要的股票价格和符号,就能够转移到我的第二个视图控制器的变量,但它似乎不工作。
守则第二个视图控制器:
class SecondViewController: UIViewController {
var passedSymbol: String!
var passedPrice: String!
@IBOutlet weak var symbol: UILabel!
@IBOutlet weak var price: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
print("passed \(passedSymbol)")
print("second view")
dispatch_async(dispatch_get_main_queue()) {
self.symbol.text = self.passedSymbol
self.price.text = self.passedPrice
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
输出语句,当我把“AAPL”到searchField
working
passed
second view
Everyone is fine, file downloaded successfully.
AAPL 100.529999
首先,不这样做:
var stockSymbol = String()
var stockPrice = String()
这是一个不好的习惯,停止编译器抱怨未初始化变量,但完全忽略了斯威夫特自选的力量。
相反,这样做:
var stockSymbol:String!
var stockPrice:String!
这将确保当您尝试使用中的变量没有设定值,你会得到一个异常。
现在,您得到空值(或者如果您提出我的建议更改会得到异常)的原因是您按下按钮时启动了异步数据提取,但是立即启动了继续,可能是因为您有一个与该按钮以及touchUpInside
处理程序关联的操作。
您需要删除动作segue,并通过ctrl-从场景顶部的黄色View Controller
图标拖动到目标视图控制器并创建一个标识符,并像往常一样给新的segue一个标识符。
然后,您可以将您的buttonPressed
函数更改为在检索到数据后调用segue;
@IBAction func buttonPressed(sender: AnyObject) {
let requestURL: NSURL = NSURL(string: "https://finance.yahoo.com/webservice/v1/symbols/\(textField.text!)/quote?format=json")!
let urlRequest: NSMutableURLRequest = NSMutableURLRequest(URL: requestURL)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(urlRequest) {
(data, response, error) -> Void in
let httpResponse = response as! NSHTTPURLResponse
let statusCode = httpResponse.statusCode
if (statusCode == 200) {
print("Everyone is fine, file downloaded successfully.")
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options:.AllowFragments)
if let resources = json["list"]?!["resources"] as? [[String:AnyObject]] {
if let fields = resources[0]["resource"]?["fields"] as? [String:String], price = fields["price"], symbol = fields["symbol"] {
self.stockSymbol = symbol
self.stockPrice = price
print(self.stockSymbol, self.stockPrice)
dispatch_async(dispatch_get_main_queue(), {
self.performSegueWithIdentifier("searchResults",sender:sender)
})
}
}
} catch {
print("Error with Json: \(error)")
//end catch
}
} //end if status code == 200
} //end task
task.resume()
}
它的工作!非常感谢 :) – Nick
的原因应该是,当你去到第二的ViewController,你有没有得到第一个视图控制器中的数据。 dataTaskWithRequest是一个异步函数,这意味着它运行在另一个线程而不是主要的UI线程上。你可以做的是等到你在第一个视图控制器得到数据,然后调用segue。控制台上的打印信息可能会让您感到困惑,因为您已经获取了数据,但实际上可能会在调用segue之后发生并导致没有数据通过。
我删除了异步,它仍然不起作用 – Nick
你是什么意思删除异步?它本身是异步的。 –
请显示'SecondViewController'的代码以及任何打印语句的输出。 – sschale