NSUserDefaultsとは何か、UserDefaults APIとiOS設定の操作

著者: IT Sectr 公開日: 2026-03-12 読了時間: 10 分

NSUserDefaultsは、iOS、watchOS、tvOS、macOSにおけるキー-バリューデータストレージであり、アプリケーションの設定や構成を保存するために設計されています。データはアプリケーションのサンドボックス内のplistファイルに保存され、NSUbiquitousKeyValueStoreを介して自動的にiCloudと同期されます。公式ドキュメントによるとApple Developer、2025NSUserDefaultsはプリミティブ型の保存をサポートしています:String、Int、Bool、Float、Double、Data、Date、Array、Dictionary。このクラスはSwift 3以降UserDefaultsに名称変更されましたが、Objective-Cでの名前NSUserDefaultsはコードベースやAppleのドキュメントで広く使用され続けています。

重要ポイント

  • NSUserDefaultsはiOSおよびmacOS上のキー-バリューストレージで、plistファイルに簡単なアプリケーション設定を保存します。
  • 9つのデータ型をサポート:String、Int、Bool、Float、Double、Data、Date、Array、Dictionary。
  • データはデベロッパーのサポートによりNSUbiquitousKeyValueStoreを介してiCloudと自動的に同期されます。
  • ドメインの連鎖に沿ったカスケード値検索を行うドメインシステムを使用します。
  • 機密データの保存には、AppleはNSUserDefaultsではなくKeychainの使用を推奨しています。

NSUserDefaultsとは?

NSUserDefaults(SwiftではUserDefaults)は、plist形式でキー-バリューペアを保存するためのAppleの組み込みメカニズムです。iOS、iPadOS、watchOS、tvOS、macOSのすべてのAppleプラットフォームで利用できます。主な目的は、ユーザー設定、インターフェースの状態、初回起動フラグ、選択オプション、その他のアプリケーション再起動後も持続する単純なデータを保存することです。

各iOSアプリケーションには隔離されたサンドボックスがあり、NSUserDefaultsはこのサンドボックス内のLibrary/PreferencesディレクトリにBundle Identifierという名前のファイルで保存されます。plistファイルにはキーと値のペアが含まれ、キーは文字列、値はサポートされている型のいずれかです。ファイルサイズに制限はありませんが、AppleはUserDefaultsには設定のみを保存し、大量のデータは保存しないことを推奨しています。

iOS 8以降、NSUserDefaultsはApp Groupsをサポートし始めました。これは同じデベロッパーのアプリケーションとその拡張機能(ウィジェット、watchOSコンパニオンアプリ)間の共有ストレージです。これにはApp Group識別子を持つinit?(suiteName:)イニシャライザを使用します。これにより、例えばTodayウィジェットが保存ロジックを複製することなくメインアプリケーションから設定を読み取ることができます。

ストレージ形式:デバイス上のplist

物理的には、NSUserDefaultsはバイナリplistファイルに保存されます:{Sandbox}/Library/Preferences/com.example.myapp.plist。ファイルはコンパクトさと読み取り速度のためにバイナリplist形式(NSPropertyListBinaryFormat_v1_0)を使用しています。macOSでは、互換性のためにファイルがXML形式の場合もあります。AndroidのSharedPreferencesとは異なり、UserDefaultsのplistファイルはDictionaryとArrayを介してネストされた構造を含むことができます。

NSUserDefaultsファイルはデフォルトでは暗号化されていません。データは平文で保存され、デバイスへの物理アクセスやバックアップを介して読み取られる可能性があります。機密データ(パスワード、トークン、暗号化キー)を保存するには、Appleはオペレーティングシステムレベルで自動的にデータを暗号化するKeychainの使用を強く推奨しています。

iOSでのNSUserDefaultsの仕組み

NSUserDefaultsは、メモリキャッシュと定期的なディスク同期の原則で動作します。標準のUserDefaults.standardインスタンスへの最初のアクセス時に、システムはplistファイルをDictionaryとしてRAMにロードします。後続のすべての読み取りはメモリから実行されます。書き込みも最初にメモリで行われ、ディスクへの同期はバックグラウンドスレッドで定期的に行われます。

書き込み操作はset(_:forKey:)メソッドを使用します。このメソッドはオプショナルなAny?型の値を受け入れます。値はnilにすることもできます。これはキーを削除するために使用されます。以前は即時ディスク書き込みのためにsynchronize()メソッドが使用されていましたが、iOS 7およびOS X 10.9以降は不要になりました。システムが定期的に自動でデータを同期します。Appleは公式ドキュメントでsynchronize()を冗長であると宣言しています。

UserDefaultsのレジスタとドメイン

NSUserDefaultsは値の検索を整理するためにレジスタ(ドメイン)システムを使用します。アプリケーションがキーによって値を要求すると、UserDefaultsは特定の順序でドメインを順次チェックします:最初にNSArgumentDomain(コマンドライン引数)、次にアプリケーションドメイン、次にNSGlobalDomain(システム設定)、次に言語固有のドメイン、最後にNSRegistrationDomain(register(defaults:)を介して登録されたデフォルト値)。

swift
import Foundation

// UserDefaultsの標準インスタンス
let defaults = UserDefaults.standard

// 値の書き込み
defaults.set("アンナ・ペトロワ", forKey: "username")
defaults.set(28, forKey: "age")
defaults.set(true, forKey: "isLoggedIn")

// デフォルト値の登録
defaults.register(defaults: [
    "theme": "system",
    "fontSize": 14
])

// デフォルト値の戻り値を伴う読み取り
let theme = defaults.string(forKey: "theme") ?? "system"
let fontSize = defaults.integer(forKey: "fontSize")

NSRegistrationDomainはプログラム上のドメインであり、メモリにのみ存在し、ディスクには保存されません。アプリケーションがアプリケーションドメインに独自の値を書き込むまで適用されるデフォルト値を設定するために使用されます。これにより、開発中に集中管理できるデフォルト設定の単一構成ポイントを作成できます。

NSUserDefaultsの主要メソッド

NSUserDefaultsはデータの読み書きのための型付きメソッドのセットを提供します:string(forKey:)、integer(forKey:)、bool(forKey:)、float(forKey:)、double(forKey:)、data(forKey:)、array(forKey:)、dictionary(forKey:)、object(forKey:)。各読み取りメソッドには、保存される値の自動型推論を行う対応する書き込みメソッドset(_:forKey:)があります。UserDefaultsのSwiftバージョンは強い型付けを使用しますが、Objective-Cバージョンはidを受け入れ、返します。

読み取りメソッド (Swift)データ型デフォルト値
string(forKey:)String?nil
integer(forKey:)Int0
bool(forKey:)Boolfalse
float(forKey:)Float0.0
double(forKey:)Double0.0
data(forKey:)Data?nil

synchronizeとその関連性

NSUserDefaultsのsynchronize()メソッドは、すべての変更をメモリからディスクに強制的に書き込みます。初期のiOSバージョンでは、データの永続性を保証するために毎回の書き込み後にこのメソッドを呼び出す必要がありました。iOS 7以降、システムはバックグラウンドスレッドで自動的にUserDefaultsを同期し、Appleは公式にsynchronize()を冗長と宣言しました。このメソッドを呼び出してもエラーにはなりませんが、追加の永続性の保証はありません。

変更を監視するために、NSUserDefaultsUserDefaults.didChangeNotification通知とKVO観察メソッドaddObserver(_:forKeyPath:options:context:)を提供します。SwiftUIでは、@AppStorageプロパティラッパーが利用可能で、UserDefaultsの値をUIの更新と自動的に同期します。@AppStorageはUserDefaultsと同じ型をサポートし、SwiftUIアプリケーションで設定を操作するための推奨方法です。

swift
// KVOによる変更の監視
class SettingsViewModel: NSObject {
    override func observeValue(
        forKeyPath keyPath: String?,
        of object: Any?,
        change: [NSKeyValueChangeKey: Any]?,
        context: UnsafeMutableRawPointer?
    ) {
        guard let keyPath else { return }
        print("キーが変更されました:\(keyPath)")
    }
}

// SwiftUI - AppStorage
struct SettingsView: View {
    @AppStorage("theme") private var theme: String = "system"

    var body: some View {
        Picker("テーマ", selection: $theme) {
            Text("システム").tag("system")
            Text("ライト").tag("light")
            Text("ダーク").tag("dark")
        }
    }
}

App Groups(アプリケーションとその拡張機能間の共有ストレージ)で作業するには、App Group識別子を持つUserDefaults(suiteName:)イニシャライザを使用します。例:“group.com.example.myapp”。このインスタンスに書き込まれたデータは、メインアプリケーション、ウィジェット、watchOSコンパニオンアプリ、および同じApp Groupに属する他の拡張機能からアクセス可能です。各suiteインスタンスは個別のplistファイルに保存されます。

NSUserDefaults vs ストレージの代替手段

その便利さとシンプルさにもかかわらず、NSUserDefaultsはiOS上のすべてのデータタイプに対するユニバーサルなストレージソリューションではありません。ボリューム、重要度、セキュリティ要件に応じて、Appleはそれぞれ特定のユースケースに最適化された複数の代替手段を提供しています。

ソリューション使用すべき場合制限事項
NSUserDefaultsインターフェース設定と構成大規模データや機密情報には不適切
Keychainパスワード、トークン、暗号化キー使用が複雑、低速
CoreDataリレーションシップを持つ構造化データ10–20の設定には過剰
FileManagerドキュメント、画像、バイナリデータ手動ファイル管理が必要
CloudKitデバイス間のクラウド同期iCloudアカウントとネットワーク接続が必要

Keychain — 安全なストレージ

Keychainは機密データのためのAppleの安全なストレージです。NSUserDefaultsとは異なり、Keychain内のすべてのデータは、対応するデバイスではSecure Enclaveからのハードウェア暗号化を使用してオペレーティングシステムレベルで暗号化されます。Keychainはデバイスとともに自動的にロックおよびロック解除され、Keychain Access Groupsを介して同じデベロッパーのアプリケーション間でのアクセス共有をサポートします。

Keychainの主な欠点はAPIの複雑さです。単に文字列を保存するだけでも、クラス(kSecClassGenericPassword)、サービス(kSecAttrService)、アカウント(kSecAttrAccount)、実際のデータ(kSecValueData)の属性を指定してSecItemAddクエリを作成する必要があります。Keychainの操作を簡素化するために、KeychainAccessやSwiftKeychainWrapperなどのサードパーティラッパーが存在し、UserDefaultsと同様の便利なキー-バリューインターフェースを提供しています。

SwiftでのNSUserDefaults使用例

実用的な例を考えてみましょう。NSUserDefaultsを使用してiOSアプリケーションでオンボーディング状態(ウェルカム画面)を保存および復元します。初回起動時にユーザーはオンボーディング画面を表示し、完了後にUserDefaultsにフラグが保存されます。以降の起動ではオンボーディングはスキップされます。SwiftUIでは@AppStorageが使用され、UIKitではUserDefaults.standardへの直接アクセスが使用されます。

オンボーディング状態の保存

オンボーディングステータスを保存するためにUserDefaultsとの連携をカプセル化するOnboardingManagerを作成しましょう。マネージャーは状態を確認するためのisOnboardingCompletedプロパティとフラグを設定するmarkOnboardingCompletedメソッドを提供します。タイプミスを防ぐためにストレージキーは定数に抽出されています。ユニットテストのために、マネージャーはUserDefaultsProtocolを使用し、実際のストレージをMockUserDefaultsに置き換えることができます。

swift
class OnboardingManager {
    private let defaults: UserDefaults
    private let hasSeenKey = "has_seen_onboarding"

    init(defaults: UserDefaults = .standard) {
        self.defaults = defaults
    }

    var isOnboardingCompleted: Bool {
        defaults.bool(forKey: hasSeenKey)
    }

    func markOnboardingCompleted() {
        defaults.set(true, forKey: hasSeenKey)
    }

    func resetOnboarding() {
        defaults.removeObject(forKey: hasSeenKey)
    }
}

// アプリケーションでの使用
let onboardingManager = OnboardingManager()
if !onboardingManager.isOnboardingCompleted {
    showOnboarding()
} else {
    showMainScreen()
}

構造化されたProfileオブジェクトなど、より複雑な設定を保存するには、CodableプロトコルとJSONEncoder/JSONDecoderの使用をお勧めします。オブジェクトはJSONEncoderを介してDataにシリアライズされ、set(_:forKey:)を介して保存され、読み取り時にJSONDecoderを介してDataからオブジェクトにデシリアライズされます。このアプローチにより、型安全性を失うことなくUserDefaultsに複雑な構造を保存できます。

swift
struct UserProfile: Codable {
    let name: String
    let age: Int
    let preferences: [String: String]
}

extension UserDefaults {
    func save<T: Codable>(_ value: T, forKey key: String) {
        if let data = try? JSONEncoder().encode(value) {
            set(data, forKey: key)
        }
    }

    func load<T: Codable>(_ type: T.Type, forKey key: String) -> T? {
        guard let data = data(forKey: key) else { return nil }
        return try? JSONDecoder().decode(type, from: data)
    }
}

// 使用
let profile = UserProfile(name: "アンナ", age: 28, preferences: ["theme": "dark"])
UserDefaults.standard.save(profile, forKey: "user_profile")
let loaded = UserDefaults.standard.load(UserProfile.self, forKey: "user_profile")

NSUserDefaultsは大量のデータを保存するように設計されていないことを覚えておくことが重要です。Appleは保存するデータを数十キロバイト程度に制限することを推奨しています。大きなオブジェクト(画像、ドキュメント、シリアライズされたモデル)を保存するには、Documentsディレクトリを持つFileManagerまたはCoreDataを使用してください。さらに、UserDefaultsはデータスキーマのバージョニングをサポートしていません。Codableモデルの構造が変更されると、古いデータがデシリアライズに失敗する可能性があり、これはアプリケーションコードで処理する必要があります。

よくある質問

NSUserDefaultsはAndroidのSharedPreferencesとどう違いますか?

どちらもキー-バリューストアですが、NSUserDefaultsはより多くの型(Data、Date、Array、Dictionary)をサポートし、自動的にiCloudと同期します。SharedPreferencesはデータをXMLに保存し、NSUserDefaultsはplist形式を使用します。NSUserDefaultsにはカスケード検索を持つドメインシステムがありますが、SharedPreferencesはファイル名を持つ単純なフラット構造を使用します。

NSUserDefaultsにパスワードを保存しても安全ですか?

いいえ、NSUserDefaultsはデータを暗号化なしで平文で保存します。パスワード、トークン、暗号化キーには、Secure Enclaveレベルでデータを暗号化するKeychainを使用してください。Keychainは秘密を読み取る前に生体認証(Face ID / Touch ID)などのアクセス属性もサポートしています。

デバイス間でNSUserDefaultsを同期するには?

同じユーザーのデバイス間での同期には、NSUbiquitousKeyValueStore—iCloudクラウドキー-バリューストレージを使用します。あるデバイスでこのサービスに書き込まれたデータは、同じiCloudアカウントを持つ他のすべてのデバイスに自動的に表示されます。最大容量:アプリケーションあたり1 MB、1024キー。

NSUserDefaultsからすべてのデータを削除するには?

すべてのデータを削除するには、アプリケーションのBundle Identifierを指定してremovePersistentDomain(forName:)メソッドを呼び出します。個別の値を削除するにはremoveObject(forKey:)を使用します。完全な設定リセット:UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!)。すべての削除は即座にインメモリキャッシュに適用されます。

NSUserDefaultsの最大データサイズは?

AppleはNSUserDefaultsのサイズに厳格な制限を設けていませんが、保存する全データの総量は100 KBを超えないことが推奨されています。より大容量の場合はCoreDataまたはFileManagerを使用してください。1 MBを超えるデータを保存すると、アプリケーション起動時の読み取りパフォーマンスが著しく低下する可能性があります。

まとめ

  • NSUserDefaultsは、plist形式で簡単なアプリケーション設定を保存するためのAppleの組み込みキー-バリューストレージです。
  • 9つのデータ型をサポート:String、Int、Bool、Float、Double、Data、Date、Array、Dictionary。
  • NSRegistrationDomain、NSGlobalDomain、アプリケーションドメインを通じたカスケード検索を持つドメインシステムを使用します。
  • Appleデバイス間の同期には、Appleはアプリケーションあたり1 MBの制限があるNSUbiquitousKeyValueStoreを提供しています。
  • セキュリティのために、パスワードやトークンにはNSUserDefaultsではなくKeychainを使用してください。
  • SwiftUIでは、自動UI同期を行う@AppStorageプロパティラッパーが推奨方法です。
  • 大規模または構造化データには、NSUserDefaultsの代わりにCoreDataまたはFileManagerを選択してください。

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください