{"id":21801943,"url":"https://github.com/illescasdaniel/simpleprefs","last_synced_at":"2026-03-16T08:34:51.325Z","repository":{"id":119506836,"uuid":"230946111","full_name":"illescasDaniel/SimplePrefs","owner":"illescasDaniel","description":"A simple way to manage your app preferences in your Swift projects","archived":false,"fork":false,"pushed_at":"2020-03-02T18:48:01.000Z","size":175,"stargazers_count":6,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-13T18:54:47.236Z","etag":null,"topics":["alternative","encrypted","preferences","swift","userdefaults"],"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/illescasDaniel.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,"zenodo":null}},"created_at":"2019-12-30T16:24:30.000Z","updated_at":"2024-06-26T14:56:07.000Z","dependencies_parsed_at":null,"dependency_job_id":"ca272765-52a0-40d7-9169-833369a36b8e","html_url":"https://github.com/illescasDaniel/SimplePrefs","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/illescasDaniel/SimplePrefs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/illescasDaniel%2FSimplePrefs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/illescasDaniel%2FSimplePrefs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/illescasDaniel%2FSimplePrefs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/illescasDaniel%2FSimplePrefs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/illescasDaniel","download_url":"https://codeload.github.com/illescasDaniel/SimplePrefs/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/illescasDaniel%2FSimplePrefs/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260063529,"owners_count":22953542,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["alternative","encrypted","preferences","swift","userdefaults"],"created_at":"2024-11-27T11:21:40.520Z","updated_at":"2026-03-16T08:34:51.267Z","avatar_url":"https://github.com/illescasDaniel.png","language":"Swift","readme":"# SimplePrefs\n\n[![Swift version](https://img.shields.io/badge/Swift-5-orange.svg)](https://swift.org/download)\n[![Version](https://img.shields.io/badge/version-2.5.x-green.svg)](https://github.com/illescasDaniel/SimplePrefs/releases)\n[![license](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/illescasDaniel/SimplePrefs/blob/master/LICENSE)\n\nA simple way to manage your app preferences in your Swift projects (compatible with iOS, macOS, etc).\n\n**⚠️ Warning:** the app uses the Apple library ***CryptoKit***. **You need to add a flag to your project** in order to compile it for a lower version than what the framework supports.\nThis is not something I can fix since since is not my fault. See more: https://stackoverflow.com/questions/58287922/cryptokit-craches-app-on-phones-with-ios-version-below-13\n\n**TL;DR:** just add `-weak_framework CryptoKit` in \"Other Linker Flags\" in your project settings. \n\n## API (Preferences Managers):\n```swift\nassociatedtype Value: Codable\n\nfunc load() -\u003e Bool\n\nfunc getProperty\u003cT\u003e(_ keyPath: KeyPath\u003cValue,T\u003e) -\u003e T\nfunc setProperty\u003cT\u003e(_ keyPath: WritableKeyPath\u003cValue,T\u003e, _ value: T)\nsubscript\u003cT\u003e(keyPath: WritableKeyPath\u003cValue,T\u003e) -\u003e T\n\nfunc save() -\u003e Bool\n\nfunc delete() -\u003e Bool\nfunc deleteReplacing(with newValue: Value) -\u003e Bool\n```\n\n### Specific **preferences managers** available:\n- `SimplePrefs.File`: saves preferences as a **plain JSON file**.\n- `SimplePrefs.EncryptedFile`: saves preferences as en **encrypted JSON file**.\n- `SimplePrefs.Keychain`: saves preferences on **user's keychain**, the whole model object is saved with a **single key**.\n- `SimplePrefs.UserDefaults`: saves preferences using **`UserDefaults`**  .\n- `SimplePrefs.Mock`: doesn't persist anything but conforms to the same protocol as the others, it just uses a default instance passed in the constructor.\n\n**Note:** all preferences managers sync with their respective underlying storage ONLY when calling the `load` or `save` methods.\n\nAlso, there are these \"**Properties managers**\", which behave similarly but you must create a model with specific keys for each value. \n**These are in sync with their underlying storage** all the time:\n- `SimplePrefs.UserDefaultsProperties`: saves preferences using **`UserDefaults`**.\n- `SimplePrefs.CacheProperties`: saves preferences using **`NSCache`**.\n- `SimplePrefs.KeychainProperties`: saves preferences on user's keychain, **every value has its own key**.\n\n## Usage\n\nYou need a **model** with the properties you want to save:\n```swift\nstruct UserPreferences: Codable {\n    var age: Int?\n    var isDarkModeEnabled: Bool = false\n    var person: Person = .init(name: \"John\") // must conform to `Codable`\n}\n\n// Only necessary for `SimplePrefs.UserDefaults`\nextension UserPreferences: SimplePrefs.UserDefaultsKey {\n    // It is recommended to use custom key values like these in order to save\n    // unique keys into userDefaults\n    enum CodingKeys: String, CodingKey, CaseIterable {\n        case age = \"UserPreferences.age\"\n        case isDarkModeEnabled = \"UserPreferences.isDarkModeEnabled\"\n        case person = \"UserPreferences.person\"\n    }\n}\n```\nFor **Properties managers**:\n```swift\nimport enum SimplePrefs.SimplePrefs\n\nstruct UserPreferencesProperties {\n    \n    typealias key = SimplePrefs.Properties.Key\n    \n    @key(\"age\")\n    var age: Int?\n    \n    @key(\"isDarkModeEnabled\", defaultValue: false)\n    var isDarkModeEnabled: Bool?\n    \n    @key(\"person\", defaultValue: Person(name: \"John\"))\n    var person: Person?\n}\n\n// necessary for UserDefaults or Keychain\nextension UserPreferencesProperties: SimplePrefs.Properties.KeysProtocol {\n    var allProperties: SimplePrefs.Properties.Keys {[\n        $age, $isDarkModeEnabled, $person\n    ]}\n}\n\n```\n\nThe recommended way of using your preferences:\n```swift\nenum AppPrefs {\n    #if DEBUG\n    typealias Instance = SimplePrefs.Mock\u003cUserPreferences\u003e\n    static let instance = Instance(defaultValue: .init(\n        age: 22,\n        isDarkModeEnabled: false,\n        person: .init(name: \"Peter\"\n    )))\n    #else\n    typealias Instance = SimplePrefs.File\u003cUserPreferences\u003e\n    static let instance = Instance(defaultValue: .init())\n    #endif\n}\n\nvar appPrefs: AppPrefs.Instance { AppPrefs.instance }\n```\n\nUsage:\n```swift\nappPrefs.load() // - loads preferences\n\nappPrefs[\\.isDarkModeEnabled] // gets a value\nappPrefs[\\.age] = 60 // sets a value\n// also: appPrefs.setProperty(\\.age, value: 60)\n// also: appPrefs.getProperty(\\.isDarkModeEnabled)\n\n// for \"properties managers\":\nappPrefs[\\.$isDarkModeEnabled] // gets a value\nappPrefs[\\.$age] = 60 // sets a value\n\nappPrefs.save() // - saves preferences\n\n// On iOS you may call the `save` method in\n// `func applicationDidEnterBackground(UIApplication)` and/or `func applicationWillTerminate(UIApplication)`.\n```\n\n## Motivation\n\nWe all have used `UserDefaults` to store small data, mainly for user preferences in an application. Though is fast and reliable, you must store values using unique keys, which you should have as constants (or in an enum).\n`UserDefaults` is easy but have some disadvantages like small capacity, having to use string keys to store and retrieve values, is not easy to get this preferences as something you can send or download over the internet (remote preferences saved in the cloud for example!).\n\nThat's basically why I created **`SimplePrefs`**, which have different classes that store your preferences in different ways.\nYou can save data as a **.json file** so its way easier to manage it, or in an **encrypted** file (with Apple's new CryptoKit), or save it on the **keychain** if you prefer, or even use **`UserDefaults`** as its storage (useful when using a `Settings.bundle` for your app preferences in the Settings app)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fillescasdaniel%2Fsimpleprefs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fillescasdaniel%2Fsimpleprefs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fillescasdaniel%2Fsimpleprefs/lists"}