{"id":32147891,"url":"https://github.com/kylehughes/persistentkeyvaluekit","last_synced_at":"2026-05-03T02:02:46.536Z","repository":{"id":269134882,"uuid":"762303217","full_name":"kylehughes/PersistentKeyValueKit","owner":"kylehughes","description":"Perfectly-shaped interfaces for UserDefaults and NSUbiquitiousKeyValueStore.","archived":false,"fork":false,"pushed_at":"2026-05-03T00:15:33.000Z","size":79,"stargazers_count":50,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-05-03T01:25:11.444Z","etag":null,"topics":["ios","ipados","macos","swift","swift-6","swiftpm","swiftui","visionos","watchos"],"latest_commit_sha":null,"homepage":"https://kylehughes.github.io/PersistentKeyValueKit/","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/kylehughes.png","metadata":{"files":{"readme":"README.md","changelog":null,"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}},"created_at":"2024-02-23T13:55:19.000Z","updated_at":"2026-05-03T00:15:34.000Z","dependencies_parsed_at":"2024-12-21T08:12:22.516Z","dependency_job_id":"af01e0f3-3441-4fc1-9afc-5fc7637ff3d3","html_url":"https://github.com/kylehughes/PersistentKeyValueKit","commit_stats":null,"previous_names":["kylehughes/persistentkeyvaluekit"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/kylehughes/PersistentKeyValueKit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kylehughes%2FPersistentKeyValueKit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kylehughes%2FPersistentKeyValueKit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kylehughes%2FPersistentKeyValueKit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kylehughes%2FPersistentKeyValueKit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kylehughes","download_url":"https://codeload.github.com/kylehughes/PersistentKeyValueKit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kylehughes%2FPersistentKeyValueKit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32555839,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T00:31:16.350Z","status":"online","status_checked_at":"2026-05-03T02:00:09.297Z","response_time":103,"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":["ios","ipados","macos","swift","swift-6","swiftpm","swiftui","visionos","watchos"],"created_at":"2025-10-21T09:00:46.617Z","updated_at":"2026-05-03T02:02:46.525Z","avatar_url":"https://github.com/kylehughes.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PersistentKeyValueKit\n\n[![Platform Versions](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fkylehughes%2FPersistentKeyValueKit%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/kylehughes/PersistentKeyValueKit)\n[![Swift Versions](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fkylehughes%2FPersistentKeyValueKit%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/kylehughes/PersistentKeyValueKit)\n[![Test](https://github.com/kylehughes/PersistentKeyValueKit/actions/workflows/test.yml/badge.svg)](https://github.com/kylehughes/PersistentKeyValueKit/actions/workflows/test.yml)\n\n*Perfectly-shaped interfaces for `UserDefaults` and `NSUbiquitousKeyValueStore`.*\n\n## About\n\nPersistentKeyValueKit provides a comprehensive, type-safe, and universal interface for `UserDefaults` and \n`NSUbiquitousKeyValueStore`. It makes it easy to persist and retrieve any type from storage throughout your codebase. \nThe framework encourages:\n\n- Defining persistence logic on a per-type basis\n- Composing persistence logic from common building blocks\n- Using the static accessor pattern to centrally define keys\n\nPersistentKeyValueKit is heavy with opinions, concepts, and types, but the implementation is lightweight and tries to \nsit right on top of the familiar storage APIs.\n\nAll constraints of [`UserDefaults`][user-defaults-docs] and [`NSUbiquitousKeyValueStore`][ubiquitous-store-docs] apply. \nFamiliarity with these storage systems is recommended. Data is not automatically migrated between stores.\n\nPersistentKeyValueKit is backed by a robust test suite.\n\n[ubiquitous-store-docs]: https://developer.apple.com/documentation/foundation/nsubiquitouskeyvaluestore\n[user-defaults-docs]: https://developer.apple.com/documentation/foundation/userdefaults\n\n### Capabilities\n\n- [x] Strongly-typed key-value pairs.\n- [x] Persistence for any type that conforms to `KeyValuePersistible`.\n- [x] Universal interface for `UserDefaults` and `NSUbiquitousKeyValueStore`.\n- [x] Type-safe property wrapper and view modifier for SwiftUI.\n- [x] AsyncSequence for observing key changes in any context.\n- [x] Built-in support for all primitive (i.e. property list) types.\n- [x] Built-in representations for all common ways to persist values.\n- [x] Keys that are only mutable in Debug builds.\n- [x] Swift 6 language mode support.\n\n## Supported Platforms\n\n- iOS 15.0+\n- macOS 13.0+\n- tvOS 15.0+\n- visionOS 1.0+\n- watchOS 8.0+\n\n## Requirements\n\n- Xcode 26.0+\n\n## Documentation\n\n[Documentation is available on GitHub Pages](https://kylehughes.github.io/PersistentKeyValueKit).\n\n## Installation\n\n### Swift Package Manager\n\n```swift\ndependencies: [\n    .package(url: \"https://github.com/kylehughes/PersistentKeyValueKit.git\", .upToNextMajor(from: \"1.1.0\")),\n]\n```\n\n## Quick Start\n\nMake a type persistible by conforming to `KeyValuePersistible`.\n\n```swift\nimport PersistentKeyValueKit\n\nenum RuntimeColorScheme: String {\n    case dark\n    case light\n    case system\n}\n\nextension RuntimeColorScheme: KeyValuePersistible {\n    static var persistentKeyValueRepresentation: some PersistentKeyValueRepresentation\u003cSelf\u003e {\n        RawRepresentablePersistentKeyValueRepresentation()\n    }\n}\n```\n\nDefine a key whose value is the type.\n\n```swift\nimport PersistentKeyValueKit\n\nextension PersistentKeyProtocol where Self == PersistentKey\u003cRuntimeColorScheme\u003e {\n    static var runtimeColorScheme: Self {\n        Self(\"RuntimeColorScheme\", defaultValue: .system)\n    }\n}\n```\n\nUse the value in a SwiftUI view…\n\n```swift\nimport PersistentKeyValueKit\n\nstruct SettingsView: View {\n    @PersistentValue(.runtimeColorScheme)\n    var runtimeColorScheme\n}\n```\n\n…or anywhere else.\n\n```swift\nuserDefaults.get(.runtimeColorScheme)\n```\n\n```swift\nuserDefaults.set(.runtimeColorScheme, to: .dark)\n```\n\nObserve the same key from async code.\n\n```swift\nfor await runtimeColorScheme in userDefaults.values(for: .runtimeColorScheme) {\n    apply(runtimeColorScheme)\n}\n```\n\n## Usage\n\n### Keys\n\n#### Define and Access a Key\n\nA `PersistentKey\u003cValue\u003e` maps a unique identifier to a strongly-typed `Value` that persists between launches of an \napplication.\n\nIt is recommended to use the static accessor pattern to define and access keys. This pattern allows you to define keys \nin common locations and access them anywhere in a type-safe manner. The APIs are designed to be as ergonomic as possible\nfor this pattern.\n\ne.g.\n\n```swift\nextension PersistentKeyProtocol where Self == PersistentKey\u003cDate\u003e {\n    static var mostRecentLaunchDate: Self {\n        Self(\"MostRecentLaunchDate\", defaultValue: .distantPast)\n    }\n}\n```\n\nDynamically-identified keys can be defined with static accessors as well.\n\ne.g.\n\n```swift\nextension PersistentKeyProtocol where Self == PersistentKey\u003cString?\u003e {\n    static func selectedLayoutID(forListID listID: String) -\u003e Self {\n        Self(\"\\(listID)::SelectedLayoutID\", defaultValue: nil)\n    }\n}\n```\n\nKey-value pairs can be stored locally in `UserDefaults`—e.g. `UserDefaults.standard`, `UserDefaults(suiteName:)`— or in\niCloud in `NSUbiquitousKeyValueStore.default`.\n\ne.g.\n\n```swift\nuserDefaults.set(.mostRecentLaunchDate, to: .now)\n```\n\n```swift\nif let layoutID = NSUbiquitousKeyValueStore.default.get(.selectedLayoutID(forListID: listID)) {\n```\n\n#### Define and Access a Debug Key\n\nA debug key is a key whose value is modifiable in Debug builds but not in Release builds. This lets you use keys\nfor development and testing purposes without worrying about them being modifiable in production, and while minimizing \nthe amount of conditional code you need to write.\n\nAll key-based interfaces accept `PersistentKeyProtocol`, which both `PersistentKey` and `PersistentDebugKey` conform to.\n\n\u003e [!WARNING]\n\u003e Debug keys will only work if compiling this framework from source (e.g. as a SwiftPM dependency). If using a pre-built \n\u003e binary then the `DEBUG` code paths will likely not be included and default values will always be used.\n\ne.g.\n\n```swift\nextension PersistentKeyProtocol where Self == PersistentDebugKey\u003cBool\u003e {\n    static var isAppStoreRatingEnabled: Self {\n        Self(\n            \"IsAppStoreRatingEnabled\", \n            debugDefaultValue: false, \n            releaseDefaultValue: true\n        )\n    }\n}\n```\n\n```swift\nuserDefaults.set(.isAppStoreRatingEnabled, to: false)\n```\n\n```swift\nuserDefaults.get(.isAppStoreRatingEnabled) // false in Debug, true in Release\n```\n\n### Make a Type Persistible\n\nMake a type persistible by conforming to `KeyValuePersistible`.\n\n`KeyValuePersistible` has one requirement: \n\n```swift\nstatic var persistentKeyValueRepresentation: some PersistentKeyValueRepresentation\u003cSelf\u003e { get }\n```\n\nA representation is a type that describes how a value is persisted: how it is stored inside of `UserDefaults` or \n`NSUbiquitousKeyValueStore`, and how it is retrieved. \n\nMany common representations are provided and it is easy to build custom ones inside of the `KeyValuePersistible` \nimplementation. The primitive types for the stores are natively represented, so your responsibility is to transform your \ntype to-and-from a primitive one.\n\ne.g.\n\n```swift\nextension UIContentSizeCategory: KeyValuePersistible {\n    static var persistentKeyValueRepresentation: some PersistentKeyValueRepresentation\u003cSelf\u003e {\n        RawRepresentablePersistentKeyValueRepresentation()\n    }\n}\n```\n\n#### Primitive Types\n\nPrimitive types are natively supported by `UserDefaults` and/or `NSUbiquitousKeyValueStore`. These types are all \n`KeyValuePersistible` and are stored directly with little-to-no transformation. All other `KeyValuePersistible` \ntypes must be transformed into a primitive type through a `PersistentKeyValueRepresentation`.\n\nThe primitive types are:\n\n- `Array\u003cElement\u003e where Element: KeyValuePersistible`\n- `Bool`\n- `Data`\n- `Dictionary\u003cString, Value\u003e where Value: KeyValuePersistible`\n- `Double`\n- `Float`\n- `Int`\n- `Optional\u003cWrapped\u003e where Wrapped: KeyValuePersistible`\n- `String`\n- `URL`\n\n### Persistence Representations\n\nThere are built-in representations that cover the most common use cases for applications. They are all described here. \nTheir building blocks are available if necessary, but not described here.\n\n#### `ProxyPersistentKeyValueRepresentation`\n\n`ProxyPersistentKeyValueRepresentation` is a representation that uses the representation of `Proxy` as its own. The \n`Proxy` type must be a `KeyValuePersistible` type.\n\nUse this representation to rely on an existing representation that's suitable for the type.\n\nThis is the base representation for types to build on top of. A common pattern is to use a primitive type as the proxy \ntype, but any `KeyValuePersistible` type can be used as the proxy type. There is no limit to the layers of indirection.\n\ne.g.\n\n`Date` is persisted as `TimeInterval` (i.e. `Double`).\n\n```swift\nextension Date: KeyValuePersistible {\n    public static var persistentKeyValueRepresentation: some PersistentKeyValueRepresentation\u003cSelf\u003e {\n        ProxyPersistentKeyValueRepresentation(\n            to: \\.timeIntervalSinceReferenceDate,\n            from: Date.init(timeIntervalSinceReferenceDate:)\n        )\n    }\n}\n```\n\n#### `RawRepresentablePersistentKeyValueRepresentation`\n\n`RawRepresentablePersistentKeyValueRepresentation` is a proxy representation that persists a `RawRepresentable` value as \nits `RawValue`, if `RawValue` is `KeyValuePersistible`.\n\ne.g.\n\n`NotificationFrequency` is persisted as `String`.\n\n```swift\nenum NotificationFrequency: String {\n    case daily\n    case weekly\n    case monthly\n}\n```\n\n```swift\nextension NotificationFrequency: KeyValuePersistible {\n    static var persistentKeyValueRepresentation: some PersistentKeyValueRepresentation\u003cSelf\u003e {\n        RawRepresentablePersistentKeyValueRepresentation()\n    }\n}\n```\n\n#### `CodablePersistentKeyValueRepresentation`\n\n`CodablePersistentKeyValueRepresentation` is a proxy representation that persists a value as the `Input`/`Output` type\nof the given encoder and decoder.\n\ne.g.\n\n`Contact` is persisted as `Data`.\n\n```swift\nstruct Contact: Codable, Sendable {\n    let nickname: String\n    let dateOfBirth: Date\n}\n```\n\n```swift\n@available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, *)\nextension Contact: KeyValuePersistible {\n    static var persistentKeyValueRepresentation: some PersistentKeyValueRepresentation\u003cSelf\u003e {\n        CodablePersistentKeyValueRepresentation()\n    }\n}\n```\n\nThis convenience initializer is provided for the default `JSONDecoder` and `JSONEncoder`. The `Decoder` and `Encoder` \ncan be supplied in other initializers.\n\n#### `LosslessStringConvertiblePersistentKeyValueRepresentation`\n\n`LosslessStringConvertiblePersistentKeyValueRepresentation` is a proxy representation that persists a value as a \n`String`, as defined by its `LosslessStringConvertible` conformance.\n\ne.g.\n\n`Character` is persisted as `String`.\n\n```swift\nextension Character: KeyValuePersistible {\n    static var persistentKeyValueRepresentation: some PersistentKeyValueRepresentation\u003cSelf\u003e {\n        LosslessStringConvertiblePersistentKeyValueRepresentation()\n    }\n}\n```\n\n#### Custom Representation for a Single Key\n\nEvery `KeyValuePersistible` type has an associated `PersistentKeyValueRepresentation` type and \n`persistentKeyValueRepresentation` property. This is the default representation used to persist the value with a store.\n\nHowever, a representation for a single key can be provided at definition time—even if the value isn't \n`KeyValuePersistible`. This is useful for:\n\n- One-off keys for nonconforming types.\n- Handling older values stored differently from the default representation.\n\ne.g.\n\n`Date?` is persisted as `String` using the ISO 8601 format.\n\n```swift\nextension PersistentKeyProtocol where Self == PersistentKey\u003cDate?\u003e {\n    static var mostRecentAppStoreReviewRequestDate: Self {\n        Self(\n            \"MostRecentAppStoreReviewRequestDate\",\n            defaultValue: nil,\n            representation: ProxyPersistentKeyValueRepresentation(\n                to: { date in date.ISO8601Format() },\n                from: { string in try? Date.ISO8601FormatStyle().parse(string) }\n            )\n        )\n    }\n}\n```\n\n### SwiftUI\n\n#### Property Wrapper\n\n`PersistentValue` is a property wrapper that provides a type-safe way to access and modify values from `UserDefaults` or \n`NSUbiquitousKeyValueStore` in SwiftUI views. It supports automatic observation and updates whenever the value changes\nin the given store, locally or otherwise.\n\nThe default store is the `defaultPersistentKeyValueStore` from the environment. If unset, the default store is\n`UserDefaults.standard`.\n\ne.g.\n\n```swift\n@PersistentValue(.isAppStoreRatingEnabled)\nvar isAppStoreRatingEnabled: Bool\n```\n\n```swift\n@PersistentValue(.isAppStoreRatingEnabled, store: .ubiquitous)\nvar isAppStoreRatingEnabled: Bool\n```\n\n##### View Modifier\n\nA view modifier is provided to set the default store used by any `@PersistentValue` property wrapper in the view (or \nits descendants). The default store can be overridden by supplying one directly in the `@PersistentValue` declaration.\n\ne.g.\n\n```swift\nextension App: SwiftUI.App {\n    var body: some Scene {\n        RootView()\n            .defaultPersistentKeyValueStore(.ubiquitous)\n    }\n}\n```\n\n### `AsyncSequence`\n\n`PersistentKeyValues` observes a persistent key as an `AsyncSequence`. Use it outside SwiftUI when you want key changes\nwithout writing KVO or `NotificationCenter` code.\n\nThe same sequence is available from the store.\n\n```swift\nfor await username in UserDefaults.standard.values(for: .username) {\n    usernameLabel.text = username\n}\n```\n\nIt is also available from the key.\n\n```swift\nlet usernameKey: PersistentKey\u003cString\u003e = .username\n\nfor await username in usernameKey.values(in: UserDefaults.standard) {\n    usernameLabel.text = username\n}\n```\n\nBy default, `values(for:)` and `values(in:)` emit the current value first, then later changes.\n\nUse `changes(for:)` or `changes(in:)` to skip the current value and observe only later changes.\n\n```swift\nfor await username in UserDefaults.standard.changes(for: .username) {\n    handleChange(username: username)\n}\n```\n\nPending changes use `.bufferingNewest(1)` by default. If the consumer falls behind, it receives the latest pending\nvalue instead of an unbounded backlog of intermediate values. Pass `.unbounded` to receive every observed value.\n\n```swift\nfor await username in UserDefaults.standard.changes(for: .username, bufferingPolicy: .unbounded) {\n    recordChange(username: username)\n}\n```\n\nEach iterator registers with the store. It deregisters when iteration ends, the iterator is released, or the task is\ncancelled. Iterate from a cancellable task and cancel it when the owner no longer needs updates.\n\n### `UserDefaults` Registration\n\nPersistentKeyValueKit supports traditional `UserDefaults` registration. The default value of the key will be registered\nas the default value in the registration domain of the instance of `UserDefaults`.\n\ne.g.\n\n`1` will be registered for key `LaunchCount` in the defaults dictionary in the registration domain for `UserDefaults`.\n\n```swift\nextension PersistentKeyProtocol where Self == PersistentKey\u003cInt\u003e {\n    static var launchCount: Self {\n        Self(\"LaunchCount\", defaultValue: 1)\n    }\n}\n```\n\n```swift\nuserDefaults.register(.launchCount)\n```\n\n\u003e [!NOTE]\n\u003e Registration isn't necessary when using PersistentKeyValueKit exclusively since default values are handled through key \n\u003e definitions. It becomes useful when sharing `UserDefaults` with other frameworks that don't use PersistentKeyValueKit, \n\u003e ensuring default values are available to code using raw `UserDefaults` APIs.\n\n## Important Behavior Differences\n\nPersistentKeyValueKit strives to be type-safe infrastructure on top of the platform storage APIs. Behavior is changed\nonly when it was overwhelmingly idiomatic, modern, or necessary to do so.\n\n### No Implicit Defaults\n\nThe platform storage APIs use implicit defaults. For example, `UserDefaults` will return `false` for `Bool` values for\nkeys that are not set (or removed), or `0` for `Int`. There is no way to distinguish these implicit values from an \nunset key; no way to represent a `nil` value, or the absence of a value.\n\nPersistentKeyValueKit requires an explicit default value for every key. This is the value that will be returned for an \nunset key, or key with the wrong type of value. It can be different for each key. This provides granular control over \nthe value, as well as type-safe optionality. If the key needs to represent a `nil` value, or absence of a value, then \nthe key can be defined with an `Optional` type and its default value can be `nil`.\n\ne.g.\n\nThis key's value can be `nil`, and if no value is set then `nil` will be returned. The caller can distinguish an unset\nkey from a `true` or `false` value.\n\n```swift\nextension PersistentKeyProtocol where Self == PersistentKey\u003cBool?\u003e {\n    static var arePushNotificationsEnabled: Self {\n        Self(\"ArePushNotificationsEnabled\", defaultValue: nil)\n    }\n}\n```\n\nThis key's value cannot be `nil` and will return `true` if no value is set. The caller cannot distinguish an unset key\nfrom a `true` value.\n\n```swift\nextension PersistentKeyProtocol where Self == PersistentKey\u003cBool\u003e {\n    static var arePushNotificationsEnabled: Self {\n        Self(\"ArePushNotificationsEnabled\", defaultValue: true)\n    }\n}\n```\n\n\u003e [!NOTE]\n\u003e An enum with three cases is often better than an `Optional\u003cBool\u003e` for absolute clarity in what the absence of a \n\u003e boolean value means.\n\n### No Heterogeneous Collections\n\nThe platform storage APIs support heterogeneous arrays (`Array\u003cAny\u003e`) and dictionaries (`Dictionary\u003cString, Any\u003e`).\n\nPersistentKeyValueKit does not natively support heterogeneous collections for the sake of ergonomics. Overlapping\nprotocol conformances (i.e. for `KeyValuePersistible`) are not allowed, so the decision was made to favor homogeneous\ncollections that are more frequently used in Swift.\n\ni.e.\n\n| ✅ `KeyValuePersistible`                           | ❌ `KeyValuePersistible`            |\n| ---------------------------------------------------| ------------------------------------|\n| `[Element] where Element: KeyValuePersistible`     | `[any KeyValuePersistible]`         |\n| `[String: Value] where Value: KeyValuePersistible` | `[String: any KeyValuePersistible]` |\n\nHeterogeneous arrays are unwieldy to use with Swift: the caller needs to know the type at each index. Heterogeneous \ndictionaries are understandable—serializing keyed types—but properly supporting them within the framework delivered no \nperformance benefit over using a `Codable` representation.\n\nHeterogeneous collections can be used by conforming a type to `PrimitiveKeyValuePersistible` and interfacing with the \nstorage APIs directly. This is the fastest way to persist a keyed type. This is not recommended—there are no \naffordances for property list safety or proxy representations—but it is available.\n\n### Limited `NSUbiquitousKeyValueStore` Observability\n\nThere is no platform support for observing changes to keys in `NSUbiquitousKeyValueStore`. The only affordance is\nlistening for external changes from other devices. PersistentKeyValueKit implements observability for all mutations\nmade through the framework: any `@PersistentValue` or `AsyncSequence` using `NSUbiquitousKeyValueStore` will\nautomatically update with any changes made by PersistentKeyValueKit anywhere, on any device. However, any changes to\n`NSUbiquitousKeyValueStore` made outside of the framework will not be automatically reflected in `@PersistentValue`\nproperties or `AsyncSequence` iterations.\n\n## Contributions\n\nPersistentKeyValueKit is not accepting source contributions at this time. Bug reports will be considered.\n\n## Author\n\n[Kyle Hughes](https://kylehugh.es)\n\n[![Bluesky][bluesky_image]][bluesky_url]  \n[![LinkedIn][linkedin_image]][linkedin_url]  \n[![Mastodon][mastodon_image]][mastodon_url]\n\n[bluesky_image]: https://img.shields.io/badge/Bluesky-0285FF?logo=bluesky\u0026logoColor=fff\n[bluesky_url]: https://bsky.app/profile/kylehugh.es\n[linkedin_image]: https://img.shields.io/badge/LinkedIn-0A66C2?logo=linkedin\u0026logoColor=fff\n[linkedin_url]: https://www.linkedin.com/in/kyle-hughes\n[mastodon_image]: https://img.shields.io/mastodon/follow/109356914477272810?domain=https%3A%2F%2Fmister.computer\u0026style=social\n[mastodon_url]: https://mister.computer/@kyle\n\n## Resources\n\n- Apple: [Designing for Key-Value Data in iCloud](https://developer.apple.com/library/archive/documentation/General/Conceptual/iCloudDesignGuide/Chapters/DesigningForKey-ValueDataIniCloud.html)\n- Apple: [Preferences and Settings Programming Guide](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/UserDefaults/Introduction/Introduction.html#//apple_ref/doc/uid/10000059i)\n\n## License\n\nPersistentKeyValueKit is available under the MIT license. \n\nSee `LICENSE` for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkylehughes%2Fpersistentkeyvaluekit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkylehughes%2Fpersistentkeyvaluekit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkylehughes%2Fpersistentkeyvaluekit/lists"}