0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SwiftでUserDefaultsを管理する方法

Last updated at Posted at 2025-03-10

SwiftでUserDefaultsを簡単&安全に管理する方法

はじめに

iOSアプリ開発では、UserDefaults を使用してユーザー設定やアプリの状態を保存することが一般的です。

余談ですが、UserDefaultsの情報は.plistという拡張子をもったファイルに保存されます。実際に plistに保存されるのはこんな感じのXMLデータになります。

<plist version="1.0">
<dict>
    <key>isDarkMode</key>
    <true/>
    <key>username</key>
    <string>zkpn</string>
</dict>
</plist>

UserDefaultsの基本的な使い方

まず、UserDefaultsの基本的な操作方法をおさらいします。

let defaults = UserDefaults.standard

// 値を保存
defaults.set(true, forKey: "isDarkMode")

// 値を取得
let isDarkMode = defaults.bool(forKey: "isDarkMode")

// 値を削除
defaults.removeObject(forKey: "isDarkMode")

この方法でも十分動作しますが、キーのハードコーディングや型安全性の欠如 が問題となります。


プロパティラッパーを使ってUserDefaultsを簡単に扱う

Swiftの PropertyWrapper を利用すると、UserDefaultsの操作を簡潔に記述できます。プロパティラッパーについては公式がわかりやすいので興味ある方はぜひ。

UserDefault プロパティラッパーの作成

@propertyWrapper
struct UserDefault<T> {
    private let key: String
    private let defaultValue: T
    private let storage: UserDefaults
    
    init(_ key: String, defaultValue: T, storage: UserDefaults = .standard) {
        self.key = key
        self.defaultValue = defaultValue
        self.storage = storage
    }
    
    var wrappedValue: T {
        get {
            storage.object(forKey: key) as? T ?? defaultValue
        }
        set {
            storage.set(newValue, forKey: key)
        }
    }
}

この @UserDefault を利用すれば、UserDefaultsの値を簡潔に管理できます。

使用例

class AppSettings {
    @UserDefault("isDarkMode", defaultValue: false)
    static var isDarkMode: Bool

    @UserDefault("username", defaultValue: "")
    static var username: String
}
// 値を設定
AppSettings.isDarkMode = true
AppSettings.username = "zkpn"

// 値を取得
print(AppSettings.isDarkMode) // true
print(AppSettings.username)   // "zkpn"

この方法を使うと、UserDefaultsのキー管理を簡略化し、型安全にアクセスできるようになります。


UserDefaultsの管理をプロトコルで統一する

プロトコルを利用すると、UserDefaultsの管理を統一的に行う ことができます。

UserDefaultsStorageProtocol の定義

protocol UserDefaultsStorageProtocol {
    var isDarkMode: Bool { get set }
    var username: String { get set }
}

UserDefaultsStorage の実装

final class UserDefaultsStorage: UserDefaultsStorageProtocol {
    @UserDefault("isDarkMode", defaultValue: false)
    var isDarkMode: Bool
    
    @UserDefault("username", defaultValue: "")
    var username: String
}

この方法を採用すると、

  • UserDefaultsのアクセスが統一される
  • UserDefaultsStorageProtocol に準拠することで、テスト時にモックデータと差し替え可能

といったメリットがあります。


UserDefaultsにCodableなデータを保存する

通常、UserDefaultsには String, Int, Bool などのプリミティブ型しか保存できません。しかし、Codable を活用すると、複雑なデータ構造も保存できます。

Codableを使った保存と取得

struct UserProfile: Codable {
    let name: String
    let age: Int
}

@propertyWrapper
struct CodableUserDefault<T: Codable> {
    private let key: String
    private let defaultValue: T
    private let storage: UserDefaults

    init(_ key: String, defaultValue: T, storage: UserDefaults = .standard) {
        self.key = key
        self.defaultValue = defaultValue
        self.storage = storage
    }

    var wrappedValue: T {
        get {
            if let data = storage.data(forKey: key),
               let value = try? JSONDecoder().decode(T.self, from: data) {
                return value
            }
            return defaultValue
        }
        set {
            if let data = try? JSONEncoder().encode(newValue) {
                storage.set(data, forKey: key)
            }
        }
    }
}

使用例

class UserManager {
    @CodableUserDefault("userProfile", defaultValue: UserProfile(name: "Guest", age: 0))
    static var userProfile: UserProfile
}
// データを保存
UserManager.userProfile = UserProfile(name: "zkpn", age: 30)

// データを取得
print(UserManager.userProfile.name) // "zkpn"
print(UserManager.userProfile.age)  // 30

これにより、Codable に準拠したデータを簡単にUserDefaultsに保存・取得できるようになります。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?