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

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

新規登録して質問してみよう
ただいま回答率
85.46%
非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Swift

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

Q&A

0回答

784閲覧

Combineを利用するメソッドを、while文のloop処理で複数回行う方法

tomaa

総合スコア84

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Swift

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

0グッド

0クリップ

投稿2020/11/22 16:33

前提・実現したいこと

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

Combineframeworkを使う非同期処理を、他のメソッド内whileのloop処理の中で、複数回行い、それぞれの処理結果を利用したいです。

sink()を利用し、値の取得が終了する際の処理の中で、次のメソッド(whileのloop処理を行う)に値を渡しているのですが、うまく動作しません。


動作概要
0. 指定の日付の平均気温を取得するエンドポイントを利用し、気温を取得する(記載のコードの場合は15.0)メソッドを準備する

  1. 1のメソッドをwhile文で複数回行い(記載のコードの場合は3回)、合計の気温の値を利用する(記載のコードの場合は45.0)

どのような対応をすれば、期待する動作になるでしょうか?

発生している問題

期待する表示

counter:1 totalTemp:15.0 counter:2 totalTemp:30.0 counter:3 totalTemp:45.0 2020-11-22 23:15:03.755907+0700 Sample[84786:7191186] [] nw_protocol_get_quic_image_block_invoke dlopen libquic failed ---------- dayTemp:15.0 receiveCompletion:finished

実際の表示

counter:1 totalTemp:0.0 counter:2 totalTemp:0.0 counter:3 totalTemp:0.0 2020-11-22 23:15:03.755907+0700 Sample[84786:7191186] [] nw_protocol_get_quic_image_block_invoke dlopen libquic failed ---------- dayTemp:15.0 receiveCompletion:finished

該当のソースコード

swift

1 var weatherInfos:WeatherInfos? 2 3 func whileTempCombine(date: String,getTemp:@escaping(Float)->Void){ 4 5 var counter:Int = 0 6 var totalTemp:Float = 0.0 7 8 while counter < 3 9 { 10 counter += 1 11 self.getTemperatureCombine(block_no: block_no, date: date, getDayTemp: {returnData in 12 totalTemp += returnData}) 13 print("counter:(counter)") 14 print("totalTemp:(totalTemp)") 15 } 16 getTemp(totalTemp) 17 } 18 19 20 var cancellable: AnyCancellable? = nil 21 22 func getTemperatureCombine(date: String,getDayTemp:@escaping(Float)->Void){ 23 var dayTemp:Float = 0.0 24 25 let endpoint: String = "https://sample.com/api/temp_day/?date=(date)" 26 let url = URL(string: endpoint) 27 let urlRequest = URLRequest(url: url!) 28 29 cancellable = URLSession.shared.dataTaskPublisher(for: urlRequest) 30 .map({(data, res) in 31 return data 32 }) 33 .decode(type: [WeatherInfos].self, decoder: JSONDecoder()) 34 .sink(receiveCompletion: {completion in 35 print("receiveCompletion:(completion)") 36 print("dayTemp:(dayTemp)") // 15.0 37 getDayTemp(dayTemp) 38 } 39 , receiveValue: {value in 40 for info in value{ 41 dayTemp += info.temp 42 print("dayTemp:(dayTemp)") 43 } 44 }) 45 } 46 47 struct WeatherInfos:Codable,Identifiable { 48 var id: Int 49 var temp: Float 50 } 51

ContentView.swift

swift

1import SwiftUI 2 3struct ContentView: View { 4 5 @EnvironmentObject var appState: AppState 6 @State var temp:Float = 0.0 7 8 var body: some View { 9 VStack{ 10 if appState.isLoading{ 11 Progress() 12 } 13 Text(String(temp)) 14 Button(action:{ 15 appState.whileTempCombine(date: "2020-11-01", getTemp: { returnData in 16 temp = returnData 17 }) 18 19 }){ 20 Text("実行") 21 } 22 } 23 } 24}

試したこと

getDayTemp(dayTemp)の処理をreceiveValue クロージャーの中で行っても、同じ結果となります。

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

Xcode:Version 12.0.1

iOS:13.0

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

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

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

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

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

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問