Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Extracted MagicalRecord helper methods into separate category files

  • Loading branch information...
commit df242726d9df1ef19931076ecd1353c9c095c831 1 parent 666550b
@casademora casademora authored
Showing with 1,016 additions and 897 deletions.
  1. +27 −0 MagicalRecord/Categories/DataImport/MagicalImportFunctions.h
  2. +101 −0 MagicalRecord/Categories/DataImport/MagicalImportFunctions.m
  3. +1 −1  MagicalRecord/Categories/DataImport/NSEntityDescription+MagicalDataImport.m
  4. +1 −1  MagicalRecord/Categories/DataImport/NSObject+MagicalDataImport.m
  5. +1 −1  MagicalRecord/Categories/DataImport/NSRelationshipDescription+MagicalDataImport.m
  6. +1 −1  MagicalRecord/Categories/NSManagedObject+MagicalDataImport.h
  7. +16 −12 MagicalRecord/Categories/NSManagedObject+MagicalDataImport.m
  8. +1 −1  MagicalRecord/Categories/NSManagedObject+MagicalRecord.h
  9. +5 −12 MagicalRecord/Categories/NSManagedObject+MagicalRecord.m
  10. +1 −1  MagicalRecord/Categories/NSManagedObjectContext+MagicalRecord.h
  11. +17 −64 MagicalRecord/Categories/NSManagedObjectContext+MagicalRecord.m
  12. +1 −1  MagicalRecord/Categories/NSManagedObjectModel+MagicalRecord.h
  13. +1 −5 MagicalRecord/Categories/NSManagedObjectModel+MagicalRecord.m
  14. +1 −1  MagicalRecord/Categories/NSPersistentStore+MagicalRecord.h
  15. +1 −4 MagicalRecord/Categories/NSPersistentStore+MagicalRecord.m
  16. +1 −1  MagicalRecord/Categories/NSPersistentStoreCoordinator+MagicalRecord.h
  17. +7 −14 MagicalRecord/Categories/NSPersistentStoreCoordinator+MagicalRecord.m
  18. +30 −57 MagicalRecord/CoreData+MagicalRecord.h
  19. +3 −3 MagicalRecord/{MRCoreDataAction.h → MagicalRecord+Actions.h}
  20. +1 −7 MagicalRecord/{MRCoreDataAction.m → MagicalRecord+Actions.m}
  21. +22 −0 MagicalRecord/MagicalRecord+ErrorHandling.h
  22. +94 −0 MagicalRecord/MagicalRecord+ErrorHandling.m
  23. +24 −0 MagicalRecord/MagicalRecord+Options.h
  24. +38 −0 MagicalRecord/MagicalRecord+Options.m
  25. +21 −0 MagicalRecord/MagicalRecord+Setup.h
  26. +51 −0 MagicalRecord/MagicalRecord+Setup.m
  27. +15 −0 MagicalRecord/MagicalRecord+ShorthandSupport.h
  28. +146 −0 MagicalRecord/MagicalRecord+ShorthandSupport.m
  29. +18 −0 MagicalRecord/MagicalRecord+iCloud.h
  30. +45 −0 MagicalRecord/MagicalRecord+iCloud.m
  31. +29 −0 MagicalRecord/MagicalRecord.h
  32. +91 −0 MagicalRecord/MagicalRecord.m
  33. +0 −90 MagicalRecord/MagicalRecordHelpers.h
  34. +0 −493 MagicalRecord/MagicalRecordHelpers.m
  35. +7 −5 Project Files/Mac App Unit Tests/GHUnitTestMain.m
  36. +158 −73 Project Files/Magical Record.xcodeproj/project.pbxproj
  37. +2 −6 Project Files/Unit Tests/Fixtures/iOS/TestModel.xcdatamodeld/TestModel.xcdatamodel/contents
  38. +9 −9 Project Files/Unit Tests/ImportSingleEntityWithNoRelationshipsTests.m
  39. +4 −4 Project Files/Unit Tests/MagicalDataImportTestCase.m
  40. +1 −1  Project Files/Unit Tests/{MagicalRecordHelperTests.h → MagicalRecordTests.h}
  41. +14 −14 Project Files/Unit Tests/{MagicalRecordHelperTests.m → MagicalRecordTests.m}
  42. +3 −8 Project Files/Unit Tests/NSManagedObjectContextHelperTests.m
  43. +2 −2 Project Files/Unit Tests/NSManagedObjectHelperTests.m
  44. +4 −4 Project Files/Unit Tests/NSPersistentStoreCoordinatorHelperTests.m
  45. +0 −1  Project Files/iOS App Unit Tests/iOS App Unit Tests-Prefix.pch
View
27 MagicalRecord/Categories/DataImport/MagicalImportFunctions.h
@@ -0,0 +1,27 @@
+//
+// MagicalImportFunctions.h
+// Magical Record
+//
+// Created by Saul Mora on 3/7/12.
+// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+
+NSDate * adjustDateForDST(NSDate *date);
+NSDate * dateFromString(NSString *value, NSString *format);
+NSString * attributeNameFromString(NSString *value);
+NSString * primaryKeyNameFromString(NSString *value);
+
+#if TARGET_OS_IPHONE
+
+UIColor * UIColorFromString(NSString *serializedColor);
+
+#else
+
+NSColor * NSColorFromString(NSString *serializedColor);
+
+#endif
+extern id (*colorFromString)(NSString *);
+
View
101 MagicalRecord/Categories/DataImport/MagicalImportFunctions.m
@@ -0,0 +1,101 @@
+//
+// MagicalImportFunctions.m
+// Magical Record
+//
+// Created by Saul Mora on 3/7/12.
+// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved.
+//
+
+#import "MagicalImportFunctions.h"
+
+
+#pragma mark - Data import helper functions
+
+NSString * attributeNameFromString(NSString *value)
+{
+ NSString *firstCharacter = [[value substringToIndex:1] capitalizedString];
+ return [firstCharacter stringByAppendingString:[value substringFromIndex:1]];
+}
+
+NSString * primaryKeyNameFromString(NSString *value)
+{
+ NSString *firstCharacter = [[value substringToIndex:1] lowercaseString];
+ return [firstCharacter stringByAppendingFormat:@"%@ID", [value substringFromIndex:1]];
+}
+
+NSDate * adjustDateForDST(NSDate *date)
+{
+ NSTimeInterval dstOffset = [[NSTimeZone localTimeZone] daylightSavingTimeOffsetForDate:date];
+ NSDate *actualDate = [date dateByAddingTimeInterval:dstOffset];
+
+ return actualDate;
+}
+
+NSDate * dateFromString(NSString *value, NSString *format)
+{
+ NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
+ [formatter setTimeZone:[NSTimeZone localTimeZone]];
+ [formatter setLocale:[NSLocale currentLocale]];
+ [formatter setDateFormat:format];
+
+ NSDate *parsedDate = [formatter dateFromString:value];
+
+ return parsedDate;
+}
+
+NSInteger* newColorComponentsFromString(NSString *serializedColor);
+NSInteger* newColorComponentsFromString(NSString *serializedColor)
+{
+ NSScanner *colorScanner = [NSScanner scannerWithString:serializedColor];
+ NSString *colorType;
+ [colorScanner scanUpToString:@"(" intoString:&colorType];
+
+ NSInteger *componentValues = malloc(4 * sizeof(NSInteger));
+ if ([colorType hasPrefix:@"rgba"])
+ {
+ NSCharacterSet *rgbaCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@"(,)"];
+
+ NSInteger *componentValue = componentValues;
+ while (![colorScanner isAtEnd])
+ {
+ [colorScanner scanCharactersFromSet:rgbaCharacterSet intoString:nil];
+ [colorScanner scanInteger:componentValue];
+ componentValue++;
+ }
+ }
+ //else if ([colorType hasPrefix:@"hsba"])
+ //else if ([colorType hasPrefix:@""])
+ return componentValues;
+}
+
+#if TARGET_OS_IPHONE
+
+UIColor * UIColorFromString(NSString *serializedColor)
+{
+ NSInteger *componentValues = newColorComponentsFromString(serializedColor);
+ UIColor *color = [UIColor colorWithRed:(componentValues[0] / 255.)
+ green:(componentValues[1] / 255.)
+ blue:(componentValues[2] / 255.)
+ alpha:componentValues[3]];
+
+ free(componentValues);
+ return color;
+}
+id (*colorFromString)(NSString *) = UIColorFromString;
+
+#else
+
+NSColor * NSColorFromString(NSString *serializedColor)
+{
+ NSInteger *componentValues = newColorComponentsFromString(serializedColor);
+ NSColor *color = [NSColor colorWithDeviceRed:(componentValues[0] / 255.)
+ green:(componentValues[1] / 255.)
+ blue:(componentValues[2] / 255.)
+ alpha:componentValues[3]];
+ free(componentValues);
+ return color;
+}
+id (*colorFromString)(NSString *) = NSColorFromString;
+
+
+#endif
View
2  MagicalRecord/Categories/DataImport/NSEntityDescription+MagicalDataImport.m
@@ -28,7 +28,7 @@ - (NSManagedObject *) MR_createInstanceFromDictionary:(id)objectData inContext:(
NSManagedObject *relatedObject = [[self class] insertNewObjectForEntityForName:[self name]
inManagedObjectContext:context];
- [relatedObject MR_importValuesForKeysWithDictionary:objectData];
+ [relatedObject MR_importValuesForKeysWithObject:objectData];
return relatedObject;
}
View
2  MagicalRecord/Categories/DataImport/NSObject+MagicalDataImport.m
@@ -8,7 +8,7 @@
#import "NSObject+MagicalDataImport.h"
#import "NSManagedObject+MagicalDataImport.h"
-#import "MagicalRecordHelpers.h"
+#import "MagicalRecord.h"
#import "CoreData+MagicalRecord.h"
NSUInteger const kMagicalRecordImportMaximumAttributeFailoverDepth = 10;
View
2  MagicalRecord/Categories/DataImport/NSRelationshipDescription+MagicalDataImport.m
@@ -8,7 +8,7 @@
#import "NSRelationshipDescription+MagicalDataImport.h"
#import "NSManagedObject+MagicalDataImport.h"
-#import "MagicalRecordHelpers.h"
+#import "MagicalRecord.h"
@implementation NSRelationshipDescription (MagicalRecord_DataImport)
View
2  MagicalRecord/Categories/NSManagedObject+MagicalDataImport.h
@@ -19,7 +19,7 @@ extern NSString * const kMagicalRecordImportRelationshipTypeKey;
@interface NSManagedObject (MagicalRecord_DataImport)
-- (void) MR_importValuesForKeysWithDictionary:(id)objectData;
+- (void) MR_importValuesForKeysWithObject:(id)objectData;
- (void) MR_updateValuesForKeysWithDictionary:(id)objectData;
+ (id) MR_importFromDictionary:(id)data;
View
28 MagicalRecord/Categories/NSManagedObject+MagicalDataImport.m
@@ -9,7 +9,7 @@
#import "CoreData+MagicalRecord.h"
#import <objc/runtime.h>
-void swizzle(Class c, SEL orig, SEL new);
+void MR_swizzle(Class c, SEL orig, SEL new);
NSString * const kMagicalRecordImportCustomDateFormatKey = @"dateFormat";
NSString * const kMagicalRecordImportDefaultDateFormatString = @"yyyy-MM-dd'T'HH:mm:ss'Z'";
@@ -163,6 +163,9 @@ - (void) MR_setRelationships:(NSDictionary *)relationships forKeysWithDictionary
SEL shouldImportSelector = @selector(shouldImport:);
BOOL implementsShouldImport = [self respondsToSelector:shouldImportSelector];
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
if (![self MR_importValue:relatedObjectData forKey:relationshipName])
{
@@ -185,12 +188,13 @@ - (void) MR_setRelationships:(NSDictionary *)relationships forKeysWithDictionary
}
}
}
+#pragma clang diagnostic pop
}
}
-- (void) MR_importValuesForKeysWithDictionary:(id)objectData
+- (void) MR_importValuesForKeysWithObject:(id)objectData
{
- swizzle([objectData class], @selector(valueForUndefinedKey:), @selector(MR_valueForUndefinedKey:));
+ MR_swizzle([objectData class], @selector(valueForUndefinedKey:), @selector(MR_valueForUndefinedKey:));
if ([self respondsToSelector:@selector(willImport)])
{
[self performSelector:@selector(willImport)];
@@ -224,11 +228,11 @@ - (void) MR_importValuesForKeysWithDictionary:(id)objectData
{
relatedObject = [self MR_findObjectForRelationship:relationshipInfo withData:objectData];
}
- [relatedObject MR_importValuesForKeysWithDictionary:objectData];
+ [relatedObject MR_importValuesForKeysWithObject:objectData];
[self MR_addObject:relatedObject forRelationship:relationshipInfo];
}];
- swizzle([objectData class], @selector(valueForUndefinedKey:), @selector(MR_valueForUndefinedKey:));
+ MR_swizzle([objectData class], @selector(valueForUndefinedKey:), @selector(MR_valueForUndefinedKey:));
if ([self respondsToSelector:@selector(didImport)])
{
@@ -238,7 +242,7 @@ - (void) MR_importValuesForKeysWithDictionary:(id)objectData
- (void) MR_updateValuesForKeysWithDictionary:(id)objectData
{
- swizzle([objectData class], @selector(valueForUndefinedKey:), @selector(MR_valueForUndefinedKey:));
+ MR_swizzle([objectData class], @selector(valueForUndefinedKey:), @selector(MR_valueForUndefinedKey:));
if ([self respondsToSelector:@selector(willImport)])
{
[self performSelector:@selector(willImport)];
@@ -266,7 +270,7 @@ - (void) MR_updateValuesForKeysWithDictionary:(id)objectData
[self MR_addObject:relatedObject forRelationship:relationshipInfo];
}];
- swizzle([objectData class], @selector(valueForUndefinedKey:), @selector(MR_valueForUndefinedKey:));
+ MR_swizzle([objectData class], @selector(valueForUndefinedKey:), @selector(MR_valueForUndefinedKey:));
if ([self respondsToSelector:@selector(didImport)])
{
@@ -277,7 +281,7 @@ - (void) MR_updateValuesForKeysWithDictionary:(id)objectData
+ (id) MR_importFromDictionary:(id)objectData inContext:(NSManagedObjectContext *)context;
{
NSManagedObject *managedObject = [self MR_createInContext:context];
- [managedObject MR_importValuesForKeysWithDictionary:objectData];
+ [managedObject MR_importValuesForKeysWithObject:objectData];
return managedObject;
}
@@ -296,7 +300,7 @@ + (id) MR_updateFromDictionary:(id)objectData inContext:(NSManagedObjectContext
if (!managedObject)
{
managedObject = [self MR_createInContext:context];
- [managedObject MR_importValuesForKeysWithDictionary:objectData];
+ [managedObject MR_importValuesForKeysWithObject:objectData];
}
else
{
@@ -319,7 +323,7 @@ + (NSArray *) MR_importFromArray:(NSArray *)listOfObjectData inContext:(NSManage
{
NSMutableArray *objectIDs = [NSMutableArray array];
- [MRCoreDataAction saveDataWithBlock:^(NSManagedObjectContext *localContext)
+ [MagicalRecord saveDataWithBlock:^(NSManagedObjectContext *localContext)
{
[listOfObjectData enumerateObjectsWithOptions:0 usingBlock:^(id obj, NSUInteger idx, BOOL *stop)
{
@@ -346,7 +350,7 @@ + (NSArray *) MR_updateFromArray:(NSArray *)listOfObjectData inContext:(NSManage
{
NSMutableArray *objectIDs = [NSMutableArray array];
- [MRCoreDataAction saveDataWithBlock:^(NSManagedObjectContext *localContext)
+ [MagicalRecord saveDataWithBlock:^(NSManagedObjectContext *localContext)
{
[listOfObjectData enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
@@ -367,7 +371,7 @@ + (NSArray *) MR_updateFromArray:(NSArray *)listOfObjectData inContext:(NSManage
@end
-void swizzle(Class c, SEL orig, SEL new)
+void MR_swizzle(Class c, SEL orig, SEL new)
{
Method origMethod = class_getInstanceMethod(c, orig);
Method newMethod = class_getInstanceMethod(c, new);
View
2  MagicalRecord/Categories/NSManagedObject+MagicalRecord.h
@@ -5,7 +5,7 @@
//
#import <CoreData/CoreData.h>
-#import "MagicalRecordHelpers.h"
+#import "MagicalRecord.h"
#define kMagicalRecordDefaultBatchSize 20
View
17 MagicalRecord/Categories/NSManagedObject+MagicalRecord.m
@@ -31,7 +31,7 @@ + (NSArray *) MR_executeFetchRequest:(NSFetchRequest *)request inContext:(NSMana
if (results == nil)
{
- [MagicalRecordHelpers handleErrors:error];
+ [MagicalRecord handleErrors:error];
}
return results;
}
@@ -65,7 +65,7 @@ + (void) MR_performFetch:(NSFetchedResultsController *)controller
NSError *error = nil;
if (![controller performFetch:&error])
{
- [MagicalRecordHelpers handleErrors:error];
+ [MagicalRecord handleErrors:error];
}
}
@@ -128,7 +128,6 @@ + (NSArray *) MR_sortAscending:(BOOL)ascending attributes:(NSArray *)attributesT
{
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:attributeName ascending:ascending];
[attributes addObject:sortDescriptor];
- MR_RELEASE(sortDescriptor);
}
return attributes;
@@ -148,7 +147,6 @@ + (NSFetchRequest *)MR_createFetchRequestInContext:(NSManagedObjectContext *)con
{
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[self MR_entityDescriptionInContext:context]];
- MR_AUTORELEASE(request);
return request;
}
@@ -192,7 +190,7 @@ + (NSUInteger) MR_countOfEntitiesWithContext:(NSManagedObjectContext *)context;
{
NSError *error = nil;
NSUInteger count = [context countForFetchRequest:[self MR_createFetchRequestInContext:context] error:&error];
- [MagicalRecordHelpers handleErrors:error];
+ [MagicalRecord handleErrors:error];
return count;
}
@@ -209,7 +207,7 @@ + (NSUInteger) MR_countOfEntitiesWithPredicate:(NSPredicate *)searchFilter inCon
[request setPredicate:searchFilter];
NSUInteger count = [context countForFetchRequest:request error:&error];
- [MagicalRecordHelpers handleErrors:error];
+ [MagicalRecord handleErrors:error];
return count;
}
@@ -295,7 +293,6 @@ + (NSFetchRequest *) MR_requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)
NSSortDescriptor *sortBy = [[NSSortDescriptor alloc] initWithKey:sortTerm ascending:ascending];
[request setSortDescriptors:[NSArray arrayWithObject:sortBy]];
- MR_AUTORELEASE(sortBy);
return request;
}
@@ -319,11 +316,9 @@ + (NSFetchRequest *) MR_requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)
{
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:sortKey ascending:ascending];
[sortDescriptors addObject:sortDescriptor];
- MR_AUTORELEASE(sortDescriptor);
}
[request setSortDescriptors:sortDescriptors];
- MR_AUTORELEASE(sortDescriptors);
return request;
}
@@ -398,7 +393,6 @@ + (NSFetchedResultsController *) MR_fetchController:(NSFetchRequest *)request de
sectionNameKeyPath:groupKeyPath
cacheName:cacheName];
controller.delegate = delegate;
- MR_AUTORELEASE(controller);
return controller;
}
@@ -745,7 +739,6 @@ + (NSNumber *) MR_aggregateOperation:(NSString *)function onAttribute:(NSString
NSAttributeDescription *attributeDescription = [[[self MR_entityDescription] attributesByName] objectForKey:attributeName];
[ed setExpressionResultType:[attributeDescription attributeType]];
NSArray *properties = [NSArray arrayWithObject:ed];
- MR_RELEASE(ed);
NSFetchRequest *request = [self MR_requestAllWithPredicate:predicate inContext:context];
[request setPropertiesToFetch:properties];
@@ -769,7 +762,7 @@ - (id) MR_inContext:(NSManagedObjectContext *)otherContext
{
NSError *error = nil;
NSManagedObject *inContext = [otherContext existingObjectWithID:[self objectID] error:&error];
- [MagicalRecordHelpers handleErrors:error];
+ [MagicalRecord handleErrors:error];
return inContext;
}
View
2  MagicalRecord/Categories/NSManagedObjectContext+MagicalRecord.h
@@ -5,7 +5,7 @@
// Copyright 2010 Magical Panda Software, LLC All rights reserved.
//
-#import "MagicalRecordHelpers.h"
+#import "MagicalRecord.h"
extern NSString * const kMagicalRecordDidMergeChangesFromiCloudNotification;
View
81 MagicalRecord/Categories/NSManagedObjectContext+MagicalRecord.m
@@ -30,20 +30,17 @@ + (NSManagedObjectContext *)MR_defaultContext
}
}
-+ (void) MR_setDefaultContext:(NSManagedObjectContext *)moc
++ (void)MR_setDefaultContext:(NSManagedObjectContext *)moc
{
NSPersistentStoreCoordinator *coordinator = [NSPersistentStoreCoordinator MR_defaultStoreCoordinator];
- if ([MagicalRecordHelpers isICloudEnabled])
+ if ([MagicalRecord isICloudEnabled])
{
[defaultManageObjectContext_ MR_stopObservingiCloudChangesInCoordinator:coordinator];
}
- MR_RETAIN(moc);
- MR_RELEASE(defaultManageObjectContext_);
-
defaultManageObjectContext_ = moc;
- if ([MagicalRecordHelpers isICloudEnabled])
+ if ([MagicalRecord isICloudEnabled])
{
[defaultManageObjectContext_ MR_observeiCloudChangesInCoordinator:coordinator];
}
@@ -92,7 +89,7 @@ - (void) MR_stopObservingContext:(NSManagedObjectContext *)otherContext
- (void) MR_observeiCloudChangesInCoordinator:(NSPersistentStoreCoordinator *)coordinator;
{
- if (![MagicalRecordHelpers isICloudEnabled]) return;
+ if (![MagicalRecord isICloudEnabled]) return;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(MR_mergeChangesFromiCloud:)
name:NSPersistentStoreDidImportUbiquitousContentChangesNotification
@@ -102,7 +99,7 @@ - (void) MR_observeiCloudChangesInCoordinator:(NSPersistentStoreCoordinator *)co
- (void) MR_stopObservingiCloudChangesInCoordinator:(NSPersistentStoreCoordinator *)coordinator;
{
- if (![MagicalRecordHelpers isICloudEnabled]) return;
+ if (![MagicalRecord isICloudEnabled]) return;
[[NSNotificationCenter defaultCenter] removeObserver:self
name:NSPersistentStoreDidImportUbiquitousContentChangesNotification
object:coordinator];
@@ -184,7 +181,7 @@ - (BOOL) MR_saveWithErrorHandler:(void (^)(NSError *))errorCallback;
}
else if (error)
{
- [MagicalRecordHelpers handleErrors:error];
+ [MagicalRecord handleErrors:error];
}
}
}
@@ -194,16 +191,10 @@ - (BOOL) MR_saveWithErrorHandler:(void (^)(NSError *))errorCallback;
- (void) MR_saveWrapper;
{
-#if MR_USE_ARC
@autoreleasepool
{
[self MR_save];
}
-#else
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [self MR_save];
- [pool drain];
-#endif
}
#pragma mark - Threading Helpers
@@ -227,14 +218,7 @@ - (BOOL) MR_saveOnMainThread;
- (BOOL) MR_notifiesMainContextOnSave;
{
- THREAD_ISOLATION_ENABLED(
- NSNumber *notifies = objc_getAssociatedObject(self, kMagicalRecordNotifiesMainContextAssociatedValueKey);
- return notifies ? [notifies boolValue] : NO;
- )
- PRIVATE_QUEUES_ENABLED(
- return [self parentContext] == [[self class] MR_defaultContext];
- )
- return NO;
+ return [self parentContext] == [[self class] MR_defaultContext];
}
- (void) MR_setNotifiesMainContextOnSave:(BOOL)enabled;
@@ -242,22 +226,10 @@ - (void) MR_setNotifiesMainContextOnSave:(BOOL)enabled;
NSManagedObjectContext *mainContext = [[self class] MR_defaultContext];
if (self != mainContext)
{
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
- THREAD_ISOLATION_ENABLED(
- SEL selector = enabled ? @selector(MR_observeContextOnMainThread:) : @selector(MR_stopObservingContext:);
- objc_setAssociatedObject(self, kMagicalRecordNotifiesMainContextAssociatedValueKey, [NSNumber numberWithBool:enabled], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
-
- [mainContext performSelector:selector withObject:self];
- )
-#pragma clang diagnostic pop
-
- PRIVATE_QUEUES_ENABLED(
- if (enabled)
- {
- [self setParentContext:mainContext];
- }
- )
+ if (enabled)
+ {
+ [self setParentContext:mainContext];
+ }
}
}
@@ -288,20 +260,11 @@ + (NSManagedObjectContext *) MR_contextWithStoreCoordinator:(NSPersistentStoreCo
if (coordinator != nil)
{
MRLog(@"Creating MOContext %@", [NSThread isMainThread] ? @" *** On Main Thread ***" : @"");
- THREAD_ISOLATION_ENABLED(
- MRLog(@"Creating context in Thread Isolation Mode");
- context = [[NSManagedObjectContext alloc] init];
- [context setPersistentStoreCoordinator:coordinator];
- )
- PRIVATE_QUEUES_ENABLED(
MRLog(@"Creating context in Context Private Queue Mode");
context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[context performBlockAndWait:^{
[context setPersistentStoreCoordinator:coordinator];
}];
- )
-
- MR_AUTORELEASE(context);
}
return context;
}
@@ -322,22 +285,12 @@ + (NSManagedObjectContext *) MR_contextThatNotifiesDefaultContextOnMainThread;
{
NSManagedObjectContext *context = nil;
- THREAD_ISOLATION_ENABLED
- (
- MRLog(@"Creating Context - Using Thread Isolation Mode");
- context = [self MR_context];
- context.MR_notifiesMainContextOnSave = YES;
- )
-
- PRIVATE_QUEUES_ENABLED
- (
- MRLog(@"Creating Context - Using Private queue mode");
- context = [[self alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
- if (context != [self MR_defaultContext])
- {
- [context setParentContext:[NSManagedObjectContext MR_defaultContext]];
- }
- )
+ MRLog(@"Creating Context - Using Private queue mode");
+ context = [[self alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
+ if (context != [self MR_defaultContext])
+ {
+ [context setParentContext:[NSManagedObjectContext MR_defaultContext]];
+ }
return context;
}
View
2  MagicalRecord/Categories/NSManagedObjectModel+MagicalRecord.h
@@ -6,7 +6,7 @@
//
#import <Foundation/Foundation.h>
-#import "MagicalRecordHelpers.h"
+#import "MagicalRecord.h"
@interface NSManagedObjectModel (MagicalRecord)
View
6 MagicalRecord/Categories/NSManagedObjectModel+MagicalRecord.m
@@ -16,7 +16,7 @@ @implementation NSManagedObjectModel (MagicalRecord)
+ (NSManagedObjectModel *) MR_defaultManagedObjectModel
{
- if (defaultManagedObjectModel_ == nil && [MagicalRecordHelpers shouldAutoCreateManagedObjectModel])
+ if (defaultManagedObjectModel_ == nil && [MagicalRecord shouldAutoCreateManagedObjectModel])
{
[self MR_setDefaultManagedObjectModel:[self MR_mergedObjectModelFromMainBundle]];
}
@@ -25,8 +25,6 @@ + (NSManagedObjectModel *) MR_defaultManagedObjectModel
+ (void) MR_setDefaultManagedObjectModel:(NSManagedObjectModel *)newDefaultModel
{
- MR_RETAIN(newDefaultModel);
- MR_RELEASE(defaultManagedObjectModel_);
defaultManagedObjectModel_ = newDefaultModel;
}
@@ -39,7 +37,6 @@ + (NSManagedObjectModel *) MR_mergedObjectModelFromMainBundle;
+ (NSManagedObjectModel *) MR_newManagedObjectModel
{
NSManagedObjectModel *model = [self MR_mergedObjectModelFromMainBundle];
- MR_RETAIN(model);
return model;
}
@@ -68,7 +65,6 @@ + (NSManagedObjectModel *) MR_newManagedObjectModelNamed:(NSString *)modelFileNa
+ (NSManagedObjectModel *) MR_managedObjectModelNamed:(NSString *)modelFileName
{
NSManagedObjectModel *model = [self MR_newManagedObjectModelNamed:modelFileName];
- MR_AUTORELEASE(model);
return model;
}
View
2  MagicalRecord/Categories/NSPersistentStore+MagicalRecord.h
@@ -5,7 +5,7 @@
// Copyright 2010 Magical Panda Software, LLC All rights reserved.
//
-#import "MagicalRecordHelpers.h"
+#import "MagicalRecord.h"
// option to autodelete store if it already exists
View
5 MagicalRecord/Categories/NSPersistentStore+MagicalRecord.m
@@ -22,8 +22,6 @@ + (NSPersistentStore *) MR_defaultPersistentStore
+ (void) MR_setDefaultPersistentStore:(NSPersistentStore *) store
{
- MR_RETAIN(store);
- MR_RELEASE(defaultPersistentStore_);
defaultPersistentStore_ = store;
}
@@ -47,7 +45,6 @@ + (NSURL *) MR_urlForStoreName:(NSString *)storeFileName
{
NSArray *paths = [NSArray arrayWithObjects:[self MR_applicationDocumentsDirectory], [self MR_applicationStorageDirectory], nil];
NSFileManager *fm = [[NSFileManager alloc] init];
- MR_AUTORELEASE(fm);
for (NSString *path in paths)
{
@@ -70,7 +67,7 @@ + (NSURL *) MR_cloudURLForUbiqutiousContainer:(NSString *)bucketName;
{
cloudURL = [fileManager URLForUbiquityContainerIdentifier:bucketName];
}
- MR_AUTORELEASE(fileManager);
+
return cloudURL;
}
View
2  MagicalRecord/Categories/NSPersistentStoreCoordinator+MagicalRecord.h
@@ -5,7 +5,7 @@
// Copyright 2010 Magical Panda Software, LLC All rights reserved.
//
-#import "MagicalRecordHelpers.h"
+#import "MagicalRecord.h"
#import "NSPersistentStore+MagicalRecord.h"
extern NSString * const kMagicalRecordPSCDidCompleteiCloudSetupNotification;
View
21 MagicalRecord/Categories/NSPersistentStoreCoordinator+MagicalRecord.m
@@ -20,7 +20,7 @@ @implementation NSPersistentStoreCoordinator (MagicalRecord)
+ (NSPersistentStoreCoordinator *) MR_defaultStoreCoordinator
{
- if (defaultCoordinator_ == nil && [MagicalRecordHelpers shouldAutoCreateDefaultPersistentStoreCoordinator])
+ if (defaultCoordinator_ == nil && [MagicalRecord shouldAutoCreateDefaultPersistentStoreCoordinator])
{
[self MR_setDefaultStoreCoordinator:[self MR_newPersistentStoreCoordinator]];
}
@@ -29,8 +29,6 @@ + (NSPersistentStoreCoordinator *) MR_defaultStoreCoordinator
+ (void) MR_setDefaultStoreCoordinator:(NSPersistentStoreCoordinator *)coordinator
{
- MR_RETAIN(coordinator);
- MR_RELEASE(defaultCoordinator_);
defaultCoordinator_ = coordinator;
if (defaultCoordinator_ != nil)
@@ -54,7 +52,7 @@ - (void) MR_createPathToStoreFileIfNeccessary:(NSURL *)urlForStore
if (!pathWasCreated)
{
- [MagicalRecordHelpers handleErrors:error];
+ [MagicalRecord handleErrors:error];
}
}
@@ -72,7 +70,7 @@ - (NSPersistentStore *) MR_addSqliteStoreNamed:(id)storeFileName withOptions:(__
error:&error];
if (!store)
{
- [MagicalRecordHelpers handleErrors:error];
+ [MagicalRecord handleErrors:error];
}
return store;
}
@@ -90,7 +88,7 @@ - (NSPersistentStore *) MR_addInMemoryStore
error:&error];
if (!store)
{
- [MagicalRecordHelpers handleErrors:error];
+ [MagicalRecord handleErrors:error];
}
return store;
}
@@ -126,7 +124,7 @@ + (NSPersistentStoreCoordinator *) MR_coordinatorWithAutoMigratingSqliteStoreNam
{
[coordinator performSelector:@selector(MR_addAutoMigratingSqliteStoreNamed:) withObject:storeFileName afterDelay:0.5];
}
- MR_AUTORELEASE(coordinator);
+
return coordinator;
}
@@ -136,15 +134,14 @@ + (NSPersistentStoreCoordinator *) MR_coordinatorWithInMemoryStore
NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
[coordinator MR_addInMemoryStore];
- MR_AUTORELEASE(coordinator);
return coordinator;
}
+ (NSPersistentStoreCoordinator *) MR_newPersistentStoreCoordinator
{
- NSPersistentStoreCoordinator *coordinator = [self MR_coordinatorWithSqliteStoreNamed:[MagicalRecordHelpers defaultStoreName]];
- MR_RETAIN(coordinator);
+ NSPersistentStoreCoordinator *coordinator = [self MR_coordinatorWithSqliteStoreNamed:[MagicalRecord defaultStoreName]];
+
return coordinator;
}
@@ -225,7 +222,6 @@ + (NSPersistentStoreCoordinator *) MR_coordinatorWithiCloudContainerID:(NSString
cloudStorePathComponent:subPathComponent
completion:completionHandler];
- MR_AUTORELEASE(psc);
return psc;
}
@@ -235,7 +231,6 @@ + (NSPersistentStoreCoordinator *) MR_coordinatorWithPersitentStore:(NSPersisten
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
[psc MR_addSqliteStoreNamed:[persistentStore URL] withOptions:nil];
- MR_AUTORELEASE(psc);
return psc;
}
@@ -245,7 +240,6 @@ + (NSPersistentStoreCoordinator *) MR_coordinatorWithSqliteStoreNamed:(NSString
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
[psc MR_addSqliteStoreNamed:storeFileName withOptions:options];
- MR_AUTORELEASE(psc);
return psc;
}
@@ -263,7 +257,6 @@ - (NSMutableDictionary *) MR_dictionaryByMergingDictionary:(NSDictionary *)d;
{
NSMutableDictionary *mutDict = [self mutableCopy];
[mutDict addEntriesFromDictionary:d];
- MR_AUTORELEASE(mutDict);
return mutDict;
}
View
87 MagicalRecord/CoreData+MagicalRecord.h
@@ -12,7 +12,9 @@
#endif
#endif
-#if MR_ENABLE_ACTIVE_RECORD_LOGGING
+#ifdef __OBJC__
+
+#if MR_ENABLE_ACTIVE_RECORD_LOGGING != 0
#ifdef LOG_VERBOSE
#define MRLog(...) DDLogVerbose(__VA_ARGS__)
#else
@@ -22,66 +24,37 @@
#define MRLog(...) ((void)0)
#endif
-#import <CoreData/CoreData.h>
-
-#ifndef MR_USE_ARC
-#define MR_USE_ARC __has_feature(objc_arc)
-#endif
-
-#ifndef kCFCoreFoundationVersionNumber_iPhoneOS_5_0
-#define kCFCoreFoundationVersionNumber_iPhoneOS_5_0 674.0
-#endif
-
-#ifndef kCFCoreFoundationVersionNumber_10_7
-#define kCFCoreFoundationVersionNumber_10_7 635.0
-#endif
+// #if !( __has_feature(objc_arc) && __has_feature(objc_arc_weak) )
+// #error MagicalRecord now requires ARC to be enabled
+// #endif
-#if TARGET_OS_IPHONE == 0
-#define MR_MINIMUM_PRIVATE_QUEUE_CF_VERSION kCFCoreFoundationVersionNumber_10_7
-#else
-#define MR_MINIMUM_PRIVATE_QUEUE_CF_VERSION kCFCoreFoundationVersionNumber_iPhoneOS_5_0
-#endif
+ #import <CoreData/CoreData.h>
-#define PRIVATE_QUEUES_ENABLED(...) \
- if (kCFCoreFoundationVersionNumber >= MR_MINIMUM_PRIVATE_QUEUE_CF_VERSION) \
- { \
- __VA_ARGS__ \
- }
+ #ifdef MR_SHORTHAND
+ #import "MagicalRecordShorthand.h"
+ #endif
-#define THREAD_ISOLATION_ENABLED(...) \
- if (kCFCoreFoundationVersionNumber < MR_MINIMUM_PRIVATE_QUEUE_CF_VERSION) \
- { \
- __VA_ARGS__ \
- }
+ #import "MagicalRecord.h"
+ #import "MagicalRecord+Actions.h"
+ #import "MagicalRecord+ErrorHandling.h"
+ #import "MagicalRecord+Options.h"
+ #import "MagicalRecord+ShorthandSupport.h"
+ #import "MagicalRecord+Setup.h"
+ #import "MagicalRecord+iCloud.h"
+ #import "NSManagedObject+MagicalRecord.h"
+ #import "NSManagedObjectContext+MagicalRecord.h"
+ #import "NSPersistentStoreCoordinator+MagicalRecord.h"
+ #import "NSManagedObjectModel+MagicalRecord.h"
+ #import "NSPersistentStore+MagicalRecord.h"
-#if MR_USE_ARC
-#define MR_RETAIN(xx)
-#define MR_RELEASE(xx)
-#define MR_AUTORELEASE(xx)
-#else
-#define MR_RETAIN(xx) [xx retain];
-#define MR_RELEASE(xx) [xx release];
-#define MR_AUTORELEASE(xx) [xx autorelease];
-#endif
+ #import "MagicalImportFunctions.h"
+ #import "NSManagedObject+MagicalDataImport.h"
+ #import "NSNumber+MagicalDataImport.h"
+ #import "NSObject+MagicalDataImport.h"
+ #import "NSString+MagicalDataImport.h"
+ #import "NSAttributeDescription+MagicalDataImport.h"
+ #import "NSRelationshipDescription+MagicalDataImport.h"
+ #import "NSEntityDescription+MagicalDataImport.h"
-#ifdef MR_SHORTHAND
-#import "MagicalRecordShorthand.h"
#endif
-
-#import "MagicalRecordHelpers.h"
-#import "MRCoreDataAction.h"
-
-#import "NSManagedObject+MagicalRecord.h"
-#import "NSManagedObjectContext+MagicalRecord.h"
-#import "NSPersistentStoreCoordinator+MagicalRecord.h"
-#import "NSManagedObjectModel+MagicalRecord.h"
-#import "NSPersistentStore+MagicalRecord.h"
-
-#import "NSManagedObject+MagicalDataImport.h"
-#import "NSNumber+MagicalDataImport.h"
-#import "NSObject+MagicalDataImport.h"
-#import "NSString+MagicalDataImport.h"
-#import "NSAttributeDescription+MagicalDataImport.h"
-#import "NSRelationshipDescription+MagicalDataImport.h"
-#import "NSEntityDescription+MagicalDataImport.h"
View
6 MagicalRecord/MRCoreDataAction.h → MagicalRecord/MagicalRecord+Actions.h
@@ -20,9 +20,7 @@ typedef enum
MRCoreDataLookupOptionWithNewContext = 1 << 0
} MRCoreDataLookupOption;
-@interface MRCoreDataAction : NSObject
-
-+ (void) cleanUp;
+@interface MagicalRecord (Actions)
#ifdef NS_BLOCKS_AVAILABLE
@@ -39,3 +37,5 @@ typedef enum
#endif
@end
+
+void cleanup_save_queue();
View
8 MagicalRecord/MRCoreDataAction.m → MagicalRecord/MagicalRecord+Actions.m
@@ -6,7 +6,6 @@
// Copyright 2011 Magical Panda Software. All rights reserved.
//
-//#import "ARCoreDataAction.h"
#import "CoreData+MagicalRecord.h"
#import "NSManagedObjectContext+MagicalRecord.h"
#import <dispatch/dispatch.h>
@@ -34,12 +33,7 @@ void cleanup_save_queue()
}
}
-@implementation MRCoreDataAction
-
-+ (void) cleanUp
-{
- cleanup_save_queue();
-}
+@implementation MagicalRecord (Actions)
#ifdef NS_BLOCKS_AVAILABLE
View
22 MagicalRecord/MagicalRecord+ErrorHandling.h
@@ -0,0 +1,22 @@
+//
+// MagicalRecord+ErrorHandling.h
+// Magical Record
+//
+// Created by Saul Mora on 3/6/12.
+// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved.
+//
+
+#import "MagicalRecord.h"
+
+@interface MagicalRecord (ErrorHandling)
+
++ (void) handleErrors:(NSError *)error;
+- (void) handleErrors:(NSError *)error;
+
++ (void) setErrorHandlerTarget:(id)target action:(SEL)action;
++ (SEL) errorHandlerAction;
++ (id) errorHandlerTarget;
+
++ (void) cleanUpErrorHanding;
+
+@end
View
94 MagicalRecord/MagicalRecord+ErrorHandling.m
@@ -0,0 +1,94 @@
+//
+// MagicalRecord+ErrorHandling.m
+// Magical Record
+//
+// Created by Saul Mora on 3/6/12.
+// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved.
+//
+
+#import "MagicalRecord+ErrorHandling.h"
+
+
+static id errorHandlerTarget = nil;
+static SEL errorHandlerAction = nil;
+
+
+@implementation MagicalRecord (ErrorHandling)
+
++ (void) cleanUpErrorHanding;
+{
+ errorHandlerTarget = nil;
+ errorHandlerAction = nil;
+}
+
++ (void) defaultErrorHandler:(NSError *)error
+{
+ NSDictionary *userInfo = [error userInfo];
+ for (NSArray *detailedError in [userInfo allValues])
+ {
+ if ([detailedError isKindOfClass:[NSArray class]])
+ {
+ for (NSError *e in detailedError)
+ {
+ if ([e respondsToSelector:@selector(userInfo)])
+ {
+ MRLog(@"Error Details: %@", [e userInfo]);
+ }
+ else
+ {
+ MRLog(@"Error Details: %@", e);
+ }
+ }
+ }
+ else
+ {
+ MRLog(@"Error: %@", detailedError);
+ }
+ }
+ MRLog(@"Error Message: %@", [error localizedDescription]);
+ MRLog(@"Error Domain: %@", [error domain]);
+ MRLog(@"Recovery Suggestion: %@", [error localizedRecoverySuggestion]);
+}
+
++ (void) handleErrors:(NSError *)error
+{
+ if (error)
+ {
+ // If a custom error handler is set, call that
+ if (errorHandlerTarget != nil && errorHandlerAction != nil)
+ {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
+ [errorHandlerTarget performSelector:errorHandlerAction withObject:error];
+#pragma clang diagnostic pop
+ }
+ else
+ {
+ // Otherwise, fall back to the default error handling
+ [self defaultErrorHandler:error];
+ }
+ }
+}
+
++ (id) errorHandlerTarget
+{
+ return errorHandlerTarget;
+}
+
++ (SEL) errorHandlerAction
+{
+ return errorHandlerAction;
+}
+
++ (void) setErrorHandlerTarget:(id)target action:(SEL)action
+{
+ errorHandlerTarget = target; /* Deliberately don't retain to avoid potential retain cycles */
+ errorHandlerAction = action;
+}
+
+- (void) handleErrors:(NSError *)error
+{
+ [[self class] handleErrors:error];
+}
+
+@end
View
24 MagicalRecord/MagicalRecord+Options.h
@@ -0,0 +1,24 @@
+//
+// MagicalRecord+Options.h
+// Magical Record
+//
+// Created by Saul Mora on 3/6/12.
+// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved.
+//
+
+#import "MagicalRecord.h"
+
+@interface MagicalRecord (Options)
+
+//global options
+// enable/disable logging
+// add logging provider
+// autocreate new PSC per Store
+// autoassign new instances to default store
++ (BOOL) shouldAutoCreateManagedObjectModel;
++ (void) setShouldAutoCreateManagedObjectModel:(BOOL)shouldAutoCreate;
++ (BOOL) shouldAutoCreateDefaultPersistentStoreCoordinator;
++ (void) setShouldAutoCreateDefaultPersistentStoreCoordinator:(BOOL)shouldAutoCreate;
+
+
+@end
View
38 MagicalRecord/MagicalRecord+Options.m
@@ -0,0 +1,38 @@
+//
+// MagicalRecord+Options.m
+// Magical Record
+//
+// Created by Saul Mora on 3/6/12.
+// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved.
+//
+
+#import "MagicalRecord+Options.h"
+
+static BOOL shouldAutoCreateManagedObjectModel_;
+static BOOL shouldAutoCreateDefaultPersistentStoreCoordinator_;
+
+@implementation MagicalRecord (Options)
+
+#pragma mark - Options
+
++ (BOOL) shouldAutoCreateManagedObjectModel;
+{
+ return shouldAutoCreateManagedObjectModel_;
+}
+
++ (void) setShouldAutoCreateManagedObjectModel:(BOOL)shouldAutoCreate;
+{
+ shouldAutoCreateManagedObjectModel_ = shouldAutoCreate;
+}
+
++ (BOOL) shouldAutoCreateDefaultPersistentStoreCoordinator;
+{
+ return shouldAutoCreateDefaultPersistentStoreCoordinator_;
+}
+
++ (void) setShouldAutoCreateDefaultPersistentStoreCoordinator:(BOOL)shouldAutoCreate;
+{
+ shouldAutoCreateDefaultPersistentStoreCoordinator_ = shouldAutoCreate;
+}
+
+@end
View
21 MagicalRecord/MagicalRecord+Setup.h
@@ -0,0 +1,21 @@
+//
+// MagicalRecord+Setup.h
+// Magical Record
+//
+// Created by Saul Mora on 3/7/12.
+// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved.
+//
+
+#import "MagicalRecord.h"
+
+@interface MagicalRecord (Setup)
+
++ (void) setupCoreDataStack;
++ (void) setupCoreDataStackWithInMemoryStore;
++ (void) setupAutoMigratingCoreDataStack;
+
++ (void) setupCoreDataStackWithStoreNamed:(NSString *)storeName;
++ (void) setupCoreDataStackWithAutoMigratingSqliteStoreNamed:(NSString *)storeName;
+
+
+@end
View
51 MagicalRecord/MagicalRecord+Setup.m
@@ -0,0 +1,51 @@
+//
+// MagicalRecord+Setup.m
+// Magical Record
+//
+// Created by Saul Mora on 3/7/12.
+// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved.
+//
+
+#import "MagicalRecord+Setup.h"
+
+@implementation MagicalRecord (Setup)
+
++ (void) setupCoreDataStack
+{
+ NSManagedObjectContext *context = [NSManagedObjectContext MR_context];
+ [NSManagedObjectContext MR_setDefaultContext:context];
+}
+
++ (void) setupAutoMigratingCoreDataStack
+{
+ [self setupCoreDataStackWithAutoMigratingSqliteStoreNamed:[self defaultStoreName]];
+}
+
++ (void) setupCoreDataStackWithStoreNamed:(NSString *)storeName
+{
+ NSPersistentStoreCoordinator *coordinator = [NSPersistentStoreCoordinator MR_coordinatorWithSqliteStoreNamed:storeName];
+ [NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:coordinator];
+
+ NSManagedObjectContext *context = [NSManagedObjectContext MR_contextWithStoreCoordinator:coordinator];
+ [NSManagedObjectContext MR_setDefaultContext:context];
+}
+
++ (void) setupCoreDataStackWithAutoMigratingSqliteStoreNamed:(NSString *)storeName
+{
+ NSPersistentStoreCoordinator *coordinator = [NSPersistentStoreCoordinator MR_coordinatorWithAutoMigratingSqliteStoreNamed:storeName];
+ [NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:coordinator];
+
+ NSManagedObjectContext *context = [NSManagedObjectContext MR_contextWithStoreCoordinator:coordinator];
+ [NSManagedObjectContext MR_setDefaultContext:context];
+}
+
++ (void) setupCoreDataStackWithInMemoryStore;
+{
+ NSPersistentStoreCoordinator *coordinator = [NSPersistentStoreCoordinator MR_coordinatorWithInMemoryStore];
+ [NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:coordinator];
+
+ NSManagedObjectContext *context = [NSManagedObjectContext MR_contextWithStoreCoordinator:coordinator];
+ [NSManagedObjectContext MR_setDefaultContext:context];
+}
+
+@end
View
15 MagicalRecord/MagicalRecord+ShorthandSupport.h
@@ -0,0 +1,15 @@
+//
+// MagicalRecord+ShorthandSupport.h
+// Magical Record
+//
+// Created by Saul Mora on 3/6/12.
+// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved.
+//
+
+#import "MagicalRecord.h"
+
+@interface MagicalRecord (ShorthandSupport)
+
++ (void) swizzleShorthandMethods;
+
+@end
View
146 MagicalRecord/MagicalRecord+ShorthandSupport.m
@@ -0,0 +1,146 @@
+//
+// MagicalRecord+ShorthandSupport.m
+// Magical Record
+//
+// Created by Saul Mora on 3/6/12.
+// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved.
+//
+
+#import "MagicalRecord+ShorthandSupport.h"
+#import <objc/runtime.h>
+
+
+static NSString * const kMagicalRecordCategoryPrefix = @"MR_";
+#ifdef MR_SHORTHAND
+static BOOL methodsHaveBeenSwizzled = NO;
+#endif
+
+
+//Dynamic shorthand method helpers
+BOOL addMagicalRecordShortHandMethodToPrefixedClassMethod(Class class, SEL selector);
+BOOL addMagicalRecordShorthandMethodToPrefixedInstanceMethod(Class klass, SEL originalSelector);
+
+void swizzleInstanceMethods(Class originalClass, SEL originalSelector, Class targetClass, SEL newSelector);
+void replaceSelectorForTargetWithSourceImpAndSwizzle(Class originalClass, SEL originalSelector, Class newClass, SEL newSelector);
+
+
+@implementation MagicalRecord (ShorthandSupport)
+
+#pragma mark - Support methods for shorthand methods
+
+#ifdef MR_SHORTHAND
++ (BOOL) MR_resolveClassMethod:(SEL)originalSelector
+{
+ BOOL resolvedClassMethod = [self MR_resolveClassMethod:originalSelector];
+ if (!resolvedClassMethod)
+ {
+ resolvedClassMethod = addMagicalRecordShortHandMethodToPrefixedClassMethod(self, originalSelector);
+ }
+ return resolvedClassMethod;
+}
+
++ (BOOL) MR_resolveInstanceMethod:(SEL)originalSelector
+{
+ BOOL resolvedClassMethod = [self MR_resolveInstanceMethod:originalSelector];
+ if (!resolvedClassMethod)
+ {
+ resolvedClassMethod = addMagicalRecordShorthandMethodToPrefixedInstanceMethod(self, originalSelector);
+ }
+ return resolvedClassMethod;
+}
+
+//In order to add support for non-prefixed AND prefixed methods, we need to swap the existing resolveClassMethod: and resolveInstanceMethod: implementations with the one in this class.
++ (void) updateResolveMethodsForClass:(Class)klass
+{
+ replaceSelectorForTargetWithSourceImpAndSwizzle(self, @selector(MR_resolveClassMethod:), klass, @selector(resolveClassMethod:));
+ replaceSelectorForTargetWithSourceImpAndSwizzle(self, @selector(MR_resolveInstanceMethod:), klass, @selector(resolveInstanceMethod:));
+}
+
++ (void) swizzleShorthandMethods;
+{
+ if (methodsHaveBeenSwizzled) return;
+
+ NSArray *classes = [NSArray arrayWithObjects:
+ [NSManagedObject class],
+ [NSManagedObjectContext class],
+ [NSManagedObjectModel class],
+ [NSPersistentStore class],
+ [NSPersistentStoreCoordinator class], nil];
+
+ [classes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
+ Class klass = (Class)obj;
+
+ [self updateResolveMethodsForClass:klass];
+ }];
+ methodsHaveBeenSwizzled = YES;
+}
+#endif
+
+@end
+
+#pragma mark - Support functions for runtime shorthand Method calling
+
+void replaceSelectorForTargetWithSourceImpAndSwizzle(Class sourceClass, SEL sourceSelector, Class targetClass, SEL targetSelector)
+{
+ Method sourceClassMethod = class_getClassMethod(sourceClass, sourceSelector);
+ Method targetClassMethod = class_getClassMethod(targetClass, targetSelector);
+
+ Class targetMetaClass = objc_getMetaClass([NSStringFromClass(targetClass) cStringUsingEncoding:NSUTF8StringEncoding]);
+
+ BOOL methodWasAdded = class_addMethod(targetMetaClass, sourceSelector,
+ method_getImplementation(targetClassMethod),
+ method_getTypeEncoding(targetClassMethod));
+
+ if (methodWasAdded)
+ {
+ class_replaceMethod(targetMetaClass, targetSelector,
+ method_getImplementation(sourceClassMethod),
+ method_getTypeEncoding(sourceClassMethod));
+ }
+}
+
+BOOL addMagicalRecordShorthandMethodToPrefixedInstanceMethod(Class klass, SEL originalSelector)
+{
+ NSString *originalSelectorString = NSStringFromSelector(originalSelector);
+ if ([originalSelectorString hasPrefix:@"_"] || [originalSelectorString hasPrefix:@"init"]) return NO;
+
+ if (![originalSelectorString hasPrefix:kMagicalRecordCategoryPrefix])
+ {
+ NSString *prefixedSelector = [kMagicalRecordCategoryPrefix stringByAppendingString:originalSelectorString];
+ Method existingMethod = class_getInstanceMethod(klass, NSSelectorFromString(prefixedSelector));
+
+ if (existingMethod)
+ {
+ BOOL methodWasAdded = class_addMethod(klass,
+ originalSelector,
+ method_getImplementation(existingMethod),
+ method_getTypeEncoding(existingMethod));
+
+ return methodWasAdded;
+ }
+ }
+ return NO;
+}
+
+
+BOOL addMagicalRecordShortHandMethodToPrefixedClassMethod(Class klass, SEL originalSelector)
+{
+ NSString *originalSelectorString = NSStringFromSelector(originalSelector);
+ if (![originalSelectorString hasPrefix:kMagicalRecordCategoryPrefix])
+ {
+ NSString *prefixedSelector = [kMagicalRecordCategoryPrefix stringByAppendingString:originalSelectorString];
+ Method existingMethod = class_getClassMethod(klass, NSSelectorFromString(prefixedSelector));
+
+ if (existingMethod)
+ {
+ Class metaClass = objc_getMetaClass([NSStringFromClass(klass) cStringUsingEncoding:NSUTF8StringEncoding]);
+ BOOL methodWasAdded = class_addMethod(metaClass,
+ originalSelector,
+ method_getImplementation(existingMethod),
+ method_getTypeEncoding(existingMethod));
+
+ return methodWasAdded;
+ }
+ }
+ return NO;
+}
View
18 MagicalRecord/MagicalRecord+iCloud.h
@@ -0,0 +1,18 @@
+//
+// MagicalRecord+iCloud.h
+// Magical Record
+//
+// Created by Saul Mora on 3/7/12.
+// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved.
+//
+
+#import "MagicalRecord.h"
+
+@interface MagicalRecord (iCloud)
+
++ (BOOL) isICloudEnabled;
++ (void) setupCoreDataStackWithiCloudContainer:(NSString *)icloudBucket localStoreNamed:(NSString *)localStore;
++ (void) setupCoreDataStackWithiCloudContainer:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)pathSubcomponent;
++ (void) setupCoreDataStackWithiCloudContainer:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)pathSubcomponent completion:(void(^)(void))completion;
+
+@end
View
45 MagicalRecord/MagicalRecord+iCloud.m
@@ -0,0 +1,45 @@
+//
+// MagicalRecord+iCloud.m
+// Magical Record
+//
+// Created by Saul Mora on 3/7/12.
+// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved.
+//
+
+#import "MagicalRecord+iCloud.h"
+
+@implementation MagicalRecord (iCloud)
+
+#pragma mark - iCloud Methods
+
++ (BOOL) isICloudEnabled;
+{
+ NSURL *cloudURL = [NSPersistentStore MR_cloudURLForUbiqutiousContainer:nil];
+ return cloudURL != nil;
+}
+
++ (void) setupCoreDataStackWithiCloudContainer:(NSString *)icloudBucket localStoreNamed:(NSString *)localStore;
+{
+ NSString *contentNameKey = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];
+ [self setupCoreDataStackWithiCloudContainer:icloudBucket contentNameKey:contentNameKey localStoreNamed:localStore cloudStorePathComponent:nil];
+}
+
++ (void) setupCoreDataStackWithiCloudContainer:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)pathSubcomponent;
+{
+ [self setupCoreDataStackWithiCloudContainer:containerID contentNameKey:contentNameKey localStoreNamed:localStoreName cloudStorePathComponent:pathSubcomponent completion:nil];
+}
+
++ (void) setupCoreDataStackWithiCloudContainer:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)pathSubcomponent completion:(void(^)(void))completion;
+{
+ NSPersistentStoreCoordinator *coordinator = [NSPersistentStoreCoordinator MR_coordinatorWithiCloudContainerID:containerID
+ contentNameKey:contentNameKey
+ localStoreNamed:localStoreName
+ cloudStorePathComponent:pathSubcomponent
+ completion:completion];
+ [NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:coordinator];
+
+ NSManagedObjectContext *context = [NSManagedObjectContext MR_contextWithStoreCoordinator:coordinator];
+ [NSManagedObjectContext MR_setDefaultContext:context];
+}
+
+@end
View
29 MagicalRecord/MagicalRecord.h
@@ -0,0 +1,29 @@
+//
+// MagicalRecord.h
+//
+// Created by Saul Mora on 3/11/10.
+// Copyright 2010 Magical Panda Software, LLC All rights reserved.
+//
+
+#if TARGET_OS_IPHONE == 0
+#define MAC_PLATFORM_ONLY YES
+#endif
+
+#ifdef NS_BLOCKS_AVAILABLE
+
+@class NSManagedObjectContext;
+typedef void (^CoreDataBlock)(NSManagedObjectContext *context);
+
+#endif
+
+@interface MagicalRecord : NSObject
+
++ (NSString *) currentStack;
+
++ (void) cleanUp;
+
++ (void) setDefaultModelFromClass:(Class)klass;
++ (void) setDefaultModelNamed:(NSString *)modelName;
++ (NSString *) defaultStoreName;
+
+@end
View
91 MagicalRecord/MagicalRecord.m
@@ -0,0 +1,91 @@
+//
+// MagicalRecord.m
+//
+// Created by Saul Mora on 3/11/10.
+// Copyright 2010 Magical Panda Software, LLC All rights reserved.
+//
+
+#import "CoreData+MagicalRecord.h"
+
+@interface MagicalRecord (Internal)
+
++ (void) cleanUpStack;
+
+@end
+
+
+@implementation MagicalRecord
+
++ (void) cleanUp
+{
+ cleanup_save_queue();
+ [self cleanUpErrorHanding];
+ [self cleanUpStack];
+}
+
++ (void) cleanUpStack;
+{
+ [NSManagedObjectContext MR_setDefaultContext:nil];
+ [NSManagedObjectModel MR_setDefaultManagedObjectModel:nil];
+ [NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:nil];
+ [NSPersistentStore MR_setDefaultPersistentStore:nil];
+}
+
++ (NSString *) currentStack
+{
+ NSMutableString *status = [NSMutableString stringWithString:@"Current Default Core Data Stack: ---- \n"];
+
+ [status appendFormat:@"Context: %@\n", [NSManagedObjectContext MR_defaultContext]];
+ [status appendFormat:@"Model: %@\n", [[NSManagedObjectModel MR_defaultManagedObjectModel] entityVersionHashesByName]];
+ [status appendFormat:@"Coordinator: %@\n", [NSPersistentStoreCoordinator MR_defaultStoreCoordinator]];
+ [status appendFormat:@"Store: %@\n", [NSPersistentStore MR_defaultPersistentStore]];
+
+ return status;
+}
+
++ (void) setDefaultModelNamed:(NSString *)modelName;
+{
+ NSManagedObjectModel *model = [NSManagedObjectModel MR_managedObjectModelNamed:modelName];
+ [NSManagedObjectModel MR_setDefaultManagedObjectModel:model];
+}
+
++ (void) setDefaultModelFromClass:(Class)klass;
+{
+ NSBundle *bundle = [NSBundle bundleForClass:klass];
+ NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:[NSArray arrayWithObject:bundle]];
+ [NSManagedObjectModel MR_setDefaultManagedObjectModel:model];
+}
+
++ (NSString *) defaultStoreName;
+{
+ NSString *defaultName = [[[NSBundle mainBundle] infoDictionary] valueForKey:(id)kCFBundleNameKey];
+ if (defaultName == nil)
+ {
+ defaultName = kMagicalRecordDefaultStoreFileName;
+ }
+ if (![defaultName hasSuffix:@"sqlite"])
+ {
+ defaultName = [defaultName stringByAppendingPathExtension:@"sqlite"];
+ }
+
+ return defaultName;
+}
+
+
+#pragma mark - initialize
+
++ (void) initialize;
+{
+ if (self == [MagicalRecord class])
+ {
+#ifdef MR_SHORTHAND
+ [self swizzleShorthandMethods];
+#endif
+ [self setShouldAutoCreateManagedObjectModel:YES];
+ [self setShouldAutoCreateDefaultPersistentStoreCoordinator:YES];
+ }
+}
+
+@end
+
+
View
90 MagicalRecord/MagicalRecordHelpers.h
@@ -1,90 +0,0 @@
-//
-// MagicalRecordHelpers.h
-//
-// Created by Saul Mora on 3/11/10.
-// Copyright 2010 Magical Panda Software, LLC All rights reserved.
-//
-
-#if TARGET_OS_IPHONE == 0
-#define MAC_PLATFORM_ONLY YES
-#endif
-
-#ifdef NS_BLOCKS_AVAILABLE
-
-@class NSManagedObjectContext;
-typedef void (^CoreDataBlock)(NSManagedObjectContext *context);
-
-#endif
-
-@interface MagicalRecordHelpers : NSObject
-
-+ (NSString *) currentStack;
-
-+ (void) cleanUp;
-
-+ (void) handleErrors:(NSError *)error;
-- (void) handleErrors:(NSError *)error;
-
-+ (void) setErrorHandlerTarget:(id)target action:(SEL)action;
-+ (SEL) errorHandlerAction;
-+ (id) errorHandlerTarget;
-
-+ (void) setDefaultModelForTestCase:(Class)aClass;
-+ (void) setDefaultModelNamed:(NSString *)modelName;
-+ (NSString *) defaultStoreName;
-
-//global options
-// enable/disable logging
-// add logging provider
-// autocreate new PSC per Store
-// autoassign new instances to default store
-+ (BOOL) shouldAutoCreateManagedObjectModel;
-+ (void) setShouldAutoCreateManagedObjectModel:(BOOL)shouldAutoCreate;
-+ (BOOL) shouldAutoCreateDefaultPersistentStoreCoordinator;
-+ (void) setShouldAutoCreateDefaultPersistentStoreCoordinator:(BOOL)shouldAutoCreate;
-
-
-+ (void) setupCoreDataStack;
-+ (void) setupCoreDataStackWithInMemoryStore;
-+ (void) setupAutoMigratingCoreDataStack;
-
-+ (void) setupCoreDataStackWithStoreNamed:(NSString *)storeName;
-+ (void) setupCoreDataStackWithAutoMigratingSqliteStoreNamed:(NSString *)storeName;
-
-#pragma mark - iCloud Support
-
-+ (BOOL) isICloudEnabled;
-+ (void) setupCoreDataStackWithiCloudContainer:(NSString *)icloudBucket localStoreNamed:(NSString *)localStore;
-+ (void) setupCoreDataStackWithiCloudContainer:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)pathSubcomponent;
-+ (void) setupCoreDataStackWithiCloudContainer:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)pathSubcomponent completion:(void(^)(void))completion;
-
-#ifdef NS_BLOCKS_AVAILABLE
-#pragma mark DEPRECATED_METHOD
-
-+ (void) performSaveDataOperationWithBlock:(CoreDataBlock)block;
-+ (void) performSaveDataOperationInBackgroundWithBlock:(CoreDataBlock)block;
-+ (void) performLookupOperationWithBlock:(CoreDataBlock)block;
-+ (void) performSaveDataOperationInBackgroundWithBlock:(CoreDataBlock)block completion:(void(^)(void))callback;
-
-#endif
-
-@end
-
-
-//Helper Functions
-NSDate * adjustDateForDST(NSDate *date);
-NSDate * dateFromString(NSString *value, NSString *format);
-NSString * attributeNameFromString(NSString *value);
-NSString * primaryKeyNameFromString(NSString *value);
-
-#if TARGET_OS_IPHONE
-
-UIColor * UIColorFromString(NSString *serializedColor);
-
-#else
-
-NSColor * NSColorFromString(NSString *serializedColor);
-
-#endif
-extern id (*colorFromString)(NSString *);
-
View
493 MagicalRecord/MagicalRecordHelpers.m
@@ -1,493 +0,0 @@
-//
-// MagicalRecordHelpers.m
-//
-// Created by Saul Mora on 3/11/10.
-// Copyright 2010 Magical Panda Software, LLC All rights reserved.
-//
-
-#import "CoreData+MagicalRecord.h"
-#import <objc/runtime.h>
-
-static NSString * const kMagicalRecordCategoryPrefix = @"MR_";
-#ifdef MR_SHORTHAND
-static BOOL methodsHaveBeenSwizzled = NO;
-#endif
-
-static id errorHandlerTarget = nil;
-static SEL errorHandlerAction = nil;
-
-static BOOL shouldAutoCreateManagedObjectModel_;
-static BOOL shouldAutoCreateDefaultPersistentStoreCoordinator_;
-
-//Dynamic shorthand method helpers
-BOOL addMagicalRecordShortHandMethodToPrefixedClassMethod(Class class, SEL selector);
-BOOL addMagicalRecordShorthandMethodToPrefixedInstanceMethod(Class klass, SEL originalSelector);
-
-void swizzleInstanceMethods(Class originalClass, SEL originalSelector, Class targetClass, SEL newSelector);
-void replaceSelectorForTargetWithSourceImpAndSwizzle(Class originalClass, SEL originalSelector, Class newClass, SEL newSelector);
-
-@implementation MagicalRecordHelpers
-
-+ (void) cleanUp
-{
- errorHandlerTarget = nil;
- errorHandlerAction = nil;
- [MRCoreDataAction cleanUp];
- [NSManagedObjectContext MR_setDefaultContext:nil];
- [NSManagedObjectModel MR_setDefaultManagedObjectModel:nil];
- [NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:nil];
- [NSPersistentStore MR_setDefaultPersistentStore:nil];
-}
-
-+ (NSString *) currentStack
-{
- NSMutableString *status = [NSMutableString stringWithString:@"Current Default Core Data Stack: ---- \n"];
-
- [status appendFormat:@"Context: %@\n", [NSManagedObjectContext MR_defaultContext]];
- [status appendFormat:@"Model: %@\n", [[NSManagedObjectModel MR_defaultManagedObjectModel] entityVersionHashesByName]];
- [status appendFormat:@"Coordinator: %@\n", [NSPersistentStoreCoordinator MR_defaultStoreCoordinator]];
- [status appendFormat:@"Store: %@\n", [NSPersistentStore MR_defaultPersistentStore]];
-
- return status;
-}
-
-+ (void) defaultErrorHandler:(NSError *)error
-{
- NSDictionary *userInfo = [error userInfo];
- for (NSArray *detailedError in [userInfo allValues])
- {
- if ([detailedError isKindOfClass:[NSArray class]])
- {
- for (NSError *e in detailedError)
- {
- if ([e respondsToSelector:@selector(userInfo)])
- {
- MRLog(@"Error Details: %@", [e userInfo]);
- }
- else
- {
- MRLog(@"Error Details: %@", e);
- }
- }
- }
- else
- {
- MRLog(@"Error: %@", detailedError);
- }
- }
- MRLog(@"Error Message: %@", [error localizedDescription]);
- MRLog(@"Error Domain: %@", [error domain]);
- MRLog(@"Recovery Suggestion: %@", [error localizedRecoverySuggestion]);
-}
-
-+ (void) handleErrors:(NSError *)error
-{
- if (error)
- {
- // If a custom error handler is set, call that
- if (errorHandlerTarget != nil && errorHandlerAction != nil)
- {
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
- [errorHandlerTarget performSelector:errorHandlerAction withObject:error];
-#pragma clang diagnostic pop
- }
- else
- {
- // Otherwise, fall back to the default error handling
- [self defaultErrorHandler:error];
- }
- }
-}
-
-+ (id) errorHandlerTarget
-{
- return errorHandlerTarget;
-}
-
-+ (SEL) errorHandlerAction
-{
- return errorHandlerAction;
-}
-
-+ (void) setErrorHandlerTarget:(id)target action:(SEL)action
-{
- errorHandlerTarget = target; /* Deliberately don't retain to avoid potential retain cycles */
- errorHandlerAction = action;
-}
-
-- (void) handleErrors:(NSError *)error
-{
- [[self class] handleErrors:error];
-}
-
-+ (void) setDefaultModelNamed:(NSString *)modelName;
-{
- NSManagedObjectModel *model = [NSManagedObjectModel MR_managedObjectModelNamed:modelName];
- [NSManagedObjectModel MR_setDefaultManagedObjectModel:model];
-}
-
-+ (void) setDefaultModelForTestCase:(Class)class;
-{
- NSBundle *bundle = [NSBundle bundleForClass:class];
- NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:[NSArray arrayWithObject:bundle]];
- [NSManagedObjectModel MR_setDefaultManagedObjectModel:model];
-}
-
-+ (NSString *) defaultStoreName;
-{
- NSString *defaultName = [[[NSBundle mainBundle] infoDictionary] valueForKey:(id)kCFBundleNameKey];
- if (defaultName == nil)
- {
- defaultName = kMagicalRecordDefaultStoreFileName;
- }
- if (![defaultName hasSuffix:@"sqlite"])
- {
- defaultName = [defaultName stringByAppendingPathExtension:@"sqlite"];
- }
-
- return defaultName;
-}
-
-+ (void) setupCoreDataStack
-{
- NSManagedObjectContext *context = [NSManagedObjectContext MR_context];
- [NSManagedObjectContext MR_setDefaultContext:context];
-}
-
-+ (void) setupAutoMigratingCoreDataStack
-{
- [self setupCoreDataStackWithAutoMigratingSqliteStoreNamed:[self defaultStoreName]];
-}
-
-+ (void) setupCoreDataStackWithStoreNamed:(NSString *)storeName
-{
- NSPersistentStoreCoordinator *coordinator = [NSPersistentStoreCoordinator MR_coordinatorWithSqliteStoreNamed:storeName];
- [NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:coordinator];
-
- NSManagedObjectContext *context = [NSManagedObjectContext MR_contextWithStoreCoordinator:coordinator];
- [NSManagedObjectContext MR_setDefaultContext:context];
-}
-
-+ (void) setupCoreDataStackWithAutoMigratingSqliteStoreNamed:(NSString *)storeName
-{
- NSPersistentStoreCoordinator *coordinator = [NSPersistentStoreCoordinator MR_coordinatorWithAutoMigratingSqliteStoreNamed:storeName];
- [NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:coordinator];
-
- NSManagedObjectContext *context = [NSManagedObjectContext MR_contextWithStoreCoordinator:coordinator];
- [NSManagedObjectContext MR_setDefaultContext:context];
-}
-
-+ (void) setupCoreDataStackWithInMemoryStore;
-{
- NSPersistentStoreCoordinator *coordinator = [NSPersistentStoreCoordinator MR_coordinatorWithInMemoryStore];
- [NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:coordinator];
-
- NSManagedObjectContext *context = [NSManagedObjectContext MR_contextWithStoreCoordinator:coordinator];
- [NSManagedObjectContext MR_setDefaultContext:context];
-}
-
-#pragma mark - iCloud Methods
-
-+ (BOOL) isICloudEnabled;
-{
- NSURL *cloudURL = [NSPersistentStore MR_cloudURLForUbiqutiousContainer:nil];
- return cloudURL != nil;
-}
-
-+ (void) setupCoreDataStackWithiCloudContainer:(NSString *)icloudBucket localStoreNamed:(NSString *)localStore;
-{
- NSString *contentNameKey = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];
- [self setupCoreDataStackWithiCloudContainer:icloudBucket contentNameKey:contentNameKey localStoreNamed:localStore cloudStorePathComponent:nil];
-}
-
-+ (void) setupCoreDataStackWithiCloudContainer:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)pathSubcomponent;
-{
- [self setupCoreDataStackWithiCloudContainer:containerID contentNameKey:contentNameKey localStoreNamed:localStoreName cloudStorePathComponent:pathSubcomponent completion:nil];
-}
-
-+ (void) setupCoreDataStackWithiCloudContainer:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)pathSubcomponent completion:(void(^)(void))completion;
-{
- NSPersistentStoreCoordinator *coordinator = [NSPersistentStoreCoordinator MR_coordinatorWithiCloudContainerID:containerID
- contentNameKey:contentNameKey
- localStoreNamed:localStoreName
- cloudStorePathComponent:pathSubcomponent
- completion:completion];
- [NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:coordinator];
-
- NSManagedObjectContext *context = [NSManagedObjectContext MR_contextWithStoreCoordinator:coordinator];
- [NSManagedObjectContext MR_setDefaultContext:context];
-}
-
-#pragma mark - Options
-
-+ (BOOL) shouldAutoCreateManagedObjectModel;
-{
- return shouldAutoCreateManagedObjectModel_;
-}
-
-+ (void) setShouldAutoCreateManagedObjectModel:(BOOL)shouldAutoCreate;
-{
- shouldAutoCreateManagedObjectModel_ = shouldAutoCreate;
-}
-
-+ (BOOL) shouldAutoCreateDefaultPersistentStoreCoordinator;
-{
- return shouldAutoCreateDefaultPersistentStoreCoordinator_;
-}
-
-+ (void) setShouldAutoCreateDefaultPersistentStoreCoordinator:(BOOL)shouldAutoCreate;
-{
- shouldAutoCreateDefaultPersistentStoreCoordinator_ = shouldAutoCreate;
-}
-
-
-#ifdef NS_BLOCKS_AVAILABLE
-#pragma mark DEPRECATED_METHOD
-
-+ (void) performSaveDataOperationWithBlock:(CoreDataBlock)block;
-{
- [MRCoreDataAction saveDataWithBlock:block];
-}
-
-+ (void) performSaveDataOperationInBackgroundWithBlock:(CoreDataBlock)block;
-{
- [MRCoreDataAction saveDataInBackgroundWithBlock:block];
-}
-
-+ (void) performLookupOperationWithBlock:(CoreDataBlock)block;
-{
- [MRCoreDataAction lookupWithBlock:block];
-}
-
-+ (void) performSaveDataOperationInBackgroundWithBlock:(CoreDataBlock)block completion:(void(^)(void))callback;
-{
- [MRCoreDataAction saveDataInBackgroundWithBlock:block completion:callback];
-}
-
-#endif
-
-#pragma mark - Support methods for shorthand methods
-
-#ifdef MR_SHORTHAND
-+ (BOOL) MR_resolveClassMethod:(SEL)originalSelector
-{
- BOOL resolvedClassMethod = [self MR_resolveClassMethod:originalSelector];
- if (!resolvedClassMethod)
- {
- resolvedClassMethod = addMagicalRecordShortHandMethodToPrefixedClassMethod(self, originalSelector);
- }
- return resolvedClassMethod;
-}
-
-+ (BOOL) MR_resolveInstanceMethod:(SEL)originalSelector
-{
- BOOL resolvedClassMethod = [self MR_resolveInstanceMethod:originalSelector];
- if (!resolvedClassMethod)
- {
- resolvedClassMethod = addMagicalRecordShorthandMethodToPrefixedInstanceMethod(self, originalSelector);
- }
- return resolvedClassMethod;
-}
-
-//In order to add support for non-prefixed AND prefixed methods, we need to swap the existing resolveClassMethod: and resolveInstanceMethod: implementations with the one in this class.
-+ (void) updateResolveMethodsForClass:(Class)klass
-{
- replaceSelectorForTargetWithSourceImpAndSwizzle(self, @selector(MR_resolveClassMethod:), klass, @selector(resolveClassMethod:));
- replaceSelectorForTargetWithSourceImpAndSwizzle(self, @selector(MR_resolveInstanceMethod:), klass, @selector(resolveInstanceMethod:));
-}
-
-+ (void) swizzleShorthandMethods;
-{
- if (methodsHaveBeenSwizzled) return;
-
- NSArray *classes = [NSArray arrayWithObjects:
- [NSManagedObject class],
- [NSManagedObjectContext class],
- [NSManagedObjectModel class],
- [NSPersistentStore class],
- [NSPersistentStoreCoordinator class], nil];
-
- [classes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
- Class klass = (Class)obj;
-
- [self updateResolveMethodsForClass:klass];
- }];
- methodsHaveBeenSwizzled = YES;
-}
-#endif
-
-#pragma mark - initialize
-
-+ (void) initialize;
-{
- if (self == [MagicalRecordHelpers class])
- {
-#ifdef MR_SHORTHAND
- [self swizzleShorthandMethods];
-#endif
- [self setShouldAutoCreateManagedObjectModel:YES];
- [self setShouldAutoCreateDefaultPersistentStoreCoordinator:YES];
- }
-}
-
-@end
-
-#pragma mark - Support functions for runtime shorthand Method calling
-
-void replaceSelectorForTargetWithSourceImpAndSwizzle(Class sourceClass, SEL sourceSelector, Class targetClass, SEL targetSelector)
-{
- Method sourceClassMethod = class_getClassMethod(sourceClass, sourceSelector);
- Method targetClassMethod = class_getClassMethod(targetClass, targetSelector);
-
- Class targetMetaClass = objc_getMetaClass([NSStringFromClass(targetClass) cStringUsingEncoding:NSUTF8StringEncoding]);
-
- BOOL methodWasAdded = class_addMethod(targetMetaClass, sourceSelector,
- method_getImplementation(targetClassMethod),
- method_getTypeEncoding(targetClassMethod));
-
- if (methodWasAdded)
- {
- class_replaceMethod(targetMetaClass, targetSelector,
- method_getImplementation(sourceClassMethod),
- method_getTypeEncoding(sourceClassMethod));
- }
-}
-
-BOOL addMagicalRecordShorthandMethodToPrefixedInstanceMethod(Class klass, SEL originalSelector)
-{
- NSString *originalSelectorString = NSStringFromSelector(originalSelector);
- if ([originalSelectorString hasPrefix:@"_"] || [originalSelectorString hasPrefix:@"init"]) return NO;
-
- if (![originalSelectorString hasPrefix:kMagicalRecordCategoryPrefix])
- {
- NSString *prefixedSelector = [kMagicalRecordCategoryPrefix stringByAppendingString:originalSelectorString];
- Method existingMethod = class_getInstanceMethod(klass, NSSelectorFromString(prefixedSelector));
-
- if (existingMethod)
- {
- BOOL methodWasAdded = class_addMethod(klass,
- originalSelector,
- method_getImplementation(existingMethod),
- method_getTypeEncoding(existingMethod));
-
- return methodWasAdded;
- }
- }
- return NO;
-}
-
-
-BOOL addMagicalRecordShortHandMethodToPrefixedClassMethod(Class klass, SEL originalSelector)
-{
- NSString *originalSelectorString = NSStringFromSelector(originalSelector);
- if (![originalSelectorString hasPrefix:kMagicalRecordCategoryPrefix])
- {
- NSString *prefixedSelector = [kMagicalRecordCategoryPrefix stringByAppendingString:originalSelectorString];
- Method existingMethod = class_getClassMethod(klass, NSSelectorFromString(prefixedSelector));
-
- if (existingMethod)
- {
- Class metaClass = objc_getMetaClass([NSStringFromClass(klass) cStringUsingEncoding:NSUTF8StringEncoding]);
- BOOL methodWasAdded = class_addMethod(metaClass,
- originalSelector,
- method_getImplementation(existingMethod),
- method_getTypeEncoding(existingMethod));
-
- return methodWasAdded;
- }
- }
- return NO;
-}
-
-#pragma mark - Data import helper functions
-
-NSString * attributeNameFromString(NSString *value)
-{
- NSString *firstCharacter = [[value substringToIndex:1] capitalizedString];
- return [firstCharacter stringByAppendingString:[value substringFromIndex:1]];
-}
-
-NSString * primaryKeyNameFromString(NSString *value)
-{
- NSString *firstCharacter = [[value substringToIndex:1] lowercaseString];
- return [firstCharacter stringByAppendingFormat:@"%@ID", [value substringFromIndex:1]];
-}
-
-NSDate * adjustDateForDST(NSDate *date)
-{
- NSTimeInterval dstOffset = [[NSTimeZone localTimeZone] daylightSavingTimeOffsetForDate:date];
- NSDate *actualDate = [date dateByAddingTimeInterval:dstOffset];
-
- return actualDate;
-}
-
-NSDate * dateFromString(NSString *value, NSString *format)
-{
- NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
- [formatter setTimeZone:[NSTimeZone localTimeZone]];
- [formatter setLocale:[NSLocale currentLocale]];
- [formatter setDateFormat:format];
-
- NSDate *parsedDate = [formatter dateFromString:value];
- MR_AUTORELEASE(formatter);
-
- return parsedDate;
-}
-
-NSInteger* newColorComponentsFromString(NSString *serializedColor);
-NSInteger* newColorComponentsFromString(NSString *serializedColor)
-{
- NSScanner *colorScanner = [NSScanner scannerWithString:serializedColor];
- NSString *colorType;
- [colorScanner scanUpToString:@"(" intoString:&colorType];
-
- NSInteger *componentValues = malloc(4 * sizeof(NSInteger));
- if ([colorType hasPrefix:@"rgba"])
- {
- NSCharacterSet *rgbaCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@"(,)"];
-
- NSInteger *componentValue = componentValues;
- while (![colorScanner isAtEnd])
- {
- [colorScanner scanCharactersFromSet:rgbaCharacterSet intoString:nil];
- [colorScanner scanInteger:componentValue];
- componentValue++;
- }
- }
- //else if ([colorType hasPrefix:@"hsba"])
- //else if ([colorType hasPrefix:@""])
- return componentValues;
-}
-
-#if TARGET_OS_IPHONE
-
-UIColor * UIColorFromString(NSString *serializedColor)
-{
- NSInteger *componentValues = newColorComponentsFromString(serializedColor);
- UIColor *color = [UIColor colorWithRed:(componentValues[0] / 255.)
- green:(componentValues[1] / 255.)
- blue:(componentValues[2] / 255.)
- alpha:componentValues[3]];
-
- free(componentValues);
- return color;
-}
-id (*colorFromString)(NSString *) = UIColorFromString;
-
-#else
-
-NSColor * NSColorFromString(NSString *serializedColor)
-{
- NSInteger *componentValues = newColorComponentsFromString(serializedColor);
- NSColor *color = [NSColor colorWithDeviceRed:(componentValues[0] / 255.)
- green:(componentValues[1] / 255.)
- blue:(componentValues[2] / 255.)
- alpha:componentValues[3]];
- free(componentValues);
- return color;
-}
-id (*colorFromString)(NSString *) = NSColorFromString;
-
-
-#endif
View
12 Project Files/Mac App Unit Tests/GHUnitTestMain.m
@@ -58,8 +58,9 @@ int main(int argc, char *argv[]) {
*/
NSSetUncaughtExceptionHandler(&exceptionHandler);
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
+ @autoreleasepool {
+
+
// Register any special test case classes
//[[GHTesting sharedInstance] registerClassName:@"GHSpecialTestCase"];
@@ -70,15 +71,16 @@ int main(int argc, char *argv[]) {
retVal = [GHTestRunner run];
} else {
// To run all tests (from ENV)
- GHTestApp *app = [[GHTestApp alloc] init];
+ [[GHTestApp alloc] init];
// To run a different test suite:
//GHTestSuite *suite = [GHTestSuite suiteWithTestFilter:@"GHSlowTest,GHAsyncTestCaseTest"];
//GHTestApp *app = [[GHTestApp alloc] initWithSuite:suite];
// Or set global:
//GHUnitTest = @"GHSlowTest";
[NSApp run];
- [app release];
+
}
- [pool release];
+
return retVal;
+ }
}
View
231 Project Files/Magical Record.xcodeproj/project.pbxproj
@@ -12,6 +12,15 @@
C70B6E7713D0F66000709450 /* NSManagedObjectModelHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C70B6E7613D0F66000709450 /* NSManagedObjectModelHelperTests.m */; };