Skip to content

Commit 9f8edc5

Browse files
committedMay 23, 2022
SSYMOCManager now uses CoreDataProgressiveMigration instead of the deprecated SSYPersistentDocumentMultiMigrator.
1 parent 3f90a38 commit 9f8edc5

File tree

2 files changed

+123
-137
lines changed

2 files changed

+123
-137
lines changed
 

‎SSYMOCManager.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@
8585
the application's Resources which contains the various versions of
8686
managed object models (.mom) files required to migrate an existing
8787
sqlite store. This parameter is needed to perform multi-hop migration
88-
of existing sqlite stores by SSYPersistentDocumentMultiMigrator.
88+
of existing sqlite stores by CoreDataProgressiveMigration classes.
8989
If you do not wish to support multi-hop migration, you may pass nil
9090
and only Core Data's built-in single-hop automatic migration will
9191
be used. For store types other than sqlite, this parameter is ignored.

‎SSYMOCManager.m

+122-136
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#import "NSString+LocalizeSSY.h"
66
#import "NSError+InfoAccess.h"
77
#import "NSBundle+MainApp.h"
8-
#import "SSYPersistentDocumentMultiMigrator.h"
98
#import "NSManagedObjectContext+Cheats.h"
109
#import "NSError+DecodeCodes.h"
1110
#import "NSObject+MoreDescriptions.h"
@@ -17,7 +16,17 @@
1716
/* BSManagedDocument is a open source replacement for NSPersistentDocument.
1817
It is recommended for any Core Data document-based app.
1918
https://github.com/jerrykrinock/BSManagedDocument
20-
*/
19+
20+
Objective-C declaration for SSYMOCManager+Swift.h, which must be compiled
21+
in your target. The normal, easier way to do this is simply
22+
#import "YourTarget-Swift.h"
23+
which refers to the header automatically generated by Xcode.
24+
But we don't know what YourTarget is. */
25+
@interface SSYMOCManager (Swift)
26+
+ (BOOL)migrateIfNeededWithUrl:(NSURL*)url
27+
momdName:(NSString*)momdName
28+
error:(NSError**)error_p;
29+
@end
2130

2231
static NSManagedObjectContext* static_pasteboardManagedObjectContext = nil;
2332

@@ -180,35 +189,35 @@ + (void)removeStoreAtUrl:(NSURL*)url
180189
}
181190

182191
+ (NSPersistentStoreCoordinator*)persistentStoreCoordinatorType:(NSString*)storeType
183-
identifier:(NSString*)identifier
184-
momdName:(NSString*)momdName
192+
identifier:(NSString*)identifier
193+
momdName:(NSString*)momdName
185194
options:(NSDictionary*)options
186195
nukeAndPaveIfCorrupt:(BOOL)nukeAndPaveIfCorrupt
187-
error_p:(NSError**)error_p {
188-
NSPersistentStore* persistentStore = nil ;
189-
190-
NSArray* bundles = [NSArray arrayWithObject:[NSBundle mainAppBundle]] ;
191-
NSManagedObjectModel* mergedMOM = [NSManagedObjectModel mergedModelFromBundles:bundles] ;
192-
NSPersistentStoreCoordinator* newPSC = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mergedMOM] ;
193-
194-
if ([storeType isEqualToString:NSSQLiteStoreType]) {
195-
NSURL* url = [self sqliteStoreURLWithIdentifier:identifier] ;
196-
// i.e file://localhost/Users/jk/Library/Application%20Support/BookMacster/BookMacster.sql
197-
198-
NSFileManager* fm = [NSFileManager defaultManager] ;
199-
BOOL ok = YES ;
200-
201-
// An undocumented fact about addPersistentStoreWithType:configuration:URL:options:error:
202-
// is that if the parent folder does not exist, the method will fail to create a
203-
// persistent store with no explanation. So we make sure it exists
204-
NSString* parentPath = [[url path] stringByDeletingLastPathComponent] ;
205-
196+
error_p:(NSError**)error_p {
197+
NSPersistentStore* persistentStore = nil ;
198+
199+
NSArray* bundles = [NSArray arrayWithObject:[NSBundle mainAppBundle]] ;
200+
NSManagedObjectModel* mergedMOM = [NSManagedObjectModel mergedModelFromBundles:bundles] ;
201+
NSPersistentStoreCoordinator* newPSC = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mergedMOM] ;
202+
203+
if ([storeType isEqualToString:NSSQLiteStoreType]) {
204+
NSURL* url = [self sqliteStoreURLWithIdentifier:identifier] ;
205+
// i.e file://localhost/Users/jk/Library/Application%20Support/BookMacster/BookMacster.sql
206+
207+
NSFileManager* fm = [NSFileManager defaultManager] ;
208+
BOOL ok = YES ;
209+
210+
// An undocumented fact about addPersistentStoreWithType:configuration:URL:options:error:
211+
// is that if the parent folder does not exist, the method will fail to create a
212+
// persistent store with no explanation. So we make sure it exists
213+
NSString* parentPath = [[url path] stringByDeletingLastPathComponent] ;
214+
206215
if (!parentPath) {
207216
ok = NO ;
208217
}
209218

210-
BOOL isDirectory = NO ;
211-
BOOL fileExists = NO ;
219+
BOOL isDirectory = NO ;
220+
BOOL fileExists = NO ;
212221

213222
if (ok) {
214223
[fm fileExistsAtPath:parentPath isDirectory:&isDirectory] ;
@@ -218,50 +227,32 @@ + (NSPersistentStoreCoordinator*)persistentStoreCoordinatorType:(NSString*)store
218227
error:error_p] ;
219228
}
220229
}
221-
222-
NSError* error = nil ;
223-
if (ok && ((fileExists && !isDirectory) || !fileExists)) {
224-
// Create parent directory
225-
ok = [fm createDirectoryAtPath:parentPath
226-
withIntermediateDirectories:YES
227-
attributes:nil
228-
error:&error] ;
229-
}
230-
231-
if (!ok) {
232-
NSString* msg = [NSString stringWithFormat:
233-
@"Could not create directory at %@",
234-
parentPath] ;
230+
231+
NSError* error = nil ;
232+
if (ok && ((fileExists && !isDirectory) || !fileExists)) {
233+
// Create parent directory
234+
ok = [fm createDirectoryAtPath:parentPath
235+
withIntermediateDirectories:YES
236+
attributes:nil
237+
error:&error] ;
238+
}
239+
240+
if (!ok) {
241+
NSString* msg = [NSString stringWithFormat:
242+
@"Could not create directory at %@",
243+
parentPath] ;
235244
error = [SSYMakeError(95745, msg) errorByAddingUnderlyingError:error] ;
236245
NSLog(@"%@", error) ;
237-
if (error_p) {
238-
*error_p = error ;
246+
if (error_p) {
247+
*error_p = error ;
239248
}
240-
}
241-
242-
if (ok) {
243-
if (momdName) {
244-
// Using Multi-Hop Migration
245-
ok = [SSYPersistentDocumentMultiMigrator migrateIfNeededStoreAtUrl:url
246-
storeOptions:options
247-
storeType:NSSQLiteStoreType
248-
momdName:momdName
249-
document:nil
250-
error_p:error_p] ;
251-
}
252-
else {
253-
// Using Core Data's built-in Single-Hop Migration only
254-
NSDictionary* moreOption = [NSDictionary dictionaryWithObjectsAndKeys:
255-
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
256-
nil] ;
257-
if (options) {
258-
options = [options dictionaryByAddingEntriesFromDictionary:moreOption] ;
259-
}
260-
else {
261-
options = moreOption ;
262-
}
263-
}
264-
249+
}
250+
251+
if (ok) {
252+
ok = [self migrateIfNeededWithUrl:url
253+
momdName:momdName
254+
error:&error];
255+
265256
if (ok) {
266257
// Add persistent store to it
267258
persistentStore = [newPSC addPersistentStoreWithType:NSSQLiteStoreType
@@ -280,76 +271,71 @@ + (NSPersistentStoreCoordinator*)persistentStoreCoordinatorType:(NSString*)store
280271
didSimulateBadStoreOnce = YES;
281272
}
282273
#endif
283-
if (!persistentStore) {
284-
BOOL fileExists = [fm fileExistsAtPath:[url path]] ;
285-
if (fileExists) {
286-
if (nukeAndPaveIfCorrupt) {
287-
// If we did not get a store but file exists, must be a corrupt file or store.
288-
[self removeStoreAtUrl:url
289-
tildefy:NO];
290-
persistentStore = [newPSC addPersistentStoreWithType:NSSQLiteStoreType
291-
configuration:nil
292-
URL:url
293-
options:options
294-
error:error_p] ;
295-
}
296-
297-
if (!persistentStore) {
298-
if (error_p) {
299-
NSString* msg = [NSString stringWithFormat:@"Click 'Move' to move the unreadable database\n%@\nto your desktop and start a new database. The item properties in your old database will not be available to %@.",
300-
[url path],
301-
[[NSBundle mainAppBundle] objectForInfoDictionaryKey:@"CFBundleExecutable"]] ;
302-
// We used CFBundleExecutable instead of CFBundleName to get an unlocalized app name.
303-
*error_p = [*error_p errorByAddingLocalizedRecoverySuggestion:msg] ;
304-
NSArray* recoveryOptions = [NSArray arrayWithObjects:
305-
[NSString localize:@"move"],
306-
[NSString localize:@"cancel"],
307-
nil] ;
308-
*error_p = [*error_p errorByAddingLocalizedRecoveryOptions:recoveryOptions] ;
309-
*error_p = [*error_p errorByAddingRecoveryAttempter:[self sharedMOCManager]] ;
310-
*error_p = [*error_p errorByAddingUserInfoObject:url
311-
forKey:constKeyStoreUrl] ;
312-
}
313-
}
314-
}
315-
else {
316-
NSString* msg = [NSString stringWithFormat:
317-
@"Could not create persistent store file at path %@",
318-
[url absoluteString]] ;
319-
NSLog(@"%@", msg) ;
320-
if (error_p) {
321-
*error_p = SSYMakeError(51298, msg) ;
322-
}
323-
}
324-
}
325-
}
326-
else if ([*error_p involvesCode:SSYPersistentDocumentMultiMigratorErrorCodeNoSourceModel
327-
domain:SSYPersistentDocumentMultiMigratorErrorDomain]) {
328-
[[self class] removeStoreAtUrl:url
329-
tildefy:YES] ;
330-
}
331-
}
332-
}
333-
else if ([storeType isEqualToString:NSInMemoryStoreType]) {
334-
persistentStore = [newPSC addPersistentStoreWithType:NSInMemoryStoreType
335-
configuration:nil
336-
URL:nil
337-
options:options
338-
error:error_p] ;
339-
340-
if (!persistentStore) {
341-
NSLog(@"Internal Error 535-1498. Failed to create inMemory persistent store") ;
342-
}
343-
}
344-
345-
if (!persistentStore) {
346-
// If persistentStore could not be added, we don't want the
347-
// newPSC to be returned because it won't work
348-
[newPSC release] ;
349-
newPSC = nil ;
350-
}
351-
352-
return [newPSC autorelease] ;
274+
if (!persistentStore) {
275+
BOOL fileExists = [fm fileExistsAtPath:[url path]] ;
276+
if (fileExists) {
277+
if (nukeAndPaveIfCorrupt) {
278+
// If we did not get a store but file exists, must be a corrupt file or store.
279+
[self removeStoreAtUrl:url
280+
tildefy:NO];
281+
persistentStore = [newPSC addPersistentStoreWithType:NSSQLiteStoreType
282+
configuration:nil
283+
URL:url
284+
options:options
285+
error:error_p] ;
286+
}
287+
288+
if (!persistentStore) {
289+
if (error_p) {
290+
NSString* msg = [NSString stringWithFormat:@"Click 'Move' to move the unreadable database\n%@\nto your desktop and start a new database. The item properties in your old database will not be available to %@.",
291+
[url path],
292+
[[NSBundle mainAppBundle] objectForInfoDictionaryKey:@"CFBundleExecutable"]] ;
293+
// We used CFBundleExecutable instead of CFBundleName to get an unlocalized app name.
294+
*error_p = [*error_p errorByAddingLocalizedRecoverySuggestion:msg] ;
295+
NSArray* recoveryOptions = [NSArray arrayWithObjects:
296+
[NSString localize:@"move"],
297+
[NSString localize:@"cancel"],
298+
nil] ;
299+
*error_p = [*error_p errorByAddingLocalizedRecoveryOptions:recoveryOptions] ;
300+
*error_p = [*error_p errorByAddingRecoveryAttempter:[self sharedMOCManager]] ;
301+
*error_p = [*error_p errorByAddingUserInfoObject:url
302+
forKey:constKeyStoreUrl] ;
303+
}
304+
}
305+
}
306+
else {
307+
NSString* msg = [NSString stringWithFormat:
308+
@"Could not create persistent store file at path %@",
309+
[url absoluteString]] ;
310+
NSLog(@"%@", msg) ;
311+
if (error_p) {
312+
*error_p = SSYMakeError(51298, msg) ;
313+
}
314+
}
315+
}
316+
}
317+
}
318+
}
319+
else if ([storeType isEqualToString:NSInMemoryStoreType]) {
320+
persistentStore = [newPSC addPersistentStoreWithType:NSInMemoryStoreType
321+
configuration:nil
322+
URL:nil
323+
options:options
324+
error:error_p] ;
325+
326+
if (!persistentStore) {
327+
NSLog(@"Internal Error 535-1498. Failed to create inMemory persistent store") ;
328+
}
329+
}
330+
331+
if (!persistentStore) {
332+
// If persistentStore could not be added, we don't want the
333+
// newPSC to be returned because it won't work
334+
[newPSC release] ;
335+
newPSC = nil ;
336+
}
337+
338+
return [newPSC autorelease] ;
353339
}
354340

355341
- (NSManagedObjectContext*)managedObjectContextType:(NSString*)type

0 commit comments

Comments
 (0)
Please sign in to comment.