Skip to content
This repository was archived by the owner on Nov 24, 2021. It is now read-only.

Commit

Permalink
Merge pull request #4 from NSElvis/version-2-0-0
Browse files Browse the repository at this point in the history
ANDYDataManager 2.0
  • Loading branch information
NSElvis committed Jan 30, 2015
2 parents 0f4f3cf + 5d7cef4 commit a7eb9c6
Show file tree
Hide file tree
Showing 13 changed files with 211 additions and 183 deletions.
56 changes: 0 additions & 56 deletions ANDYDataManager/ANDYDataManager.h

This file was deleted.

14 changes: 7 additions & 7 deletions ANDYDataManager.podspec → ANDYDataStack.podspec
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
Pod::Spec.new do |s|
s.name = "ANDYDataManager"
s.version = "1.2.2"
s.summary = "CoreData stack set up boilerplate."
s.name = "ANDYDataStack"
s.version = "2.0"
s.summary = "Core Data stack set up boilerplate."
s.description = <<-DESC
* Feeling tired of having CoreData boilerplate in your AppDelegate?
* Feeling tired of having Core Data boilerplate in your AppDelegate?
* No more.
DESC
s.homepage = "https://github.com/NSElvis/ANDYDataManager"
s.homepage = "https://github.com/NSElvis/ANDYDataStack"
s.license = {
:type => 'MIT',
:file => 'LICENSE'
Expand All @@ -15,10 +15,10 @@ Pod::Spec.new do |s|
s.social_media_url = "http://twitter.com/NSElvis"
s.platform = :ios, '5.0'
s.source = {
:git => 'https://github.com/NSElvis/ANDYDataManager.git',
:git => 'https://github.com/NSElvis/ANDYDataStack.git',
:tag => s.version.to_s
}
s.source_files = 'ANDYDataManager/'
s.source_files = 'ANDYDataStack/'
s.frameworks = 'Foundation', 'CoreData'
s.requires_arc = true
end
58 changes: 58 additions & 0 deletions ANDYDataStack/ANDYDataStack.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
@import Foundation;
@import CoreData;


typedef NS_ENUM(NSInteger, ANDYDataStoreType) {
ANDYDataInMemoryStoreType = 0,
ANDYDataSQLiteStoreType
};

@interface ANDYDataStack : NSObject

/*!
* @discussion Creates an instance of ANDYDataStack with SQLiteStoreType using the app's name as a Core Data model name.
* @return An instance of @c ANDYDataStack or @c nil if the model is not found.
*/
- (instancetype)init;

/*!
* @discussion Creates an instance of ANDYDataStack with SQLiteStoreType.
* @param modelName The name of the Core Data model.
* @return An instance of @c ANDYDataStack or @c nil if the model is not found.
*/
- (instancetype)initWithModelName:(NSString *)modelName;

/*!
* @discussion Creates an instance of ANDYDataStack with SQLiteStoreType.
* @param modelName The name of the Core Data model.
* @param bundle The bundle where the Core Data model is located.
* @param storeType The store type, either @c SQLite or @c InMemory.
* @return An instance of @c ANDYDataStack or @c nil if the model is not found.
*/
- (instancetype)initWithModelName:(NSString *)modelName
bundle:(NSBundle *)bundle
storyType:(ANDYDataStoreType)storeType NS_DESIGNATED_INITIALIZER;

/*!
* Provides a NSManagedObjectContext appropriate for use on the main
* thread.
*/
@property (strong, nonatomic, readonly) NSManagedObjectContext *mainThreadContext;

/*!
* Provides a safe way to perform an operation in a background
* operation by using a context.
*/
- (void)performInBackgroundContext:(void (^)(NSManagedObjectContext *context))operation;

/*!
* Saves current state of mainContext into the database.
*/
- (void)persistContext;

/*!
* Destroys state of ANDYDataStack.
*/
- (void)destroy;

@end
109 changes: 57 additions & 52 deletions ANDYDataManager/ANDYDataManager.m → ANDYDataStack/ANDYDataStack.m
Original file line number Diff line number Diff line change
@@ -1,60 +1,55 @@
#import "ANDYDataManager.h"
#import "ANDYDataStack.h"

@import UIKit;

@interface ANDYDataManager ()
@interface ANDYDataStack ()

@property (strong, nonatomic, readwrite) NSManagedObjectContext *mainContext;
@property (strong, nonatomic, readwrite) NSManagedObjectContext *mainThreadContext;
@property (strong, nonatomic) NSManagedObjectContext *writerContext;
@property (strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;

@property (nonatomic) BOOL inMemoryStore;
@property (nonatomic) ANDYDataStoreType storeType;
@property (nonatomic, copy) NSString *modelName;
@property (nonatomic, strong) NSBundle *modelBundle;

@end

@implementation ANDYDataManager
@implementation ANDYDataStack

+ (void)setUpStackWithInMemoryStore
- (instancetype)init
{
[[self sharedManager] setInMemoryStore:YES];
}
NSBundle *bundle = [NSBundle mainBundle];
NSString *bundleName = [[bundle infoDictionary] objectForKey:@"CFBundleName"];

+ (void)setModelName:(NSString *)modelName
{
[[self sharedManager] setModelName:modelName];
return [self initWithModelName:bundleName];
}

+ (void)setModelBundle:(NSBundle *)modelBundle
- (instancetype)initWithModelName:(NSString *)modelName
{
[[self sharedManager] setModelBundle:modelBundle];
}
NSBundle *bundle = [NSBundle mainBundle];

+ (ANDYDataManager *)sharedManager
{
static ANDYDataManager *__sharedInstance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
__sharedInstance = [[ANDYDataManager alloc] init];
});

return __sharedInstance;
return [self initWithModelName:modelName
bundle:bundle
storyType:ANDYDataSQLiteStoreType];
}

- (NSString *)modelName
- (instancetype)initWithModelName:(NSString *)modelName
bundle:(NSBundle *)bundle
storyType:(ANDYDataStoreType)storeType
{
if (_modelName) return _modelName;

NSBundle *bundle = (self.modelBundle) ?: [NSBundle mainBundle];
self = [super init];
if (!self) return nil;

NSString *string = [[bundle infoDictionary] objectForKey:@"CFBundleName"];
_modelName = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
_modelName = modelName;
_modelBundle = bundle;
_storeType = storeType;

return _modelName;
return self;
}

#pragma mark - Private methods

- (void)setUpSaveNotificationForContext:(NSManagedObjectContext *)context
{
[[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectContextDidSaveNotification
Expand All @@ -76,7 +71,7 @@ - (void)setUpSaveNotificationForContext:(NSManagedObjectContext *)context

- (void)saveContext
{
NSManagedObjectContext *managedObjectContext = self.mainContext;
NSManagedObjectContext *managedObjectContext = self.mainThreadContext;
[managedObjectContext performBlock:^{
if (managedObjectContext != nil) {
NSError *error = nil;
Expand All @@ -91,7 +86,7 @@ - (void)saveContext
- (void)persistContext
{
NSManagedObjectContext *writerManagedObjectContext = self.writerContext;
NSManagedObjectContext *managedObjectContext = self.mainContext;
NSManagedObjectContext *managedObjectContext = self.mainThreadContext;

[managedObjectContext performBlock:^{
NSError *error = nil;
Expand All @@ -113,7 +108,7 @@ - (void)persistContext
- (void)resetContext
{
NSManagedObjectContext *writerManagedObjectContext = self.writerContext;
NSManagedObjectContext *managedObjectContext = self.mainContext;
NSManagedObjectContext *managedObjectContext = self.mainThreadContext;

[managedObjectContext performBlock:^{
[managedObjectContext reset];
Expand All @@ -132,18 +127,18 @@ - (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL

#pragma mark - Core Data stack

- (NSManagedObjectContext *)mainContext
- (NSManagedObjectContext *)mainThreadContext
{
if (_mainContext) return _mainContext;
if (_mainThreadContext) return _mainThreadContext;

_mainContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
_mainContext.undoManager = nil;
_mainContext.parentContext = self.writerContext;
_mainContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy;
_mainThreadContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
_mainThreadContext.undoManager = nil;
_mainThreadContext.parentContext = self.writerContext;
_mainThreadContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy;

[self setUpSaveNotificationForContext:_mainContext];
[self setUpSaveNotificationForContext:_mainThreadContext];

return _mainContext;
return _mainThreadContext;
}

- (NSManagedObjectContext *)writerContext
Expand Down Expand Up @@ -180,7 +175,17 @@ - (NSPersistentStoreCoordinator *)persistentStoreCoordinator

NSDictionary *options = @{NSMigratePersistentStoresAutomaticallyOption: @YES, NSInferMappingModelAutomaticallyOption: @YES};

NSString *storeType = (self.inMemoryStore) ? NSInMemoryStoreType : NSSQLiteStoreType;
NSString *storeType;

switch (self.storeType) {
case ANDYDataInMemoryStoreType:
storeType = NSInMemoryStoreType;
break;
case ANDYDataSQLiteStoreType:
storeType = NSSQLiteStoreType;
break;
}

NSError *error = nil;

_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
Expand Down Expand Up @@ -226,7 +231,7 @@ - (NSURL *)applicationDocumentsDirectory

#pragma mark - Class methods

+ (void)performInBackgroundContext:(void (^)(NSManagedObjectContext *context))operation
- (void)performInBackgroundContext:(void (^)(NSManagedObjectContext *context))operation
{
NSManagedObjectContext *context = [self backgroundContext];
[context performBlock:^{
Expand All @@ -236,14 +241,14 @@ + (void)performInBackgroundContext:(void (^)(NSManagedObjectContext *context))op
}];
}

+ (NSManagedObjectContext *)backgroundContext
- (NSManagedObjectContext *)backgroundContext
{
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
context.persistentStoreCoordinator = [[self sharedManager] persistentStoreCoordinator];
context.persistentStoreCoordinator = self.persistentStoreCoordinator;
context.undoManager = nil;
context.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy;

[[NSNotificationCenter defaultCenter] addObserver:[self sharedManager]
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(backgroundThreadDidSave:)
name:NSManagedObjectContextDidSaveNotification
object:context];
Expand All @@ -257,8 +262,8 @@ - (void)backgroundThreadDidSave:(NSNotification *)notification
format:@"Background context saved in the main thread. Use context's `performBlock`"];
} else {
// sync changes made on the background thread's context to the main thread's context
[self.mainContext performBlock:^(){
[self.mainContext mergeChangesFromContextDidSaveNotification:notification];
[self.mainThreadContext performBlock:^(){
[self.mainThreadContext mergeChangesFromContextDidSaveNotification:notification];
}];
}
}
Expand All @@ -271,15 +276,15 @@ - (void)destroy
NSURL *storeURL = store.URL;

self.writerContext = nil;
self.mainContext = nil;
self.mainThreadContext = nil;
self.managedObjectModel = nil;
self.persistentStoreCoordinator = nil;
self.inMemoryStore = NO;

NSFileManager *fileManager = [NSFileManager defaultManager];

NSError *error = nil;
if ([fileManager fileExistsAtPath:storeURL.path])
[fileManager removeItemAtURL:storeURL error:&error];
if ([fileManager fileExistsAtPath:storeURL.path]) [fileManager removeItemAtURL:storeURL error:&error];

if (error) {
NSLog(@"error deleting sqlite file");
abort();
Expand Down
Loading

0 comments on commit a7eb9c6

Please sign in to comment.