Simple object persistence in Swift.
Includes support for NSUserDefaults
, NSUbiquitousKeyValueStore
and the file system.
Add the following to your Podfile:
pod 'PersistentObject'
Add the following to your Cartfile:
github "mattcomi/PersistentObject"
To persist an object, initialize a PersistentObject
with the desired repository. For example, to persist a Vehicle
to a file:
let persistentVehicle = PersistentObject<Vehicle>(filename: "file.txt")
Or, to persist a Person
to the NSUserDefaults
database:
let persistentPerson = PersistentObject<Person>(userDefaultsKey: personKey)
If a PersistentObject
exists in the repository, that is, if it has been persisted previously, it will be unarchived and initialized. To access the underlying object:
if let person = persistentPerson.object {
print("Hi, my name is \(person.name)")
}
If a PersistentObject
does not yet exist in the repository, you will need to initialize it yourself:
if persistentPerson.object == nil {
persistentPerson.reset(Person(name: "Brian Doyle-Murray"))
}
The underlying object is automatically archived to its repository when the app enters the background and when the PersistentObject
is deinitialized. You may also trigger it manually:
persistentPerson.save()
You may also synchronize the repository:
persistentPerson.synchronize()
Manual synchronization is typically only necessary when:
- The underlying repository is a
UbiquituousKeyValueStoreRepository
- You require fast-as-possible upload to iCloud after changing the object
The follow repositories are supported currently:
FileRepository
: Persists to a fileUbiquituousKeyValueStoreRepository
: Persists to theUbiquituousKeyValueStore
UserDefaultsRepository
: Persists to theUserDefaults
database
These repositories require that the object being persisted is NSCoding
compliant.
A Repository
may support external changes. For example, when using the UbiquituousKeyValueStoreRepository
, it is possible for the value to change in iCloud. If an external change occurs, the PersistentObject
's underlying object is replaced, invalidating any references. To be notified when this occurs, provide a delegate when initializing the PersistentObject
:
let delegate = PersistentObjectDelegate<Person>()
delegate.objectChangedExternally = { (persistentObject) in
// handle the external change
}
let p = PersistentObject<Person>(
ubiquituousKeyValueStoreKey: "personKey",
delegate: delegate)
To provide a custom repository, you may implement the Repository
protocol:
public protocol Repository {
associatedtype ObjectType
var delegate: RepositoryDelegate<ObjectType> { get }
func archive(_ object: ObjectType?)
func unarchive() -> ObjectType
func synchronize()
}
Then, to initialize a PersistentObject
with that Repository
:
let p = PersistentObject<Person>(repository: MyCustomRepository())