Prephirences is a Swift library that provides useful protocols and convenience methods to manage application preferences, configurations and app-state. UserDefaults

Overview

Prephirences - Preϕrences

License Platform Language Issues Cocoapod Carthage compatible Build Status

Become a Patron! Buy me a coffee

Prephirences is a Swift library that provides useful protocols and convenience methods to manage application preferences, configurations and app-state.

  @Preference(key: "enabled")
  var enabled: Bool?

  @UserDefaultsPreference(key: "my.string.pref")
  var pref: String?

  @MutablePreference(preferences: UserDefaults.standard, key: "enabled")
  var enabled: Bool?
let userDefaults = UserDefaults.standard
if let enabled = userDefaults["enabled"] as? Bool {..}
userDefaults["mycolorkey", archive] = UIColor.blue

Preferences is not only UserDefaults, it could be also :

  • Keychain to store credential
  • Any dictionary
  • Application information from Bundle
  • File stored preferences (ex: plist)
  • iCloud stored preferences NSUbiquitousKeyValueStore
  • or your own private application preferences

ie. any object which implement the simple protocol PreferencesType, which define key value store methods.

You can also combine multiples preferences and work with them transparently (see Composing)

Contents

Usage

Creating

The simplest implementation of PreferencesType is DictionaryPreferences

// From Dictionary
var fromDico = DictionaryPreferences(myDictionary)
// or literal
var fromDicoLiteral: DictionaryPreferences = ["myKey": "myValue", "bool": true]

// From filepath
if let fromFile = DictionaryPreferences(filePath: "/my/file/path") {..}
// ...in main bundle ##
if let fromFile = DictionaryPreferences(filename: "prefs", ofType: "plist") {..}

Accessing

You can access with all methods defined in PreferencesType protocol

if let myValue = fromDicoLiteral.object(forKey: "myKey") {..}
if let myValue = fromDicoLiteral["bool"] as? Bool {..}

var hasKey = fromDicoLiteral.hasObject(forKey: "myKey")
var myValue = fromDicoLiteral.bool(forKey: "myKey")
..

If you want to access using RawRepresentable enum.

enum MyKey: PreferenceKey/*String*/ {
   case Key1, Key2, ...
}
if let myValue = fromDicoLiteral.object(forKey: MyKey.Key1) {..}
var myValue = fromDicoLiteral.bool(forKey: MyKey.Key2)

⚠️ RawRepresentableKey must be imported, see setup.

Modifying

Modifiable preferences implement the protocol MutablePreferencesTypes

The simplest implementation is MutableDictionaryPreferences

var mutableFromDico: MutableDictionaryPreferences = ["myKey": "myValue"]

mutableFromDico["newKey"] = "newValue"
mutableFromDico.set("myValue", forKey: "newKey")
mutableFromDico.set(true, forKey: "newKey")
...

You can append dictionary or other PreferencesType using operators

mutableFromDico += ["newKey": "newValue", "otherKey": true]

You can also remove one preference

mutableFromDico -= "myKey"

Apply operators to one preference

You can extract a MutablePreference from any MutablePreferencesTypes and apply operators according to its value type

var intPref: MutablePreference<Int> = aPrefs.preference(forKey: "intKey")
var intPref: MutablePreference<Int> = aPrefs <| "intKey"

intPref++
intPref--
intPref += 30
intPref -= 30
intPref *= 20
intPref %= 7
intPref /= 3

switch(intPref) {
   case 1: println("one")
   case 2...10: println("not one or zero but...")
   default: println("unkwown")
}

var boolPref: MutablePreference<Bool> = aPrefs <| "boolKey")

boolPref &= false
boolPref |= true
boolPref != true

You can also use some methods to change value

var stringPref: MutablePreference<String> = userDefaults <| "stringKey"
stringPref.apply { value in
  return value?.uppercaseString
}

or transform the value type using closures

let intFromBoolPref : MutablePreference<Int> = boolPref.transform { value in
  return (value ?? false) ? 1:0
}

Transformation and archiving

Before storing or accessing the value, transformation could be applied, which conform to protocol PreferenceTransformation.

This allow to archive, to change type, return default value if nil and many more.

You can get and set value using subscript

userDefaults["aKey", myTransformation] = myObject

if let object = userDefaults["aKey", myTransformation] {...}

If you extract one preference, use transformation property to setup the transformation

var aPref: MutablePreference<MyObject> = userDefaults <| "aKey"
aPref.transformation = myTransformation

or you can use some utility functions to specify a default value when the stored value match a condition

public var intValueMin10: MutablePreference<Int> {
  get {
    return userDefaults.preference(forKey: "intKey")
          .whenNil(use: 100)
          .ensure(when: lessThan100, use: 100)
  }
  set {..}
}

Archiving

Archiving is particularly useful with NSUserDefaults because NSUserDefaults can't store all type of objects. The following functions could help by transforming the value into an other type

You can archive into Data using this two methods

userDefaults.set(objectToArchive: UIColor.blueColor(), forKey: "colorKey")
userDefaults["colorKey", .Archive] = UIColor.blueColor()

and unarchive using

if let color = userDefaults.unarchiveObject(forKey: "colorKey") as? UIColor {..}
if let color = userDefaults["colorKey", .Archive]  as? UIColor {..}

If you extract one preference, use transformation property to setup archive mode

var colorPref: MutablePreference<UIColor> = userDefaults <| "colorKey"
colorPref.transformation = TransformationKey.Archive
colorPref.value = UIColor.redColor()
if let color = colorPref.value as? UIColor {..}

NSValueTransformer

You can also apply for all objects type an NSValueTransformer, to transform into JSON for instance

userDefaults["colorKey", myValueTransformerToJson] = myComplexObject

if let object = userDefaults["colorKey", myValueTransformerToJson] {...}

⚠️ allowsReverseTransformation must return true

Store RawRepresentable objects

For RawRepresentable objects like enum you can use the computed attribute preferenceTransformation as transformation

enum PrefEnum: String {
    case One, Two, Three
}
var pref: MutablePreference<PrefEnum> = preferences <| "enumKey"
pref.transformation = PrefEnum.preferenceTransformation
pref.value = PrefEnum.Two

Some implementations

UserDefaults

UserDefaults implement PreferencesType and can be acceded with same methods

let userDefaults = UserDefaults.standard

if let myValue = userDefaults["mykey"] as? Bool {..}

NSUserDefaults implement also MutablePreferencesType and can be modified with same methods

userDefaults["mykey"] = "myvalue"
// with type to archive
userDefaults["mykey", .Archive] = UIColor.blueColor()

Bundle

All Bundle implement PreferencesType, allowing to access Info.plist file.

For instance the Bundle.main contains many useful informations about your application.

Prephirences framework come with some predefined enums described in apple documentations and defined in PropertyListKeys.swift

let bundle = Bundle.main
let applicationName = bundle[.CFBundleName] as? String

NSUbiquitousKeyValueStore

To store in iCloud, NSUbiquitousKeyValueStore implement also PreferencesType

See composing chapter to merge and synchronize iCloud preferences with other preferences.

Key Value Coding

Foundation classes

You can wrap an object respond to implicit protocol NSKeyValueCoding in KVCPreferences or MutableKVCPreferences

let kvcPref = MutableKVCPreferences(myObject)

Be sure to affect the correct object type

Swift classes

Using ReflectingPreferences you can easily access to a struct or swift class. Just add extension.

struct PreferenceStruct {
    var color: String = "red"
    var age: Int
    let enabled: Bool = true
}
extension PreferenceStruct: ReflectingPreferences {}

You can then use all functions from PreferencesType

var pref = PreferenceStruct(color: "red", age: 33)
if pref["color"] as? String { .. }

Core Data

You can wrap on NSManageObject in ManageObjectPreferences or MutableManageObjectPreferences

let managedPref = ManageObjectPreferences(myManagedObject)

Plist

There is many way to play with plist files

  • You can use Plist (with the useful write method)
  • You can init DictionaryPreferences or MutableDictionaryPreferences with plist file
  • You can read dictionary from plist file and use set(dictionary: on any mutable preferences

Keychain

To store into keychain, use an instance of KeychainPreferences

KeychainPreferences.sharedInstance // default instance with main bundle id
var keychain = KeychainPreferences(service: "com.github.example")

then store String or Data

keychain["anUserName"] = "password-encoded"

if let pass = keychain.stringForKey("anUserName") {..}

Accessibility

keychain.accessibility = .AccessibleAfterFirstUnlock

Sharing Keychain items

keychain.accessGroup = "AKEY.shared"

NSCoder

NSCoder is partially supported (dictionary is not available)

When you implementing NSCoding you can do

init?(coder decoder: NSCoder) {
  self.init()
  self.intVar = decoder["intVarKey"] as? Int ?? 0
  // or self.intVar = decoder.integer(forKey: "intVar")
  self.stringVar = decoder["stringVarKey"] as? String ?? ""
}

func encodeWithCoder(coder: NSCoder) {
  coder["intVarKey"] = self.intVar
  coder["stringVarKey"] = self.stringVar
}

Custom implementations

Preferences

Create a custom object that conform to PreferencesType is very easy.

extension MyCustomPreferences: PreferencesType {
    func object(forKey: String) -> Any? {
        // return an object according to key
    }
    func dictionary() -> [String : Any] {
        // return a full dictionary of key value
    }
}

Only two functions are mandatory, others are automatically mapped but can be overrided for performance or readability.

  • In the same way you can implement MutablePreferencesType with set and removeObject(forKey: methods.
  • If you structure give a list of keys instead of a full dictionary, you can instead conform to PreferencesAdapter and implement func keys() -> [String].
  • You have a collection of object with each object could define a key and a value take a look at CollectionPreferencesAdapter or see NSHTTPCookieStorage implementation.

Accessing using custom key

Instead of using string or string constants, you can use an enum to define a list of keys

First create your enum with String raw value

enum MyEnum: String {
  case MyFirstKey
  case MySecondKey
}

Then add a subscript for your key

extension PreferencesType {
    subscript(key: MyEnum) -> Any? {
        return self[key.rawValue]
    }
}

Finally access your information

if let firstValue = bundle[.MyFirstKey] {..}

You can do the same with MutablePreferencesType

Proxying preferences with prefix

You can defined a subcategory of preferences prefixed with your own string like that

let myAppPrefs = MutableProxyPreferences(preferences: userDefaults, key: "myAppKey.")
// We have :
userDefaults["myAppKey.myKey"] == myAppPrefs["myKey"] // is true

This allow prefixing all your preferences (user defaults) with same key

Composing

Composing allow to aggregate multiples PreferencesType objects into one PreferencesType

let myPreferences = CompositePreferences([fromDico, fromFile, userDefaults])
// With array literal
let myPreferences: CompositePreferences = [fromDico, fromFile, userDefaults]

// Mutable, only first mutable will be affected
let myPreferences: MutableCompositePreferences = [fromDico, fromFile, userDefaults]

You can access or modify this composite preferences like any PreferencesType.

  1. When accessing, first preferences that define a value for a specified key will respond
  2. When modifying, first mutable preferences will be affected by default, but you can set MutableCompositePreferences attribute affectOnlyFirstMutable to false to affect all mutable preferences, allowing you for instance to duplicate preferences in iCloud

The main goal is to define read-only preferences for your app (in code or files) and some mutable preferences (like UserDefaults, NSUbiquitousKeyValueStore). You can then access to one preference value without care about the origin.

Managing preferences instances

If you want to use Prephirences into a framework or want to get a Preferences without adding dependencies between classes, you can register any PreferencesType into Prephirences

as shared instance

Prephirences.sharedInstance = myPreferences

or by providing an Hashable key

Prephirences.register(preferences: myPreferences, forKey: "myKey")
Prephirences.instances()["myKey"] = myPreferences
Prephirences.instances()[NSStringFromClass(self.dynamicType)] = currentClassPreferences

Then you can access it anywhere

if let pref = Prephirences.instance(forKey: "myKey") {..}
if let pref = Prephirences.instances()["myKey"] {..}

Remote preferences

By using remote preferences you can remotely control the behavior of your app.

If you use Alamofire, Alamofire-Prephirences will help you to load preferences from remote JSON or Plist

Encrypt your preferences

You can use framework CryptoPrephirences to encrypt/decrypt your preferences using cipher from CryptoSwift

Setup

Using Cocoapods

CocoaPods is a centralized dependency manager for Objective-C and Swift. Go here to learn more.

  1. Add the project to your Podfile.

    use_frameworks!
    
    pod 'Prephirences'
  2. Run pod install and open the .xcworkspace file to launch Xcode.

For core data

Add pod 'Prephirences/CoreData'

For RawRepresentable key

Add pod 'Prephirences/RawRepresentableKey'

For PropertyListKeys

Add pod 'Prephirences/Keys'

Using Carthage

Carthage is a decentralized dependency manager for Objective-C and Swift.

  1. Add the project to your Cartfile.

    github "phimage/Prephirences"
    
  2. Run carthage update and follow the additional steps in order to add Prephirences to your project.

Using xcode project

  1. Drag Prephirences.xcodeproj to your project/workspace or open it to compile it
  2. Add the Prephirences framework to your project

Logo

By kodlian

Comments
  • Unable to store to keychain

    Unable to store to keychain

    Hey there,

    This was working fine for me previously, but now that I've started to prepare my project for appstore release (creating separate environment for dev/staging/prod as well as having different app id's for each of them), I'm unable to store strings in the keychain....

    I'm not sure what I'm missing. It works fine if I save to lets say user defaults, but for some reason it stopped working saving to the keychain.

    Is there anything you can think of that needs to be enabled in order to use the keychain? Am I missing some entitlements (Keychain Sharing is turned off, since I don't want to share items that I store)?

    Sorry I know this most likely has nothing to do with your code, but hoping you can help me out. I've tried to Google this and wasted all day today to figure this out but I'm not getting anywhere.

    Thanks

    bug 
    opened by jyounus 6
  • Add PreferencesTabViewController to project

    Add PreferencesTabViewController to project

    Hello I tried to follow your Readme but i currently get this error:

    2015-07-26 20:49:18.408 T-Rex[50694:618288] An uncaught exception was raised
    2015-07-26 20:49:18.408 T-Rex[50694:618288] Cannot remove an observer <Prephirences.PreferencesTabViewController 0x608000101290> for the key path "preferencesTabViewSize" from <T_Rex.GeneralPreferencesView 0x608000100a20> because it is not registered as an observer.
    

    I did the following setup:

    • Added NSTabViewController in storyboard
    • Set its class to PreferencesTabViewController
    • Set PreferencesTabViewController delegate to the "No Shadow Tab View"
    • Changed Custom Classes of all of the tabs NSViewControllers to my own implementations
    • Own ViewController implementation follows this template:
    
    import Cocoa
    import Prephirences
    
    class GeneralPreferencesView : NSViewController, PreferencesTabViewItemControllerType {
        //if content changes, set this variable accordingly in order to update tab size automatically
        var preferencesTabViewSize: NSSize = NSSize(width: 0, height: 300)
    
    }
    
    

    Not sure what I am doing wrong ?! The error is due to an unset observer to preferencesTabViewSize but I don't know what I am missing ?

    opened by dehlen 4
  • Logo.png is part of the compiled framework

    Logo.png is part of the compiled framework

    Hey there,

    I've noticed that when I compile my project and check the IPA file (extract it), the Prephirences.framework file has the Logo.png file inside of it.

    It's not a big deal, but would be great if it could be excluded. I've included a screenshot. I'm using this with Cocoapods.

    EDIT: I'm assuming the logo isn't needed, which is why I've opened this "issue".

    Thanks

    Screenshot

    opened by jyounus 3
  • Minor typo in readme

    Minor typo in readme

    I just noticed a typo in the readme and thought I'd point it out as opposed to assuming "someone else will do it."

    Under Transformation and Archiving you have substrict where you likely meant subscript.

    opened by thecodewarrior 2
  • Xcode 7.3 & Swift 2.2

    Xcode 7.3 & Swift 2.2

    Hey,

    Now that both of them are officially released, are you planning to merge the Swift 2.2 branch into master and push a new update to Cocoapods any time soon? Or are there some issues that you still need to sort out first?

    Thanks

    opened by jyounus 2
  • Compilation error by Xcode7.0 beta6.

    Compilation error by Xcode7.0 beta6.

    Hi, I integrated prephirences into my project by cocopoads, the code is pod 'Prephirences', :git => 'https://github.com/phimage/Prephirences.git', :branch => '2.0.0'. Now in Xcode7.0 beta6 i get a compilation error. Type 'Bool' does not comform to protocol 'LogicalOperationsType', in Preference.swift line 256. I don't know how to fix it, could you please help me? Thank you!

    opened by chenjsa 2
  • NSUserDefaults does not have a member named 'subscript'

    NSUserDefaults does not have a member named 'subscript'

    Don't know if I'm doing something wrong here, but just tried the example and it throws an error.

    let userDefaults = NSUserDefaults.standardUserDefaults()
    
    if let myValue = userDefaults["mykey"] as? Bool {..}
    

    NSUserDefaults does not have a member named 'subscript'

    If I use objectForKey, it works.

    let userDefaults = NSUserDefaults.standardUserDefaults()
    
    if let myValue = userDefaults.objectForKey("mykey") as? Bool {..}
    

    Same situation when trying to modify it. userDefaults["mykey"] = "myvalue" does not work.

    opened by sebastiaanluca 2
  • Ini file parsing and Automatic UI/View building

    Ini file parsing and Automatic UI/View building

    Hi Eric,

    Hope you are doing well !

    I was looking at your great repo and was wondering if there is a way to parse a local .ini configuration file (please find below an example) and to load the settings, and build a cascade series of views for each sections and switch parameters from the app. The ciphering features is really cool btw !

    Excerpt of the .ini file:

    [Homography]
    allCornersVisible=false
    homographyComputed=true
    ignoreWhenAllInliers=false
    method="1:LMEDS;RANSAC;RHO"
    minAngle=0
    minimumInliers=10
    opticalFlow=false
    opticalFlowEps=0.01
    opticalFlowIterations=30
    opticalFlowMaxLevel=3
    opticalFlowWinSize=16
    ransacReprojThr=5
    rectBorderWidth=4
    
    [NearestNeighbor]
    1Strategy="1:Linear;KDTree;KMeans;Composite;Autotuned;Lsh;BruteForce"
    2Distance_type="0:EUCLIDEAN_L2;MANHATTAN_L1;MINKOWSKI;MAX;HIST_INTERSECT;HELLINGER;CHI_SQUARE_CS;KULLBACK_LEIBLER_KL;HAMMING"
    3nndrRatioUsed=true
    4nndrRatio=0.8
    5minDistanceUsed=false
    6minDistance=1.6
    7ConvertBinToFloat=false
    Autotuned_build_weight=0.01
    Autotuned_memory_weight=0
    Autotuned_sample_fraction=0.10000000000000001
    Autotuned_target_precision=0.80000000000000004
    BruteForce_gpu=false
    Composite_branching=32
    Composite_cb_index=0.20000000000000001
    Composite_centers_init="0:RANDOM;GONZALES;KMEANSPP"
    Composite_iterations=11
    Composite_trees=4
    KDTree_trees=4
    KMeans_branching=32
    KMeans_cb_index=0.20000000000000001
    KMeans_centers_init="0:RANDOM;GONZALES;KMEANSPP"
    KMeans_iterations=11
    Lsh_key_size=20
    Lsh_multi_probe_level=2
    Lsh_table_number=12
    search_checks=32
    search_eps=0
    

    Thanks in advance. As we are on github, I wrote it in english but I am french too :-)

    Cheers, Luc Michalski

    opened by ghost 1
  • Update sharedInstance type

    Update sharedInstance type

    sharedInstance is type MutableDictionaryPreferences, however the definition does not specify it's mutability.

    This particularly causes an issue when using Alamofire-Prephirences because the associated extensions only work with MutablePreferencesType.

    opened by brandons 1
  • Example App?

    Example App?

    Not an issue ...

    Great framework! Any chance you have (or know of) a sample application that use prephirences? it would be great to see how you use this in practice (beyond the snippets in the Read Me).

    Thanks!

    enhancement 
    opened by MikeManzo 1
  • Updated Keychain accessible Docs to latest API

    Updated Keychain accessible Docs to latest API

    Hi, thanks for all your work.

    While reading through your README and playing around with Prephirences, I noticed the .accessibility-property has been renamed to .accessible. And all enum cases of SecurityAttributeAccessible were renamed, too.

    opened by vknabel 0
  • UserDefaults clearAll doesn't work with a custom suite name

    UserDefaults clearAll doesn't work with a custom suite name

    In order to share preferences between my app and its extensions, I'm using UserDefaults(suiteName: "someSuiteName") instead UserDefaults.standard.

    Because of the custom suite (domain name), the method clearAll from Prephirences doesn't work, as it uses the bundle identifier as the domain name (as implemented here: https://github.com/phimage/Prephirences/blob/5.0.1/Sources/UserDefaults%2BPrephirences.swift#L64).

    Could you please provide some support for a custom suiteName?

    opened by cassianodialpad 0
  • Possible issue with keychain and archiving objects

    Possible issue with keychain and archiving objects

    I believe I am having an issue when trying to get archived objects from the keychain.

    They always come back as nil.

    Take the following code:

            var preferences = UserDefaults.standard
            preferences["color", .archive] = UIColor.red
            let color = preferences["color", .archive]  as? UIColor
            print(color)
            
            var keychainPreferences = KeychainPreferences.sharedInstance
            keychainPreferences["color2", .archive] = UIColor.red
            let color2 = keychainPreferences["color2", .archive]  as? UIColor
            print(color2)
    

    Results in:

    Optional(UIExtendedSRGBColorSpace 1 0 0 1)
    nil
    
    bug 
    opened by jsm174 2
Releases(5.3.1)
  • 5.2.0(May 29, 2021)

    Update with Xcode 12.5, fix swift test

    add some property wrapper

    @KeychainPreference(key: "xxx" ) var securePref: String?
    
    @BundlePreference(coreFoundationKeys: .CFBundleInfoDictionaryVersion ) var version: String?
    
    Source code(tar.gz)
    Source code(zip)
  • 5.1.0(Oct 2, 2019)

    Update to swift 5.1

    Property wrapper

    @Preference(key: "enabled")
      var enabled: Bool?
    
      @UserDefaultsPreference(key: "my.string.pref")
      var pref: String?
    
      @MutablePreference(preferences: UserDefaults.standard, key: "enabled")
      var enabled: Bool?
    

    Dynamic member

    UserDefaults.standard.myValue
    
    Source code(tar.gz)
    Source code(zip)
  • 5.0.0(Oct 2, 2019)

  • 4.1.0(Sep 18, 2018)

  • 4.0.1(Apr 27, 2018)

  • 4.0.0(Apr 27, 2018)

  • 3.0.0(Sep 16, 2016)

  • 2.2.1(Jul 27, 2016)

    • some utility functions to specify a default value when the stored value match a condition
     public var intValueMin10: MutablePreference<Int> {
       get {
         return userDefaults.preferenceForKey("intKey")
               .whenNil(use: 100)
              .ensure(when: lessThan100, use: 100)
      }
     set {..}
    }
    
    • and... new protocol PreferenceTransformation : Before storing or accessing the value, transformation could be applied. This allow to archive, to change type, return default value if nil and many more.
    userDefaults["aKey", myTransformation] = myObject
    

    :warning: TransformationKey implement this protocol. transfomationattribute of MutablePreference has type changed. If you use before aPref.transformation = .Archive. Now you must use aPref.transformation = TransformationKey.Archive or aPref.transformationKey = Transformation.Archive

    • Utility functions for RawRepresentable objects

      • get an RawRepresentableobject with rawRepresentableForKey and set with setRawValue
      • For RawRepresentable objects like enum you can use the computed attribute preferenceTransformation as transformation
      enum PrefEnum: String { case One, Two, Three}
      var pref: MutablePreference<PrefEnum> = preferences <| "enumKey"
      pref.transformation = PrefEnum.preferenceTransformation
      pref.value = PrefEnum.Two
      
    Source code(tar.gz)
    Source code(zip)
  • 2.2.0(Jul 27, 2016)

  • 2.0.8(Jul 27, 2016)

    NSCoder implement MutablePreferencesType

     init?(coder decoder: NSCoder) {
       self.init()
       self.intVar = decoder["intVarKey"] as? Int ?? 0
       // or self.intVar = decoder.integerForKey("intVar")
       self.stringVar = decoder["stringVarKey"] as? String ?? ""
     }
    
     func encodeWithCoder(coder: NSCoder) {
       coder["intVarKey"] = self.intVar
       coder["stringVarKey"] = self.stringVar
     }
    
    
    Source code(tar.gz)
    Source code(zip)
  • 2.0.5(Dec 16, 2015)

    Allow to adapt a collection to PreferencesType

    • using two closures, one to get key, the other to get the value from the collection element
    struct Couple {
         var name: String
         var value: AnyObject
    }
    let collection: [Couple] = ...
    let preferences = CollectionPreferencesAdapter(
         collection: collection,
         mapKey: {$0.name}
         mapValue: {$0.value}
    )
    

    For instance NSHTTPCookieStorage which contains a collection of NSHTTPCookie conform now to protocol PreferencesType

    Source code(tar.gz)
    Source code(zip)
  • 2.0.4(Dec 2, 2015)

    • Access application informations from NSBundle (which now conform to PreferencesType)
    let bundle = NSBundle.mainBundle()
    let applicationName = bundle[.CFBundleName] as? String
    
    • Add information about setup using Carthage

    Carthage compatible

    Source code(tar.gz)
    Source code(zip)
  • 2.0.3(Nov 24, 2015)

    • Operator or subscript to archive/convert object
    userDefaults["mycolorkey", .Archive] = UIColor.blueColor()
    
    • any object could conform to PreferencesType by extending ReflectingPreferences
    struct PreferenceStruct {
        var color: String = "red"
        var age: Int
        let enabled: Bool = true
    }
    extension PreferenceStruct: ReflectingPreferences {}
    if pref["color"] as? String { .. }
    
    • PreferencesController to allow binding on all PreferencesType (inspired from NSUserDefaultsController) for OSX
    Source code(tar.gz)
    Source code(zip)
  • 2.0.2(Nov 1, 2015)

    New

    Add tvOS, watchOS compatibility

    Change

    Change logo Remove many redundant code using protocol extension Move operators to a separate file

    Fix

    Fix Plist write immediatly if using one of set methods

    Source code(tar.gz)
    Source code(zip)
  • 2.0.1(Sep 30, 2015)

  • 2.0.0(Sep 18, 2015)

  • 1.2.2(Jul 30, 2015)

  • 1.2.1(Jun 16, 2015)

  • 1.2.0(Jun 10, 2015)

    Add Preference<T> where T is the type of value for a specific preference key Operators can be applied to MutablePreference<T> to modify preferences

    Source code(tar.gz)
    Source code(zip)
  • 1.1.0(Jun 8, 2015)

  • 0.0.2(May 20, 2015)

Owner
Eric Marchand
🧙🍺🥊🥋🏓
Eric Marchand
🔍 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
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 Dec 26, 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.3k Dec 31, 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 841 Dec 23, 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
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
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 216 Dec 22, 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
Elegant library to manage the interactions between view and model in Swift

An assistant to manage the interactions between view and model ModelAssistant is a mediator between the view and model. This framework is tailored to

Seyed Samad Gholamzadeh 28 Jan 29, 2022
GraphQLite is a toolkit to work with GraphQL servers easily. It also provides several other features to make life easier during iOS application development.

What is this? GraphQLite is a toolkit to work with GraphQL servers easily. It also provides several other features to make life easier during iOS appl

Related Code 2.8k Jan 9, 2023
iForage helps foragers to track and manage foraging spots around them using CloudKit

iForage CloudKit Preface To expand on what I've created here: https://github.com/LynchConnor/iForage, I initially developed the app using Firebase. Th

Connor Lynch 3 Jul 14, 2022
Views as functions of their state.

Few.swift React-inspired library for writing AppKit/UIKit UIs which are functions of their state.1 SwiftBox is used for layout. Why UIs are big, messy

Josh Abernathy 1.1k Dec 24, 2022
KeyPathKit is a library that provides the standard functions to manipulate data along with a call-syntax that relies on typed keypaths to make the call sites as short and clean as possible.

KeyPathKit Context Swift 4 has introduced a new type called KeyPath, with allows to access the properties of an object with a very nice syntax. For in

Vincent Pradeilles 406 Dec 25, 2022
A library that provides the ability to import/export Realm files from a variety of data container formats.

Realm Converter Realm Converter is an open source software utility framework to make it easier to get data both in and out of Realm. It has been built

Realm 212 Dec 9, 2022
CloudKit, Apple’s remote data storage service, provides a possibility to store app data using users’ iCloud accounts as a back-end storage service.

CloudKit, Apple’s remote data storage service, provides a possibility to store app data using users’ iCloud accounts as a back-end storage service. He

Yalantis 252 Nov 4, 2022
Ios-App-ication-Swift - A simple iOS application made in Xcode using Swift

?? iPhone Calculator A simple iOS application made in Xcode using Swift. This ap

Kushal Shingote 1 Feb 2, 2022
A Library for iOS developers to check newer version of app from the app store

swift-app-update-checker A very simple solution check new version of your application is available on store or not. Example To run the example project

wajeehulhassan 6 May 13, 2022
Link - a macos application for keeping important and complicated urls in one place

Link Description Link is a macos application for keeping important and complicat

Johan Solbakken 2 Jul 21, 2022
A external macos application to generate and execute tuist commands

Tuist Menu Bar App An external macos application to generate and execute tuist commands. How it works? Parses all tasks and their arguments with the -

Aytug Sevgi 3 May 25, 2022