SwiftUI 3-3-2. JSONファイルを読み込む

前節で, ストレージにJSONファイルを書き込みました. 今回はファイルが正しく書き込みされているか確認する意味も込めてストレージのファイルの読み込み処理を追加します. 前回のコードに続けて書く PhotoDataの中に load( path: )関数 を作成する ファイルが存在するかを FileManager.default.fileExists( atPath: ) で確認 ファイルがない場合は空の配列を返すようにする URL( fileURLWithPath:path ) で読込パスをURLに変換する try! Data( contentOf:url ) でファイルを読み込む 3-02で作成済みの PhotoData.parse( json: ) で[PhotoData]に変換して返す コード1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 import Foundation struct PhotoData : Identifiable, Codable, Equatable { var id:String = UUID()....

2023-03-28 · 2024-07-28

SwiftUI 3-3-3. JSONファイル読み書きコードの改善・例外の対応

3-3-1でJSONファイルの書き出し, 3-3-2でJSONファイルの読み込みを扱いました. これらのコードを使いやすくするため, 例外の処理などを加えて改善します。 まず, JSON保存側の処理の見直しです. PhotoData.save( path: data: )関数 を例外に対応させる 基本的に3-2-3と同様の作業を行う try! を try にする do { ~ } catch { ~ } を使って例外発生を捉える catch内で例外時の処理を記述する コード1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 import Foundation struct PhotoData : Identifiable, Codable, Equatable { var id:String = UUID()....

2023-03-28 · 2023-03-30

SwiftUI 3-3-4. JSONファイルの削除

JSONの書き出し, JSONの読み込みはできました. ストレージに書き出したファイルは残るようになりましたが, 書き出したJSONファイルが不要になることもあるでしょう. 今回は作成したJSONファイルを削除する処理を追加します. PhotoDataに clear( path: )関数 を追加する FileManager.default.removeItem( atPath: ) でファイルを削除する do { ~ } catch { ~ } を使い例外に対応した処理も書く コード1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 import Foundation struct PhotoData : Identifiable, Codable, Equatable { var id:String = UUID()....

2023-03-28 · 2024-07-28

SwiftUI 3-3-5. JSONファイルの有無とAppの挙動・初期化

前回までで、JSONファイルの書き出し・読み込み・削除ができるようになりました. これらを踏まえ,Appの挙動に視点を移して考えてみます. Appはインストールして初めて立ち上げる初回起動などがあります. 初回起動する前はもちろんJSONファイルなどは書き出していないのでファイルは存在しません. ファイルが存在しないときどう処理するかなどを考える必要があります. ファイルに限りませんが, 初回起動はAppが正しく動作するための準備処理を書くことが多いです. 今回は Documentsフォルダにuser_photos.jsonがないとき, 初期化処理として **
Resources/photos.jsonを読み込む** ようにPhotoData.load関数をカスタマイズしてみます. 前回のコードに続けて書く PhotoDataの load( path: )関数 でファイルが見つからなかったときに処理を追加する 初期データとしてResources/photos.jsonを読み込む コード1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 import Foundation struct PhotoData : Identifiable, Codable, Equatable { var id:String = UUID()....

2023-03-28 · 2024-07-28

SwiftUI 3-1-2. データを追加する

前回でデータの変更が可能になりました. 今回はデータを追加する方法を紹介します. まずデータを増やすためのボタンを設置します. ボタンの設置のためリストのヘッダをカスタマイズします. ContentViewを開き, List内のSectionの書き方を変更する Sectionの( “景色写真” )を消す Section { ~ } の後に header: { Viewデザイン } を追加する 「景色写真」の文字は, headerの中のTextで表示する ヘッダに文字だけでなく, 他のView部品を入れられるようになる コード1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 import SwiftUI struct ContentView: View { @State var photos:[PhotoData] = [ PhotoData( type:"景色", imageName:"CC0_01", title:"景色1", message:"森と山です" ), PhotoData( type:"景色", imageName:"CC0_04", title:"景色2", message:"きれいな湖です" ), PhotoData( type:"景色", imageName:"CC0_06", title:"景色3", message:"フィレンツェです" ), PhotoData( type:"景色", imageName:"CC0_07", title:"景色4", message:"ひまわりです" ), PhotoData( type:"景色", imageName:"CC0_10", title:"景色5", message:"海に日が沈みます" ) ] var body: some View { List { Section { ForEach( $photos ) { bind_photo in NavigationLink( destination:{ SceneryDetail( data:bind_photo ) }, label: { SceneryRow( data:bind_photo....

2023-03-23 · 2024-07-28

SwiftUI 3-1-3. データを削除する

前回, Viewからデータを追加できる例を紹介しました. 今回は逆にデータを削除する例を紹介します. これはリストの機能を使うとシンプルに実現できます. ContentViewのSectionのForEachに.onDelete { … }を追加する ForEachで繰り返し表示している項目を右スライドできるようになる onDelete内で photos.remove( atOffsets: ) を呼ぶ 該当する位置のデータを削除できる( onDeleteのindex_setに該当のデータ位置が入っている ) Photosの中身も減っているのでprintなどで確認すると良い コード1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 import SwiftUI struct ContentView: View { @State var photos:[PhotoData] = [ PhotoData( type:"景色", imageName:"CC0_01", title:"景色1", message:"森と山です" ), PhotoData( type:"景色", imageName:"CC0_04", title:"景色2", message:"きれいな湖です" ), PhotoData( type:"景色", imageName:"CC0_06", title:"景色3", message:"フィレンツェです" ), PhotoData( type:"景色", imageName:"CC0_07", title:"景色4", message:"ひまわりです" ), PhotoData( type:"景色", imageName:"CC0_10", title:"景色5", message:"海に日が沈みます" ) ] var body: some View { List { Section { ForEach( $photos ) { bind_photo in NavigationLink( destination:{ SceneryDetail( data:bind_photo ) }, label: { SceneryRow( data:bind_photo....

2023-03-23 · 2024-07-28

SwiftUI 3-2-1. JSONから構造体への変換とファイルのバンドル

前節ではSwift内のデータの編集を紹介しました. この節では, これまでSwiftに直接書き込んでいたリストのデータをファイルから読み込んでみます。多くのアプリケーションは用いるデータを外部から得てくることがほとんどです. 今回はその1例としてJSONファイルを読み込んでリスト表示にしてみます. SFSwiftUI03-2.swiftpm を開く (サンプルコード) 03-1を完了したコードと同様 photos配列を空っぽにしている 後で読み込むためのJSONファイルが入っている データがないため, プレビューも何もない状態から始まることを確認 コード1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 import SwiftUI struct ContentView: View { @State var photos:[PhotoData] = [] var body: some View { List { Section { ForEach( $photos ) { bind_photo in NavigationLink( destination:{ SceneryDetail( data:bind_photo ) }, label: { SceneryRow( data:bind_photo....

2023-03-23 · 2024-07-28

SwiftUI 3-0-1. 3章の目標・進め方・サンプルコード

3章の進め方と目標 SwiftUI入門の3章は、まず1,2章をご覧いただいた上で進めることをお勧めします。 この章では以下のことを目標にしています。 2章5節で紹介したデータとビューの連携をさらに深める データの変更とビューの更新 JSON形式のデータを扱い,ビューで表現する サーバからデータを取得して,ビューで表現する 触れていく中で1つずつ理解できるよう工夫しています。1節目から進めていただけると幸いです。 サンプルコード 各ページから 1,2章と同様サンプルコードが必要になるタイミングで各ページに用意しています。必要に応じて入手してご利用ください。 Githubから Githubにも公開しています。一括してサンプルコードが欲しい方はこちらから取得してください。 https://github.com/wdkk/ShigeFuji-SwiftUI-swiftpm

2023-03-09 · 2023-03-30

SwiftUI 3-1-1. 変更可能なデータを準備する

この節では2-5で作成したリストのプログラムをベースに, Appのデータを後から変更できるようにします. まず2-5までのコード作成が完了した状態をつくります. SFSwiftUI03-1.swiftpm を開く (サンプルコード) 2-5を完了させるとできあがるコードとほぼ同様のものとなる ContentView : リスト画面 MyApp : 起動時の処理 PhotoData : 写真データ構造体 SceneryDetail : 写真データの詳細画面 SceneryRow : 写真リストのビュー ただし簡単のため, FoodAndDrink関連のデータと画面は除いている コードの詳細は2-5-1を参考にしてください. 実行すると次のような画面の動きになります. 起動したとき リスト項目を押して画面遷移 今回は, このコードをスタートにまずデータを変更できるように変更します. ContentViewを開き, var photos を @State var photos に変更する ForEachに使うデータをphotosから$photosに変更する 繰り返しで得られるデータがBinding型になる. 変数名も bind_photo にしてわかりやすくする SceneryDetailにbind_photoを渡す SceneryRowにbind_photoを直接渡せないため, bind_photo.wrappedValue を指定する. Bindingで包んだ中身(PhotoData型)を取り出せる コード1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import SwiftUI struct ContentView: View { @State var photos:[PhotoData] = [ PhotoData( type:"景色", imageName:"CC0_01", title:"景色1", message:"森と山です" ), PhotoData( type:"景色", imageName:"CC0_04", title:"景色2", message:"きれいな湖です" ), PhotoData( type:"景色", imageName:"CC0_06", title:"景色3", message:"フィレンツェです" ), PhotoData( type:"景色", imageName:"CC0_07", title:"景色4", message:"ひまわりです" ), PhotoData( type:"景色", imageName:"CC0_10", title:"景色5", message:"海に日が沈みます" ) ] var body: some View { List { Section( "景色写真" ) { ForEach( $photos ) { bind_photo in NavigationLink( destination:{ SceneryDetail( data:bind_photo ) }, label: { SceneryRow( data:bind_photo....

2023-03-09 · 2024-06-06

SwiftUI 2-5-1. リストとNavigationの連携

前節ではデータとViewを独立させ, 繰り返し処理(Foreach)を使ってデータの数の分だけリストを作ることを行いました。データは 構造体 でわかりやすく整理した上で配列に必要な分だけデータを追加することができるようになりました。今節では前節のデータ構造を用いながら,2-1節で触れた画面遷移を連携させていきます。 SFSwiftUI02-5.swiftpm を開く (サンプルコード) 中身が2-4を終えた段階と同じであることを確認する MyApp.swiftを開き, NavigationStack を追加, ContentViewを包む コード1 1 2 3 4 5 6 7 8 9 10 11 12 13 import SwiftUI @main struct MyApp: App { var body: some Scene { WindowGroup { NavigationStack { ContentView() .preferredColorScheme( .light ) } } } } 次にContentViewのナビゲーション設定を行います。 ContentView.swiftを開き, Listに .navigationTitle を追加する コード2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 import SwiftUI struct ContentView: View { var photos:[PhotoData] = [ PhotoData( type:"景色", imageName:"CC0_01", title:"景色1", message:"森と山です" ), PhotoData( type:"景色", imageName:"CC0_04", title:"景色2", message:"きれいな湖です" ), PhotoData( type:"景色", imageName:"CC0_06", title:"景色3", message:"フィレンツェです" ), PhotoData( type:"景色", imageName:"CC0_07", title:"景色4", message:"ひまわりです" ), PhotoData( type:"景色", imageName:"CC0_10", title:"景色5", message:"海に日が沈みます" ), PhotoData( type:"食べ物", imageName:"CC0_05", title: "ハンバーガーセット", message: "おいしいです" ), PhotoData( type:"食べ物", imageName:"CC0_08", title: "カフェラテ", message: "おちつきます" ), PhotoData( type:"食べ物", imageName:"CC0_09", title: "ケーキ", message: "あまいです" ), PhotoData( type:"食べ物", imageName:"CC0_12", title: "お酒", message: "酔います" ) ] var body: some View { List { Section( "景色写真" ) { ForEach( photos....

2023-01-22 · 2024-07-28