画面遷移先でAPIから取得した情報を表示させたいのですが、今それができません。
MainStoryyboardの配置は
です。右側の”ここでチェック!”のボタンを押すと、左側の画像に遷移して気温のところにAPIから取得した現在の気温を表示させたいです。
右側の画面にくっつけてある、ViewControllerには
import UIKit class ViewController: UIViewController { @IBOutlet weak var weatherImage: UIImageView! @IBOutlet weak var checkButton: UIButton! let dataManager = WeatherDataManager() override func viewDidLoad() { super.viewDidLoad() self.dataManager.dataRequest() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } @IBAction func checkButton(_ sender: Any) { let storyboard: UIStoryboard = self.storyboard! let nextView = storyboard.instantiateViewController(withIdentifier: "next") as! CheckViewController self.present(nextView, animated: true, completion: nil) if dataManager.weatherData?.weather == "Clouds" { weatherImage.image = UIImage(named: "cloud") } else if dataManager.weatherData?.weather == "Clear" { weatherImage.image = UIImage(named: "sunny") } else if dataManager.weatherData?.weather == "Rain" { weatherImage.image = UIImage(named: "rain") } // print(WeatherDataModel(data:).dynamicTyp) // self.checkButton.isHidden = true } }
と書きました。”ここでチェック!”を押したらcheckButtonメソッドが呼ばれ、Storyboardの左側の画面(CheckViewControllerがくっついている)に遷移します。しかし、左側の画像に遷移して気温のところにAPIから取得した現在の気温は表示されず、かつ if dataManager.weatherData?.weather 〜のif-else文が呼ばれず、天気ごとに表示させる画像を変える(表示させる画像はAssets.xcassetsに入っている)という部分ができません。
CheckViewControllerには、
import Foundation import UIKit class CheckViewController: UIViewController { @IBOutlet weak var tempLabel: UILabel! // APIリクエストや、レスポンスデータを利用するため クラス インスタンス let dataManager = WeatherDataManager() override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. // ここでAPIリクエストを行う self.dataManager.dataRequest() // 気温 ラベルに取得した気温を表示させる tempLabel.text = dataManager.weatherData?.temp.description } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } }
と書きました。
// 気温 ラベルに取得した気温を表示させる tempLabel.text = dataManager.weatherData?.temp.description
のコードがあるからラベルに現在の気温を表示させるところはできているはずなのですが、表示されない理由がわかりません。checkButtonメソッドに書いた
let storyboard: UIStoryboard = self.storyboard! let nextView = storyboard.instantiateViewController(withIdentifier: "next") as! CheckViewController self.present(nextView, animated: true, completion: nil)
のコードを書く場所を間違ったのでしょうか?
WeatherDataManager.swiftには
import Foundation // 必要なフレームワークをインポートする import Alamofire import SwiftyJSON // AlamofireによるAPI通信を管理するクラスを定 義する class WeatherDataManager: NSObject { // レスポンスデータをパースするモデルクラス イ ンスタンスを格納するプロパティ var weatherData: WeatherDataModel? // リクエストするURL let url = "http://api.openweathermap.org/data/2.5/forecast?units=metric&q=Tokyo&APPID=2ec06eb3d8b93310aa2773a10f1dafe4" // APIリクエストを実行する func dataRequest() { // AlamofireによるAPI通信 Alamofire.request(url).responseJSON { response in switch response.result { case .success(let value): // 通信成功時 処理 // レスポンスデータをJSON型に変換する // これ SwiftyJSON ルール let json = JSON(value) // print("here") // print(json) // JSONデータを引数に渡してモデルクラス インスタンスを生成 self.weatherData = WeatherDataModel(data: json) // デバッグ用 ログ出力を行う // print(value) case .failure(let error): break // 通信失敗時 処理 // 今回 ログ出力だけ print(error) } } } }
と書きました。
WeatherDataModel.swiftには
import Foundation // 必要なフレームワークをインポートする import SwiftyJSON // SwiftyJSONによるパースを行うクラス class WeatherDataModel: NSObject { // 今日 天気(晴れ、雨等)を格納するプロパティ var weather: String = "" // 気温を格納するプロパティ var temp: Int = 0 // weatherDataManagerクラスから初期化される init?(data: JSON) { // 引数で渡ってきたJSONデータをここでパースする // 今日 天気データを取得して変数に格納する self.weather = data["list"][0]["weather"][0]["main"].stringValue //気温データを取得して変数に格納する self.temp = data["list"][0]["main"]["temp"].intValue } }
と書きました。
fuzzballさんのコメントを受け、CheckViewControllerを以下のように書き換えました。
import Foundation import UIKit class CheckViewController: UIViewController { @IBOutlet weak var weatherImage: UIImageView! @IBOutlet weak var tempLabel: UILabel! // APIリクエストや、レスポンスデータを利用するため クラス インスタンス let dataManager = WeatherDataManager() override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. // ここでAPIリクエストを行う if dataManager.weatherData?.weather == "Clouds" { // 「Clouds」だったら「曇り」 画像を表示する weatherImage.image = UIImage(named: "cloud") } else if dataManager.weatherData?.weather == "Clear" { // 「Clear」だったら「晴れ」 画像を表示する weatherImage.image = UIImage(named: "sunny") } else if dataManager.weatherData?.weather == "Rain" { // 「Rain」だったら「雨」 画像を表示する weatherImage.image = UIImage(named: "rain") } self.dataManager.dataRequest() print("here") print(dataManager.weatherData) // 気温 ラベルに取得した気温を表示させる tempLabel.text = dataManager.weatherData?.temp.description } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } }
このように書き換え実行すると
2017-08-01 15:23:03.412 WeatherApp[9709:864615] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<WeatherApp.ViewController 0x7fecff505a80> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key weatherImage.'
とエラーが出て落ちてしまいました。
WeatherDataManagerも書き換え、
import Foundation // 必要なフレームワークをインポートする import Alamofire import SwiftyJSON // AlamofireによるAPI通信を管理するクラスを定 義する class WeatherDataManager: NSObject { // レスポンスデータをパースするモデルクラス イ ンスタンスを格納するプロパティ var weatherData: WeatherDataModel? // リクエストするURL let url = "http://api.openweathermap.org/data/2.5/forecast?units=metric&q=Tokyo&APPID=2ec06eb3d8b93310aa2773a10f1dafe4" // APIリクエストを実行する func dataRequest() { // AlamofireによるAPI通信 Alamofire.request(url).responseJSON { response in switch response.result { case .success(let value): // 通信成功時 処理 // レスポンスデータをJSON型に変換する // これ SwiftyJSON ルール let json = JSON(value) // JSONデータを引数に渡してモデルクラス インスタンスを生成 self.weatherData = WeatherDataModel(data: json) case .failure(let error): break // 通信失敗時 処理 // 今回 ログ出力だけ print(error) } } } // 気温 ラベルに取得した気温を表示させる tempLabel.text = dataManager.weatherData?.temp.description }
としましたが、tempLabelがないと言われ(その通りなのですが。
しかし、CheckViewControllerに定義したものを WeatherDataManagerの方に持ってくる方法がわからなかった)ました。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2017/08/01 06:32
2017/08/01 06:41
退会済みユーザー
2017/08/01 07:40
2017/08/01 07:56
退会済みユーザー
2017/08/01 08:21
2017/08/01 08:31