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

时间:2018-08-19 12:49:40

标签: ios json swift xcode viewcontroller

我正在尝试将JSON值传递给另一个ViewController,在这种情况下,它是用户希望输入的任何城市中当前天气的描述。我可以在主View Controller(ViewController)上很好地获取和显示JSON数据,但是我想让它显示在我的第二个View Controller(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 <<
    }

1 个答案:

答案 0 :(得分:2)

您将要通过segue传递数据。当即将执行搜索时,您的第一个视图控制器将具有名为https://developer.apple.com/documentation/uikit/uiviewcontroller/1621490-prepareforsegueprepareForSegue

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

例如

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

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

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