ios - I am trying to call a function from my main ViewController and use it to load JSON data in my Second ViewController
问题描述
I am making a weather app for iOS, and I am trying to call a variable from my main ViewController, to be used in my second ViewController, I am using API data from OpenWeatherMap to display weather data, this works fine on the Main ViewController, and I want it displayed on the second one, as an 'Advanced details' section, that will display the max/min temp, and air pressure etc. (things people don't care about).
I have made an instance of my Main ViewController 'var myCustomViewController: ViewController = ViewController (nibName: nil, bundle: nil)' which works fine, and I am able to call labels, variables, TextBoxes etc from the Main Viewcontroller, but I cannot call the variable 'weatherData', which is the decoder for my JSON data.
In my second View Controller, I want to say 'if let gmain = (myCustomViewController.weatherData.main.tempmax' for example, to get the maximum temperature, but it does not recognise 'weatherData'. I'm very stuck on this and would appreciate any help. Thank you.
Structs in my Main 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?
}
Main ViewController code below:
let text: String = userValue.text!
guard let APIUrl = URL(string: "https://api.openweathermap.org/data/2.5/weather?q=" + text + "&appid=e7b2054dc37b1f464d912c00dd309595&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)
}
}
}
if (self.LocationLabel != nil)
{
if let gmain = weatherData.name {
print(gmain)
DispatchQueue.main.async {
self.LocationLabel.text! = "Current Weather in: " + String (gmain)
}
}
}
Second ViewController code below:
var myCustomViewController: ViewController = ViewController (nibName: nil, bundle: nil) //Inheriting from other viewController
if (self.descriptionLabel != nil)
{
if let gmain = (myCustomViewController.weatherData { //NOT RECOGNISING weatherData <<<<<
print(gmain)
DispatchQueue.main.async {
self.descriptionLabel.text! = String (gmain)
}
}
}
}
解决方案
在您的 MainViewController 代码中,您有以下行:
let weatherData = try decoder.decode(MyWeather.self, from: data)
这是在一个方法里面,比如viewDidLoad
?如果是这样,则weatherData
不是 MainViewController 的属性,并且不能被子类访问。您必须将其定义为任何函数范围之外的属性(例如,在文件顶部,就在左括号之后):
var weatherData = ...
然后这样称呼它:
do {
weatherData = ...
推荐阅读
- ui5-webcomponents - 标签容器渲染问题
- arrays - 套接字序列化错误,需要一个类似字节的对象,而不是 'str'
- database - 如何在 MongoDB 中获取到周末的日期?
- java - 以漂亮的文本格式化结构化日志(单行序列化 JSON)的“gcloud app logs tail”输出
- node.js - nodejs计算具有相同值的dynamodb记录-聚合分组
- php - PDO 驱动程序在 Debian 10 中没有价值
- ios - 如何将关联域附加到 CoreNFC 中 NFCNDEFPayload 的 NFC 标签中
- java - Android 应用程序在模拟器中使用 java 代码崩溃
- html - 如何使用 JQUERY 检查所有“th”值?
- java - 如何在放心的拦截器中设置内容类型?