Operation block supports throwing

This commit is contained in:
Pedro Piñera Buendía 2016-04-05 10:05:25 +02:00
parent ef6dc3ef03
commit 5dc069b8fe
7 changed files with 108 additions and 92 deletions

View File

@ -129,9 +129,14 @@ Although `Context`s offer `insertion` and `deletion` methods that you can use it
- **Save**: All the changes you apply to that context are in a memory state unless you call the `save()` method. That method will persist the changes to your store and propagate them across all the available contexts.
```swift
db.operation { (context, save) -> Void in
// Do your operations here
save()
do {
db.operation { (context, save) throws -> Void in
// Do your operations here
save()
}
}
catch {
// There was an error in the operation
}
```
@ -139,11 +144,16 @@ db.operation { (context, save) -> Void in
You can use the context `new()` method to initialize a model **without inserting it in the context**:
```swift
db.operation { (context, save) -> Void in
let newTask: Track = try! context.new()
newTask.name = "Make CoreData easier!"
try! context.insert(newTask)
save()
do {
db.operation { (context, save) throws -> Void in
let newTask: Track = try! context.new()
newTask.name = "Make CoreData easier!"
try! context.insert(newTask)
save()
}
}
catch {
// There was an error in the operation
}
```
> In order to insert the model into the context you use the insert() method.
@ -152,10 +162,15 @@ db.operation { (context, save) -> Void in
You can use the `create()` for initializing and inserting in the context in the same operation:
```swift
db.operation { (context, save) -> Void in
let newTask: Track = try! context.create()
newTask.name = "Make CoreData easier!"
save()
do {
db.operation { (context, save) throws -> Void in
let newTask: Track = try! context.create()
newTask.name = "Make CoreData easier!"
save()
}
}
catch {
// There was an error in the operation
}
```
@ -163,13 +178,18 @@ db.operation { (context, save) -> Void in
In a similar way you can use the `remove()` method from the context passing the objects you want to remove from the database:
```swift
db.operation { (context, save) -> Void in
let john: User? = try! context.request(User.self).filteredWith("id", equalTo: "1234").fetch().first
if let john = john {
try! context.remove([john])
save()
do {
db.operation { (context, save) -> Void in
let john: User? = try! context.request(User.self).filteredWith("id", equalTo: "1234").fetch().first
if let john = john {
try! context.remove([john])
save()
}
}
}
catch {
// There was an error in the operation
}
```
### Reactive Interface

View File

@ -39,30 +39,36 @@ public class CoreDataDefaultStorage: Storage {
return _context
}
public func operation(operation: (context: Context, save: () -> Void) -> Void) throws {
public func operation(operation: (context: Context, save: () -> Void) throws -> Void) throws {
let context: NSManagedObjectContext = self.saveContext as! NSManagedObjectContext
var _error: ErrorType!
context.performBlockAndWait {
operation(context: context, save: { () -> Void in
do {
try context.save()
}
catch {
_error = error
}
if self.rootSavingContext.hasChanges {
self.rootSavingContext.performBlockAndWait({
do {
try self.rootSavingContext.save()
}
catch {
_error = error
}
})
}
})
do {
try operation(context: context, save: { () -> Void in
do {
try context.save()
}
catch {
_error = error
}
if self.rootSavingContext.hasChanges {
self.rootSavingContext.performBlockAndWait({
do {
try self.rootSavingContext.save()
}
catch {
_error = error
}
})
}
})
} catch {
_error = error
}
}
if let error = _error {
throw error
}
if let error = _error { throw error }
}
public func removeStore() throws {

View File

@ -40,28 +40,33 @@ public class CoreDataiCloudStorage: Storage {
}
}
public func operation(operation: (context: Context, save: () -> Void) -> Void) throws {
public func operation(operation: (context: Context, save: () -> Void) throws -> Void) throws {
let context: NSManagedObjectContext = (self.saveContext as? NSManagedObjectContext)!
var _error: ErrorType!
context.performBlockAndWait {
operation(context: context, save: { () -> Void in
do {
try context.save()
}
catch {
_error = error
}
if self.rootSavingContext.hasChanges {
self.rootSavingContext.performBlockAndWait {
do {
try self.rootSavingContext.save()
}
catch {
_error = error
do {
try operation(context: context, save: { () -> Void in
do {
try context.save()
}
catch {
_error = error
}
if self.rootSavingContext.hasChanges {
self.rootSavingContext.performBlockAndWait {
do {
try self.rootSavingContext.save()
}
catch {
_error = error
}
}
}
}
})
})
}
catch {
_error = error
}
}
if let error = _error {
throw error

View File

@ -12,7 +12,7 @@ public protocol Storage: CustomStringConvertible, Requestable {
var saveContext: Context! { get }
var memoryContext: Context! { get }
func removeStore() throws
func operation(operation: (context: Context, save: () -> Void) -> Void) throws
func operation(operation: (context: Context, save: () -> Void) throws -> Void) throws
func fetch<T: Entity>(request: Request<T>) throws -> [T]
}

View File

@ -11,12 +11,7 @@ public extension Storage {
do {
try self.operation { (context, saver) in
op(context: context, save: {
do {
try saver()
}
catch {
observer.sendFailed(Error.Store(error))
}
saver()
})
observer.sendCompleted()
}
@ -41,12 +36,7 @@ public extension Storage {
do {
try self.operation { (context, saver) in
op(context: context, save: {
do {
try saver()
}
catch {
observer.sendFailed(Error.Store(error))
}
saver()
})
observer.sendCompleted()
}

View File

@ -8,12 +8,7 @@ public extension Storage {
do {
try self.operation { (context, saver) -> Void in
op(context: context, save: { () -> Void in
do {
try saver()
}
catch {
observer.onError(error)
}
saver()
})
observer.onCompleted()
}
@ -37,12 +32,7 @@ public extension Storage {
do {
try self.operation { (context, saver) in
op(context: context, save: { () -> Void in
do {
try saver()
}
catch {
observer.onError(error)
}
saver()
})
observer.onCompleted()
}

View File

@ -61,23 +61,28 @@ public class RealmDefaultStorage: Storage {
try NSFileManager.defaultManager().removeItemAtPath(Realm().path)
}
public func operation(operation: (context: Context, save: () -> Void) -> Void) throws {
public func operation(operation: (context: Context, save: () -> Void) throws -> Void) throws {
let context: Realm = self.saveContext as! Realm
context.beginWrite()
var save: Bool = false
var _error: ErrorType!
operation(context: context, save: { () -> Void in
defer {
save = true
}
do {
try context.commitWrite()
}
catch {
context.cancelWrite()
_error = error
}
})
do {
try operation(context: context, save: { () -> Void in
defer {
save = true
}
do {
try context.commitWrite()
}
catch {
context.cancelWrite()
_error = error
}
})
}
catch {
_error = error
}
if !save {
context.cancelWrite()
}