mcpField
S
swift-settingskit

swift-settingskit

github.com/secondskyデザイン・UI240122 回インストール5 週間前に更新
リポジトリ

swift-settingskit について

Swift SettingsKit は、Apple プラットフォームの SwiftUI アプリ向けに設定画面を構築する Swift パッケージです。設定項目を検索可能なグループに整理し、デバイスに応じてナビゲーションと表示形式を調整します。

主な機能

  1. 01設定グループとコントロール
  2. 02設定画面の検索機能
  3. 03サイドバーと単一列のスタイル
  4. 04階層化された設定構成
  5. 05@Observable モデルとのリアクティブなバインディング
  6. 06プラットフォームに応じた表示

活用シーン

  1. 01検索可能なアプリ設定画面の構築
  2. 02設定を入れ子のセクションに整理
  3. 03Apple デバイス間での設定表示
  4. 04機能フラグに応じた設定の表示

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/secondsky/claude-skills --skill swift-settingskit

インストール後、Claude Code で/swift-settingskitを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

assets/
basic-settings-template.swift
custom-style-template.swift
demo-app-template.swift
modular-settings-template.swift
references/
advanced-patterns.md
api-reference.md
performance-edge-cases.md
search-implementation.md
styling-guide.md

詳細

Swift SettingsKit

ステータス:本番環境で利用可能 ✅ 最終更新日:2025-11-23 依存関係:なし(スタンドアロンの Swift パッケージ) 最新バージョン:SettingsKit 1.0.0+

対応ツールチェーン

最小要件:

  • Swift:6.0+(@Observable マクロと SettingsKit のコンパイルに必要)
  • Xcode:16.0+(Swift 6.0 ツールチェーンを提供)
  • プラットフォーム:iOS 17.0+ / macOS 14.0+ / watchOS 10.0+ / tvOS 17.0+ / visionOS 1.0+

注:@Observable は Swift 5.9 で導入されましたが、SettingsKit の Package.swift では最小ツールチェーンバージョンとして Swift 6.0+ が指定されています。このスキルのすべての例は Swift 6.0+ を対象としています。


クイックスタート(5 分)

1. SettingsKit パッケージを追加する

Xcode から Swift パッケージをプロジェクトに追加します。

// File → Add Package Dependencies
// Enter: https://github.com/aeastr/SettingsKit.git
// Version: 1.0.0 or later

または Package.swift から追加します:

dependencies: [
    .package(url: "https://github.com/aeastr/SettingsKit.git", from: "1.0.0")
]

重要な理由:

  • SettingsKit の最新の SwiftUI 機能には iOS 17+ / macOS 14+ が必要です
  • @Observable マクロのサポートには Swift 6.0+ が必要です
  • フレームワークはすべての Apple プラットフォームに適応します
2. Observable な設定モデルを作成する
import SwiftUI
import SettingsKit

@Observable
class AppSettings {
    var notificationsEnabled = true
    var darkMode = false
    var username = "Guest"
    var fontSize: Double = 14.0
}

重要:

  • @Published や ObservableObject ではなく、@Observable マクロを使用してください
  • SettingsKit は Swift の最新のオブザベーションシステム向けに設計されています
  • 設定モデルはバインディングのために SwiftUI 環境に配置する必要があります
3. SettingsContainer プロトコルを実装する
struct MySettings: SettingsContainer {
    @Environment(AppSettings.self) var appSettings

    var settingsBody: some SettingsContent {
        @Bindable var settings = appSettings

        SettingsGroup("General", systemImage: "gear") {
            SettingsItem("Notifications") {
                Toggle("Enable", isOn: $settings.notificationsEnabled)
            }

            SettingsItem("Dark Mode") {
                Toggle("Enable", isOn: $settings.darkMode)
            }
        }

        SettingsGroup("Profile", systemImage: "person") {
            SettingsItem("Username") {
                TextField("Username", text: $settings.username)
            }

            SettingsItem("Font Size") {
                Slider(value: $settings.fontSize, in: 10...24)
                Text("\(Int(settings.fontSize))pt")
            }
        }
    }
}

重要:

  • @Observable モデルからバインディングを作成するには、@Bindable ラッパーを使用する必要があります
  • settingsBody は View ではなく SettingsContent を返します
  • サイドバースタイルでは、グループはナビゲーションリンク(タップ可能な行)として表示されます
4. アプリに追加する
import SwiftUI
import SettingsKit

@main
struct MyApp: App {
    @State private var settings = AppSettings()

    var body: some Scene {
        WindowGroup {
            MySettings()
                .environment(settings)
        }
    }
}

結果: 次の機能を備えた設定インターフェイスが完成します。

  • 自動ナビゲーション(iPad/Mac ではサイドバー、iPhone では単一カラム)
  • 組み込みの検索機能
  • プラットフォームに適応した表示
  • リアクティブな状態更新

4 ステップのセットアップ手順

ステップ 1:パッケージ依存関係をインストールする

Xcode の Swift Package Manager から SettingsKit を追加します。

  1. File → Add Package Dependencies
  2. リポジトリ URL を入力します:https://github.com/aeastr/SettingsKit.git
  3. 「1.0.0」から「Up to Next Major Version」を選択します
  4. アプリのターゲットに追加します

重要なポイント:

  • Swift 6.0 をサポートするには Xcode 16.0+ が必要です
  • パッケージにはすべてのプラットフォーム(iOS、macOS、watchOS、tvOS、visionOS)が含まれます
  • 追加の設定は不要です
ステップ 2:設定データモデルを定義する

設定の状態を保持する @Observable クラスを作成します。

import SwiftUI

@Observable
class AppSettings {
    // General settings
    var notificationsEnabled = true
    var soundEnabled = true
    var hapticFeedback = true

    // Appearance settings
    var darkMode = false
    var accentColor: Color = .blue
    var fontSize: Double = 16.0

    // User profile
    var username = ""
    var email = ""
    var profileImageURL: URL?
}

重要なポイント:

  • 最新のオブザベーションには @Observable マクロ(Swift 6.0+)を使用します
  • すべてのプロパティをデフォルト値で初期化します
  • 設定モデルはビューのロジックから分離します
  • 派生状態を表す計算プロパティを含めることができます
ステップ 3:設定階層を構築する

SettingsContainer プロトコルを実装して、設定 UI を定義します。

import SettingsKit

struct MySettings: SettingsContainer {
    @Environment(AppSettings.self) var appSettings

    var settingsBody: some SettingsContent {
        @Bindable var settings = appSettings

        // Navigation group (tappable row)
        SettingsGroup("General", systemImage: "gear") {
            SettingsItem("Notifications") {
                Toggle("Enable", isOn: $settings.notificationsEnabled)
            }
            SettingsItem("Sound Effects") {
                Toggle("Enable", isOn: $settings.soundEnabled)
            }
        }
        .settingsTags(["notifications", "sounds", "alerts"])

        // Inline group (section header)
        SettingsGroup("Quick Settings", .inline) {
            SettingsItem("Dark Mode") {
                Toggle("Enable", isOn: $settings.darkMode)
            }
        }

        // Nested navigation
        SettingsGroup("Profile", systemImage: "person") {
            SettingsGroup("Account", systemImage: "person.circle") {
                SettingsItem("Username") {
                    TextField("Username", text: $settings.username)
                }
                SettingsItem("Email") {
                    TextField("Email", text: $settings.email)
                }
            }
        }
    }
}

重要なポイント:

  • SettingsGroup はナビゲーションリンク(デフォルト)またはセクション見出し(.inline)を作成します
  • SettingsItem は個々のコントロールをラップします
  • 検索で見つけやすくするには .settingsTags([...]) を追加します
  • グループは階層を深くするために無制限にネストできます
ステップ 4:表示スタイルを設定する

設定の表示方法を選択します。

// Sidebar style (default) - Split view on iPad/Mac
MySettings(settings: settings)
    .settingsStyle(.sidebar)

// Single column style - Clean list on all platforms
MySettings(settings: settings)
    .settingsStyle(.single)

// Custom style - Full control over appearance
MySettings(settings: settings)
    .settingsStyle(MyCustomStyle())

重要なポイント:

  • .sidebar:選択ベースのナビゲーションを使用する NavigationSplitView(デフォルト)
  • .single:プッシュナビゲーションを使用する単一の NavigationStack
  • カスタムスタイルは SettingsStyle プロトコルに準拠します
  • プラットフォームはデバイスの状況に合わせて自動的に適応します

重要なルール

必ず行うこと

✅ 設定モデルには @Observable を使用する - SettingsKit のリアクティブシステムに必要です ✅ 環境内の設定を @Bindable でラップする - settingsBody での双方向バインディングを有効にします ✅ 重要なグループに検索可能なタグを追加する - .settingsTags([...]) によって見つけやすくなります ✅ 設定モデルを SwiftUI 環境に配置する - 親ビューで .environment(settings) を使用します ✅ すべてのインタラクティブなコントロールに SettingsItem を使用する - 適切な検索インデックスを確保します

絶対にしてはいけないこと

❌ ObservableObject と @Published は絶対に使用しないでください - SettingsKit では最新の @Observable が必要です ❌ @Bindable ラッパーなしでバインディングを作成しないでください - コンパイルエラーが発生します ❌ settingsBody に負荷の高い計算処理を記述しないでください - レンダリングのたびに計算されるため、軽量に保ってください ❌ 設定を環境に注入し忘れないでください - 実行時クラッシュの原因になります ❌ シンプルなコントロールに CustomSettingsGroup を使用しないでください - 不必要に検索インデックスを迂回します


既知の問題の防止

このスキルでは、ドキュメントに記載された5件の問題を防止します。

問題 #1:「型 'Binding' の値を、想定される引数の型 'Binding' に変換できません」

エラー: @Bindable ラッパーなしで @Observable プロパティにバインドしようとしたときに発生するコンパイルエラー 出典: Swift の並行処理移行ガイド、Observable マクロのドキュメント 発生する理由: @Published プロパティとは異なり、@Observable モデルでバインディングを作成するには @Bindable ラッパーが必要です 防止方法: バインディングを作成する前に、必ず settingsBody で @Bindable var settings = appSettings を使用してください

問題 #2: モデルが変更されても設定 UI が更新されない

エラー: トグルスイッチ、スライダー、テキストフィールドにモデルの変更が反映されません 出典: SettingsKit の GitHub イシュー、SwiftUI の監視システムに関するドキュメント 発生する理由: 設定モデルが SwiftUI 環境に正しく注入されておらず、監視が機能しなくなっています 防止方法: 親ビューで .environment(settings) を使用し、SettingsContainer で @Environment(AppSettings.self) を使用してください

問題 #3: サイドバースタイルでナビゲーション状態が競合する

エラー: 設定項目を選択しても移動しない、またはナビゲーションスタックが破損します 出典: SettingsKit のアーキテクチャドキュメント、NavigationSplitView のベストプラクティス 発生する理由: サイドバースタイルで SettingsGroup の代わりに NavigationLink を直接使用すると、状態が競合します 防止方法: ナビゲーションには必ず SettingsGroup を使用し(NavigationLink を直接使用しないでください)、SettingsKit にナビゲーション状態を管理させてください

問題 #4: カスタムグループが検索結果に表示されない

エラー: CustomSettingsGroup のコンテンツが検索機能で見つかりません 出典: SettingsKit の README —「カスタムグループはタイトル/アイコン/タグで検索できますが、コンテンツは要素のインデックス化なしでレンダリングされます」 発生する理由: CustomSettingsGroup は UI を完全に制御するために標準のインデックス化を迂回するため、検索対象になるのはメタデータのみです 防止方法: 検索可能なコンテンツには通常の SettingsGroup/SettingsItem を使用し、複雑なカスタム UI に限って CustomSettingsGroup を使用してください

問題 #5: macOS で「Nil coalescing」実行時エラーが発生して設定がクラッシュする

エラー: 遷移先ベースのナビゲーションの問題により、macOS で設定を開くとアプリがクラッシュします 出典: SettingsKit の macOS 固有の実装に関する注意事項 発生する理由: macOS ではコントロールの更新に関する問題を防ぐため、選択ベースではなく遷移先ベースの NavigationLink を使用しますが、ナビゲーション状態を適切に設定する必要があります 防止方法: SettingsKit にナビゲーションスタックを作成させてください。macOS では SettingsContainer を独自の NavigationStack でラップしないでください


設定ファイルのリファレンス

Package.swift(完全な例)
// swift-tools-version: 6.0
import PackageDescription

let package = Package(
    name: "MyApp",
    platforms: [
        .iOS(.v17),
        .macOS(.v14),
        .watchOS(.v10),
        .tvOS(.v17),
        .visionOS(.v1)
    ],
    products: [
        .executable(name: "MyApp", targets: ["MyApp"])
    ],
    dependencies: [
        .package(url: "https://github.com/aeastr/SettingsKit.git", from: "1.0.0")
    ],
    targets: [
        .executableTarget(
            name: "MyApp",
            dependencies: [
                .product(name: "SettingsKit", package: "SettingsKit")
            ]
        )
    ]
)

これらの設定を使用する理由:

  • プラットフォームのバージョンは SettingsKit の最小要件(iOS 17 以降など)に適合しています
  • @Observable マクロには Swift tools バージョン 6.0 以降が必要です
  • SettingsKit はセマンティックバージョニングを使用してパッケージ依存関係に追加されています

よく使われるパターン

パターン 1: モジュール化された設定グループ

複雑な設定セクションを別々の SettingsContent 型に分割すると、整理しやすくなります。

struct NotificationSettings: SettingsContent {
    @Bindable var settings: AppSettings

    var body: some SettingsContent {
        SettingsGroup("Notifications", systemImage: "bell") {
            SettingsItem("Enable Notifications") {
                Toggle("Enable", isOn: $settings.notificationsEnabled)
            }

            if settings.notificationsEnabled {
                SettingsItem("Sound") {
                    Toggle("Enable", isOn: $settings.soundEnabled)
                }
                SettingsItem("Badge") {
                    Toggle("Show badge", isOn: $settings.badgeEnabled)
                }
            }
        }
        .settingsTags(["notifications", "alerts", "sounds", "badges"])
    }
}

// Use in main settings:
var settingsBody: some SettingsContent {
    NotificationSettings(settings: settings)
    AppearanceSettings(settings: settings)
    PrivacySettings(settings: settings)
}

使用する場面: 5 つ以上のグループがある複雑な設定階層、条件付きコンテンツ、またはチームで別々のセクションを分担する場合

パターン 2: 検索可能なカスタム開発者ツール

CustomSettingsGroup を使うと、高度な UI を実現しながら検索可能な状態を保てます。

CustomSettingsGroup("Developer Tools", systemImage: "hammer") {
    VStack(spacing: 20) {
        GroupBox("Debug Information") {
            VStack(alignment: .leading, spacing: 8) {
                Text("App Version: 1.0.0")
                Text("Build: 42")
                Text("Environment: Production")
            }
            .frame(maxWidth: .infinity, alignment: .leading)
        }

        Button("Clear Cache") {
            clearCache()
        }
        .buttonStyle(.borderedProminent)

        Button("Export Logs", systemImage: "square.and.arrow.up") {
            exportLogs()
        }
    }
    .padding()
}
.settingsTags(["debug", "testing", "logs", "advanced"])

使用する場面: 標準の SettingsItem パターンに合わない複雑なカスタム UI で、タグから検索できる必要もある場合

パターン 3:条件付きの設定表示

機能フラグやユーザー権限に基づいて設定を表示/非表示にします。

SettingsGroup("Advanced", systemImage: "gearshape.2") {
    SettingsItem("Enable Advanced Features") {
        Toggle("Enable", isOn: $settings.showAdvanced)
    }

    if settings.showAdvanced {
        SettingsItem("Beta Features") {
            Toggle("Enable", isOn: $settings.betaFeaturesEnabled)
        }

        SettingsItem("Developer Mode") {
            Toggle("Enable", isOn: $settings.developerMode)
        }
    }

    if settings.developerMode {
        SettingsGroup("Developer Options", systemImage: "wrench.and.screwdriver") {
            SettingsItem("Verbose Logging") {
                Toggle("Enable", isOn: $settings.verboseLogging)
            }
        }
    }
}

使用する場面:機能フラグ、ユーザー権限レベル、複雑さの段階的な開示

パターン 4:すべてのコントロールタイプ

SettingsItem は、SwiftUI のすべての標準コントロールに対応しています。

SettingsGroup("All Controls", systemImage: "slider.horizontal.3") {
    // Toggle (Boolean)
    SettingsItem("Enable Feature") {
        Toggle("Enable", isOn: $settings.featureEnabled)
    }

    // Slider (Continuous value)
    SettingsItem("Volume") {
        VStack(alignment: .leading, spacing: 8) {
            Slider(value: $settings.volume, in: 0...100)
            Text("\(Int(settings.volume))%")
                .font(.caption)
                .foregroundStyle(.secondary)
        }
    }

    // TextField (Text input)
    SettingsItem("Username") {
        TextField("Enter username", text: $settings.username)
            .textFieldStyle(.roundedBorder)
    }

    // Picker (Selection)
    SettingsItem("Theme") {
        Picker("", selection: $settings.theme) {
            Text("Light").tag(Theme.light)
            Text("Dark").tag(Theme.dark)
            Text("Auto").tag(Theme.auto)
        }
        .pickerStyle(.segmented)
    }

    // Stepper (Increment/Decrement)
    SettingsItem("Font Size") {
        Stepper("\(Int(settings.fontSize)) pt", value: $settings.fontSize, in: 10...24)
    }

    // Button (Action)
    SettingsItem("Reset Settings") {
        Button("Reset") {
            resetSettings()
        }
        .buttonStyle(.borderedProminent)
        .tint(.red)
    }

    // ColorPicker (Color selection)
    SettingsItem("Accent Color") {
        ColorPicker("Choose color", selection: $settings.accentColor)
    }

    // DatePicker (Date/Time selection)
    SettingsItem("Reminder Time") {
        DatePicker("", selection: $settings.reminderTime, displayedComponents: .hourAndMinute)
    }
}

使用する場面:設定の構築時に利用できるコントロールを確認する場合


リファレンスを読み込むタイミング

特定のトピックについて詳細なドキュメントが必要な場合は、追加のリファレンスファイルを読み込みます。

  • references/api-reference.md を読み込む場合:SettingsContainer の高度なカスタマイズ、カスタム SettingsContent タイプを実装する場合、またはすべてのプロトコルとモディファイアの詳細な API ドキュメントが必要な場合

  • references/styling-guide.md を読み込む場合:設定の外観をカスタマイズする場合、カスタム SettingsStyle を実装する場合、またはプラットフォーム固有のスタイル設定のガイダンスが必要な場合

  • references/search-implementation.md を読み込む場合:カスタム検索ロジックを実装する場合、検索動作をデバッグする場合、または SettingsKit の検索アーキテクチャを理解する必要がある場合

  • references/advanced-patterns.md を読み込む場合:複雑な入れ子の階層を構築する場合、動的な設定を実装する場合、永続化に取り組む場合、または本番環境向けのアーキテクチャパターンが必要な場合

  • references/performance-edge-cases.md を読み込む場合:大規模な設定階層(グループ 100 個以上、アイテム 1000 個以上)を構築する場合、パフォーマンスの問題が発生した場合、またはストレステストのガイダンスや最適化戦略が必要な場合


同梱リソースの使用

スクリプト(scripts/)

スクリプトは含まれていません — SettingsKit は純粋な Swift パッケージであり、ビルドスクリプトは不要です。

リファレンス(references/)

高度なトピックに関する詳細なドキュメントファイル:

  • references/api-reference.md - SettingsKit のすべてのプロトコル、型、モディファイアに関する完全な API ドキュメント
  • references/styling-guide.md - 設定の外観のカスタマイズとプラットフォーム固有の動作に関する包括的なガイド
  • references/search-implementation.md - 検索アーキテクチャ、カスタム検索の実装、検索スコアリングの詳細な解説
  • references/advanced-patterns.md - 複雑な階層、状態管理、永続化、テストに関する本番環境向けのパターン
  • references/performance-edge-cases.md - パフォーマンス最適化、ストレステスト、大規模な階層への対応

読み込むタイミング:具体的な状況については、上記の「リファレンスを読み込むタイミング」セクションを参照してください。

アセット(assets/)

すぐにセットアップできる Swift テンプレートファイル:

  • assets/basic-settings-template.swift - 最小限の設定実装一式
  • assets/custom-style-template.swift - カスタム SettingsStyle の実装テンプレート(5 例)
  • assets/modular-settings-template.swift - 設定を複数のファイルに整理するパターン
  • assets/demo-app-template.swift - 公式 SettingsKit デモに準拠した完全なデモアプリ(プロパティ 25 個以上、すべてのコントロールタイプ、ストレステスト)

依存関係

必須:

  • Swift 6.0+(@Observable マクロのサポートに必要)
  • iOS 17.0+ / macOS 14.0+ / watchOS 10.0+ / tvOS 17.0+ / visionOS 1.0+
  • SwiftUI フレームワーク(組み込み)

任意:

  • なし — SettingsKit は外部依存関係のないスタンドアロンのフレームワークです

公式ドキュメント


パッケージバージョン(2025-11-23 確認済み)

{
  "dependencies": {
    "SettingsKit": "1.0.0"
  }
}

プラットフォーム要件:

  • iOS 17.0+
  • macOS 14.0+
  • watchOS 10.0+
  • tvOS 17.0+
  • visionOS 1.0+
  • Swift 6.0+
  • Xcode 16.0+

本番環境での例

このスキルは、公式の SettingsKit リポジトリとそのサンプルに基づいています。

  • リポジトリ:https://github.com/Aeastr/SettingsKit
  • ライセンス:MIT
  • 検証:✅ iOS 17+、macOS 14+、watchOS 10+、tvOS 17+、visionOS 1+ でテスト済み
  • アーキテクチャ:検索可能でリアクティブな設定を実現する、メタデータ/ビュー/レンダリングのハイブリッドシステム

トラブルシューティング

問題:「'SettingsContainer' がスコープ内に見つかりません」

解決方法:ファイルの先頭で SettingsKit をインポートします:import SettingsKit。Xcode プロジェクトの設定で、パッケージがターゲットの依存関係に追加されていることを確認してください。

問題:モデルが変更されても設定の切り替えが更新されない

解決方法:設定モデルが SwiftUI の環境に含まれていること(.environment(settings))、およびバインディングを作成する前に settingsBody で @Bindable ラッパーを使用していることを確認してください。

問題:サイドバースタイルでナビゲーションが動作しない

解決方法:SettingsGroup を使用していること(直接 NavigationLink を使用していないこと)、また SettingsContainer をカスタムの NavigationStack/NavigationSplitView でラップしていないことを確認してください。

問題:カスタム設定が検索で見つからない

解決方法:関連キーワードを含むグループに .settingsTags([...]) を追加してください。CustomSettingsGroup のコンテンツはインデックス化されません。検索可能なコントロールには SettingsItem を使用してください。


完全なセットアップチェックリスト

このチェックリストを使って、セットアップを確認してください。

  • SettingsKit パッケージが Swift Package Manager 経由で追加されている(1.0.0 以降)
  • 最小プラットフォームバージョンの要件を満たしている(iOS 17 以降/macOS 14 以降/Swift 6.0 以降)
  • 設定モデルで ObservableObject ではなく @Observable を使用している
  • SettingsContainer プロトコルを settingsBody で実装している
  • バインディングを作成する前に @Bindable ラッパーを使用している
  • 設定モデルを環境に注入している(.environment(settings))
  • 設定グループで検索用に .settingsTags([...]) を使用している
  • アプリがエラーなしでコンパイルできる
  • 対象プラットフォームで設定 UI が正しく表示される
  • 検索機能が動作する(タグ付けしたキーワードを検索してみてください)
  • 設定の状態が保持され、リアクティブに更新される

質問や問題がありますか?

  1. 詳細な API ドキュメントについては references/api-reference.md を確認してください
  2. 複雑なシナリオについては references/advanced-patterns.md を参照してください
  3. 4 ステップのセットアップ手順をすべて確認してください
  4. 公式リポジトリを確認してください:https://github.com/Aeastr/SettingsKit
  5. Swift 6.0 以降および iOS 17 以降/macOS 14 以降の要件を満たしていることを確認してください

コメント