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

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

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

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

Q&A

解決済

1回答

639閲覧

1つ目のAPI接続で取得したデータを、2つ目のAPI接続の条件に設定して値を取得する方法

tomaa

総合スコア84

Swift

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

0グッド

1クリップ

投稿2020/11/10 02:50

編集2020/11/10 05:14

前提・実現したいこと

SwiftUIを利用してアプリを開発しています。

下記の仕様の動作を行いたいのですが、目的どおりに動きません。

  • 登録されている複数の情報(①測定開始日と、②測定開始日から今日までの各日の気温)をViewにリスト形式で表示する

  • ②の各日の気温は、①で設定した測定開始日から今日まで範囲のものとなる

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

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

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

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

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

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

coco_bauer

2020/11/10 04:48

1つ目のAPI接続、2つ目のAPI接続、で利用しているAPIの仕様を質問に追加してください。 何をするAPIなのかが判らないのに、うまく使える訳がないですから。
tomaa

2020/11/10 05:14

コメントありがとうございます。API仕様を質問に追加しました。
guest

回答1

0

自己解決

下記の方法(クロージャを利用する)で目的の動きとなりました。

VegetableInfoRow.swift

... @State var weatherAveInfos:[WeatherAveInfos]? ... ForEach(self.weatherAveInfos ?? []){ info in Text(String(info.ave_temp)) } ... }.onAppear(){ appState.makeGetCallWeatherAveTemp(start_date: info.start_date, total: {returnData in self.weatherAveInfos = returnData }) } ...

AppState.swift

... func makeGetCallWeatherAveTemp(start_date:String,total:@escaping([WeatherAveInfos])->Void ) { ... DispatchQueue.main.async { do{ self.weatherAveInfos = try JSONDecoder().decode([WeatherAveInfos].self, from: responseData) let aveInfos:[WeatherAveInfos] = self.weatherAveInfos! total(aveInfos) ...

投稿2020/11/10 10:13

tomaa

総合スコア84

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問