Default is a Modern interface to UserDefaults + Codable support

Overview

Default

Build Status platforms Swift 5.0 CocoaPods compatible Carthage compatible License

Modern interface to UserDefaults + Codable support

What is Default?

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. You can use only the Codable support extensions or the DefaultStorable protocol extensions or both. (or none, that's cool too)

Features

  • Read and write custom objects directly to UserDefaults that conform to Codable
  • Provides an alternative API to UserDefaults with DefaultStorable

Don't see a feature you need?

Feel free to open an Issue requesting the feature you want or send over a pull request!

Why default?

This library has Storing keys and values in defaults the normal way is error prone because typing out the string value for a key every time leaves the possibility of mistyped keys and keeping track of which keys are used and what is currently stored in UserDefaults is somewhat hard. Defining 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. Using objects specifically for storing a set of data in UserDefaults allows settings for a certain piece of data to be logically grouped together.

Usage

DefaultStorable - A better way of interacting with UserDefaults

Instead of manually adding key values to the key store or having to implement NSCoding manually and bloating up object code, you can simply and clearly define defaults objects with a clear intent of being used as a means of storing defaults.

Much like how conforming to Codable gets you a lot for free, so does conforming to DefaultStorable. **The object conforming to DefaultStorable must also conform to Codable:

Say we want to store theme settings in UserDefaults (fair enough right?) we first define our object conforming to Codable and DefaultStorable.

Define object conforming to DefaultStorable

struct VisualSettings: Codable, DefaultStorable {
    let themeName: String
    let backgroundImageURL: URL?
}

Create & Save the object to UserDefaults

let settings = VisualSettings(themeName: "bright", backgroundImageURL: URL(string: "https://..."))
settings.write()

If 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:):

let settings = VisualSettings(themeName: "bright", backgroundImageURL: URL(string: "https://..."))
settings.write(withKey: "someUniqueKey")

Read it back later when ya need it!

if let settings = VisualSettings.read() {
    // Do something
}

If you saved the default under a unque key then it can be read back by providing the optional argument to read(forKey:):

if let settings = VisualSettings.read(forKey: "someUniqueKey") {
    // Do something
}

Swift 4 Codable Support

This library offers support for directly storing custom objects within UserDefaults that conform to Codable. With the release of Swift 4 comes the Codable protocol, which provides support for serializing objects. UserDefaults has not been updated to work with Swift 4's Codable protocol so if saving custom objects directly to UserDefaults is necessary then that object must support NSCoding and inherit from NSObject.

// 1: Declare object (just conform to Codable, getting default encoder / decoder implementation for free)
struct VolumeSetting: Codable {
    let sourceName: String
    let value: Double
}

let setting = VolumeSetting(sourceName: "Super Expensive Headphone Amp", value: 0.4)
let key: String = String(describing: VolumeSetting.self)

// 2: Write
UserDefaults.standard.df.store(setting, forKey: key)

// 3: Read
UserDefaults.standard.df.fetch(forKey: key, type: VolumeSetting.self)

Customization

If the default behaviour of Default does not quite fit your needs, then any of the default implementation details can be overridden.

The most commonly overridden properties are defaultIdentifier and defaults.

defaultIdentifier

defaultIdentifier is the key by which your object will be stored. This defaults to the type name of the object being stored.

  public static var defaultIdentifier: String {
        return String(describing: type(of: self))
    }

defaults

defaults will return the UserDefaults database that your application will store defaults objects in. The default implementation returns UserDefaults.standard

    public static var defaults: UserDefaults {
        return UserDefaults.standard
    }

How does this library work?

UserDefaults requires custom types to confrom to NSCoding and be a subclass of NSObject. Doing that is a little time consuming, and conforming to NSCoding requires implementing Decoding / Encoding methods that take a bit of code to implement. The 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! This library takes advantage of the Codable protocol introduced in Swift 4. The way it works is by taking an object that conforms to Codable and encoding it into a Data object which can then be stored in UserDefaults, then when you want to read it back out again just convert using Codable again!

It's that Simple!

Installation

Carthage

If you use Carthage to manage your dependencies, simply add Default to your Cartfile:

github "Nirma/Default"

If 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.

CocoaPods

If you use CocoaPods to manage your dependencies, simply add Default to your Podfile:

pod 'Default'

Requirements

  • Xcode 9.0
  • Swift 4.0+

Contribution

Contributions are more than welcome!

License

Default is free software, and may be redistributed under the terms specified in the LICENSE file.

Comments
  • Clear key

    Clear key

    What would the proper method for clearing a stored object?

    Would be nice to have:

    var me: User? = nil
    me = User(...)
    me.write()
    ....
    //logout
    me.clear()
    print(me) --> nil
    me.read() --> nil
    
    opened by nitrag 4
  • UserDefaults usage with suiteName

    UserDefaults usage with suiteName

    Thanks for this excellent library,

    I have been using this library with the UserDefaults(suiteName: but I am facing issues in removing all values by removePersistentDomain.

    Is it recommended to use it with UserDefaults(suiteName: ?

    Also can we have remove All or remove feature

    Cheers

    opened by mukyasa 2
  • Seemengly crashes when model of class is changed

    Seemengly crashes when model of class is changed

    Hi,

    Not sure if this is chance or not, but it happened to me twice that fetch crashed after the model (variables) of my class changed. Since changing the model on upgrades is a fairly common thing, I wonder if this can be somehow avoided/repaired?

    opened by jacobokoenig 2
  • Delete .swift-version

    Delete .swift-version

    opened by RomanPodymov 1
  • Hope to support Rxswift

    Hope to support Rxswift

    For example UserDefaults.standard.rx.observe(UserModel.self, "key").subscribe(onNext: { (model) in print(model) }).disposed(by: dis) is not working. because observe is Data, Thx

    opened by github410117 1
  • Function naming

    Function naming

    DefaultStorable

    Instead of:

    static func fetchFromDefaults(key: String?) -> Self?
    func storeToDefaults(key: String?)
    

    I think we should have:

    static func fetch(key: String?) -> Self?
    func store(key: String?)
    

    Or maybe also have the parameter unnamed, not exactly sure on that yet. What do you think about it?

    opened by Cyberbeni 1
  • Support for adding new member to struct

    Support for adding new member to struct

    For example, in my app version 1.1, there is a struct:

    struct A: Codable, DefaultStorable {
      var aMember:Int
    }
    
    A.write()     // ok
    

    In my new version 1.2, the struct has new member:

    struct A: Codable, DefaultStorable {
      var aMember:Int
      var aNewMember:Int
    }
    
    let a = A.read()    // -> nil
    

    Could you please add some way to support migrating old data to new data structure? Some user callbacks, maybe? Right now I have to do it like this:

    if let a = A.read() {
          self.a = a;
     } else if let a1_1 = A1_1.read(forKey: "A.Type") {
          a = A();
          a.aMember = a1_1.aMember;
     }
    opened by peerobo 0
  • Make APPLICATION_EXTENSION_API_ONLY YES on macOS environment

    Make APPLICATION_EXTENSION_API_ONLY YES on macOS environment

    I'm writing a Safari extension application with this framework on the macOS environment, and to use it for App Extension APPLICATION_EXTENSION_API_ONLY option needs to be YES. So, I've changed it to YES on the macOS environment.

    opened by milkcocoa 0
Releases(3.0.0)
  • 3.0.0(Apr 8, 2019)

  • 2.1.0(Jan 7, 2018)

    This release introduces adds a new clear() method that adds a method for deleting Default objects.

    Thanks @nitrag for putting this together!

    Source code(tar.gz)
    Source code(zip)
  • 2.0.0(Nov 20, 2017)

    Summary

    The release's focus is about shortening the read / write method names and adding support for having a default value for when the value being read is currently not stored in the users defaults.

    Changes

    • Writing an object to UserDefaults with Default is now accomplished with: write() or write(withKey:)
    • Reading an object from UserDefaults is now accomplished with read() or read(forKey:)
    • defaultValue has been added to the protocol, the default implementation returns nil can be customized to return a default value when nothing exists in defaults.

    @Cyberbeni Thanks so much for the pull request! Great work! 💯

    Source code(tar.gz)
    Source code(zip)
  • 1.0.0(Oct 19, 2017)

Owner
Nicholas Maccharoli
Day job is iOS / Swift dev mostly, Python and Golang enthusiast. Coding with love since 2007.
Nicholas Maccharoli
Simple, Strongly Typed UserDefaults for iOS, macOS and tvOS

DefaultsKit leverages Swift 4's powerful Codable capabilities to provide a Simple and Strongly Typed wrapper on top of UserDefaults. It uses less than 70 lines of code to acomplish this.

Nuno Dias 1.4k Dec 26, 2022
SecureDefaults is a wrapper over UserDefaults/NSUserDefaults with an extra AES-256 encryption layer

SecureDefaults for iOS, macOS Requirements • Usage • Installation • Contributing • Acknowledgments • Contributing • Author • License SecureDefaults is

Victor Peschenkov 216 Dec 22, 2022
Zephyr synchronizes specific keys and/or all of your UserDefaults over iCloud using NSUbiquitousKeyValueStore.

Zephyr ??️ Effortlessly sync UserDefaults over iCloud About Zephyr synchronizes specific keys and/or all of your UserDefaults over iCloud using NSUbiq

Arthur Ariel Sabintsev 845 Jan 6, 2023
tl;dr You love Swift's Codable protocol and use it everywhere

tl;dr You love Swift's Codable protocol and use it everywhere, who doesn't! Here is an easy and very light way to store and retrieve -reasonable amoun

Omar Albeik 452 Oct 17, 2022
SwiftyUserDefaults - Modern Swift API for NSUserDefaults

SwiftyUserDefaults makes user defaults enjoyable to use by combining expressive Swifty API with the benefits of static typing. Define your keys in one place, use value types easily, and get extra safety and convenient compile-time checks for free.

Luke 4.7k Dec 27, 2022
Modern interface to UserDefaults + Codable support

Default Modern interface to UserDefaults + Codable support What is Default? Default is a library that extends what UserDefaults can do by providing ex

Nicholas Maccharoli 475 Dec 20, 2022
🔥 🔥 🔥Support for ORM operation,Customize the PQL syntax for quick queries,Support dynamic query,Secure thread protection mechanism,Support native operation,Support for XML configuration operations,Support compression, backup, porting MySQL, SQL Server operation,Support transaction operations.

?? ?? ??Support for ORM operation,Customize the PQL syntax for quick queries,Support dynamic query,Secure thread protection mechanism,Support native operation,Support for XML configuration operations,Support compression, backup, porting MySQL, SQL Server operation,Support transaction operations.

null 60 Dec 12, 2022
Why not use UserDefaults to store Codable objects 😉

tl;dr You love Swift's Codable protocol and use it everywhere, who doesn't! Here is an easy and very light way to store and retrieve -reasonable amoun

Omar Albeik 452 Oct 17, 2022
Codable, but with Super power made custom Codable behavior easy.

Codable, but with Super power made custom Codable behavior easy.

Tsungyu Yu 24 Aug 30, 2022
This is a Swift package with support for macOS that allows to start Java Jar's with the default or a custom JVM.

Jar.swift jar runner for macos Jar.swift is created and maintaned with ❥ by Sascha Muellner. What? This is a Swift package with support for macOS that

Swift Package Repository 1 Nov 11, 2021
Swifty and modern UserDefaults

Defaults Swifty and modern UserDefaults Store key-value pairs persistently across launches of your app. It uses NSUserDefaults underneath but exposes

Sindre Sorhus 1.3k Jan 6, 2023
Swifty and modern UserDefaults

Defaults Swifty and modern UserDefaults Store key-value pairs persistently across launches of your app. It uses NSUserDefaults underneath but exposes

Sindre Sorhus 1.3k Dec 31, 2022
CodableCSV - Read and write CSV files row-by-row or through Swift's Codable interface.

CodableCSV provides: Imperative CSV reader/writer. Declarative CSV encoder/decoder. Support multiple inputs/outputs: Strings, Data blobs, URLs, and St

Marcos Sánchez-Dehesa 369 Jan 8, 2023
AppCodableStorage - Extends `@AppStorage` in SwiftUI to support any Codable object

AppCodableStorage Extends @AppStorage in SwiftUI to support any Codable object.

Andrew Pouliot 19 Nov 25, 2022
Modern-collection-view - Modern collection view for swift

Modern collection view Sample application demonstrating the use of collection vi

Nitanta Adhikari 1 Jan 24, 2022
A simple iOS app with one default and four custom transitions.

A simple iOS app with one default and four custom transitions. The app uses the same two view controllers for every transition.

coding_o 7 Aug 18, 2021
Drop in GIF Collection View. Uses Tenor as default GIFs provider.

Drop in GIF Collection View. Uses Tenor as default GIFs provider. This will allow you to easily integrate GIF image search into your app or you can use this as a GIF keyboard for your messaging needs.

null 5 May 7, 2022
A replacement of default action sheet, but has very simple usage

KPActionSheet A replacement of default action sheet, but has very simple usage. Todo Add more custom affects and styles. Installation CocoaPods KPActi

Kenny 7 Jun 27, 2022
iOS 13-compatible backports of commonly used async/await-based system APIs that are only available from iOS 15 by default.

AsyncCompatibilityKit Welcome to AsyncCompatibilityKit, a lightweight Swift package that adds iOS 13-compatible backports of commonly used async/await

John Sundell 367 Jan 5, 2023
A non gesture blocking, non clipping by default custom scroll view implementation with example code

A non gesture blocking, non clipping by default custom scroll view implementation with example code

Marco Boerner 10 Dec 6, 2022