/
NSManagedObjectContext+MagicalSaves.m
125 lines (108 loc) · 3.31 KB
/
NSManagedObjectContext+MagicalSaves.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//
// NSManagedObjectContext+MagicalSaves.m
// Magical Record
//
// Created by Saul Mora on 3/9/12.
// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved.
//
#import "NSManagedObjectContext+MagicalSaves.h"
#import "MagicalRecord+ErrorHandling.h"
#import "NSManagedObjectContext+MagicalRecord.h"
#import "MagicalRecord.h"
@interface NSManagedObjectContext (InternalMagicalSaves)
- (void) MR_saveWithErrorCallback:(void(^)(NSError *))errorCallback;
@end
@implementation NSManagedObjectContext (MagicalSaves)
- (void) MR_saveWithErrorCallback:(void(^)(NSError *))errorCallback;
{
if (![self hasChanges])
{
MRLog(@"NO CHANGES IN CONTEXT %@ - NOT SAVING", [self MR_description]);
return;
}
MRLog(@"-> Saving %@", [self MR_description]);
__block NSError *error = nil;
__block BOOL saved = NO;
@try
{
[self performBlockAndWait:^{
saved = [self save:&error];
}];
}
@catch (NSException *exception)
{
MRLog(@"Unable to perform save: %@", (id)[exception userInfo] ?: (id)[exception reason]);
}
@finally
{
if (!saved)
{
if (errorCallback)
{
errorCallback(error);
}
else
{
[MagicalRecord handleErrors:error];
}
}
}
}
- (void) MR_saveNestedContexts;
{
[self MR_saveNestedContextsErrorHandler:nil];
}
- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *))errorCallback;
{
[self MR_saveNestedContextsErrorHandler:nil completion:nil];
}
- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *))errorCallback completion:(void (^)(void))completion;
{
[self performBlock:^{
[self MR_saveWithErrorCallback:errorCallback];
if ([self parentContext]) {
[[self parentContext] performBlock:^{
[[self parentContext] MR_saveNestedContextsErrorHandler:errorCallback completion:completion];
}];
} else {
if (completion) {
dispatch_async(dispatch_get_main_queue(), ^{
completion();
});
}
}
}];
}
- (void) MR_save;
{
[self MR_saveWithErrorCallback:nil];
}
- (void) MR_saveInBackgroundCompletion:(void (^)(void))completion;
{
[self MR_saveInBackgroundErrorHandler:nil completion:completion];
}
- (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *))errorCallback;
{
[self MR_saveInBackgroundErrorHandler:errorCallback completion:nil];
}
- (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *))errorCallback completion:(void (^)(void))completion;
{
[self performBlock:^{
// Save the context
[self MR_saveWithErrorCallback:errorCallback];
// If we're the default context, save to disk too (the user expects it to persist)
if (self == [[self class] MR_defaultContext])
{
[[[self class] MR_rootSavingContext] MR_saveInBackgroundErrorHandler:errorCallback completion:completion];
}
else
{
// If we are not the default context (And therefore need to save the root context, do the completion action if one was specified
if (completion)
{
dispatch_async(dispatch_get_main_queue(), completion);
}
}
}];
}
@end