{"id":16684807,"url":"https://github.com/nirma/default","last_synced_at":"2025-04-07T17:07:21.673Z","repository":{"id":56551629,"uuid":"105729586","full_name":"Nirma/Default","owner":"Nirma","description":"Modern interface to UserDefaults + Codable support","archived":false,"fork":false,"pushed_at":"2024-09-14T08:54:25.000Z","size":139,"stargazers_count":470,"open_issues_count":0,"forks_count":21,"subscribers_count":8,"default_branch":"main","last_synced_at":"2025-03-31T16:13:52.392Z","etag":null,"topics":["hacktoberfest","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/Nirma.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}},"created_at":"2017-10-04T03:52:55.000Z","updated_at":"2025-03-29T07:39:50.000Z","dependencies_parsed_at":"2024-11-13T15:51:57.052Z","dependency_job_id":null,"html_url":"https://github.com/Nirma/Default","commit_stats":{"total_commits":43,"total_committers":9,"mean_commits":4.777777777777778,"dds":"0.41860465116279066","last_synced_commit":"8fc63ff9ab38305cb4269eb236f5a6afdb6425a3"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nirma%2FDefault","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nirma%2FDefault/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nirma%2FDefault/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nirma%2FDefault/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Nirma","download_url":"https://codeload.github.com/Nirma/Default/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247694875,"owners_count":20980733,"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":["hacktoberfest","userdefaults"],"created_at":"2024-10-12T14:45:08.568Z","updated_at":"2025-04-07T17:07:21.626Z","avatar_url":"https://github.com/Nirma.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"cassette.jpg\" width=\"40%\"\u003e\n\n# Default\n[![Build Status](https://travis-ci.org/Nirma/Default.svg?branch=master)](https://travis-ci.org/Nirma/Default)\n![platforms](https://img.shields.io/badge/platforms-iOS%20%7C%20macOS%20%7C%20tvOS%20%7C%20watchOS-333333.svg)\n![Swift 5.0](https://img.shields.io/badge/Swift-5.0-orange.svg)\n[![CocoaPods compatible](https://img.shields.io/cocoapods/v/Default.svg)](#cocoapods)\n[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)\n[![License](http://img.shields.io/:license-mit-blue.svg)](http://doge.mit-license.org)\n\nModern interface to UserDefaults + Codable support\n\n# What is Default?\n`Default` is a library that extends what `UserDefaults` can do by providing extensions for saving custom objects that conform to `Codable` and also providing a new interface to UserDefaults described below, via the protocol `DefaultStorable`.\nYou can use only the `Codable` support extensions or the `DefaultStorable` protocol extensions or both. (or none, that's cool too)\n\n# Features\n- [x] Read and write custom objects directly to `UserDefaults` that conform to `Codable`\n- [x] Provides an alternative API to `UserDefaults` with `DefaultStorable`\n\n### Don't see a feature you need?\nFeel free to open an Issue requesting the feature you want or send over a pull request!\n\n# Why default?\nThis library has \nStoring keys and values in defaults the normal way is error prone because typing out the string value for a key \nevery time leaves the possibility of mistyped keys and keeping track of which keys are used and what is currently stored in \n`UserDefaults` is somewhat hard. \nDefining objects specifically for storing in user defaults makes the job of keeping track of what is currently being stored in `UserDefaults` as simple as searching the project's source code for instances that conform to `DefaultStorable`.\nUsing objects specifically for storing a set of data in UserDefaults allows settings for a certain piece of data to be logically grouped together.\n\n# Usage\n## `DefaultStorable` - A _better way_ of interacting with `UserDefaults`\nInstead of manually adding key values to the key store or having to implement `NSCoding` manually and bloating up\nobject code, you can simply and clearly define _defaults_ objects with a clear intent of being used as a means of storing\ndefaults. \n\nMuch like how conforming to `Codable` gets you a lot for free, so does conforming to `DefaultStorable`.\n**The object conforming to `DefaultStorable` _must also conform to_ `Codable`:\n\nSay we want to store theme settings in `UserDefaults` (fair enough right?) we first define our object conforming to `Codable`  and `DefaultStorable`.\n\n### Define object conforming to `DefaultStorable`\n```swift\nstruct VisualSettings: Codable, DefaultStorable {\n    let themeName: String\n    let backgroundImageURL: URL?\n}\n```\n\n### Create \u0026 Save the object to `UserDefaults`\n```swift\nlet settings = VisualSettings(themeName: \"bright\", backgroundImageURL: URL(string: \"https://...\"))\nsettings.write()\n```\nIf you need to save the data under a different key other than the default key (the type name, in this case `\"VisualSettings\"`) then this can be achieved by providing the optional argument to `write(withKey:)`:\n```swift\nlet settings = VisualSettings(themeName: \"bright\", backgroundImageURL: URL(string: \"https://...\"))\nsettings.write(withKey: \"someUniqueKey\")\n```\n\n### Read it back later when ya need it!\n```swift\nif let settings = VisualSettings.read() {\n    // Do something\n}\n```\nIf you saved the default under a unque key then it can be read back by providing the optional argument to `read(forKey:)`:\n\n```swift\nif let settings = VisualSettings.read(forKey: \"someUniqueKey\") {\n    // Do something\n}\n```\n\n\n\n## Swift 4 `Codable` Support\nThis library offers support for directly storing custom objects within `UserDefaults` that conform to `Codable`.\nWith the release of Swift 4 comes the `Codable` protocol, which provides support for serializing objects.\n`UserDefaults` has not been updated to work with Swift 4's `Codable` protocol so if saving custom objects directly to \n`UserDefaults` is necessary then that object must support `NSCoding` and inherit from `NSObject`.\n\n```swift\n\n// 1: Declare object (just conform to Codable, getting default encoder / decoder implementation for free)\nstruct VolumeSetting: Codable {\n    let sourceName: String\n    let value: Double\n}\n\nlet setting = VolumeSetting(sourceName: \"Super Expensive Headphone Amp\", value: 0.4)\nlet key: String = String(describing: VolumeSetting.self)\n\n// 2: Write\nUserDefaults.standard.df.store(setting, forKey: key)\n\n// 3: Read\nUserDefaults.standard.df.fetch(forKey: key, type: VolumeSetting.self)\n\n```\n\n# Customization\nIf the default behaviour of `Default` does not quite fit your needs, then any of the default implementation details\ncan be overridden. \n\nThe most commonly overridden properties are `defaultIdentifier` and `defaults`.\n\n### `defaultIdentifier`\n\n`defaultIdentifier` is the key by which your object will be stored.\nThis defaults to the type name of the object being stored.\n\n```swift\n  public static var defaultIdentifier: String {\n        return String(describing: type(of: self))\n    }\n```\n\n### `defaults`\n`defaults` will return the `UserDefaults` database that your application will store defaults objects in. \nThe default implementation returns `UserDefaults.standard`\n\n```swift\n    public static var defaults: UserDefaults {\n        return UserDefaults.standard\n    }\n```\n\n### How does this library work?\n`UserDefaults` requires custom types to confrom to NSCoding and be a subclass of `NSObject`.\nDoing that is a little time consuming, and conforming to `NSCoding` requires implementing Decoding / Encoding methods\nthat take a bit of code to implement.\nThe good news is that `Data` conforms to `NSCoding` so if you can find a way to convert your object to `Data` then you can store it in `UserDefaults`, The `Codable` protocol in Swift 4 does just that!\nThis library takes advantage of the `Codable` protocol introduced in Swift 4. \nThe way it works is by taking an object that conforms to `Codable` and encoding it into \na `Data` object which can then be stored in `UserDefaults`, then when you want to read it back out again just convert using `Codable` again!\n\nIt's that Simple!\n\n## Installation\n\n#### Carthage\n\nIf you use Carthage to manage your dependencies, simply add\nDefault to your `Cartfile`:\n\n```\ngithub \"Nirma/Default\"\n```\n\nIf you use Carthage to build your dependencies, make sure you have added `Default.framework` to the \"_Linked Frameworks and Libraries_\" section of your target, and have included `Default.framework` in your Carthage framework copying build phase.\n\n#### CocoaPods\n\nIf you use CocoaPods to manage your dependencies, simply add\nDefault to your `Podfile`:\n\n```ruby\npod 'Default'\n```\n\n## Requirements\n\n* Xcode 9.0\n* Swift 4.0+\n\n## Contribution\nContributions are more than welcome!\n\n## License\n\nDefault is free software, and may be redistributed under the terms specified in the [LICENSE] file.\n\n[LICENSE]: /LICENSE\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnirma%2Fdefault","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnirma%2Fdefault","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnirma%2Fdefault/lists"}