サーバーに置いたJSON形式のデータベースにアクセスし、SwiftUIで出力したいです。
簡易的なAPI(http://mjroehkexj.m5.valueserver.jp/)を作成しサーバーに設置後、SwiftUIでデータを出力しようとするとエラーが起きてしまいます。
お恥ずかしながら、データロードに関するファンクションをしっかり理解できておらず、作成にあたり、以下のサイトを参照しております。
こちらのソースコードの、データの定義に関する記述と、APIのURLを変更すればうまく機能するかと考えていたのですが、プレビューが見られなくなってしまいました。
https://d1v1b.com/swiftui/use_data_from_api
ソースコードではしっかりと動くことが確認できました。
大学でiOSアプリ開発をしている初心者でして、初歩的な知識がなく、どこに問題があるかわからないので該当しそうなファイルをすべて記載いたします。
長いですが、お助けいただけますと嬉しいです。
発生している問題・エラーメッセージ
プレビューが見られなくなりました。コード自体にエラーメッセージはありません。
Preview Crushed
該当のソースコード
ファイル名:ProgramModels.swift
データモデルの作成、データ型の定義
SwiftUI
1import SwiftUI 2 3struct Program: Hashable, Codable { 4 var id: Int 5 var level: Int 6 var type:String 7 var type2:String 8 var typename:String 9 var name: String 10 var term: Int 11 var day: Int 12 var period: Int 13 var credit: Int 14 var teacher1: String 15 var teacher2: String 16 var teacher3: String 17 var teacher4: String 18 var teacher5: String 19 var teacher6: String 20 var teacher7: String 21 var teacher8: String 22 var teacher9: String 23 var teacher10: String 24 var url: String 25 26}
ファイル名:APIfetch.swift
APIのデータをロードするファンクション
SwiftUI
1import SwiftUI 2 3func apiFetch<T: Decodable>(_ url: String, completion: @escaping ([T]) -> Void) { 4 guard let url = URL(string: url) else { return } 5 6 URLSession.shared.dataTask(with: url) { (data, response, error) in 7 guard let data = data else { return } 8 let decoder: JSONDecoder = JSONDecoder() 9 do { 10 let resData = try decoder.decode([T].self, from: data) 11 DispatchQueue.main.async { 12 completion(resData) 13 } 14 } catch { 15 fatalError("Couldn't load (url) :\n(error)") 16 } 17 }.resume() 18} 19
ファイル名:ProgramView.swift
Viewファイル
SwiftUI
1import SwiftUI 2 3class ProgramViewModel: ObservableObject { 4 //データ初期値の設定 5 @Published var data: [Program] = 6 [Program( 7 id: -1, 8 level: -1, 9 type:"na", 10 type2:"na", 11 typename:"na", 12 name:"na", 13 term:-1, 14 day:-1, 15 period:-1, 16 credit:-1, 17 teacher1: "na", 18 teacher2: "na", 19 teacher3: "na", 20 teacher4: "na", 21 teacher5: "na", 22 teacher6: "na", 23 teacher7: "na", 24 teacher8: "na", 25 teacher9: "na", 26 teacher10: "na", 27 url: "na") 28 ] 29 30 31 init() { 32 //APIfetchの呼び出し 33 apiFetch("http://mjroehkexj.m5.valueserver.jp/"){ resData in 34 self.data = resData 35 36 } 37 } 38} 39 40 41struct ProgramView: View { 42 @ObservedObject var programVM = ProgramViewModel() 43 44 var body: some View { 45 ScrollView(.vertical, showsIndicators: false) { 46 VStack(spacing: 10) { 47 // nameを順番に表示 48 ForEach(programVM.data, id: .id) { (program) in 49 ZStack(alignment: .bottom) { 50 Text(program.name) 51 52 } 53 } 54 } 55 } 56 } 57} 58struct ProgramView_Previews: PreviewProvider { 59 static var previews: some View { 60 ProgramView() 61 } 62} 63
試したこと
作成したAPIがJSON形式のコードとして適切かどうか確認したところ、Htmlのコードを記入したままになっておりましたので該当部分は削除しました。
現在検討している問題点としては
・データをロードする段階で、うまくデータ型に割り振れていない
・そもそもAPIとして機能しておらずデータをロードできない
などを考えております。
補足情報(FW/ツールのバージョンなど)
Xcode Version 12.4 (12D4e)
Swift version 5.3.2
あなたの回答
tips
プレビュー