下記のように簡単なアイテムリストを作成してAppStorageに対する理解を深めましょう。
AppleやOrangeはアプリを再起動しても消えません。
コードは以下の通りです。
import SwiftUI
struct ContentView: View {
// AppStorageで保存するためのキー
let arrayKey = "savedArray"
// 保存されたJSONデータを読み込む
@AppStorage("savedArray") var savedArrayData: Data?
// データを配列に復元する
var savedArray: [String] {
if let data = savedArrayData,
let decodedArray = try? JSONDecoder().decode([String].self, from: data) {
return decodedArray
}
return []
}
// 新しい要素を追加するためのテキストフィールドで入力された値
@State private var newItem: String = ""
var body: some View {
VStack {
// テキストフィールドと追加ボタン
TextField("Add new item", text: $newItem)
.padding()
Button("Add") {
// 新しいアイテムを配列に追加
var arrayToSave = savedArray
arrayToSave.append(newItem)
// 配列をJSONデータに変換して保存
if let encodedData = try? JSONEncoder().encode(arrayToSave) {
UserDefaults.standard.set(encodedData, forKey: arrayKey)
}
// テキストフィールドをクリア
newItem = ""
}
// 保存されたアイテムの一覧を表示
List(savedArray, id: \.self) { item in
Text(item)
}
.padding()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
続いて、商品名と価格を保存できるようにしましょう。
このようなイメージです。
コードは以下の通りです。
import SwiftUI
struct Product: Codable, Identifiable {
var id = UUID() // 一意の識別子を提供
let name: String
let price: Int
}
struct ContentView: View {
// AppStorageで保存するためのキー
let arrayKey = "savedProducts"
// 保存された商品リストを読み込む
@AppStorage("savedProducts") var savedProductsData: Data?
// データを商品リストに復元する
var savedProducts: [Product] {
if let data = savedProductsData,
let decodedProducts = try? JSONDecoder().decode([Product].self, from: data) {
return decodedProducts
}
return []
}
// 新しい商品を追加するためのテキストフィールドで入力された値
@State private var newName: String = ""
@State private var newPrice: String = ""
var body: some View {
VStack {
// 商品名と価格を入力するテキストフィールド
HStack {
TextField("Product Name", text: $newName)
.padding()
TextField("Price", text: $newPrice)
.padding()
.keyboardType(.numberPad)
}
// 追加ボタン
Button("Add Product") {
if let price = Int(newPrice) {
let newProduct = Product(name: newName, price: price)
var productsToSave = savedProducts
productsToSave.append(newProduct)
// 配列をJSONデータに変換して保存
if let encodedData = try? JSONEncoder().encode(productsToSave) {
UserDefaults.standard.set(encodedData, forKey: arrayKey)
}
// テキストフィールドをクリア
newName = ""
newPrice = ""
}
}
.padding()
// 保存された商品の一覧を表示
List(savedProducts) { product in
VStack(alignment: .leading) {
Text(product.name)
Text("$\(product.price)")
.foregroundColor(.gray)
}
}
.padding()
Spacer()
}
.padding()
}
}
#Preview {
ContentView()
}
続いて、データを削除する機能を持たせてみましょう。
コードは以下の通りです。
import SwiftUI
struct Product: Codable, Identifiable {
var id = UUID()
let name: String
let price: Int
}
struct ContentView: View {
private let arrayKey = "savedProducts"
@State private var savedProducts: [Product] = []
@State private var newName: String = ""
@State private var newPrice: String = ""
init() {
_savedProducts = State(initialValue: loadProducts())
}
var body: some View {
VStack {
HStack {
TextField("Product Name", text: $newName)
.padding()
TextField("Price", text: $newPrice)
.padding()
.keyboardType(.numberPad)
}
Button("Add Product") {
addProduct()
}
.padding()
List {
ForEach(savedProducts) { product in
VStack(alignment: .leading) {
Text(product.name)
Text("$\(product.price)")
.foregroundColor(.gray)
}
}
.onDelete(perform: deleteProduct)
}
.padding()
Spacer()
}
.padding()
}
private func loadProducts() -> [Product] {
if let data = UserDefaults.standard.data(forKey: arrayKey),
let products = try? JSONDecoder().decode([Product].self, from: data) {
return products
}
return []
}
private func addProduct() {
if let price = Int(newPrice) {
let newProduct = Product(name: newName, price: price)
savedProducts.append(newProduct)
saveProducts()
newName = ""
newPrice = ""
}
}
private func deleteProduct(at offsets: IndexSet) {
savedProducts.remove(atOffsets: offsets)
saveProducts()
}
private func saveProducts() {
if let encodedData = try? JSONEncoder().encode(savedProducts) {
UserDefaults.standard.set(encodedData, forKey: arrayKey)
}
}
}
#Preview {
ContentView()
}
コメント