HardcoreData
Simple, elegant, and smart Core Data programming with Swift
Features
- Supports multiple persistent stores per data stack, just the way .xcdatamodeld files are supposed to. HardcoreData will also manage one data stack by default, but you can create and manage as many as you need. (see "Setting up")
- Ability to plug-in your own logging framework (or your favorite 3rd-party logger). (see "Logging and error handling")
- Makes it hard to fall into common concurrency mistakes. All Core Data tasks are encapsulated into safer, higher-level abstractions without sacrificing flexibility and customizability. (see "Saving and processing transactions")
- Provides convenient API for common use cases. (see "Fetching and querying")
- Pleasant API designed around Swift’s code elegance and type safety. (see "TL;DR sample codes")
TL;DR sample codes
Quick-setup:
HardcoreData.defaultStack.addSQLiteStore("MyStore.sqlite")
Simple transactions:
HardcoreData.beginAsynchronous { (transaction) -> Void in
let object = transaction.create(MyEntity)
object.entityID = 1
object.name = "test entity"
transaction.commit { (result) -> Void in
switch result {
case .Success(let hasChanges): println("success!")
case .Failure(let error): println(error)
}
}
}
Easy fetching:
let objects = HardcoreData.fetchAll(From(MyEntity))
let objects = HardcoreData.fetchAll(
From(MyEntity),
Where("entityID", isEqualTo: 1),
SortedBy(.Ascending("entityID"), .Descending("name")),
CustomizeFetch { (fetchRequest) -> Void in
fetchRequest.includesPendingChanges = true
}
)
Simple queries:
let count = HardcoreData.queryValue(
From(MyEntity),
Select<Int>(.Count("entityID"))
)
Architecture
For maximum safety and performance, HardcoreData will enforce coding patterns and practices it was designed for. (Don't worry, it's not as scary as it sounds.) But it is advisable to understand the "magic" of HardcoreData before you use it in your apps.
If you are already familiar with the inner workings of CoreData, here is a mapping of HardcoreData abstractions:
| Core Data | HardcoreData |
|---|---|
NSManagedObjectModel / NSPersistentStoreCoordinator(.xcdatamodeld file) |
DataStack |
NSPersistentStore("Configuration"s in the .xcdatamodeld file) |
DataStack configuration(multiple sqlite / in-memory stores per stack) |
NSManagedObjectContext |
BaseDataTransaction subclasses( SynchronousDataTransaction, AsynchronousDataTransaction, DetachedDataTransaction) |
RestKit and MagicalRecord set up their NSManagedObjectContexts this way:
This ensures maximum data integrity between contexts without blocking the main queue. But as Florian Kugler's investigation found out, merging contexts is still by far faster than saving nested contexts. HardcoreData's DataStack takes the best of both worlds by treating the main NSManagedObjectContext as a read-only context, and only allows changes to be made within transactions:
This allows for a butter-smooth main thread, while still taking advantage of safe nested contexts.