Prephirences - Preϕrences
Prephirences is a Swift library that provides useful protocols and convenience methods to manage application preferences, configurations and app-state.
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
- Setup
- Logo
Usage
Creating
The simplest implementation of PreferencesType is DictionaryPreferences
Accessing
You can access with all methods defined in PreferencesType protocol
If you want to access using RawRepresentable
enum
.
:warning: RawRepresentableKey must be imported, see setup.
Modifying
Modifiable preferences implement the protocol MutablePreferencesTypes
The simplest implementation is MutableDictionaryPreferences
You can append dictionary or other PreferencesType
using operators
You can also remove one preference
Apply operators to one preference
You can extract a MutablePreference
from any MutablePreferencesTypes
and apply operators according to its value type
You can also use some methods to change value
or transform the value type using closures
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
If you extract one preference, use transformation
property to setup the transformation
or you can use some utility functions to specify a default value when the stored value match a condition
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
and unarchive using
If you extract one preference, use transformation
property to setup archive mode
NSValueTransformer
You can also apply for all objects type an NSValueTransformer
, to transform into JSON for instance
:warning: allowsReverseTransformation
must return true
Store RawRepresentable objects
For RawRepresentable
objects like enum
you can use the computed attribute preferenceTransformation
as transformation
Some implementations
UserDefaults
UserDefaults
implement PreferencesType
and can be acceded with same methods
NSUserDefaults implement also MutablePreferencesType
and can be modified with same methods
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
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
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.
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
Plist
There is many way to play with plist files
- You can use
Plist
(with the usefulwrite
method) - You can init
DictionaryPreferences
orMutableDictionaryPreferences
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
then store String
or Data
Accessibility
Sharing Keychain items
NSCoder
NSCoder
is partially supported (dictionary
is not available)
When you implementing NSCoding you can do
Custom implementations
Preferences
Create a custom object that conform to PreferencesType
is very easy.
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
withset
andremoveObject(forKey:
methods. - If you structure give a list of keys instead of a full dictionary, you can instead conform to
PreferencesAdapter
and implementfunc keys() -> [String]
. - You have a collection of object with each object could define a key and a value take a look at
CollectionPreferencesAdapter
or seeNSHTTPCookieStorage
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
Then add a subscript for your key
Finally access your information
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
This allow prefixing all your preferences (user defaults) with same key
Composing
Composing allow to aggregate multiples PreferencesType objects into one PreferencesType
You can access or modify this composite preferences like any PreferencesType
.
- When accessing, first preferences that define a value for a specified key will respond
- When modifying, first mutable preferences will be affected by default, but you can set
MutableCompositePreferences
attributeaffectOnlyFirstMutable
tofalse
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
or by providing an Hashable
key
Then you can access it anywhere
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.
-
Add the project to your Podfile.
-
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.
-
Add the project to your Cartfile.
github "phimage/Prephirences"
-
Run
carthage update
and follow the additional steps
in order to add Prephirences to your project.
Using xcode project
- Drag Prephirences.xcodeproj to your project/workspace or open it to compile it
- Add the Prephirences framework to your project