SwiftでAppStorageを使用してデータを保存する方法

下記のように簡単なアイテムリストを作成してAppStorageに対する理解を深めましょう。

AppleやOrangeはアプリを再起動しても消えません。

コードは以下の通りです。

続いて、商品名と価格を保存できるようにしましょう。

このようなイメージです。

コードは以下の通りです。

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()
}
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

目次