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

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

= 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("unknown") } var boolPref: MutablePreference = aPrefs <| "boolKey") boolPref &= false boolPref |= true boolPref != true ">
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("unknown")
}

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 = 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 = 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 = 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.accessible = .afterFirstUnlock

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 overridden 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
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
💾 Safe, statically-typed, store-agnostic key-value storage written in Swift!

Storez ?? Safe, statically-typed, store-agnostic key-value storage Highlights Fully Customizable: Customize the persistence store, the KeyType class,

Kitz 67 Aug 7, 2022
SwiftStore - Key/Value store for Swift backed by LevelDB.

SwiftStore Key/Value store for Swift backed by LevelDB. Usage Create instances of store import SwiftStore

Hemant Sapkota 119 Dec 21, 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
Swift package to get the current user.

whoami.swift Retrieve the current user and environment through simple functions. This package can: Get the user's full name Get the user's username Ge

Nikita Rossik 0 Dec 29, 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
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
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
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
Convenience methods for creating color using RGBA hex string.

UIColor+Hex, now Swift. Convenience method for creating autoreleased color using RGBA hex string.

R0CKSTAR 1.2k Dec 23, 2022
Luminous provides you a lot of information about the system and a lot of handy methods to quickly get useful data on the iOS platform.

Luminous Example To run the example project, clone the repo, and run pod install from the Example directory first. Requirements iOS 8+ Swift 5 Xcode 1

Andrea Mario Lufino 324 Nov 27, 2022
Luminous provides you a lot of information about the system and a lot of handy methods to quickly get useful data on the iOS platform.

Luminous Example To run the example project, clone the repo, and run pod install from the Example directory first. Requirements iOS 8+ Swift 5 Xcode 1

Andrea Mario Lufino 324 Nov 27, 2022
Xcode Plugin helps you find missing methods in your class header, protocols, and super class, also makes fast inserting.

FastStub-Xcode Life is short, why waste it on meaningless typing? What is it? A code generating feature borrowed from Android Studio. FastStub automat

mrpeak 509 Jun 29, 2022
A wrapper around UICollectionViewController enabling a declarative API around it's delegate methods using protocols.

Thunder Collection Thunder Collection is a useful framework which enables quick and easy creation of collection views in iOS using a declarative appro

3 SIDED CUBE 4 Nov 6, 2022
Swift library that makes easier to serialize the user's preferences (app's settings) with system User Defaults or Property List file on disk.

PersistentStorageSerializable PersistentStorageSerializable is a protocol for automatic serialization and deserialization of Swift class, struct or NS

Ivan Rublev 163 Jun 3, 2021
Async State Machine aims to provide a way to structure an application thanks to state machines

Async State Machine Async State Machine aims to provide a way to structure an application thanks to state machines. The goal is to identify the states

Thibault Wittemberg 27 Nov 17, 2022
⚙ Add a preferences window to your macOS app in minutes

Preferences Add a preferences window to your macOS app in minutes Just pass in some view controllers and this package will take care of the rest. Requ

Sindre Sorhus 1.2k Jan 6, 2023
SwiftUI library to display a clock. You can move the arms to change the time, change the style of the clock and customise some configurations.

SwiftClockUI Clock UI for SwiftUI This library has been tested ✅ ?? macOS Catalina 10.15.3 ✅ ?? macOS Big Sur 11.6 ✅ ?? iOS 13 ✅ ?? iOS 14 ✅ ?? iOS 15

Renaud Jenny 239 Dec 29, 2022
Demonstration of using UIWindowScene and SwiftUI to provide a native-looking Mac preferences window in Catalyst

CatalystPrefsWindow Ever wondered how to create a more Mac-like preferences window for Catalyst? Perhaps Settings Bundles are too limiting for the kin

Steven Troughton-Smith 148 Dec 27, 2022
A micro UIStackView convenience API inspired by SwiftUI

Stacks A micro UIStackView convenience API inspired by SwiftUI. let stack: UIView = .hStack(alignment: .center, margins: .all(16), [ .vStack(spaci

Alexander Grebenyuk 74 Jul 27, 2022