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
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
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.2k Nov 16, 2022
AppCodableStorage - Extends `@AppStorage` in SwiftUI to support any Codable object

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

Andrew Pouliot 18 Nov 3, 2022
Effortlessly synchronize UserDefaults over iCloud.

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

Arthur Ariel Sabintsev 837 Nov 11, 2022
Prephirences is a Swift library that provides useful protocols and convenience methods to manage application preferences, configurations and app-state. UserDefaults

Prephirences - Preϕrences Prephirences is a Swift library that provides useful protocols and convenience methods to manage application preferences, co

Eric Marchand 557 Nov 22, 2022
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

Nuno Dias 1.4k Nov 20, 2022
A lightweight wrapper over UserDefaults/NSUserDefaults with an additional layer of AES-256 encryption

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

Victor Peschenkov 212 Nov 14, 2022
🔍 Browse and edit UserDefaults on your app

UserDefaults-Browser Browse and edit UserDefaults on your app. (SwiftUI or UIKit) Browse Edit (as JSON) Edit (Date) Export Note: We recommend to use S

Yusuke Hosonuma 25 Nov 3, 2022
⚙️ A tiny property wrapper for UserDefaults. Only 60 lines of code.

⚙️ A tiny property wrapper for UserDefaults. Only 60 lines of code. import Persistent extension UserDefaults { // Optional property @Per

Mezhevikin Alexey 6 Sep 28, 2022
Store and retrieve Codable objects to various persistence layers, in a couple lines of code!

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 Codable objects t

null 148 Nov 3, 2022
CodableFiles - Save and load Codable objects from DocumentDirectory on iOS Devices.

Welcome to CodableFiles, a simple library that provides an easier way to save, load or delete Codable objects in Documents directory. It’s primarily a

Egzon Pllana 35 Sep 19, 2022
CodableCloudKit allows you to easily save and retrieve Codable objects to iCloud Database (CloudKit)

CodableCloudKit CodableCloudKit allows you to easily save and retrieve Codable objects to iCloud Database (CloudKit) Features ℹ️ Add CodableCloudKit f

Laurent Grondin 65 Oct 23, 2022
MoreCodable expands the possibilities of `Codable`.

MoreCodable MoreCodable expands the possibilities of "Codable". Installation Carthage github "tattn/MoreCodable" CocoaPods pod 'MoreCodable' Feature D

Tatsuya Tanaka 371 Nov 1, 2022
Typed key-value storage solution to store Codable types in various persistence layers with few lines of code!

?? Stores A typed key-value storage solution to store Codable types in various persistence layers like User Defaults, File System, Core Data, Keychain

Omar Albeik 81 Nov 15, 2022
Modern Swift API for NSUserDefaults

SwiftyUserDefaults Modern Swift API for NSUserDefaults SwiftyUserDefaults makes user defaults enjoyable to use by combining expressive Swifty API with

Luke 4.7k Nov 16, 2022
A demo app to showcase pixel perfect, modern iOS development with SwiftUI and Combine on MVVM-C architecture.

Pixel_Perfect_SwiftUI A demo app to showcase pixel perfect, modern iOS development with SwiftUI and Combine on MVVM-C architecture. Tech Stack: Swift,

Burhan Aras 0 Jan 9, 2022
Modern Swift API for NSUserDefaults

SwiftyUserDefaults Modern Swift API for NSUserDefaults SwiftyUserDefaults makes user defaults enjoyable to use by combining expressive Swifty API with

Luke 4.7k Nov 16, 2022
A MongoDB interface for Swift [Not under active development]

MongoDB #This library is no longer under active development. I highly recommend using the robust, pure-swift alternative MongoKitten. A Swift MongoDB

Dan Appel 266 Jan 29, 2022
A stand-alone Swift wrapper around the FileMaker XML Web publishing interface, enabling access to FileMaker servers.

Perfect - FileMaker Server Connector This project provides access to FileMaker Server databases using the XML Web publishing interface. This package b

PerfectlySoft Inc. 33 Jul 13, 2022