Permalink
Browse files

no message

  • Loading branch information...
2 parents 2eaec27 + da70884 commit 3c24ce151bc19d42dbddccdc4ef8494a48f09cef @casademora casademora committed Oct 24, 2012
View
@@ -0,0 +1,59 @@
+# Changelog
+## Version 2.0.8
+* Fixed issue #287 - MR_findByAttribute:withValue:andOrderBy:ascending:inContext does not pass context through `4b97d0e` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+## Version 2.0.7
+* Fix small error in README with regard to MR_SHORTHAND `8c14cc7` - [Maik Gosenshuis](mailto:maik@gosenshuis.nl)
+* Hide intended private cleanUpErrorHandling method `a903e7e` - [Saul Mora](mailto:saul@magicalpanda.com)
+* Call completion handler on main thread. `c639ce4` - [Brandon Williams](mailto:brandon@opetopic.com)
+* Persist changes to disk when using: - [NSManagedObjectContext MR_saveInBackgroundErrorHandler:completion:] methods, AND the context is the default context - [MagicalRecord saveInBackground…] methods `8bb0d0d` - [Saul Mora](mailto:saul@magicalpanda.com)
+* [NSManagedObjectContext MR_saveInBackgroundErrorHandler:completion:] `f0246e9` - [Jwie](mailto:joey.daman@twoup.eu)
+* [NSManagedObjectContext MR_saveInBackgroundErrorHandler:completion:] `eabb147` - [Jwie](mailto:joey.daman@twoup.eu)
+* update `8b7c1c8` - [Peter Paulis](mailto:peterpaulis@Admins-MacBook-Air-2.local)
+* Correct typo `f99215b` - [Ryan Maxwell](mailto:ryanm@xwell.co.nz)
+* Update MR_SHORTHAND installation note to match main readme `222c956` - [Ryan Maxwell](mailto:ryanm@xwell.co.nz)
+* Correct typo of "persistent" in method name `86db065` - [Ryan Maxwell](mailto:ryanm@xwell.co.nz)
+* Make all requestAllSortedBy* methods consistent (allows sortTerms with commas) `33f3994` - [vguerci](mailto:vguerci@gmail.com)
+* dispatch_release is not needed by the <REDACTED> compiler `7128091` - [Saul Mora](mailto:saul@magicalpanda.com)
+* Don't run completion block if non specified `3aa2845` - [Saul Mora](mailto:saul@magicalpanda.com)
+* Make platform requirements more explicit `acff79a` - [Saul Mora](mailto:saul@magicalpanda.com)
+* Update MagicalRecord/Core/MagicalRecordShorthand.h `7daf3ad` - [Ryan Maxwell](mailto:ryanm@xwell.co.nz)
+* Added automatic store deletion if the store does not match the model `b8326a6` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Missed the configuration `22fe81a` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Updating readme with a short blurb `d8394cf` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Cleanup code is now debug-only `45d764a` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Clarified the DEBUG only nature of the fix `8842d8f` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Making background save asynchronous and fix the callback not firing `22311b7` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Added expecta matchers for tests `cff0304` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Fixing formatting issues to match project style `3bc55de` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Fixed KVC relationship mapping bug. `eaa78c2` - [Joshua Greene](mailto:jrg.developer@gmail.com)
+* Fixed an issue with aggregate actions not being performed in the specified context `9348ef5` - [Brian King](mailto:bking@agamatrix.com)
+* Adding an observer to check for icloud being setup after default context has been set. Should fix race condition in Issue #241 `5341e84` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Updated test model to actually build `2df10b1` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Clean up comments `ef16c57` - [Saul Mora](mailto:saul@magicalpanda.com)
+* Remove compile warnings `8f93070` - [Saul Mora](mailto:saul@magicalpanda.com)
+* Cleaning up iCloud setup observer code some `32f9f80` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Removes dispatch_release when iOS >= 6 || OSX >= 1080 `28a864b` - [Rod Wilhelmy](mailto:rwilhelmy@gmail.com)
+* Modifiying generateShorthand.rb to use user specified ruby `25081d0` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Automatically obtain permanent IDs when saving the default context. This should fix several crashes the community is hitting `0e34179` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Making all relevant contexts obtain a permanent id before saving `0b00e39` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Adding recommended journalling mode `a9a7643` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* fixup compiler warnings in Xcode 4.5 `5203cc1` - [Saul Mora](mailto:saul@magicalpanda.com)
+* Fix compile warnings once and for all :/ `11e5ee1` - [Saul Mora](mailto:saul@magicalpanda.com)
+* refactor internal method names to match more general objects to traverse fix another compile warning `0a6f523` - [Saul Mora](mailto:saul@magicalpanda.com)
+* - auto-migration options bug fix `1924d73` - [Alexander Belyavskiy](mailto:diejmon@me.com)
+* Don't adjust incoming NSDates for DST `da39710` - [Saul Mora](mailto:saul@magicalpanda.com)
+* fix compile error with pragma option `51fe465` - [Saul Mora](mailto:saul@magicalpanda.com)
+* Add findFirstOrderedByAttribute:ascending:context: method for getting min/max values easier `abb7314` - [Saul Mora](mailto:saul@magicalpanda.com)
+* Bumping podspec to 2.0.4 `4091c78` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Added new nestedContextSave method with completion handler `2660e73` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Bumping podspec with bugfix `a451eb4` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Fixing rookie mistake :/ `72dc5a4` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Require ARC in podspec (was compiling with retain/release in pod installations) `48cc383` - [Ryan Maxwell](mailto:ryanm@xwell.co.nz)
+* Bump tag to 2.0.6 `f2e2b7b` - [Ryan Maxwell](mailto:ryanm@xwell.co.nz)
+* Properly removing existing on-save notificaitons before replacing the default or root contexts `343b027` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Fixing potential concurrency issue with creating the actionQueue `52139bd` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Cherry picking changes that make the context description more... descriptive `a41ceee` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Rolled back a commit that broke things if cleanup was used. It created the action_queue in a dispatch_once block, and never recreated it after a cleanup `b81e70d` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* saveWithBlock was not saving parent contexts `870ca22` - [Tony Arnold](mailto:tony@thecocoabots.com)
+* Test that the current thread saveWith method actually saves `d41d744` - [Tony Arnold](mailto:tony@thecocoabots.com)
+* Bumped podspec to 2.0.7 `601869e` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
View
@@ -1,14 +1,15 @@
Pod::Spec.new do |s|
s.name = 'MagicalRecord'
- s.version = '2.0'
+ s.version = '2.0.7'
s.license = 'MIT'
- s.summary = 'Super Awesome Easy Fetching for Core Data 1!!!11!!!!1! '
+ s.summary = 'Super Awesome Easy Fetching for Core Data 1!!!11!!!!1!.'
s.homepage = 'http://github.com/magicalpanda/MagicalRecord'
s.author = { 'Saul Mora' => 'saul@magicalpanda.com' }
- s.source = { :git => 'http://github.com/magicalpanda/MagicalRecord.git', :tag => '2.0' }
+ s.source = { :git => 'https://github.com/magicalpanda/MagicalRecord.git', :tag => '2.0.7' }
s.description = 'Handy fetching, threading and data import helpers to make Core Data a little easier to use.'
s.source_files = 'MagicalRecord/**/*.{h,m}'
s.framework = 'CoreData'
+ s.requires_arc = true
def s.post_install(target)
prefix_header = config.project_pods_root + target.prefix_header_filename
@@ -137,7 +137,7 @@ - (void) MR_setRelationships:(NSDictionary *)relationships forKeysWithObject:(id
NSRelationshipDescription *relationshipInfo = [relationships valueForKey:relationshipName];
NSString *lookupKey = [[relationshipInfo userInfo] valueForKey:kMagicalRecordImportRelationshipMapKey] ?: relationshipName;
- id relatedObjectData = [relationshipData valueForKey:lookupKey];
+ id relatedObjectData = [relationshipData valueForKeyPath:lookupKey];
if (relatedObjectData == nil || [relatedObjectData isEqual:[NSNull null]])
{
@@ -1,4 +1,4 @@
-//
+ //
// NSManagedObject+MagicalFinders.m
// Magical Record
//
@@ -198,7 +198,7 @@ + (NSArray *) MR_findByAttribute:(NSString *)attribute withValue:(id)searchValue
NSPredicate *searchTerm = [NSPredicate predicateWithFormat:@"%K = %@", attribute, searchValue];
NSFetchRequest *request = [self MR_requestAllSortedBy:sortTerm ascending:ascending withPredicate:searchTerm inContext:context];
- return [self MR_executeFetchRequest:request];
+ return [self MR_executeFetchRequest:request inContext:context];
}
+ (NSArray *) MR_findByAttribute:(NSString *)attribute withValue:(id)searchValue andOrderBy:(NSString *)sortTerm ascending:(BOOL)ascending
@@ -24,4 +24,7 @@ extern NSString * const kMagicalRecordDidMergeChangesFromiCloudNotification;
- (NSString *) MR_description;
+- (void) MR_setContextWorkingName:(NSString *)workingName;
+- (NSString *) MR_contextWorkingName;
+
@end
@@ -12,6 +12,7 @@
static NSManagedObjectContext *defaultManagedObjectContext_ = nil;
static id iCloudSetupNotificationObserver = nil;
+#define kNSManagedObjectContextWorkingName @"kNSManagedObjectContextWorkingName"
@interface NSManagedObjectContext (MagicalRecordInternal)
@@ -36,9 +37,16 @@ - (NSString *) MR_description;
NSString *contextName = (self == defaultManagedObjectContext_) ? @"*** DEFAULT ***" : @"";
contextName = (self == rootSavingContext) ? @"*** BACKGROUND SAVE ***" : contextName;
- NSString *onMainThread = [NSThread isMainThread] ? @"*** MAIN THREAD ***" : @"";
+ NSString *onMainThread = [NSThread isMainThread] ? @"*** MAIN THREAD ***" : @"*** SECONDARY THREAD ***";
- return [NSString stringWithFormat:@"%@: %@ Context %@", [self description], contextName, onMainThread];
+ NSString *familyTree = [NSString string];
+ NSManagedObjectContext *parentContext = [self parentContext];
+ while (nil != parentContext) {
+ familyTree = [familyTree stringByAppendingFormat:@" ==> %@;",[parentContext MR_contextWorkingName]];
+ parentContext = [parentContext parentContext];
+ }
+
+ return [NSString stringWithFormat:@"%@: %@ Context %@ \nFamilyTree: %@", [self MR_contextWorkingName], contextName, onMainThread,familyTree];
}
+ (NSManagedObjectContext *) MR_defaultContext
@@ -52,6 +60,11 @@ + (NSManagedObjectContext *) MR_defaultContext
+ (void) MR_setDefaultContext:(NSManagedObjectContext *)moc
{
+ if (defaultManagedObjectContext_)
+ {
+ [[NSNotificationCenter defaultCenter] removeObserver:defaultManagedObjectContext_];
+ }
+
NSPersistentStoreCoordinator *coordinator = [NSPersistentStoreCoordinator MR_defaultStoreCoordinator];
if (iCloudSetupNotificationObserver) {
[[NSNotificationCenter defaultCenter] removeObserver:iCloudSetupNotificationObserver];
@@ -88,9 +101,15 @@ + (NSManagedObjectContext *) MR_rootSavingContext;
+ (void) MR_setRootSavingContext:(NSManagedObjectContext *)context;
{
+ if (rootSavingContext)
+ {
+ [[NSNotificationCenter defaultCenter] removeObserver:rootSavingContext];
+ }
+
rootSavingContext = context;
[context MR_obtainPermanentIDsBeforeSaving];
[rootSavingContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
+ [rootSavingContext MR_setContextWorkingName:@"rootSavingsContext"];
}
+ (void) MR_initializeDefaultContextWithCoordinator:(NSPersistentStoreCoordinator *)coordinator;
@@ -102,6 +121,7 @@ + (void) MR_initializeDefaultContextWithCoordinator:(NSPersistentStoreCoordinato
[self MR_setRootSavingContext:rootContext];
NSManagedObjectContext *defaultContext = [self MR_newMainQueueContext];
+ [defaultContext MR_setContextWorkingName:@"defaultContext"];
[defaultContext setParentContext:rootSavingContext];
[self MR_setDefaultContext:defaultContext];
@@ -175,11 +195,27 @@ - (void) MR_contextWillSave:(NSNotification *)notification
if ([insertedObjects count])
{
MRLog(@"Context %@ is about to save. Obtaining permanent IDs for new %lu inserted objects", [context MR_description], (unsigned long)[insertedObjects count]);
-
NSError *error = nil;
- [context obtainPermanentIDsForObjects:[insertedObjects allObjects] error:&error];
- [MagicalRecord handleErrors:error];
+ BOOL success = [context obtainPermanentIDsForObjects:insertedObjects error:&error];
+ if (!success && error) {
+ [MagicalRecord handleErrors:error];
+ }
}
}
+- (void) MR_setContextWorkingName:(NSString *)workingName;
+{
+ [[self userInfo] setObject:workingName forKey:kNSManagedObjectContextWorkingName];
+}
+
+- (NSString *) MR_contextWorkingName;
+{
+ NSString *workingName = [[self userInfo] objectForKey:kNSManagedObjectContextWorkingName];
+ if (nil == workingName) {
+ workingName = @"UndefinedWorkingContext";
+ }
+ return workingName;
+}
+
+
@end
@@ -19,5 +19,6 @@
- (void) MR_saveNestedContexts;
- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *))errorCallback;
+- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *))errorCallback completion:(void (^)(void))completion;
@end
@@ -65,10 +65,25 @@ - (void) MR_saveNestedContexts;
- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *))errorCallback;
{
- [self performBlockAndWait:^{
+ [self MR_saveNestedContextsErrorHandler:nil completion:nil];
+}
+
+- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *))errorCallback completion:(void (^)(void))completion;
+{
+ [self performBlock:^{
[self MR_saveWithErrorCallback:errorCallback];
+ if (self.parentContext) {
+ [[self parentContext] performBlock:^{
+ [[self parentContext] MR_saveNestedContextsErrorHandler:errorCallback completion:completion];
+ }];
+ } else {
+ if (completion) {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ completion();
+ });
+ }
+ }
}];
- [[self parentContext] MR_saveNestedContextsErrorHandler:errorCallback];
}
- (void) MR_save;
@@ -80,13 +95,13 @@ - (void) MR_saveErrorHandler:(void (^)(NSError *))errorCallback;
{
[self performBlockAndWait:^{
[self MR_saveWithErrorCallback:errorCallback];
+
+ if (self.parentContext) {
+ [[self parentContext] performBlockAndWait:^{
+ [[self parentContext] MR_saveErrorHandler:errorCallback];
+ }];
+ }
}];
-
- if (self == [[self class] MR_defaultContext])
- {
- // Since this is a synchronous call, I made the background context save synchronous as well to reflect the intent.
- [[[self class] MR_rootSavingContext] MR_saveErrorHandler:errorCallback];
- }
}
- (void) MR_saveInBackgroundCompletion:(void (^)(void))completion;
@@ -120,5 +135,4 @@ - (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *))errorCallback comp
}
}];
}
-
@end
@@ -17,6 +17,7 @@ dispatch_queue_t action_queue(void)
{
background_action_queue = dispatch_queue_create("com.magicalpanda.magicalrecord.actionQueue", DISPATCH_QUEUE_SERIAL);
}
+
return background_action_queue;
}
@@ -37,7 +38,7 @@ + (void) saveInBackgroundUsingContext:(NSManagedObjectContext *)localContext blo
dispatch_async(action_queue(), ^{
block(localContext);
- [localContext MR_saveInBackgroundErrorHandler:errorHandler completion:completion];
+ [localContext MR_saveNestedContextsErrorHandler:errorHandler completion:completion];
});
}
@@ -65,7 +66,7 @@ + (void) saveWithBlock:(void (^)(NSManagedObjectContext *localContext))block com
if ([localContext hasChanges])
{
- [localContext MR_saveNestedContextsErrorHandler:errorHandler];
+ [localContext MR_saveErrorHandler:errorHandler];
}
if (completion)
@@ -46,7 +46,7 @@
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
- selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.GDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
@@ -63,6 +63,11 @@
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
+ <AdditionalOption
+ key = "NSZombieEnabled"
+ value = "YES"
+ isEnabled = "YES">
+ </AdditionalOption>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
@@ -42,4 +42,44 @@ - (void)testBackgroundSaveCallsCompletionHandler
expect(didSave).will.beTruthy();
}
+- (void)testBackgroundSavesActuallySave
+{
+ __block NSManagedObjectID *objectId;
+ __block NSManagedObject *fetchedObject;
+ dispatch_group_t group = dispatch_group_create();
+ dispatch_group_enter(group);
+ [MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *localContext) {
+ NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:localContext];
+ expect([inserted hasChanges]).to.beTruthy();
+ [localContext obtainPermanentIDsForObjects:@[inserted] error:nil];
+ objectId = inserted.objectID;
+
+ } completion:^{
+ fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectWithID:objectId];
+ dispatch_group_leave(group);
+
+ }];
+
+ dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
+ expect(fetchedObject).toNot.beNil();
+ expect([fetchedObject hasChanges]).to.beFalsy();
+}
+
+- (void)testCurrentThreadSavesActuallySave
+{
+ __block NSManagedObjectID *objectId;
+ __block NSManagedObject *fetchedObject;
+ [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
+ NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:localContext];
+ expect([inserted hasChanges]).to.beTruthy();
+ [localContext obtainPermanentIDsForObjects:@[inserted] error:nil];
+ objectId = inserted.objectID;
+ }];
+
+ fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectWithID:objectId];
+
+ expect(fetchedObject).toNot.beNil();
+ expect([fetchedObject hasChanges]).to.beFalsy();
+}
+
@end

0 comments on commit 3c24ce1

Please sign in to comment.