mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-03-24 10:21:40 +01:00
restructured files, added way to transform section names in ManagedObjectListControllers
This commit is contained in:
85
README.md
85
README.md
@@ -37,11 +37,11 @@ HardcoreData.beginAsynchronous { (transaction) -> Void in
|
||||
|
||||
Easy fetching:
|
||||
```swift
|
||||
let objects = HardcoreData.fetchAll(MyEntity)
|
||||
let objects = HardcoreData.fetchAll(From(MyEntity))
|
||||
```
|
||||
```swift
|
||||
let objects = HardcoreData.fetchAll(
|
||||
MyEntity.self,
|
||||
From(MyEntity),
|
||||
Where("entityID", isEqualTo: 1),
|
||||
SortedBy(.Ascending("entityID"), .Descending("name")),
|
||||
CustomizeFetch { (fetchRequest) -> Void in
|
||||
@@ -53,7 +53,7 @@ let objects = HardcoreData.fetchAll(
|
||||
Simple queries:
|
||||
```swift
|
||||
let count = HardcoreData.queryValue(
|
||||
MyEntity.self,
|
||||
From(MyEntity),
|
||||
Select<Int>(.Count("entityID"))
|
||||
)
|
||||
```
|
||||
@@ -72,9 +72,11 @@ If you are already familiar with the inner workings of CoreData, here is a mappi
|
||||
| `NSManagedObjectContext` | `BaseDataTransaction` subclasses<br />(`SynchronousDataTransaction`, `AsynchronousDataTransaction`, `DetachedDataTransaction`) |
|
||||
|
||||
RestKit and MagicalRecord set up their `NSManagedObjectContext`s this way:
|
||||
|
||||
<img src="https://cloud.githubusercontent.com/assets/3029684/6734049/40579660-ce99-11e4-9d38-829877386afb.png" alt="nested contexts" height=271 />
|
||||
|
||||
This ensures maximum data integrity between contexts without blocking the main queue. But as <a href="http://floriankugler.com/2013/04/29/concurrent-core-data-stack-performance-shootout/">Florian Kugler's investigation</a> 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*:
|
||||
|
||||
<img src="https://cloud.githubusercontent.com/assets/3029684/6734050/4078b642-ce99-11e4-95ea-c0c1d24fbe80.png" alt="nested contexts and merge hybrid" height=212 />
|
||||
|
||||
This allows for a butter-smooth main thread, while still taking advantage of safe nested contexts.
|
||||
@@ -82,19 +84,92 @@ This allows for a butter-smooth main thread, while still taking advantage of saf
|
||||
|
||||
|
||||
## Setting up
|
||||
The simplest way to initialize HardcoreData is to add a default store to the default stack:
|
||||
```swift
|
||||
HardcoreData.defaultStack.addSQLiteStore()
|
||||
```
|
||||
This one-liner does the following:
|
||||
- Triggers the lazy-initialization of `HardcoreData.defaultStack` with a default `DataStack`
|
||||
- Sets up the stack's `NSPersistentStoreCoordinator`, the root saving `NSManagedObjectContext`, and the read-only main `NSManagedObjectContext`
|
||||
- Adds an automigrating SQLite store in the *"Application Support"* directory with the file name *"<App bundle name>.sqlite"*
|
||||
- Creates and returns the `NSPersistentStore` instance on success, or an `NSError` on failure
|
||||
|
||||
For most cases this, confuguration is already appropriate. For more hardcore settings, here is a semi-complete example:
|
||||
```swift
|
||||
let dataStack = DataStack(modelName: "MyModel") // loads from the "MyModel.xcdatamodeld" file
|
||||
|
||||
switch dataStack.addInMemoryStore(configuration: "Config1") { // creates an in-memory store with entities from the "Config1" configuration in the .xcdatamodeld file
|
||||
case .Success(let persistentStore): // persistentStore is an NSPersistentStore instance
|
||||
println("Successfully created an in-memory store: \(persistentStore)"
|
||||
case .Failure(let error): // error is an NSError instance
|
||||
println("Failed creating an in-memory store with error: \(error.description)"
|
||||
}
|
||||
|
||||
switch dataStack.addSQLiteStore(
|
||||
fileURL: sqliteFileURL, // set the target file URL for the sqlite file
|
||||
configuration: "Config2", // use entities from the "Config2" configuration in the .xcdatamodeld file
|
||||
automigrating: true, // automatically run lightweight migrations or entity policy migrations when needed
|
||||
resetStoreOnMigrationFailure: true) { // delete and recreate the sqlite file when migration conflicts occur (useful when debugging)
|
||||
case .Success(let persistentStore): // persistentStore is an NSPersistentStore instance
|
||||
println("Successfully created an sqlite store: \(persistentStore)"
|
||||
case .Failure(let error): // error is an NSError instance
|
||||
println("Failed creating an sqlite store with error: \(error.description)"
|
||||
}
|
||||
|
||||
HardcoreData.defaultStack = dataStack // pass the dataStack to HardcoreData for easier access later on
|
||||
```
|
||||
|
||||
Note that you dont need to do the `HardcoreData.defaultStack = dataStack` line. You can just as well hold a stack like this and call all methods directly from the `DataStack` instance:
|
||||
```swift
|
||||
class MyViewController: UIViewController {
|
||||
let dataStack = DataStack(modelName: "MyModel")
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
self.dataStack.addSQLiteStore()
|
||||
}
|
||||
func methodToBeCalledLaterOn() {
|
||||
let objects = self.dataStack.fetchAll(From(MyEntity))
|
||||
println(objects)
|
||||
}
|
||||
}
|
||||
```
|
||||
The difference is when you set the stack as the `HardcoreData.defaultStack`, you can call the stack's methods directly from `HardcoreData` itself:
|
||||
```swift
|
||||
|
||||
class MyViewController: UIViewController {
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
HardcoreData.dataStack.addSQLiteStore()
|
||||
}
|
||||
func methodToBeCalledLaterOn() {
|
||||
let objects = HardcoreData.fetchAll(From(MyEntity))
|
||||
println(objects)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Check out the *HardcoreData.swift* and *DataStack.swift files* if you want to explore the inner workings of the data stack.
|
||||
|
||||
|
||||
|
||||
## Saving and processing transactions
|
||||
(implemented; README pending)
|
||||
|
||||
|
||||
## Fetching and querying
|
||||
(implemented; README pending)
|
||||
|
||||
|
||||
## Logging and error handling
|
||||
(implemented; README pending)
|
||||
|
||||
|
||||
## Observing changes and notifications (currently in the works)
|
||||
|
||||
## Observing changes and notifications
|
||||
(implemented; README pending)
|
||||
|
||||
|
||||
## Importing data
|
||||
(currently implementing)
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user