SwiftUI - リストとページとJSON
1. はじめに
リストはListの使い方についてという記事にまとめたので、ここでは、JSONデータでリストと詳細ページを出力する方法をまとめておこうと思います。リストと詳細ページはコンポーネント化もしているのではじめに作成するファイルと役割を整理しておこうと思います。
- RowView.swift - リストの1行を設定するファイル
- DetailView.swift - 詳細ページを設定するファイル
- ModelData.swift - JSONファイルを変換するためのファイル(SwiftUIチュートリアルのコードを使用しています)
- DataType.swift - JSONファイルの型を設定するファイル
- ContentData.json - 出力する内容を書くJSONファイル
- ContentView.swift - リストと詳細ページをまとめて出力するファイル(SwiftUIのプロジェクト開始時に作成される)
2. JSONデータと変換
まずは、ContentData.json
というファイルを作成して下記を記述してプロジェクトに追加しておきます。メニューの「File > Add Files to ...」から追加できます。
[
{
"id": 1,
"title": "title1",
"content": "content1"
},
{
"id": 2,
"title": "title2",
"content": "content2"
},
{
"id": 3,
"title": "title3",
"content": "content3"
}
]
次にDataType.swift
というファイルを作成しJSONファイルの内容にあわせて型を定義します。
import Foundation
struct DataType: Codable {
var id: Int
var title: String
var content: String
}
Codable
- JSON などの外部表現をエンコード、デコードできる型
ModelData.swift
というファイルを作成し下記を記述します。このファイルでJSONデータの読み込みと変換をします。このコードはSwiftUIチュートリアルのstep10にあります。
import Foundation
var allData: [DataType] = load("ContentData.json")
func load<T: Decodable>(_ filename: String) -> T {
let data: Data
guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
else {
fatalError("Couldn't find \(filename) in main bundle.")
}
do {
data = try Data(contentsOf: file)
} catch {
fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
}
do {
let decoder = JSONDecoder()
return try decoder.decode(T.self, from: data)
} catch {
fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
}
}
guard let 条件 else {...}
- nilのチェックをしてアンラップ
Bundle.main.url(forResource: ファイル名, withExtension: 拡張子)
- プロジェクト内のファイル名までのURLを取得
Data(contentsOf: url)
- データオブジェクトの初期化
JSONDecoder()
- JSONオブジェクトからデータ型のインスタンスをデコード
3. 各コンポーネントを作成
RowView.swift
ファイルを作成します。このファイルでリストの1行に表示させるものを設定します。
import SwiftUI
struct RowView: View {
var data: DataType
var body: some View {
Text(data.title)
}
}
struct RowView_Previews: PreviewProvider {
static var previews: some View {
RowView(data: allData[0])
}
}
DetailView.swift
ファイルを作成します。このファイルで詳細ページに表示させるものを設定します。
import SwiftUI
struct DetailView: View {
var data: DataType
var body: some View {
VStack {
Text(data.content)
}
.navigationTitle(Text(verbatim: data.title))
.navigationBarTitleDisplayMode(.inline)
}
}
struct DetailView_Previews: PreviewProvider {
static var previews: some View {
DetailView(data: allData[0])
}
}
4. まとめて出力
ContentView.swift
に上記で作成したものを出力する設定を記述します。これでGif画像のようなものが出力させると思います。
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
List(allData, id: \.id) { item in
NavigationLink(destination: DetailView(data: item)) {
RowView(data: item)
}
}
.navigationTitle("List")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
NavigationLink(destination: リンク先)
- ナビゲーションリンクを作成
続きの記事>> リストとお気に入りとフィルター