0

I am trying to pass a JSON value to another ViewController, in this case it is the description of the current weather in any city the user wishes to enter. I have it fetching and displaying the JSON data just fine on my main View Controller (ViewController), but I want to get it to display on my second View Controller (AdvancedViewController), as an advanced and more detailed section etc. The value I am trying to pass through is 'gmain' which as you can see in my code below, is inside a button function, and is outside of the viewDidLoad().

In my AdvancedViewController code, I have made it so I can access the contents of ViewController my typing 'vc.' before entering a variable from that ViewController, I can access labels, textBoxes, buttons etc, but it does not recognise 'gmain', you can see at the bottom of my code, I am trying to assign the value of 'gmain' to my Label in the AdvancedViewController. As you can see, my code in my AdvancedViewController is in the viewDidLoad(), as I want it to be displayed to the user upon opening that specific View Controller.

I would appreciate any help as I am completely stuck, and I have been for several days now. Thank you in advance.

My JSON Structs in my ViewController below:

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?
}

GoButton function in ViewController below:

@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 Code below:

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 <<
    }
Boi
  • 23
  • 7
  • How are you going from the `MainViewController` to the `AdvancedViewController`? It seems you do not have any segue's set up. Neither do i see any `push` or `present` statements. – Rakesha Shastri Aug 19 '18 at 12:57
  • i will advise you to learn OOPs concept first. – Keshu R. Aug 19 '18 at 12:59
  • I simply added a button to my ViewController on the story board, and CTRL dragged it to AdvancedViewController, and selected 'show', so once clicked, it opens the AdvancedViewController – Boi Aug 19 '18 at 13:06

1 Answers1

3

You're going to want to pass data via a segue. When a segue is about to be performed, your first view controller will have prepareForSegue called https://developer.apple.com/documentation/uikit/uiviewcontroller/1621490-prepareforsegue

So you need to override it and implement code to read the destinationViewController from the segue argument.

For example

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

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

On a separate note, I just wanted to give you a small tip to make sure your properties in your view controllers start with a lowercase letter. All variables and properties start with a lowercase letter to stay with the naming convention. This will help a little bit with the distinction between variables (things you assign stuff to) and types (the actual data structures you instantiate and assign to variables)

bitwit
  • 2,589
  • 2
  • 28
  • 33