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

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

新規登録して質問してみよう
ただいま回答率
85.36%
Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

HttpWebRequest

HttpWebRequestとは.NETにおけるクラスであり、WebRequestクラスをHTTPに導入するものです。

Swift

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

Q&A

解決済

1回答

2145閲覧

SwiftUI http通信におけるサーバーからのデータ取得がうまくいかない

kousukehiraki

総合スコア1

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

HttpWebRequest

HttpWebRequestとは.NETにおけるクラスであり、WebRequestクラスをHTTPに導入するものです。

Swift

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

0グッド

0クリップ

投稿2021/06/20 08:24

編集2021/06/20 08:28

現在swiftUIでサーバーからスケジュールを同期するアプリを開発しています。
その中でURLSessionを使ってローカル環境のサーバーから予定の配列を取得してリストに表示する機能を実装しようとしているのですが、これが上手くいきません。
現在下記のようなコードで実装しておりますが、TodayScheduleView()内で受け取った配列を確認したところ空の配列であることがわかりました。

swift

1struct UserMemo: Codable { 2 var id: Int 3 var user_id: Int 4 var is_shortcut: Bool 5 var title: String 6 var content: String 7 var shortcut_color: String 8 var sticker_id: Int 9 var is_always: Bool 10 var is_all_day: Bool 11 var start_time: String 12 var end_time: String 13 var created_at: String 14 var updated_at: String 15} 16 17 18class UserMemoFetcher: ObservableObject { 19 private let urlLink = "http://localhost:3000/users/memos/show" 20 @Published var memos: [UserMemo] = [] 21 22 init() { 23 fetchMemoData() 24 } 25 26 func fetchMemoData() { 27 let token_key = "*****" 28 let token:String = "Bearer " + token_key 29 30 var request = URLRequest(url: URL(string: urlLink)!) 31 request.setValue(token, forHTTPHeaderField: "Authorization") 32 request.setValue("application/json", forHTTPHeaderField: "Content-Type") 33 URLSession.shared.dataTask(with: request) { (data, response, error) in 34 guard let data = data else { return } 35 let decoder: JSONDecoder = JSONDecoder() 36 do { 37 self.memos = try decoder.decode([UserMemo].self, from: data) 38 } catch { 39 print("json convert failed in JSONDecoder. " + error.localizedDescription) 40 } 41 }.resume() 42 } 43}

swift

1struct CalendarPageView: View { 2 @ObservedObject var fetcher = UserMemoFetcher() 3 var body: some View { 4 VStack(spacing:0){ 5 CalendarView() 6 TodayScheduleView(filteredUserMemos: self.fetcher.memos) //ここでサーバから受け取った配列を渡したい 7 } 8 } 9}

##試したこと
原因としてはURLSessionを通り抜けてUserMemoFetcher.memosに代入される前に実行してしまうためかと考え、あまり良い方法ではないかと思いますが、
DispatchSemaphoreを使って無理矢理同期通信にしてみました。

swift

1class UserMemoFetcher: ObservableObject { 2 private let urlLink = "http://localhost:3000/users/memos/show" 3 @Published var memos: [UserMemo] = [] 4 5 init() { 6 fetchMemoData() 7 } 8 9 func fetchMemoData() { 10 let token_key = "*****" 11 let token:String = "Bearer " + token_key 12 13 var request = URLRequest(url: URL(string: urlLink)!) 14 request.setValue(token, forHTTPHeaderField: "Authorization") 15 request.setValue("application/json", forHTTPHeaderField: "Content-Type") 16 let semaphore = DispatchSemaphore(value: 0) 17 URLSession.shared.dataTask(with: request) { (data, response, error) in 18 guard let data = data else { return } 19 let decoder: JSONDecoder = JSONDecoder() 20 do { 21 self.memos = try decoder.decode([UserMemo].self, from: data) 22 semaphore.signal() 23 } catch { 24 print("json convert failed in JSONDecoder. " + error.localizedDescription) 25 semaphore.signal() 26 } 27 }.resume() 28 semaphore.wait() 29 } 30}

この方法を、同プロジェクトファイル内のPlaygroundで試したところ、UserMemoFetcher.memos内で配列を取得できていることが確認できました。
しかし、いざView内で実装してみると、UserMemoFetcher.memosは空の配列のままでした。
もし原因、対処法を知っている方がいれば教えていただけると幸いです。
よろしくお願いいたします。

##補足
ローカルサーバについてはRuby on railsを使用しています。
サーバの動作についてはInsomniaで正常に動作していることを確認しているため、問題ないかと思います。
また、swiftのhttp通信の許可設定はしてあります。

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

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

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

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

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

hoshi-takanori

2021/06/20 11:00

self.memos への代入はメインスレッドで行う必要がありますが、self.memos に代入すれば @Publish なので表示は更新されるはず…。とりあえず、decoder.decode の結果を表示してみては。
guest

回答1

0

自己解決

自己解決しました。
配列を別のViewに渡す際に、受け取る側のViewで変数を@Binding していなかったことが原因でした。
hoshi-takanori様
真摯に考えてくださり、ありがとうございました。

投稿2021/06/21 13:51

kousukehiraki

総合スコア1

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問