PeakCoreData is a Swift microframework providing enhancements and conveniences to Core Data. It is part of the Peak Framework.
Observers
ManagedObjectObserver
The ManagedObjectObserver class can be used to observe changes made to a single managed object. State changes include when it is refreshed, updated or deleted.
var event: Event!
var eventObserver: ManagedObjectObserver<Event>!
override func viewDidLoad() {
super.viewDidLoad()
eventObserver = ManagedObjectObserver(managedObject: event)
eventObserver.startObserving() { [weak self] obj, changeType in
guard let strongSelf = self else { return }
switch changeType {
case .initialised, .refreshed, .updated:
strongSelf.updateView()
case .deleted:
strongSelf.navigationController?.popToRootViewController(animated: true)
}
}
}CountObserver
The CountObserver class can be used to observe changes to the number of NSManagedObject objects as defined by a generic type and an optional NSPredicate.
var countObserver: CountObserver<Event>!
override func viewDidLoad() {
super.viewDidLoad()
let predicate = NSPredicate(format: "%K == false", argumentArray: [#KeyPath(Event.isHidden)])
countObserver = CountObserver<Event>(predicate: predicate, context: viewContext)
countObserver.startObserving() { [weak self] count in
guard let strongSelf = self else { return }
strongSelf.countLabel.text = String(count)
}
}Fetched Data Sources
FetchedCollection
FetchedCollection is a wrapper for NSFetchedResultsController which acts as its own delegate and exposes changes though a closure.
let fetchedCollection = FetchedCollection(fetchRequest: Event.sortedFetchRequest(), context: viewContext)
fetchedCollection.onChange = { collection, update in
// use collection, or process updates
}
// subscriptable
let object = fetchedCollection[0, 0]
// or with a tuple
let object = fetchedCollection[(0, 0)]
// or with an index path
let object = fetchedCollection[IndexPath(row: 0, section: 0)]
This allows you to decouple the NSFetchedResultsController from your viewcontroller.
FetchedCollectionViewDataSource and FetchedTableViewDataSource
These classes take care of the boiler-plate code needed to use a NSFetchedResultsController with a UITableView or UICollectionView.
class EventsTableViewController: UITableViewController {
var dataSource: FetchedTableViewDataSource<EventsTableViewController>!
override func viewDidLoad() {
super.viewDidLoad()
let frc = NSFetchedResultsController(
fetchRequest: Event.sortedFetchRequest(),
managedObjectContext: viewContext,
sectionNameKeyPath: nil,
cacheName: nil
)
dataSource = FetchedTableViewDataSource(
tableView: tableView,
cellIdentifier: EventTableViewCell.cellIdentifier,
fetchedResultsController: frc,
delegate: self
)
dataSource.animateUpdates = true
dataSource.onDidChangeContent = {
print("Something changed")
}
dataSource.performFetch()
}
}
extension EventsTableViewController: FetchedTableViewDataSourceDelegate {
func identifier(forCellAt indexPath: IndexPath) -> String {
return EventTableViewCell.cellIdentifier
}
func configure(_ cell: EventTableViewCell, with object: Event) {
cell.textLabel?.text = object.date?.description
}
}Operations
CoreDataOperation
CoreDataOperation is a concurrent Operation subclass that can be used to perform core data tasks on a background thread. To use, simply subclass CoreDataOperation then override the performWork(in:) method.
Things to note about this operation:
CoreDataOperationsimply wraps theperformBackgroundTask((NSManagedObjectContext) -> Void)method onNSPersistentContainerin a operation.- To finish the operation you must call
saveAndFinish(). - Changes will only be merged in to your
viewContextif you have set theautomaticallyMergesChangesFromParentonviewContexttotrue. CoreDataOperationconforms toProducesResultand so can be used to produce aResult.
CoreDataChangesetOperation
A CoreDataOperation subclass that returns a Changeset struct containing all the NSManagedObjectID objects that were inserted and updated during the operation.
CoreDataBatchImportOperation and CoreDataSingleImportOperation
Two CoreDataChangesetOperation subclasses that can be used to import an array of intermediate objects or a single intermediate object in to Core Data. They would normally be used to import Decodable objects from your web service. These operations work automatically as long as the following requirements are met:
- The intermediate object must conform to
ManagedObjectUpdatableandUniqueIdentifiable. - The
NSManagedObjecttype you are converting to must conform toManagedObjectTypeandUniqueIdentifiable.
Protocols
ManagedObjectType and UniqueIdentifiable
To give your NSManagedObject subclasses access to a range of helper methods for inserting, deleting, fetching and counting, simply make them conform to the ManagedObjectType and UniqueIdentifiable protocols. Doing so will also allow you to use CoreDataBatchImportOperation and CoreDataSingleImportOperation.
PersistentContainerSettable
Each view controller that needs access to the NSPersistentContainer should conform to PersistentContainerSettable. Conforming to this protocol gives you easy access to the viewContext property and a method for saving the viewContext. It also allows your NSPersistentContainer to be passed around more easily in prepare(for:sender:).
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let controller = segue.destination as? PersistentContainerSettable {
controller.persistentContainer = persistentContainer
}
if let navController = segue.destination as? UINavigationController, let controller = navController.topViewController as? PersistentContainerSettable {
controller.persistentContainer = persistentContainer
}
}Getting Started
Installing
- Using Cocoapods, add
pod 'PeakCoreData'to your Podfile. import PeakCoreDatawhere necessary.
Contributing
Please read CONTRIBUTING.md for details on our code of conduct, and the process for submitting pull requests to us.
Versioning
We use SemVer for versioning.
License
This project is licensed under the MIT License - see the LICENSE.md file for details
Acknowledgments
Peak Framework
The Peak Framework is a collection of open-source microframeworks created by the team at 3Squared, named for the Peak District. It is made up of:
| Name | Description |
|---|---|
| PeakOperation | Provides enhancement and conveniences to Operation, making use of the Result type. |
| PeakNetwork | A networking framework built on top of Session using PeakOperation, leveraging the power of Codable. |
