今回作成するアプリ

ColorPickerを使用し選択したColorをUserDefaultsに保存するにはどうすればいいでしょうか?

実はUserDefaultsが対応している型が限られており(Data、String、Number(Int、Float、Double)、Date、Array、Dictionary、Boolなど)、Color は保存できる型ではありません。

つまり、文字列や数値のように以下のような構文で単純に保存することはできません。

UserDefaults.standard.set(username, forKey: "username")

今回は、その非対応のColor型をUserDefaultsに保存し永続化する方法をご紹介します。

実装

コード

import SwiftUI

class ColorData {
    private var COLOR_KEY = "COLOR_KEY"
    private let userDefaults = UserDefaults.standard
    
    func saveColor(color: Color) {
        // Convert the color into RGB
        let color = UIColor(color).cgColor
        
        // Save the RGB into an array
        if let components = color.components {
            userDefaults.set(components, forKey: COLOR_KEY)
            
            print("Colour saved!")
        }
    }
    
    func loadColor() -> Color{
        // Get the RGB array
        guard let array = userDefaults.object(forKey: COLOR_KEY) as? [CGFloat] else { return Color.black }
        
        // Create a color from the RGB array
        let color = Color(.sRGB,
                          red: array[0],
                          green: array[1],
                          blue: array[2],
                          opacity: array[3])
        
        print("Colour loaded!")
        return color
    }
}

struct ContentView: View {
    @State private var color: Color = Color.black
    private var colorData = ColorData()
    
    var body: some View {
        VStack(spacing: 10) {
            
            ColorPicker("Pick a color:", selection: $color)
            
            Rectangle()
                .frame(height: 200)
                .foregroundColor(color)
                .cornerRadius(20)
                .padding()
            
            Button("Save colour") {
                colorData.saveColor(color: color)
            }
            Spacer()
        }
        .onAppear {
            color = colorData.loadColor()
        }
        .padding()
    }
}

解説

RGBに変換し、それを配列に格納することで保存します。

取り出すときは、配列にそれぞれ格納されたRGBから再生させ、Color型に変換します。

“Save colour”のボタンを押すことでsaveColor()が発動しColorが保存されます。

また、.onAppearによってViewが表示された際にloadColor()が発動するので、再度アプリを開くと自動的に保存した色が反映されています。

動作

参考文献

環境

macOS Ventura 13.0.1

Xcode 14.2

iOS 16.2

Simulater iPhone 14 Pro Max

アイキャッチ画像 出典: App.com