{"id":26931431,"url":"https://github.com/nikolainobadi/nnswiftdatakit","last_synced_at":"2026-05-27T23:32:03.809Z","repository":{"id":284068853,"uuid":"950976607","full_name":"nikolainobadi/NnSwiftDataKit","owner":"nikolainobadi","description":"Small Package to help instantiate SwiftData for shared database access (using AppGroups)","archived":false,"fork":false,"pushed_at":"2025-11-29T20:30:25.000Z","size":25,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-12-01T03:25:22.125Z","etag":null,"topics":["swift","swiftdata","swiftdata-example","swiftui"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nikolainobadi.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-03-19T01:16:37.000Z","updated_at":"2025-11-29T20:30:28.000Z","dependencies_parsed_at":null,"dependency_job_id":"4c34a726-97bb-4ac1-a053-2e278f4edd5e","html_url":"https://github.com/nikolainobadi/NnSwiftDataKit","commit_stats":null,"previous_names":["nikolainobadi/nnswiftdatakit"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/nikolainobadi/NnSwiftDataKit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nikolainobadi%2FNnSwiftDataKit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nikolainobadi%2FNnSwiftDataKit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nikolainobadi%2FNnSwiftDataKit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nikolainobadi%2FNnSwiftDataKit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nikolainobadi","download_url":"https://codeload.github.com/nikolainobadi/NnSwiftDataKit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nikolainobadi%2FNnSwiftDataKit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33588345,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-27T02:00:06.184Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["swift","swiftdata","swiftdata-example","swiftui"],"created_at":"2025-04-02T07:17:24.214Z","updated_at":"2026-05-27T23:32:03.803Z","avatar_url":"https://github.com/nikolainobadi.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NnSwiftDataKit\n\nNnSwiftDataKit is a lightweight Swift package that streamlines the setup of SwiftData containers in apps that use App Groups. It provides:\n\n- a clean way to create a `ModelConfiguration` that stores data inside an App Group  \n- automatic access to the correct `UserDefaults` suite  \n- a one-liner to build a `ModelContainer` and `UserDefaults` together  \n- a convenient `Scene` extension for initializing a `ModelContainer`  \n- optional database path printing for debugging via a `ModelContainer` helper  \n\nThe package does **not** define any SwiftData models and does **not** manage schema or migrations. Your app remains fully in control of its domain and data types.\n\n---\n\n## Features\n- Builds a `ModelConfiguration` using an App Group identifier.\n- Returns the correct `UserDefaults` suite for the same App Group.\n- Provides a `Scene.initializeSwiftDataModelContainer` helper to inject containers cleanly.\n- Migrates existing SwiftData stores between App Groups with optional automatic cleanup.\n- Supports custom schemas and migration plans.\n- Works with iOS and macOS targets.\n\n---\n\n## Installation\n\nAdd the package to your `Package.swift` file:\n\n```swift\n    .package(url: \"https://github.com/nikolainobadi/NnSwiftDataKit\", from: \"0.9.0\")\n```\n\n---\n\n## Usage\n\n### Importing the Package\n\n```swift\nimport NnSwiftDataKit\n```\n\n---\n\n## API Overview\n- `makeAppGroupConfiguration(appGroupId:fileManager:)` → `ModelConfiguration` + `UserDefaults`\n- `makeAppGroupModelContainer(schema:appGroupId:fileManager:migrationPlan:)` → `ModelContainer` + `UserDefaults`\n- `migrateAppGroupSwiftDataStoreIfNeeded(from:to:fileManager:deleteOldAfterMigration:)` → migrates database between App Groups\n- `Scene.initializeSwiftDataModelContainer(schema:migrationPlan:configuration:printDatabasePath:)` → attaches a configured container to a scene\n- `ModelContainer.printStoreFilePath()` → logs the resolved store location\n\n---\n\n## Configuring the SwiftData Container\n\nUse `makeAppGroupConfiguration` to prepare a `ModelConfiguration` and the App Group `UserDefaults` instance (throws `SwiftDataContextError.noAppGroupAccess` if the group is unavailable):\n\n```swift\ndo {\n    let (config, defaults) = try makeAppGroupConfiguration(\n        appGroupId: \"group.com.example.app\"\n    )\n\n    print(\"App Group UserDefaults:\", defaults)\n} catch {\n    print(\"Failed to configure SwiftData container:\", error)\n}\n```\n\n---\n\n## Creating a ModelContainer Directly\n\nBuild a ready-to-use `ModelContainer` and `UserDefaults` in one step. You can pass a migration plan when needed:\n\n```swift\nlet (container, defaults) = try makeAppGroupModelContainer(\n    schema: Schema([MyModel.self]),\n    appGroupId: \"group.com.example.app\",\n    migrationPlan: MyMigrationPlan.self\n)\n\ncontainer.printStoreFilePath() // optional: logs the store location\n```\n\n---\n\n## Migrating Between App Groups\n\nIf you need to change your App Group identifier, use `migrateAppGroupSwiftDataStoreIfNeeded` to safely migrate your existing database. **This must be called before creating the ModelContainer:**\n\n```swift\ndo {\n    // Migrate from old App Group to new App Group\n    try migrateAppGroupSwiftDataStoreIfNeeded(\n        from: \"group.com.example.oldapp\",\n        to: \"group.com.example.newapp\",\n        deleteOldAfterMigration: true  // automatically removes old database after successful migration\n    )\n\n    // Now create the container with the new App Group\n    let (container, defaults) = try makeAppGroupModelContainer(\n        schema: Schema([MyModel.self]),\n        appGroupId: \"group.com.example.newapp\"\n    )\n} catch {\n    print(\"Migration or container setup failed:\", error)\n}\n```\n\nThe migration function:\n- Checks if the new App Group container exists\n- If not, but the old container exists, copies all SwiftData files to the new location\n- Optionally deletes the old container after successful migration (set `deleteOldAfterMigration: false` to keep it)\n- Is safe to call repeatedly (no-op if migration is already complete)\n\n---\n\n## Initializing the ModelContainer in your App\n\nUse the `initializeSwiftDataModelContainer` modifier inside your `Scene` builder:\n\n```swift\n@main\nstruct ExampleApp: App {\n    var body: some Scene {\n        let (config, _) = try! makeAppGroupConfiguration(\n            appGroupId: \"group.com.example.app\"\n        )\n\n        WindowGroup {\n            ContentView()\n        }\n        .initializeSwiftDataModelContainer(\n            schema: Schema([MyModel.self]),\n            migrationPlan: MyMigrationPlan.self,\n            configuration: config,\n            printDatabasePath: true\n        )\n    }\n}\n```\n\nThis initializes a SwiftData container using your App Group and applies it to the scene.\n\n---\n\n## Error Handling\n\nIf the App Group container or the associated `UserDefaults` suite cannot be accessed, the helpers throw:\n\n```swift\nSwiftDataContextError.noAppGroupAccess\n```\n\n---\n\n## Contributing\nAny feedback or ideas to enhance NnSwiftDataKit would be well received. Please feel free to [open an issue](https://github.com/nikolainobadi/NnSwiftDataKit/issues/new) if you'd like to help improve this Swift package.\n\n## License\nNnSwiftDataKit is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnikolainobadi%2Fnnswiftdatakit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnikolainobadi%2Fnnswiftdatakit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnikolainobadi%2Fnnswiftdatakit/lists"}