前提・実現したいこと
SwiftUIを利用してアプリを開発しています。
下記の仕様の動作を行いたいのですが、目的どおりに動きません。
-
登録されている複数の情報(①測定開始日と、②測定開始日から今日までの各日の気温)をViewにリスト形式で表示する
-
②の各日の気温は、①で設定した測定開始日から今日まで範囲のものとなる
発生している問題
上記の画面のイメージは、実際のコードを起動させたものですが、1つ目と2つ目の情報は、測定開始日は違う日を表示していますが、気温は両方とも同じ内容を表示しています。
これを、各リストの測定開始日に沿った条件として表示させたいです。
ちなみに、コード内部では測定開始日それぞれの条件での気温を、コンソールで表示ができていますが、Viewの表示反映させられない状況です。
気温表示 11.5 13.0 6.2 気温表示 13.7 17.3 14.9 13.8 14.3 15.6 14.8 13.4 12.8 15.5 17.3 13.5
下記の該当のソースコードに詳細を載せていますが、
①測定開始日を取得するエンドポイントと、気温を取得するエンドポイントが違う事
②気温を取得するエンドポイントには、API接続で取得した測定開始日をデータをフィルタの条件に利用する事
などが、うまくいきません。
JsonModel.swift
該当のソースコード
API仕様
/api/info/
[ { "id": 116, "start_date": "2020-11-07", "user": 126 }, { "id": 117, "start_date": "2020-10-29", "user": 126 } ]
/api/weather_ave/?start_date=2020-11-07
[ { "id": 511039, "ave_temp": 25.7 }, { "id": 511186, "ave_temp": 24.9 }, { "id": 511333, "ave_temp": 23.4 } ]
/api/weather_ave/?start_date=2020-10-29
[ { "id": 509716, "ave_temp": 25.6 }, { "id": 509863, "ave_temp": 24.1 }, { "id": 510010, "ave_temp": 23.5 }, { "id": 510157, "ave_temp": 25.7 }, { "id": 510304, "ave_temp": 26.4 }, { "id": 510451, "ave_temp": 23.7 }, { "id": 510598, "ave_temp": 23.0 }, { "id": 510745, "ave_temp": 24.4 }, { "id": 510892, "ave_temp": 26.1 }, { "id": 511039, "ave_temp": 25.7 }, { "id": 511186, "ave_temp": 24.9 }, { "id": 511333, "ave_temp": 23.4 } ]
AppState.swift
swift
1 2import Foundation 3 4struct DateInfos: Codable,Identifiable { 5 var id: Int 6 var start_date: String 7} 8 9struct WeatherAveInfos:Codable,Identifiable { 10 var id: Int 11 var ave_temp: Float 12} 13
AppState.swift
swift
1import SwiftUI 2import Foundation 3import Combine 4import UIKit 5 6class AppState: ObservableObject { 7 8 @Published var arrayDateInfos:[DateInfos]? 9 @Published var weatherAveInfos:[WeatherAveInfos]? 10 11 12func makeGetCallVegetableInfos() { 13 // Set up the URL request 14 let endpoint: String = "https://sample.com/api/info/" 15 16 guard let url = URL(string: endpoint) else { 17 print("Error: cannot create URL") 18 return 19 } 20 var urlRequest = URLRequest(url: url) 21 urlRequest.addValue("token xxxxxxxxxx", forHTTPHeaderField: "authorization") 22 // set up the session 23 let config = URLSessionConfiguration.default 24 let session = URLSession(configuration: config) 25 26 // make the request 27 let task = session.dataTask(with: urlRequest) { 28 (data, response, error) in 29 // check for any errors 30 guard error == nil else { 31 print("error calling GET") 32 print(error!) 33 return 34 } 35 // make sure we got data 36 guard let responseData = data else { 37 print("Error: did not receive data") 38 return 39 } 40 // parse the result as JSON, since that's what the API provides 41 DispatchQueue.main.async { 42 do{ self.arrayDateInfos = try JSONDecoder().decode([DateInfos].self, from: responseData) 43 }catch{ 44 print("Error: did not decode") 45 return 46 } 47 } 48 } 49 task.resume() 50 } 51} 52 53 54func makeGetCallWeatherAveTemp(start_date:String ) { 55 56 // Set up the URL request 57 let endpoint: String = "https://sample.com/api/weather_ave/?start_date=(start_date)" 58 59 guard let url = URL(string: endpoint) else { 60 print("Error: cannot create URL") 61 return 62 } 63 var urlRequest = URLRequest(url: url) 64 urlRequest.addValue("token xxxxxxxxxx", forHTTPHeaderField: "authorization") 65 // set up the session 66 let config = URLSessionConfiguration.default 67 let session = URLSession(configuration: config) 68 // make the request 69 let task = session.dataTask(with: urlRequest) { 70 (data, response, error) in 71 // check for any errors 72 guard error == nil else { 73 print("error calling GET") 74 return 75 } 76 // make sure we got data 77 guard let responseData = data else { 78 print("Error: did not receive data") 79 return 80 } 81 // parse the result as JSON, since that's what the API provides 82 DispatchQueue.main.async { 83 do{ self.weatherAveInfos = try JSONDecoder().decode([WeatherAveInfos].self, from: responseData) 84 print("気温表示") 85 for info in self.weatherAveInfos!{ 86 print(info.ave_temp) 87 } 88 }catch{ 89 print("Error: did not decode") 90 return 91 } 92 } 93 } 94 task.resume() 95} 96
HomeView.swift
swift
1import SwiftUI 2 3struct HomeView: View { 4 5 @EnvironmentObject var appState: AppState 6 7 var body: some View { 8 NavigationView{ 9 VStack{ 10 ForEach(appState.arrayDateInfos ?? []){ info in 11 VStack{ 12 VegetableInfoRow(info:info) 13 }.background(Color(.secondarySystemFill)) 14 .cornerRadius(10) 15 .padding(.top) 16 .padding(.leading) 17 .padding(.bottom) 18 } 19 }.onAppear(){ 20 appState.makeGetCallVegetableInfos() 21 } 22 } 23 } 24}
VegetableInfoRow.swift
import SwiftUI struct VegetableInfoRow: View { @EnvironmentObject var appState: AppState var info:DateInfos var body: some View { ScrollView(.horizontal) { HStack{ VStack{ VStack{ Text("測定開始日:").padding() Text(stringToStringDate(stringDate: info.start_date, format: "yyyy-MM-dd")) } } Divider() .padding() VStack{ VStack{ Text("各日の気温:").padding() ForEach(appState.weatherAveInfos ?? []){ info in Text(String(info.ave_temp)) } } } } }.onAppear(){ appState.makeGetCallWeatherAveTemp(start_date: info.start_date) } } } func stringToStringDate(stringDate: String, format:String) -> String { let formatter: DateFormatter = DateFormatter() formatter.calendar = Calendar(identifier: .gregorian) formatter.dateFormat = "yyyy/MM/dd" let newDate = formatter.date(from: stringDate)! formatter.dateFormat = format return formatter.string(from: newDate) }
補足情報(FW/ツールのバージョンなど)
Xcode:Version 12.0.1
回答1件
あなたの回答
tips
プレビュー