現在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通信の許可設定はしてあります。
回答1件
あなたの回答
tips
プレビュー