SwiftUIにてアプリ開発を行っているのですが、APIを使ってデータを取得してからViewを更新する方法がわかりません。
initに、データ取得の関数、view更新の関数を順に呼び出しているのですが、
データが取得し終わる前にview更新の関数が呼び出されてしまい、画面になにも表示されません。
以下、イメージのコードです
swift
1struct SwiftApiTest: View { 2 @ObservedObject var viewModel = SwiftApiTestViewModel(count: 10) 3 var body: some View { 4 if viewModel.isProgress { 5 ProgressView() 6 } else { 7 VStack { 8 ForEach(viewModel.subViews) {view in 9 view 10 } 11 } 12 } 13 } 14} 15 16struct SubView: View, Identifiable { 17 let id = UUID() 18 let hoge: Int 19 let fuga: String 20 init?(hoge: Int?, fuga: String?) { 21 if let hoge = hoge, 22 let fuga = fuga { 23 self.hoge = hoge 24 self.fuga = fuga 25 } else { 26 print("hogeかfugaがnilです") 27 return nil 28 } 29 } 30 var body: some View { 31 HStack { 32 Text("hoge: \(hoge)") 33 Text("fuga: \(fuga)") 34 } 35 } 36} 37 38class SwiftApiTestViewModel: ObservableObject { 39 @Published var cm = CommunicationManager() 40 @Published var subViews: [SubView] = [] 41 42 init(count: Int) { 43 // データ取得 44 resume() 45 // view更新処理 46 // 上のresume()がまだ終わっていないのに呼び出されてしまう 47 subViewDuplicator(count: count) 48 } 49 50 var isProgress: Bool { 51 cm.isProgress 52 } 53 54 var hoge: Int? { 55 var value: Int? 56 if let data = cm.apiData { 57 value = data.hoge 58 } 59 return value 60 } 61 62 var fuga: String? { 63 var str: String? 64 if let data = cm.apiData { 65 str = data.fuga 66 } 67 return str 68 } 69 70 // SubViewをcount分だけ複製して配列に入れる 71 func subViewDuplicator(count: Int) { 72 for _ in 0..<count { 73 subViews.append(SubView(hoge: hoge, fuga: fuga)!) 74 } 75 } 76 77 func resume() { 78 cm.resume() 79 } 80} 81 82class CommunicationManager { 83 struct ApiData: Decodable { 84 var hoge: Int 85 var fuga: String 86 } 87 88 // 処理中か 89 var isProgress = false 90 // 取得するデータ 91 var apiData: ApiData? 92 93 func resume() { 94 // 処理開始 95 isProgress = true 96 let url = URL(string: "url")! 97 let request = URLRequest(url: url) 98 URLSession.shared.dataTask( 99 with: request, 100 completionHandler: { data, response, error in 101 // データ取得処理 102 }) 103 // 処理終了 104 isProgress = false 105 } 106}
ものすごい雑なサンプルですが、現在作成中のアプリでは
天気apiを使って取ってきた情報(1週間天気など)を一旦別View(ここではSubView)にいれ
それを配列にしてメインViewにてForEachを使って表示させています。
resume()が終わってからsubViewDuplicator()を実行させる方法を教えていただきたいです。
DispatchQueue.main.asyncなどを使うようではありますが色々試してうまく行かなかったので
質問させていただきます。
ツッコミどころが多すぎてどこからコメントしたらいいか悩みますが、とりあえず非同期処理について学ぶことをお勧めします。
回答1件
あなたの回答
tips
プレビュー