Skip to content

Commit

Permalink
Tidy up the format and logic flow in the save handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
tonyarnold committed May 18, 2014
1 parent cf4274b commit 1662d8d
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 84 deletions.
Expand Up @@ -9,18 +9,18 @@
#import <CoreData/CoreData.h>
#import "MagicalRecordDeprecated.h"

typedef NS_OPTIONS(NSUInteger, MRSaveContextOptions) {
typedef NS_OPTIONS(NSUInteger, MRSaveOptions) {
/** No options — used for cleanliness only */
MRSaveWithoutOptions = 0,
MRSaveOptionNone = 0,

/** When saving, continue saving parent contexts until the changes are present in the persistent store */
MRSaveParentContexts = 1 << 1,

/** Perform saves synchronously, blocking execution on the current thread until the save is complete */
MRSaveSynchronously = 1 << 2,

/** Perform saves synchronously, blocking execution on the current thread until the save is complete; however, save root context asynchronously */
MRSaveAllSynchronouslyExceptRoot = 1 << 3
/** Perform saves synchronously, blocking execution on the current thread until the save is complete; however, saves root context asynchronously */
MRSaveSynchronouslyExceptRootContext = 1 << 3
};

typedef void (^MRSaveCompletionHandler)(BOOL success, NSError *error);
Expand Down Expand Up @@ -72,7 +72,7 @@ typedef void (^MRSaveCompletionHandler)(BOOL success, NSError *error);
@since Available in v2.1.0 and later.
*/
- (void) MR_saveWithOptions:(MRSaveContextOptions)mask completion:(MRSaveCompletionHandler)completion;
- (void) MR_saveWithOptions:(MRSaveOptions)mask completion:(MRSaveCompletionHandler)completion;

@end

Expand Down
Expand Up @@ -14,12 +14,12 @@

@implementation NSManagedObjectContext (MagicalSaves)

- (void)MR_saveOnlySelfWithCompletion:(MRSaveCompletionHandler)completion;
- (void) MR_saveOnlySelfWithCompletion:(MRSaveCompletionHandler)completion;
{
[self MR_saveWithOptions:MRSaveWithoutOptions completion:completion];
[self MR_saveWithOptions:MRSaveOptionNone completion:completion];
}

- (void)MR_saveOnlySelfAndWait;
- (void) MR_saveOnlySelfAndWait;
{
[self MR_saveWithOptions:MRSaveSynchronously completion:nil];
}
Expand All @@ -34,15 +34,10 @@ - (void) MR_saveToPersistentStoreAndWait;
[self MR_saveWithOptions:MRSaveParentContexts | MRSaveSynchronously completion:nil];
}

- (void)MR_saveWithOptions:(MRSaveContextOptions)mask completion:(MRSaveCompletionHandler)completion;
- (void) MR_saveWithOptions:(MRSaveOptions)mask completion:(MRSaveCompletionHandler)completion;
{
BOOL shouldSaveSync = ((mask & MRSaveSynchronously) == MRSaveSynchronously);
BOOL shouldSaveSyncExceptRoot = ((mask & MRSaveAllSynchronouslyExceptRoot) == MRSaveAllSynchronouslyExceptRoot);

BOOL syncSave = (shouldSaveSync && !shouldSaveSyncExceptRoot) || (shouldSaveSyncExceptRoot && (self != [[self class] MR_rootSavingContext]));
BOOL saveParentContexts = ((mask & MRSaveParentContexts) == MRSaveParentContexts);

if (![self hasChanges]) {
if (![self hasChanges])
{
MRLogVerbose(@"NO CHANGES IN ** %@ ** CONTEXT - NOT SAVING", [self MR_workingName]);

if (completion)
Expand All @@ -51,59 +46,64 @@ - (void)MR_saveWithOptions:(MRSaveContextOptions)mask completion:(MRSaveCompleti
completion(NO, nil);
});
}

return;
}

BOOL shouldSaveParentContexts = ((mask & MRSaveParentContexts) == MRSaveParentContexts);
BOOL shouldSaveSynchronously = ((mask & MRSaveSynchronously) == MRSaveSynchronously);
BOOL shouldSaveSynchronouslyExceptRoot = ((mask & MRSaveSynchronouslyExceptRootContext) == MRSaveSynchronouslyExceptRootContext);

BOOL saveSynchronously = (shouldSaveSynchronously && !shouldSaveSynchronouslyExceptRoot) || (shouldSaveSynchronouslyExceptRoot && (self != [[self class] MR_rootSavingContext]));

MRLogInfo(@"→ Saving %@", [self MR_description]);
MRLogVerbose(@"→ Save Parents? %@", saveParentContexts ? @"YES" : @"NO");
MRLogVerbose(@"→ Save Synchronously? %@", syncSave ? @"YES" : @"NO");
MRLogVerbose(@"→ Save Parents? %@", shouldSaveParentContexts ? @"YES" : @"NO");
MRLogVerbose(@"→ Save Synchronously? %@", saveSynchronously ? @"YES" : @"NO");

id saveBlock = ^{
BOOL saveResult = NO;
NSError *error = nil;
BOOL saved = NO;

@try
{
saved = [self save:&error];
saveResult = [self save:&error];
}
@catch(NSException *exception)
{
MRLogError(@"Unable to perform save: %@", (id)[exception userInfo] ? : (id)[exception reason]);
MRLogError(@"Unable to perform save: %@", (id)[exception userInfo] ?: (id)[exception reason]);
}

@finally
{
if (!saved) {
[MagicalRecord handleErrors:error];
[MagicalRecord handleErrors:error];

if (completion) {
dispatch_async(dispatch_get_main_queue(), ^{
completion(saved, error);
});
}
} else {
if (saveResult && shouldSaveParentContexts && [self parentContext])
{
// If we're saving parent contexts, do so
if (saveParentContexts && [self parentContext]) {
[[self parentContext] MR_saveWithOptions:mask completion:completion];
}
// Do the completion action if one was specified
else {
[[self parentContext] MR_saveWithOptions:mask completion:completion];
}
else
{
if (saveResult)
{
MRLogVerbose(@"→ Finished saving: %@", [self MR_description]);
}

if (completion) {
dispatch_async(dispatch_get_main_queue(), ^{
completion(saved, error);
});
}
if (completion)
{
dispatch_async(dispatch_get_main_queue(), ^{
completion(saveResult, error);
});
}
}
}
};

if (YES == syncSave) {
if (saveSynchronously)
{
[self performBlockAndWait:saveBlock];
} else {
}
else
{
[self performBlock:saveBlock];
}
}
Expand All @@ -113,86 +113,80 @@ - (void)MR_saveWithOptions:(MRSaveContextOptions)mask completion:(MRSaveCompleti
#pragma mark - Deprecated Methods — DO NOT USE
@implementation NSManagedObjectContext (MagicalSavesDeprecated)

- (void)MR_save;
- (void) MR_save;
{
[self MR_saveToPersistentStoreAndWait];
}

- (void)MR_saveWithErrorCallback:(void (^)(NSError *error))errorCallback;
- (void) MR_saveWithErrorCallback:(void (^)(NSError *error))errorCallback;
{
[self MR_saveWithOptions:MRSaveSynchronously|MRSaveParentContexts completion:^(BOOL success, NSError *error) {
if (!success) {
if (errorCallback) {
errorCallback(error);
}
[self MR_saveWithOptions:MRSaveSynchronously | MRSaveParentContexts completion:^(BOOL success, NSError *error) {
if (!success && errorCallback)
{
errorCallback(error);
}
}];
}

- (void)MR_saveInBackgroundCompletion:(void (^)(void))completion;
- (void) MR_saveInBackgroundCompletion:(void (^)(void))completion;
{
[self MR_saveOnlySelfWithCompletion:^(BOOL success, NSError *error) {
if (success) {
if (completion) {
completion();
}
if (success && completion)
{
completion();
}
}];
}

- (void)MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback;
- (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback;
{
[self MR_saveOnlySelfWithCompletion:^(BOOL success, NSError *error) {
if (!success) {
if (errorCallback) {
errorCallback(error);
}
if (!success && errorCallback)
{
errorCallback(error);
}
}];
}

- (void)MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion;
- (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion;
{
[self MR_saveOnlySelfWithCompletion:^(BOOL success, NSError *error) {
if (success) {
if (completion) {
completion();
}
} else {
if (errorCallback) {
errorCallback(error);
}
if (success && completion)
{
completion();
}
else if (errorCallback)
{
errorCallback(error);
}
}];
}

- (void)MR_saveNestedContexts;
- (void) MR_saveNestedContexts;
{
[self MR_saveToPersistentStoreWithCompletion:nil];
}

- (void)MR_saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback;
- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback;
{
[self MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
if (!success) {
if (errorCallback) {
errorCallback(error);
}
if (!success && errorCallback)
{
errorCallback(error);
}
}];
}

- (void)MR_saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion;
- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion;
{
[self MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
if (success) {
if (completion) {
completion();
}
} else {
if (errorCallback) {
errorCallback(error);
}
if (success && completion)
{
completion();
}
else if (errorCallback)
{
errorCallback(error);
}
}];
}
Expand Down

0 comments on commit 1662d8d

Please sign in to comment.