如何将 JSON 值从一个 ViewController 传递到另一个

Posted

技术标签:

【中文标题】如何将 JSON 值从一个 ViewController 传递到另一个【英文标题】:How to pass a JSON value from one ViewController to another 【发布时间】:2018-08-19 12:49:39 【问题描述】:

我正在尝试将 JSON 值传递给另一个 ViewController,在这种情况下,它是对用户希望进入的任何城市的当前天气的描述。我让它在我的主视图控制器 (ViewController) 上很好地获取和显示 JSON 数据,但我想让它显示在我的第二个视图控制器 (AdvancedViewController) 上,作为一个高级和更详细的部分等。我的价值试图通过的是“gmain”,正如您在下面的代码中看到的那样,它位于按钮函数内部,并且位于 viewDidLoad() 之外。

在我的 AdvancedViewController 代码中,我已经完成了它,因此我可以通过键入“vc”访问 ViewController 的内容。在从该 ViewController 输入变量之前,我可以访问标签、文本框、按钮等,但它无法识别“gmain”,您可以在我的代码底部看到,我正在尝试将“gmain”的值分配给我的AdvancedViewController 中的标签。如您所见,我的 AdvancedViewController 中的代码位于 viewDidLoad() 中,因为我希望在打开特定的 View Controller 时将其显示给用户。

如果我完全陷入困境,我将不胜感激,而且我已经坚持了好几天了。提前谢谢你。

我在下面的 ViewController 中的 JSON 结构:

struct Coordinate : Decodable 
    let lat, lon : Double?


struct Weather : Decodable 
    var id : Int?
    var main, myDescription, icon : String?

    enum CodingKeys : String, CodingKey 
        case id = "id"
        case main = "main"
        case icon = "icon"
        case myDescription = "description"
    


struct Sys : Decodable 
    let type, id : Int?
    let sunrise, sunset : Date?
    let message : Double?
    let country : String?


struct Main : Decodable 
    let temp, tempMin, tempMax : Double?
    let pressure, humidity : Int?


struct Wind : Decodable 
    let speed : Double?
    let deg : Int?


struct MyWeather : Decodable 
    let coord : Coordinate?
    let cod, visibility, id : Int?
    let name : String?
    let base : String?
    let weather : [Weather]?
    let sys : Sys?
    let main : Main?
    let wind : Wind?
    let dt : Date?

下面ViewController中的GoButton函数:

@IBAction func GoButton(_ sender: Any) 



        let text: String = userValue.text!



        guard let APIUrl = URL(string: "https://api.openweathermap.org/data/2.5/weather?q=" + text +  "&appid=***API***KEY***&units=Metric") else  return 
        //API KEY

        URLSession.shared.dataTask(with: APIUrl)  data, response, error in
            guard let data = data else  return 


            let decoder = JSONDecoder()
            //Decoder

            do 
                let weatherData = try decoder.decode(MyWeather.self, from: data)

                if (self.MainLabel != nil)
                
                    if let gmain =  (weatherData.weather?.first?.main)  //using .first because Weather is stored in an array
                        print(gmain)
                        DispatchQueue.main.async 
                            self.MainLabel.text! = String (gmain)
                        
                    

            
     catch 
        print(error.localizedDescription)
    
    .resume()

AdvancedViewController 代码如下:

class AdvancedViewController: UIViewController 

    @IBOutlet weak var Label: UILabel!


    override func viewDidLoad() 
        super.viewDidLoad()

        let vc = ViewController(nibName: "ViewController", bundle: nil)

        Label.text! = String (vc.gmain) //NOT WORKING <<
    

【问题讨论】:

你如何从MainViewControllerAdvancedViewController?看来您没有设置任何segue。我也没有看到任何 pushpresent 声明。 我会建议你先学习 OOP 的概念。 我只是在故事板上的 ViewController 中添加了一个按钮,然后 CTRL 将其拖到 AdvancedViewController,并选择了“显示”,因此一旦单击,它就会打开 AdvancedViewController 【参考方案1】:

您将希望通过 segue 传递数据。当一个 segue 即将被执行时,你的第一个视图控制器将有 prepareForSegue 称为 https://developer.apple.com/documentation/uikit/uiviewcontroller/1621490-prepareforsegue

因此您需要重写它并实现代码以从 segue 参数中读取 destinationViewController

例如

// in MainViewController
override func prepare(for segue: UIStoryboardSegue, 
  sender: Any?) 

     let nextVC = segue.destinationViewController as? AdvancedViewController
     nextVC?.data = myData

另外,我只是想给您一个小提示,以确保您的视图控制器中的属性以小写字母开头。所有变量和属性都以小写字母开头,以符合命名约定。这将有助于区分变量(您分配的东西)和类型(您实例化并分配给变量的实际数据结构)

【讨论】:

以上是关于如何将 JSON 值从一个 ViewController 传递到另一个的主要内容,如果未能解决你的问题,请参考以下文章

如何将输入/选择值从网站保存到 XML/JSON 文件并使用 JavaScript 自动加载再次填充它们

如何将双精度值从 json 转换为函数

如何将日期值从 JSON 返回到 Google Visualization API

AWS Glue 将字符串值从 postgres 转换为 json 数组

将配置值从 json 文件导入到 scss

如何将值从节点返回到原点(angular2 请求)