質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

解決済

1回答

3174閲覧

【Swift】天気予報APIを使って、予報日や天気などを取得し表示する

reo0612

総合スコア2

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

0クリップ

投稿2020/06/11 06:06

前提・実現したいこと

Livedoorの天気予報APIを使って、pickerViewで選んだ都道府県を画面遷移した時に予報日や天気、最高気温などをLabelに反映させるアプリを作ろうとしています。

発生している問題・エラーメッセージ

Buildはできるんですが、画面遷移してもAPIから取得したデータをLabelに反映されない問題が起きています。

![イメージ説明](2fbd6bb7d3083e8fbafe19280deb8a4c.png) ![イメージ説明](77df341f4946be3a2cf7963e4ea8bdb0.png)

該当のソースコード

Swift

1import UIKit 2 3class ViewController: UIViewController,UIPickerViewDelegate,UIPickerViewDataSource{ 4 5 6 @IBOutlet weak var titleLabel: UILabel! 7 @IBOutlet weak var pickerView: UIPickerView! 8 @IBOutlet weak var resultButton: UIButton! 9 10// 次のVCに渡す変数に初期値を入れておきます 11 var cityData:[String] = ["130010","東京"] 12// modelのデータを持ってきます 13 let cityList = CityList() 14 15 16 override func viewDidLoad() { 17 super.viewDidLoad() 18 19 pickerView.delegate = self 20 pickerView.dataSource = self 21 22 } 23// pickerの列の数を決める 24 func numberOfComponents(in pickerView: UIPickerView) -> Int { 25 return 1 26 } 27// pickerの行数を決める 28 func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { 29 return cityList.list.count 30 } 31// pickerに表示するデータを決める 32// ここでは取得したmodelのデータのnameを表示する 33 func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { 34 return cityList.list[row].name 35 } 36// タップしたときの動きを決める 37// 次の画面に渡す為に取得したmodelのデータから、codeとnameを変数に入れる 38 func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { 39 cityData = [cityList.list[row].code,cityList.list[row].name] 40 } 41 42// ボタンを押した時の処理 43// 画面遷移する 44 45 46 @IBAction func resultButtonAction(_ sender: Any) { 47 48 performSegue(withIdentifier: "result", sender: nil) 49 50 } 51 52// 次の画面にデータを渡す処理 53// prepareは、segueが動作するとViewControllerに通知 54 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 55 56 if segue.identifier == "result" { 57 58 let resultVC = segue.destination as! resultViewController 59 resultVC.cityData = cityData 60 61 } 62 63 } 64 65 66 67} 68 69 70import UIKit 71import SwiftyJSON 72import Alamofire 73 74import Foundation 75 76class resultViewController: UIViewController { 77 78 @IBOutlet weak var cityNameLabel: UILabel! 79 @IBOutlet weak var detailsTextView: UITextView! 80 81 @IBOutlet weak var TodayDateLabel: UILabel! 82 @IBOutlet weak var TodayWeatherLabel: UILabel! 83 @IBOutlet weak var TodayHighLabel: UILabel! 84 @IBOutlet weak var TodayLowLabel: UILabel! 85 86 @IBOutlet weak var TomorrowDateLabel: UILabel! 87 @IBOutlet weak var TomorrowWeatherLabel: UILabel! 88 @IBOutlet weak var TomorrowHighLabel: UILabel! 89 @IBOutlet weak var TomorrowLowLabel: UILabel! 90 91 let highString = "最高気温:" 92 let lowString = "最低気温:" 93 94// 取得した天気予報のデータを入れる 95 var date:String = "" 96 var weather:String = "" 97 var high:String = "" 98 var low:String = "" 99 var details:[String] = [] 100 101// viewController(前の画面)に渡し、選択した地域のデータを入れる 102 var cityData:[String] = [] 103 104 var count = 0 105 106 107 override func viewDidLoad() { 108 super.viewDidLoad() 109 110 getWeatherData(row: 0) 111 getWeatherData(row: 1) 112 113 } 114 115// 天気情報を取得 116 func getWeatherData(row: Int){ 117 118 let url = "http://weather.livedoor.com/forecast/webservice/json/v1?city=(cityData)" 119 120// Alamofireで通信 121// データを取得する 122 AF.request(url, method: .get, parameters: nil, encoding: JSONEncoding.default).responseJSON {(response) in 123 124 switch response.result { 125 case .success: 126 127// jsonを取得 128 let json:JSON = JSON(response.data as Any) 129 130// 取得したjsonから、必要なデータを取り出す 131 132// 予報日 133 let date = json["forecasts"][row]["date"].string 134// 天気 135 let weather = json["forecasts"][row]["telop"].string 136// 最高気温 137 let high = json["forecasts"][row]["temperature"]["max"]["celsius"].string 138// 最低気温 139 let low = json["forecasts"][row]["temperature"]["min"]["celsius"].string 140// 天気概況文 141 let details = json["description"]["text"].string 142 143// 取り出したデータを、それぞれの変数に入れる 144// データがない場合は、その時は"NO DATA"と入れる 145 if date != nil{ 146 147 self.date = String(date!.suffix(5)) //2020-4-10 -> 04-10 148 }else{ 149 150 self.date = "No Data" 151 152 } 153 154 if weather != nil{ 155 156 self.weather = weather! 157 158 }else{ 159 160 self.weather = "No Data" 161 162 } 163 164 if high != nil{ 165 166 self.high = "(high!)" 167 168 169 }else{ 170 171 self.high = "No Data" 172 173 174 } 175 176 if low != nil{ 177 178 self.low = "(low!)" 179 180 181 }else{ 182 183 self.low = "No Data" 184 185 } 186 187 if details != nil{ 188 189 self.details = (details?.components(separatedBy: .newlines))! //改行で分割 190 191 }else{ 192 193 self.details = ["No Details"] 194 195 } 196 197// ラベルに反映される 198 self.setWeatherData(row: row) 199 200 case .failure(let error): 201 print("エラー") 202 print(error) 203 204 } 205 206 } 207 208 } 209 210// ラベルに反映させる処理 211// 引数を与えて、todayとtomorrowで分岐 212 func setWeatherData(row: Int){ 213 214 if row == 0 { 215 216 TodayWeatherLabel.text = weather 217 TodayDateLabel.text = date 218 TodayHighLabel.text = highString + high 219 TodayLowLabel.text = lowString + low 220 221// 分割時に配列になっているので、1つ目の要素だけ表示 222// detailsTextView.text = String(details[row]) 223 224 }else if row == 1 { 225 226 TomorrowWeatherLabel.text = weather 227 TomorrowDateLabel.text = date 228 TomorrowHighLabel.text = highString + high 229 TomorrowLowLabel.text = lowString + low 230 231 } 232 233 } 234 235} 236

試したこと

まだ初めて2ヶ月ということもあり、再起動しか試せていません。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TsukubaDepot

2020/06/11 07:14

おそらく、このコードはQiitaの記事を参考にされていると思いますが、そうであれば出典を明記された方がいいかと思います。
reo0612

2020/06/11 07:25

ご返事ありがとうございます。そうですね、あーなるほどです!承知しました。
guest

回答1

0

ベストアンサー

Qiitaの記事

を参考にされたという前提で回答します。

とりあえず動かすためには次の部分の訂正と、設定の変更が必要になりますのでご確認ください。

1.resultViewController 内でのタイプミス

Swift

1 func getWeatherData(row: Int){ 2 3 let url = "http://weather.livedoor.com/forecast/webservice/json/v1?city=(cityData)"

は、オリジナルのソースコードと比較すると次の間違いだと気づかれるかと思います。

Swift

1 func getWeatherData(row: Int){ 2 3 let url = "http://weather.livedoor.com/forecast/webservice/json/v1?city=(cityData[0])"

2.ATS の設定

アプリで http 通信を行うためには、ATS (App Transport Security Settings)の設定が必要になります。Qiitaの該当記事には書かれていませんが、http通信を行うためには必要な設定となります。

下記の記事が参考になるかと思います。

投稿2020/06/11 07:51

TsukubaDepot

総合スコア5086

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

reo0612

2020/06/12 05:59

ありがとうございます。無事解決しました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問