视图控制器之间的差异传递数据

问题描述:

我试图在我的第一个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 
+0

请显示'SecondViewController'的代码以及任何打印语句的输出。 – sschale

首先,不这样做:

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() 

} 
+0

它的工作!非常感谢 :) – Nick

的原因应该是,当你去到第二的ViewController,你有没有得到第一个视图控制器中的数据。 dataTaskWithRequest是一个异步函数,这意味着它运行在另一个线程而不是主要的UI线程上。你可以做的是等到你在第一个视图控制器得到数据,然后调用segue。控制台上的打印信息可能会让您感到困惑,因为您已经获取了数据,但实际上可能会在调用segue之后发生并导致没有数据通过。

+0

我删除了异步,它仍然不起作用 – Nick

+0

你是什么意思删除异步?它本身是异步的。 –