// // CoreDataStack.m // Juick // // Created by Vitaly Takmazov on 15/10/2017. // Copyright © 2017 com.juick. All rights reserved. // #import "CoreDataStack.h" @interface CoreDataStack () @property (nonatomic, getter=isStoreLoaded) BOOL storeLoaded; @property (nonatomic, strong) NSPersistentContainer *persistentContainer; @end @implementation CoreDataStack + (NSURL *)defaultDirectoryURL { return [NSPersistentContainer defaultDirectoryURL]; } - (instancetype)initWithName:(NSString *)name { NSManagedObjectModel *mom = [NSManagedObjectModel mergedModelFromBundles:nil]; if (mom == nil) return nil; self = [super init]; if (self) { _storeLoaded = NO; _shouldAddStoreAsynchronously = YES; _shouldMigrateStoreAutomatically = YES; _shouldInferMappingModelAutomatically = YES; _readOnly = NO; _persistentContainer = [NSPersistentContainer persistentContainerWithName:name managedObjectModel:mom]; _persistentContainer.viewContext.automaticallyMergesChangesFromParent = YES; } return self; } - (void)loadStoreWithCompletionHandler:(void(^)(NSError *))handler { [self loadStoreAtURL:self.storeURL withCompletionHandler:handler]; } - (void)loadStoreAtURL:(NSURL *)storeURL withCompletionHandler:(void(^)(NSError *))handler { if (!self.persistentContainer) { NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain code:NSNotFound userInfo:nil]; if (handler) { dispatch_async(dispatch_get_main_queue(), ^{ handler(error); }); } return; } self.persistentContainer.persistentStoreDescriptions = @[[self storeDescriptionWithURL:storeURL]]; [self.persistentContainer loadPersistentStoresWithCompletionHandler: ^(NSPersistentStoreDescription *storeDescription, NSError *error) { if (error == nil) { self.storeLoaded = YES; } if (handler) { dispatch_async(dispatch_get_main_queue(), ^{ handler(error); }); } }]; } - (BOOL)persistentStoreExistsAtURL:(NSURL *)storeURL { if (storeURL.isFileURL && [NSFileManager.defaultManager fileExistsAtPath:storeURL.path]) { return YES; } return NO; } - (NSURL *)storeURL { NSArray *descriptions = self.persistentContainer.persistentStoreDescriptions; NSPersistentStoreDescription *description = [descriptions firstObject]; return description.URL; } - (BOOL)destroyPersistentStoreAtURL:(NSURL *)storeURL { NSError *error = nil; BOOL result = [self.persistentContainer.persistentStoreCoordinator destroyPersistentStoreAtURL:storeURL withType:NSSQLiteStoreType options:nil error:&error]; return result; } - (BOOL)replacePersistentStoreAtURL:(NSURL *)destinationURL withPersistentStoreFromURL:(NSURL *)sourceURL { NSError *error = nil; BOOL result = [self.persistentContainer.persistentStoreCoordinator replacePersistentStoreAtURL:destinationURL destinationOptions:nil withPersistentStoreFromURL:sourceURL sourceOptions:nil storeType:NSSQLiteStoreType error:&error]; return result; } - (NSManagedObjectContext *)viewContext { return self.persistentContainer.viewContext; } - (NSManagedObjectContext *)newPrivateContext { return [self.persistentContainer newBackgroundContext]; } - (void)performBackgroundTask:(void(^)(NSManagedObjectContext *))block { [self.persistentContainer performBackgroundTask:block]; } - (NSManagedObjectID *)managedObjectIDForURIRepresentation:(NSURL *)url { return [self.persistentContainer.persistentStoreCoordinator managedObjectIDForURIRepresentation:url]; } #pragma mark - #pragma mark === Private methods === #pragma mark - - (NSPersistentStoreDescription *)storeDescriptionWithURL:(NSURL *)URL { NSPersistentStoreDescription *description = [NSPersistentStoreDescription persistentStoreDescriptionWithURL:URL]; description.shouldAddStoreAsynchronously = self.shouldAddStoreAsynchronously; description.shouldMigrateStoreAutomatically = self.shouldMigrateStoreAutomatically; description.shouldInferMappingModelAutomatically = self.shouldInferMappingModelAutomatically; description.readOnly = self.isReadOnly; return description; } @end