Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'release/2.1.0'

Conflicts:
	Changelog.md
  • Loading branch information...
commit 94855465febdc7f1a88af6b8fafde323eb348362 2 parents 085e928 + 15891e9
@tonyarnold tonyarnold authored
Showing with 2,024 additions and 336 deletions.
  1. +13 −17 .gitignore
  2. +3 −0  .gitmodules
  3. +45 −2 Changelog.md
  4. +2 −2 MagicalRecord.podspec
  5. +0 −1  MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalObserving.m
  6. +8 −6 MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalRecord.m
  7. +77 −8 MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalSaves.h
  8. +145 −67 MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalSaves.m
  9. +2 −1  MagicalRecord/Categories/NSPersistentStoreCoordinator+MagicalRecord.m
  10. +21 −4 MagicalRecord/Core/MagicalRecord+Actions.h
  11. +96 −31 MagicalRecord/Core/MagicalRecord+Actions.m
  12. +14 −7 MagicalRecord/Core/MagicalRecordShorthand.h
  13. +22 −0 Project Files/Mac Unit Tests/Mac Unit Tests-Info.plist
  14. +11 −0 Project Files/Mac Unit Tests/Mac Unit Tests-Prefix.pch
  15. +284 −0 Project Files/Mac Unit Tests/MagicalRecord+ActionsSpec.m
  16. +528 −0 Project Files/Mac Unit Tests/NSManagedObjectContext+MagicalSavesSpec.m
  17. +478 −69 Project Files/Magical Record.xcodeproj/project.pbxproj
  18. +0 −22 ...Files/Magical Record.xcodeproj/project.xcworkspace/xcuserdata/saul.xcuserdatad/WorkspaceSettings.xcsettings
  19. +1 −1  Project Files/Magical Record.xcodeproj/xcshareddata/xcschemes/Mac App Unit Tests.xcscheme
  20. +69 −0 Project Files/Magical Record.xcodeproj/xcshareddata/xcschemes/Mac Unit Tests.xcscheme
  21. +1 −1  Project Files/Magical Record.xcodeproj/xcshareddata/xcschemes/iOS App Unit Tests.xcscheme
  22. +0 −42 Project Files/Magical Record.xcodeproj/xcuserdata/saul.xcuserdatad/xcschemes/xcschememanagement.plist
  23. +1 −0  Project Files/Third Party/Kiwi
  24. +2 −2 Project Files/Unit Tests/Fixtures/ImportSingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeysTests.m
  25. +1 −1  Project Files/Unit Tests/ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m
  26. +2 −2 Project Files/Unit Tests/ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m
  27. +3 −3 Project Files/Unit Tests/ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m
  28. +1 −1  Project Files/Unit Tests/ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m
  29. +1 −1  Project Files/Unit Tests/ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m
  30. +2 −2 Project Files/Unit Tests/ImportSingleRelatedEntityTests.m
  31. +1 −1  Project Files/Unit Tests/NSManagedObjectContextHelperTests.m
  32. +2 −2 Project Files/Unit Tests/NSManagedObjectHelperTests.m
  33. +0 −13 Project Files/Unit Tests/SaveTests.h
  34. +137 −20 Project Files/Unit Tests/SaveTests.m
  35. +51 −7 README.md
View
30 .gitignore
@@ -1,23 +1,19 @@
+# Finder
.DS_Store
-*.swp
-*~.nib
-
-build/
+# Xcode
+build/*
*.pbxuser
-*.perspective
-*.perspectivev3
-
-.hg
-.hgtags
-
+!default.pbxuser
*.mode1v3
+!default.mode1v3
*.mode2v3
+!default.mode2v3
+*.perspectivev3
+!default.perspectivev3
+*.xcworkspace
+!default.xcworkspace
+xcuserdata
+profile
+*.moved-aside
-UserInterfaceState.xcuserstate
-/Magical Record.xcodeproj/project.xcworkspace/xcuserdata/saul.xcuserdatad/UserInterfaceState.xcuserstate
-/Magical Record.xcodeproj/xcuserdata/saul.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist
-/Magical Record.xcodeproj/xcuserdata/gfurman.xcuserdatad
-Project Files/Magical Record.xcodeproj/xcuserdata
-Project Files/MagicalRecord.xcodeproj/xcuserdata/saul.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist
-Project Files/MagicalRecord.xcodeproj/xcuserdata/saul.xcuserdatad/xcschemes/iOS Test Runner.xcscheme
View
3  .gitmodules
@@ -0,0 +1,3 @@
+[submodule "Project Files/Third Party/Kiwi"]
+ path = Project Files/Third Party/Kiwi
+ url = git://github.com/allending/Kiwi.git
View
47 Changelog.md
@@ -1,8 +1,51 @@
# Changelog
-## Version 2.0.8
-* Fixed issue #287 - MR_findByAttribute:withValue:andOrderBy:ascending:inContext does not pass context through - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+## Version 2.1.0
+* Fixed issue #287 - MR_findByAttribute:withValue:andOrderBy:ascending:inContext does not pass context through `4b97d0e` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Adding changelog `da70884` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Cleanup contextWillSave method Update deleting incompatible store `2eaec27` - [Saul Mora](mailto:saul@magicalpanda.com)
+* don't check the error, rely only on the return value of methods to determine success `64a81c6` - [Saul Mora](mailto:saul@magicalpanda.com)
+* removed MR_saveErrorHandler, as it and MR_saveWithErrorCallback were essentially duplicates MR_save now only saves the current context (it was essentially doing a MR_saveNestedContexts). If you need to save all the way out to disk, use MR_saveNestedContexts. Removed the action queue, unneccesary since core data introduced it's own queue support `f7c4350` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Separate printing context chain method into its own method change contextWorkingName to property workingName `0fb7d36` - [Saul Mora](mailto:saul@magicalpanda.com)
+* Added fetchAllWithDelegate: method for NSFRC `c0a1657` - [Saul Mora](mailto:saul@magicalpanda.com)
+* Fixed Issue #294 - MR_requestAllSortedBy:ascending:inContext: did not use correct context `3656e74` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Bumping podspec version `fb81b5b` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Updating changelog `20f02ba` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Re-Added obtaining permanent ids automatically `cfccd40` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Minor formatting updates `1440623` - [Saul Mora](mailto:saul@magicalpanda.com)
+* Pass errorCallback through convenience method `5376700` - [Tony Arnold](mailto:tony@thecocoabots.com)
+* Implement new save methods `4f35e4e` - [Tony Arnold](mailto:tony@thecocoabots.com)
+* Update existing save tests to reflect save changes. Also begin adding tests for deprecated methods to ensure consistent behaviour in unmodified code. `c763d4a` - [Tony Arnold](mailto:tony@thecocoabots.com)
+* Fix compilation problems under latest Xcode. `af84aff` - [Tony Arnold](mailto:tony@thecocoabots.com)
+* Update gitignore and remove user specific xcuserdata `d0e771d` - [Tony Arnold](mailto:tony@thecocoabots.com)
+* Add Kiwi for saner asynchronous testing and remove existing GHUnit tests for save methods `55af799` - [Tony Arnold](mailto:tony@thecocoabots.com)
+* Flesh out tests for MagicalRecord+Actions and the NSManagedObjectContext+MagicalSaves category `a28d421` - [Tony Arnold](mailto:tony@thecocoabots.com)
+* The deprecated saveWithBlock: method should do it's work on the current thread `2c66056` - [Tony Arnold](mailto:tony@thecocoabots.com)
+* All deprecated and non-deprecated methods have tests to ensure their function `c2fa8c4` - [Tony Arnold](mailto:tony@thecocoabots.com)
+* Update README with details of the changes in this branch `4316422` - [Tony Arnold](mailto:tony@thecocoabots.com)
+* Update shorthand methods and import the magical saves category so that MRSaveCompletionHandler resolves `1af1201` - [Tony Arnold](mailto:tony@thecocoabots.com)
+* Updated podspec to 2.1.beta.1 `5ed45f6` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Minor text editing. `710d643` - [nerdery-isaac](mailto:isaac.greenspan@nerdery.com)
+* Added additional case that will trigger persistant store cleanup `36d1630` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Alter saveWithBlock: so that it runs asynchronously. Fixes #349. `357b62e` - [Tony Arnold](mailto:tony@thecocoabots.com)
+* Execute save completion blocks on the main dispatch queue. `065352d` - [Tony Arnold](mailto:tony@thecocoabots.com)
+* Fix broken GHUnit tests after recent changes to the save methods `0c83121` - [Tony Arnold](mailto:tony@thecocoabots.com)
+* Add Clang-style documentation for the MagicalSaves category. Also add Clang's -Wdocumentation warning to assist in writing in future documentation. `eb8865a` - [Tony Arnold](mailto:tony@thecocoabots.com)
+* Remove unused notification constant `5a40bcc` - [Tony Arnold](mailto:tony@thecocoabots.com)
+* Finalise documentation for MagicalRecord 2.1.0 `f370cdb` - [Tony Arnold](mailto:tony@thecocoabots.com)
+* Update pod spec to MagicalRecord 2.1.0 `46b6004` - [Tony Arnold](mailto:tony@thecocoabots.com)
+## 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)
+* Adding changelog `da70884` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Cleanup contextWillSave method Update deleting incompatible store `2eaec27` - [Saul Mora](mailto:saul@magicalpanda.com)
+* don't check the error, rely only on the return value of methods to determine success `64a81c6` - [Saul Mora](mailto:saul@magicalpanda.com)
+* removed MR_saveErrorHandler, as it and MR_saveWithErrorCallback were essentially duplicates MR_save now only saves the current context (it was essentially do
+* Separate printing context chain method into its own method change contextWorkingName to property workingName `0fb7d36` - [Saul Mora](mailto:saul@magicalpanda
+* Added fetchAllWithDelegate: method for NSFRC `c0a1657` - [Saul Mora](mailto:saul@magicalpanda.com)
+* Fixed Issue #294 - MR_requestAllSortedBy:ascending:inContext: did not use correct context `3656e74` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+* Bumping podspec version `fb81b5b` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
+>>>>>>> release/2.1.0
## Version 2.0.7
* Fix small error in README with regard to MR_SHORTHAND - [Maik Gosenshuis](mailto:maik@gosenshuis.nl)
* Hide intended private cleanUpErrorHandling method - [Saul Mora](mailto:saul@magicalpanda.com)
View
4 MagicalRecord.podspec
@@ -1,11 +1,11 @@
Pod::Spec.new do |s|
s.name = 'MagicalRecord'
- s.version = '2.0.8'
+ s.version = '2.1.0'
s.license = 'MIT'
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 => 'https://github.com/magicalpanda/MagicalRecord.git', :tag => '2.0.8' }
+ s.source = { :git => 'https://github.com/magicalpanda/MagicalRecord.git',:branch=>'develop', :tag => '2.1.0' }
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'
View
1  MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalObserving.m
@@ -11,7 +11,6 @@
#import "MagicalRecord.h"
#import "MagicalRecord+iCloud.h"
-static void const * kMagicalRecordNotifiesMainContextAssociatedValueKey = @"kMagicalRecordNotifiesMainContextOnSave";
NSString * const kMagicalRecordDidMergeChangesFromiCloudNotification = @"kMagicalRecordDidMergeChangesFromiCloudNotification";
View
14 MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalRecord.m
@@ -42,7 +42,7 @@ - (NSString *) MR_description;
- (NSString *) MR_parentChain;
{
- NSMutableString *familyTree = [@"" mutableCopy];
+ NSMutableString *familyTree = [@"\n" mutableCopy];
NSManagedObjectContext *currentContext = self;
do
{
@@ -84,7 +84,7 @@ + (void) MR_setDefaultContext:(NSManagedObjectContext *)moc
defaultManagedObjectContext_ = moc;
[defaultManagedObjectContext_ MR_setWorkingName:@"DEFAULT"];
-// [moc MR_obtainPermanentIDsBeforeSaving];
+ [moc MR_obtainPermanentIDsBeforeSaving];
if ([MagicalRecord isICloudEnabled])
{
[defaultManagedObjectContext_ MR_observeiCloudChangesInCoordinator:coordinator];
@@ -115,7 +115,7 @@ + (void) MR_setRootSavingContext:(NSManagedObjectContext *)context;
}
rootSavingContext = context;
-// [context MR_obtainPermanentIDsBeforeSaving];
+ [context MR_obtainPermanentIDsBeforeSaving];
[rootSavingContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
[rootSavingContext MR_setWorkingName:@"BACKGROUND SAVING (ROOT)"];
MRLog(@"Set Root Saving Context: %@", rootSavingContext);
@@ -131,7 +131,7 @@ + (void) MR_initializeDefaultContextWithCoordinator:(NSPersistentStoreCoordinato
NSManagedObjectContext *defaultContext = [self MR_newMainQueueContext];
[self MR_setDefaultContext:defaultContext];
- [defaultContext setParentContext:rootSavingContext];
+ [defaultContext setParentContext:rootContext];
}
}
@@ -161,7 +161,7 @@ + (NSManagedObjectContext *) MR_contextWithParent:(NSManagedObjectContext *)pare
{
NSManagedObjectContext *context = [self MR_contextWithoutParent];
[context setParentContext:parentContext];
-// [context MR_obtainPermanentIDsBeforeSaving];
+ [context MR_obtainPermanentIDsBeforeSaving];
return context;
}
@@ -182,7 +182,7 @@ + (NSManagedObjectContext *) MR_contextWithStoreCoordinator:(NSPersistentStoreCo
[context setPersistentStoreCoordinator:coordinator];
}];
- MRLog(@"-> Created %@", [context MR_description]);
+ MRLog(@"-> Created Context %@", [context MR_workingName]);
}
return context;
}
@@ -193,6 +193,8 @@ - (void) MR_obtainPermanentIDsBeforeSaving;
selector:@selector(MR_contextWillSave:)
name:NSManagedObjectContextWillSaveNotification
object:self];
+
+
}
- (void) MR_contextWillSave:(NSNotification *)notification
View
85 MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalSaves.h
@@ -8,17 +8,86 @@
#import <CoreData/CoreData.h>
+typedef NS_OPTIONS(NSUInteger, MRSaveContextOptions) {
+ MRSaveParentContexts = 1, ///< When saving, continue saving parent contexts until the changes are present in the persistent store
+ MRSaveSynchronously = 2 ///< Peform saves synchronously, blocking execution on the current thread until the save is complete
+};
+
+typedef void (^MRSaveCompletionHandler)(BOOL success, NSError *error);
+
@interface NSManagedObjectContext (MagicalSaves)
-- (void) MR_save;
-- (void) MR_saveWithErrorCallback:(void(^)(NSError *))errorCallback;
+/// \brief Asynchronously save changes in the current context and it's parent
+/// \param completion Completion block that is called after the save has completed. The block is passed a success state as a `BOOL` and an `NSError` instance if an error occurs. Always called on the main queue.
+/// \discussion Executes a save on the current context's dispatch queue asynchronously. This method only saves the current context, and the parent of the current context if one is set. The completion block will always be called on the main queue.
+- (void) MR_saveOnlySelfWithCompletion:(MRSaveCompletionHandler)completion;
+
+/// \brief Asynchronously save changes in the current context all the way back to the persistent store
+/// \param completion Completion block that is called after the save has completed. The block is passed a success state as a `BOOL` and an `NSError` instance if an error occurs. Always called on the main queue.
+/// \discussion Executes asynchronous saves on the current context, and any ancestors, until the changes have been persisted to the assigned persistent store. The completion block will always be called on the main queue.
+- (void) MR_saveToPersistentStoreWithCompletion:(MRSaveCompletionHandler)completion;
+
+/// \brief Synchronously save changes in the current context and it's parent
+/// \discussion Executes a save on the current context's dispatch queue. This method only saves the current context, and the parent of the current context if one is set. The method will not return until the save is complete.
+- (void) MR_saveOnlySelfAndWait;
+
+/// \brief Synchronously save changes in the current context all the way back to the persistent store
+/// \discussion Executes saves on the current context, and any ancestors, until the changes have been persisted to the assigned persistent store. The method will not return until the save is complete.
+- (void) MR_saveToPersistentStoreAndWait;
+
+/// \brief Save the current context with options
+/// \param mask bitmasked options for the save process
+/// \param completion Completion block that is called after the save has completed. The block is passed a success state as a `BOOL` and an `NSError` instance if an error occurs. Always called on the main queue.
+/// \discussion All other save methods are conveniences to this method.
+ - (void) MR_saveWithOptions:(MRSaveContextOptions)mask completion:(MRSaveCompletionHandler)completion;
+
+
+/* DEPRECATION NOTICE:
+ * The following methods are deprecated, but remain in place for backwards compatibility until the next major version (3.x)
+ */
+
+/// \brief Synchronously save changes in the current context all the way back to the persistent store
+/// \discussion Replaced by \MR_saveToPersistentStoreAndWait
+/// \deprecated
+- (void) MR_save __attribute__((deprecated));
+
+/// \brief Synchronously save changes in the current context all the way back to the persistent store
+/// \param errorCallback Block that is called if an error is encountered while saving. Always called on the main thread.
+/// \deprecated
+- (void) MR_saveWithErrorCallback:(void(^)(NSError *error))errorCallback __attribute__((deprecated));
+
+/// \brief Asynchronously save changes in the current context and it's parent
+/// \param completion Completion block that is called after the save has completed. Always called on the main queue.
+/// \deprecated
+- (void) MR_saveInBackgroundCompletion:(void (^)(void))completion __attribute__((deprecated));
+
+/// \brief Asynchronously save changes in the current context and it's parent
+/// \param errorCallback Block that is called if an error is encountered while saving. Always called on the main thread.
+/// \deprecated
+- (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback __attribute__((deprecated));
+
+/// \brief Asynchronously save changes in the current context and it's parent
+/// \param errorCallback Block that is called if an error is encountered while saving. Always called on the main thread.
+/// \param completion Completion block that is called after the save has completed. Always called on the main queue.
+/// \deprecated
+- (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion __attribute__((deprecated));
+
+/// \brief Asynchronously save changes in the current context all the way back to the persistent store
+/// \discussion Replaced by \MR_saveToPersistentStoreWithCompletion:
+/// \deprecated
+- (void) MR_saveNestedContexts __attribute__((deprecated));
-- (void) MR_saveInBackgroundCompletion:(void (^)(void))completion;
-- (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *))errorCallback;
-- (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *))errorCallback completion:(void (^)(void))completion;
+/// \brief Asynchronously save changes in the current context all the way back to the persistent store
+/// \param errorCallback Block that is called if an error is encountered while saving. Always called on the main thread.
+/// \discussion Replaced by \MR_saveToPersistentStoreWithCompletion:
+/// \deprecated
+- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback __attribute__((deprecated));
-- (void) MR_saveNestedContexts;
-- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *))errorCallback;
-- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *))errorCallback completion:(void (^)(void))completion;
+/// \brief Asynchronously save changes in the current context all the way back to the persistent store
+/// \param errorCallback Block that is called if an error is encountered while saving. Always called on the main thread.
+/// \param completion Completion block that is called after the save has completed. Always called on the main queue.
+/// \discussion Replaced by \MR_saveToPersistentStoreWithCompletion:
+/// \deprecated
+- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion __attribute__((deprecated));
@end
View
212 MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalSaves.m
@@ -11,115 +11,193 @@
#import "NSManagedObjectContext+MagicalRecord.h"
#import "MagicalRecord.h"
-@interface NSManagedObjectContext (InternalMagicalSaves)
+@implementation NSManagedObjectContext (MagicalSaves)
-- (void) MR_saveWithErrorCallback:(void(^)(NSError *))errorCallback;
+- (void)MR_saveOnlySelfWithCompletion:(MRSaveCompletionHandler)completion;
+{
+ [self MR_saveWithOptions:0 completion:completion];
+}
-@end
+- (void)MR_saveOnlySelfAndWait;
+{
+ [self MR_saveWithOptions:MRSaveSynchronously completion:nil];
+}
+- (void) MR_saveToPersistentStoreWithCompletion:(MRSaveCompletionHandler)completion;
+{
+ [self MR_saveWithOptions:MRSaveParentContexts completion:completion];
+}
-@implementation NSManagedObjectContext (MagicalSaves)
+- (void) MR_saveToPersistentStoreAndWait;
+{
+ [self MR_saveWithOptions:MRSaveParentContexts | MRSaveSynchronously completion:nil];
+}
-- (void) MR_saveWithErrorCallback:(void(^)(NSError *))errorCallback;
+- (void)MR_saveWithOptions:(MRSaveContextOptions)mask completion:(MRSaveCompletionHandler)completion;
{
- if (![self hasChanges])
- {
- MRLog(@"NO CHANGES IN CONTEXT %@ - NOT SAVING", [self MR_description]);
+ BOOL syncSave = ((mask & MRSaveSynchronously) == MRSaveSynchronously);
+ BOOL saveParentContexts = ((mask & MRSaveParentContexts) == MRSaveParentContexts);
+
+ if (![self hasChanges]) {
+ MRLog(@"NO CHANGES IN ** %@ ** CONTEXT - NOT SAVING", [self MR_workingName]);
+
+ if (completion)
+ {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ completion(NO, nil);
+ });
+ }
+
return;
}
-
- MRLog(@"-> Saving %@", [self MR_description]);
-
- __block NSError *error = nil;
- __block BOOL saved = NO;
- @try
- {
- [self performBlockAndWait:^{
+
+ MRLog(@"→ Saving %@", [self MR_description]);
+ MRLog(@"→ Save Parents? %@", @(saveParentContexts));
+ MRLog(@"→ Save Synchronously? %@", @(syncSave));
+
+ id saveBlock = ^{
+ NSError *error = nil;
+ BOOL saved = NO;
+
+ @try
+ {
saved = [self save:&error];
- }];
- }
- @catch (NSException *exception)
- {
- MRLog(@"Unable to perform save: %@", (id)[exception userInfo] ?: (id)[exception reason]);
- }
- @finally
- {
- if (!saved)
+ }
+ @catch(NSException *exception)
{
- if (errorCallback)
- {
- errorCallback(error);
- }
- else
- {
+ MRLog(@"Unable to perform save: %@", (id)[exception userInfo] ? : (id)[exception reason]);
+ }
+
+ @finally
+ {
+ if (!saved) {
[MagicalRecord handleErrors:error];
+
+ if (completion) {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ completion(saved, error);
+ });
+ }
+ } else {
+ // If we're the default context, save to disk too (the user expects it to persist)
+ if (self == [[self class] MR_defaultContext]) {
+ [[[self class] MR_rootSavingContext] MR_saveWithOptions:MRSaveSynchronously completion:completion];
+ }
+ // If we're saving parent contexts, do so
+ else if ((YES == saveParentContexts) && [self parentContext]) {
+ [[self parentContext] MR_saveWithOptions:MRSaveSynchronously | MRSaveParentContexts completion:completion];
+ }
+ // If we are not the default context (And therefore need to save the root context, do the completion action if one was specified
+ else {
+ MRLog(@"→ Finished saving: %@", [self MR_description]);
+
+ if (completion) {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ completion(saved, error);
+ });
+ }
+ }
}
}
+ };
+
+ if (YES == syncSave) {
+ [self performBlockAndWait:saveBlock];
+ } else {
+ [self performBlock:saveBlock];
}
}
-- (void) MR_saveNestedContexts;
+#pragma mark - Deprecated methods
+// These methods will be removed in MagicalRecord 3.0
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-implementations"
+
+- (void)MR_save;
{
- [self MR_saveNestedContextsErrorHandler:nil];
+ [self MR_saveToPersistentStoreAndWait];
}
-- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *))errorCallback;
+- (void)MR_saveWithErrorCallback:(void (^)(NSError *error))errorCallback;
{
- [self MR_saveNestedContextsErrorHandler:nil completion:nil];
+ [self MR_saveWithOptions:MRSaveSynchronously|MRSaveParentContexts completion:^(BOOL success, NSError *error) {
+ if (!success) {
+ if (errorCallback) {
+ errorCallback(error);
+ }
+ }
+ }];
}
-- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *))errorCallback completion:(void (^)(void))completion;
+- (void)MR_saveInBackgroundCompletion:(void (^)(void))completion;
{
- [self performBlock:^{
- [self MR_saveWithErrorCallback:errorCallback];
- if (self.parentContext) {
- [[self parentContext] performBlock:^{
- [[self parentContext] MR_saveNestedContextsErrorHandler:errorCallback completion:completion];
- }];
- } else {
+ [self MR_saveOnlySelfWithCompletion:^(BOOL success, NSError *error) {
+ if (success) {
if (completion) {
- dispatch_async(dispatch_get_main_queue(), ^{
- completion();
- });
+ completion();
}
}
}];
}
-- (void) MR_save;
+- (void)MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback;
{
- [self MR_saveWithErrorCallback:nil];
+ [self MR_saveOnlySelfWithCompletion:^(BOOL success, NSError *error) {
+ if (!success) {
+ if (errorCallback) {
+ errorCallback(error);
+ }
+ }
+ }];
}
-- (void) MR_saveInBackgroundCompletion:(void (^)(void))completion;
+- (void)MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion;
{
- [self MR_saveInBackgroundErrorHandler:nil completion:completion];
+ [self MR_saveOnlySelfWithCompletion:^(BOOL success, NSError *error) {
+ if (success) {
+ if (completion) {
+ completion();
+ }
+ } else {
+ if (errorCallback) {
+ errorCallback(error);
+ }
+ }
+ }];
}
-- (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *))errorCallback;
+- (void)MR_saveNestedContexts;
{
- [self MR_saveInBackgroundErrorHandler:errorCallback completion:nil];
+ [self MR_saveToPersistentStoreWithCompletion:nil];
}
-- (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *))errorCallback completion:(void (^)(void))completion;
+- (void)MR_saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback;
{
- [self performBlock:^{
- // Save the context
- [self MR_saveWithErrorCallback:errorCallback];
-
- // If we're the default context, save to disk too (the user expects it to persist)
- if (self == [[self class] MR_defaultContext])
- {
- [[[self class] MR_rootSavingContext] MR_saveInBackgroundErrorHandler:errorCallback completion:completion];
+ [self MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
+ if (!success) {
+ if (errorCallback) {
+ errorCallback(error);
+ }
}
- else
- {
- // If we are not the default context (And therefore need to save the root context, do the completion action if one was specified
- if (completion)
- {
- dispatch_async(dispatch_get_main_queue(), completion);
+ }];
+}
+
+- (void)MR_saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion;
+{
+ [self MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
+ if (success) {
+ if (completion) {
+ completion();
+ }
+ } else {
+ if (errorCallback) {
+ errorCallback(error);
}
}
}];
}
+
+#pragma clang diagnostic pop // ignored "-Wdeprecated-implementations"
+
@end
View
3  MagicalRecord/Categories/NSPersistentStoreCoordinator+MagicalRecord.m
@@ -77,7 +77,8 @@ - (NSPersistentStore *) MR_addSqliteStoreNamed:(id)storeFileName withOptions:(__
if (!store && [MagicalRecord shouldDeleteStoreOnModelMismatch])
{
- if ([[error domain] isEqualToString:NSCocoaErrorDomain] && [error code] == NSPersistentStoreIncompatibleVersionHashError)
+ BOOL isMigrationError = [error code] == NSPersistentStoreIncompatibleVersionHashError || [error code] == NSMigrationMissingSourceModelError;
+ if ([[error domain] isEqualToString:NSCocoaErrorDomain] && isMigrationError)
{
// Could not open the database, so... kill it!
[[NSFileManager defaultManager] removeItemAtURL:url error:nil];
View
25 MagicalRecord/Core/MagicalRecord+Actions.h
@@ -7,21 +7,38 @@
#import <Foundation/Foundation.h>
#import "NSManagedObjectContext+MagicalRecord.h"
+#import "NSManagedObjectContext+MagicalSaves.h"
@interface MagicalRecord (Actions)
-/* For saving on the current thread as the caller, only with a seperate context. Useful when you're managing your own threads/queues and need a serial call to create or change data
+/* For all background saving operations. These calls will be sent to a different thread/queue.
*/
+ (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block;
++ (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block completion:(MRSaveCompletionHandler)completion;
+
+/* For saving on the current thread as the caller, only with a seperate context. Useful when you're managing your own threads/queues and need a serial call to create or change data
+ */
++ (void) saveWithBlockAndWait:(void(^)(NSManagedObjectContext *localContext))block;
+
+/*
+ If you want to reuse the context on the current thread, use these methods.
+ */
++ (void) saveUsingCurrentThreadContextWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(MRSaveCompletionHandler)completion;
++ (void) saveUsingCurrentThreadContextWithBlockAndWait:(void (^)(NSManagedObjectContext *localContext))block;
+
+
+/* DEPRECATION NOTICE:
+ * The following methods are deprecated, but remain in place for backwards compatibility until the next major version (3.x)
+ */
/* For all background saving operations. These calls will be sent to a different thread/queue.
*/
-+ (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block;
-+ (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block completion:(void(^)(void))callback;
++ (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block __attribute__((deprecated));
++ (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block completion:(void(^)(void))completion __attribute__((deprecated));
/*
If you want to reuse the context on the current thread, use this method.
*/
-+ (void) saveInBackgroundUsingCurrentContextWithBlock:(void (^)(NSManagedObjectContext *))block completion:(void (^)(void))completion errorHandler:(void (^)(NSError *))errorHandler;
++ (void) saveInBackgroundUsingCurrentContextWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(void (^)(void))completion errorHandler:(void (^)(NSError *error))errorHandler __attribute__((deprecated));
@end
View
127 MagicalRecord/Core/MagicalRecord+Actions.m
@@ -8,63 +8,128 @@
#import "CoreData+MagicalRecord.h"
#import "NSManagedObjectContext+MagicalRecord.h"
+
@implementation MagicalRecord (Actions)
-+ (void) saveInBackgroundUsingContext:(NSManagedObjectContext *)localContext block:(void (^)(NSManagedObjectContext *))block completion:(void(^)(void))completion errorHandler:(void(^)(NSError *))errorHandler;
+#pragma mark - Asynchronous saving
+
++ (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block;
{
- [localContext performBlock: ^{
- block(localContext);
-
- [localContext MR_saveNestedContextsErrorHandler:errorHandler completion:completion];
- }];
+ [self saveWithBlock:block completion:nil];
}
-+ (void) saveInBackgroundWithBlock:(void (^)(NSManagedObjectContext *))block completion:(void (^)(void))completion errorHandler:(void (^)(NSError *))errorHandler;
++ (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block completion:(MRSaveCompletionHandler)completion;
{
NSManagedObjectContext *mainContext = [NSManagedObjectContext MR_defaultContext];
NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextWithParent:mainContext];
-
- [self saveInBackgroundUsingContext:localContext block:block completion:completion errorHandler:errorHandler];
+
+ [localContext performBlock:^{
+ if (block) {
+ block(localContext);
+ }
+
+ [localContext MR_saveWithOptions:MRSaveParentContexts|MRSaveSynchronously completion:completion];
+ }];
}
-+ (void) saveInBackgroundUsingCurrentContextWithBlock:(void (^)(NSManagedObjectContext *))block completion:(void (^)(void))completion errorHandler:(void (^)(NSError *))errorHandler;
++ (void) saveUsingCurrentThreadContextWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(MRSaveCompletionHandler)completion;
{
NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];
-
- [self saveInBackgroundUsingContext:localContext block:block completion:completion errorHandler:errorHandler];
+
+ [localContext performBlock:^{
+ if (block) {
+ block(localContext);
+ }
+
+ [localContext MR_saveWithOptions:MRSaveParentContexts|MRSaveSynchronously completion:completion];
+ }];
}
-
-+ (void) saveWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(void (^)(void))completion errorHandler:(void (^)(NSError *))errorHandler;
+
+
+#pragma mark - Synchronous saving
+
++ (void) saveWithBlockAndWait:(void(^)(NSManagedObjectContext *localContext))block;
{
NSManagedObjectContext *mainContext = [NSManagedObjectContext MR_defaultContext];
NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextWithParent:mainContext];
- block(localContext);
-
- if ([localContext hasChanges])
- {
- [localContext MR_saveWithErrorCallback:errorHandler];
- }
-
- if (completion)
- {
- dispatch_async(dispatch_get_main_queue(), completion);
- }
+ [localContext performBlockAndWait:^{
+ if (block) {
+ block(localContext);
+ }
+
+ [localContext MR_saveWithOptions:MRSaveParentContexts|MRSaveSynchronously completion:nil];
+ }];
}
-+ (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block
-{
- [self saveWithBlock:block completion:nil errorHandler:nil];
++ (void) saveUsingCurrentThreadContextWithBlockAndWait:(void (^)(NSManagedObjectContext *localContext))block;
+{
+ NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];
+
+ [localContext performBlockAndWait:^{
+ if (block) {
+ block(localContext);
+ }
+
+ [localContext MR_saveWithOptions:MRSaveParentContexts|MRSaveSynchronously completion:nil];
+ }];
}
+
+#pragma mark - Deprecated methods
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-implementations"
+
+ (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block
{
- [self saveInBackgroundWithBlock:block completion:nil errorHandler:nil];
+ [[self class] saveWithBlock:block completion:nil];
+}
+
++ (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block completion:(void(^)(void))completion
+{
+ NSManagedObjectContext *mainContext = [NSManagedObjectContext MR_defaultContext];
+ NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextWithParent:mainContext];
+
+ [localContext performBlock:^{
+ if (block)
+ {
+ block(localContext);
+ }
+
+ [localContext MR_saveToPersistentStoreAndWait];
+
+ if (completion)
+ {
+ completion();
+ }
+ }];
}
-+ (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block completion:(void(^)(void))callback
++ (void) saveInBackgroundUsingCurrentContextWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(void (^)(void))completion errorHandler:(void (^)(NSError *error))errorHandler;
{
- [self saveInBackgroundWithBlock:block completion:callback errorHandler:nil];
+ NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];
+
+ [localContext performBlock:^{
+ if (block) {
+ block(localContext);
+ }
+
+ [localContext MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
+ if (success) {
+ if (completion) {
+ completion();
+ }
+ }
+ else {
+ if (errorHandler) {
+ errorHandler(error);
+ }
+ }
+ }];
+ }];
}
+#pragma clang diagnostic pop // ignored "-Wdeprecated-implementations"
+
@end
View
21 MagicalRecord/Core/MagicalRecordShorthand.h
@@ -131,14 +131,21 @@
+ (void) cleanUp;
- (NSString *) description;
@end
+#import "NSManagedObjectContext+MagicalSaves.h"
@interface NSManagedObjectContext (MagicalSavesShortHand)
-- (void) save;
-- (void) saveErrorHandler:(void (^)(NSError *))errorCallback;
-- (void) saveInBackgroundCompletion:(void (^)(void))completion;
-- (void) saveInBackgroundErrorHandler:(void (^)(NSError *))errorCallback;
-- (void) saveInBackgroundErrorHandler:(void (^)(NSError *))errorCallback completion:(void (^)(void))completion;
-- (void) saveNestedContexts;
-- (void) saveNestedContextsErrorHandler:(void (^)(NSError *))errorCallback;
+- (void) saveOnlySelfWithCompletion:(MRSaveCompletionHandler)completion;
+- (void) saveToPersistentStoreWithCompletion:(MRSaveCompletionHandler)completion;
+- (void) saveOnlySelfAndWait;
+- (void) saveToPersistentStoreAndWait;
+- (void) saveWithOptions:(MRSaveContextOptions)mask completion:(MRSaveCompletionHandler)completion;
+- (void) save __attribute__((deprecated));
+- (void) saveWithErrorCallback:(void(^)(NSError *error))errorCallback __attribute__((deprecated));
+- (void) saveInBackgroundCompletion:(void (^)(void))completion __attribute__((deprecated));
+- (void) saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback __attribute__((deprecated));
+- (void) saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion __attribute__((deprecated));
+- (void) saveNestedContexts __attribute__((deprecated));
+- (void) saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback __attribute__((deprecated));
+- (void) saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion __attribute__((deprecated));
@end
@interface NSManagedObjectContext (MagicalThreadingShortHand)
+ (NSManagedObjectContext *) contextForCurrentThread;
View
22 Project Files/Mac Unit Tests/Mac Unit Tests-Info.plist
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.magicalpanda.${PRODUCT_NAME:rfc1034identifier}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+</dict>
+</plist>
View
11 Project Files/Mac Unit Tests/Mac Unit Tests-Prefix.pch
@@ -0,0 +1,11 @@
+//
+// Prefix header for all source files of the 'Mac Unit Tests' target in the 'Mac Unit Tests' project
+//
+
+#ifdef __OBJC__
+ #import <Cocoa/Cocoa.h>
+ #import <CoreData/CoreData.h>
+
+ #define MR_SHORTHAND
+ #import "CoreData+MagicalRecord.h"
+#endif
View
284 Project Files/Mac Unit Tests/MagicalRecord+ActionsSpec.m
@@ -0,0 +1,284 @@
+#import "Kiwi.h"
+
+// Project
+#import "SingleEntityWithNoRelationships.h"
+
+SPEC_BEGIN(MagicalRecordActionsSpec)
+
+describe(@"MagicalRecord", ^{
+ beforeEach(^{
+ // Occurs before each enclosed "it" block
+ [MagicalRecord setDefaultModelFromClass:[self class]];
+ [MagicalRecord setupCoreDataStackWithInMemoryStore];
+ });
+
+ afterEach(^{
+ // Occurs after each enclosed "it" block
+ [MagicalRecord cleanUp];
+ });
+
+ context(@"synchronous save action", ^{
+ it(@"should save", ^{
+ __block NSManagedObjectID *objectId;
+
+ [MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) {
+ NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:localContext];
+
+ [[@([inserted hasChanges]) should] beTrue];
+
+ [localContext obtainPermanentIDsForObjects:@[inserted] error:nil];
+ objectId = [inserted objectID];
+ }];
+
+ [[objectId should] beNonNil];
+
+ NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
+
+ [[fetchedObject should] beNonNil];
+ [[@([fetchedObject hasChanges]) should] beFalse];
+ });
+ });
+
+ context(@"asynchronous save action", ^{
+ it(@"should call completion block on the main thread", ^{
+ __block BOOL completionBlockCalled = NO;
+ __block BOOL completionBlockIsOnMainThread = NO;
+
+ [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
+ [SingleEntityWithNoRelationships MR_createInContext:localContext];
+ } completion:^(BOOL success, NSError *error) {
+ // Ignore the success state — we only care that this block is executed on the main thread
+ completionBlockCalled = YES;
+ completionBlockIsOnMainThread = [NSThread isMainThread];
+ }];
+
+ [[expectFutureValue(@(completionBlockCalled)) shouldEventually] beTrue];
+ });
+
+ it(@"should save", ^{
+ __block BOOL saveSuccessState = NO;
+ __block NSManagedObjectID *objectId;
+ __block NSManagedObject *fetchedObject;
+
+ [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
+ NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:localContext];
+
+ [[@([inserted hasChanges]) should] beTrue];
+
+ [localContext obtainPermanentIDsForObjects:@[inserted] error:nil];
+ objectId = [inserted objectID];
+ } completion:^(BOOL success, NSError *error) {
+ saveSuccessState = success;
+ fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
+ }];
+
+ [[expectFutureValue(@(saveSuccessState)) shouldEventually] beTrue];
+ [[expectFutureValue(fetchedObject) shouldEventually] beNonNil];
+ [[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beFalse];
+ });
+ });
+
+ context(@"current thread save action", ^{
+ context(@"running synchronously", ^{
+ it(@"should save", ^{
+ __block NSManagedObjectID *objectId;
+
+ [MagicalRecord saveUsingCurrentThreadContextWithBlockAndWait:^(NSManagedObjectContext *localContext) {
+ NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:localContext];
+
+ [[@([inserted hasChanges]) should] beTrue];
+
+ [localContext obtainPermanentIDsForObjects:@[inserted] error:nil];
+ objectId = [inserted objectID];
+ }];
+
+ [[objectId should] beNonNil];
+
+ NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
+
+ [[fetchedObject should] beNonNil];
+ [[@([fetchedObject hasChanges]) should] beFalse];
+ });
+ });
+
+ context(@"running asynchronously", ^{
+ it(@"should call completion block on the main thread", ^{
+ __block BOOL completionBlockCalled = NO;
+ __block BOOL completionBlockIsOnMainThread = NO;
+
+ [MagicalRecord saveUsingCurrentThreadContextWithBlock:^(NSManagedObjectContext *localContext) {
+ [SingleEntityWithNoRelationships MR_createInContext:localContext];
+ } completion:^(BOOL success, NSError *error) {
+ // Ignore the success state — we only care that this block is executed on the main thread
+ completionBlockCalled = YES;
+ completionBlockIsOnMainThread = [NSThread isMainThread];
+ }];
+
+ [[expectFutureValue(@(completionBlockCalled)) shouldEventually] beTrue];
+ });
+
+ it(@"should save", ^{
+ __block BOOL saveSuccessState = NO;
+ __block NSError *saveError;
+ __block NSManagedObjectID *objectId;
+
+ [MagicalRecord saveUsingCurrentThreadContextWithBlock:^(NSManagedObjectContext *localContext) {
+ NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:localContext];
+
+ [[@([inserted hasChanges]) should] beTrue];
+
+ [localContext obtainPermanentIDsForObjects:@[inserted] error:nil];
+ objectId = [inserted objectID];
+ } completion:^(BOOL success, NSError *error) {
+ saveSuccessState = success;
+ saveError = error;
+ }];
+
+ [[expectFutureValue(@(saveSuccessState)) shouldEventually] beTrue];
+ [[expectFutureValue(saveError) shouldEventually] beNil];
+ [[expectFutureValue(objectId) shouldEventually] beNonNil];
+
+ NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
+
+ [[expectFutureValue(fetchedObject) shouldEventually] beNonNil];
+ [[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beFalse];
+ });
+ });
+ });
+
+
+ // We're testing for deprecated method function — ignore the warnings
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+ context(@"deprecated method", ^{
+ context(@"saveInBackgroundWithBlock:", ^{
+ it(@"should save", ^{
+ __block NSManagedObjectID *objectId;
+
+ [MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *localContext) {
+ NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:localContext];
+
+ [[@([inserted hasChanges]) should] beTrue];
+
+ [localContext obtainPermanentIDsForObjects:@[inserted] error:nil];
+ objectId = [inserted objectID];
+ }];
+
+ [[expectFutureValue(objectId) shouldEventually] beNonNil];
+
+ NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
+
+ [[expectFutureValue(objectId) shouldEventually] beNonNil];
+ [[expectFutureValue(fetchedObject) shouldEventually] beNonNil];
+ [[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beFalse];
+ });
+ });
+
+ context(@"saveInBackgroundWithBlock:completion:", ^{
+ it(@"should call completion block", ^{
+ __block BOOL completionBlockCalled = NO;
+
+ [MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *localContext) {
+ [SingleEntityWithNoRelationships MR_createInContext:localContext];
+ } completion:^{
+ completionBlockCalled = YES;
+ }];
+
+ [[expectFutureValue(@(completionBlockCalled)) shouldEventually] beTrue];
+ });
+
+ it(@"should save", ^{
+ __block NSManagedObjectID *objectId;
+ __block NSManagedObject *fetchedObject;
+
+ [MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *localContext) {
+ NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:localContext];
+
+ [[@([inserted hasChanges])should] beTrue];
+
+ [localContext obtainPermanentIDsForObjects:@[inserted] error:nil];
+ objectId = [inserted objectID];
+ } completion:^{
+ [[objectId should] beNonNil];
+
+ fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
+ }];
+
+ [[expectFutureValue(objectId) shouldEventually] beNonNil];
+ [[expectFutureValue(fetchedObject) shouldEventually] beNonNil];
+ [[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beFalse];
+ });
+ });
+
+ context(@"saveInBackgroundUsingCurrentContextWithBlock:completion:errorHandler:", ^{
+
+ context(@"should call", ^{
+ __block BOOL completionBlockCalled = NO;
+ __block BOOL errorBlockCalled = NO;
+
+ afterEach(^{
+ completionBlockCalled = NO;
+ errorBlockCalled = NO;
+ });
+
+ it(@"completion block", ^{
+ [MagicalRecord saveInBackgroundUsingCurrentContextWithBlock:^(NSManagedObjectContext *localContext) {
+ [SingleEntityWithNoRelationships MR_createInContext:localContext];
+ } completion:^{
+ completionBlockCalled = YES;
+ } errorHandler:^(NSError *error) {
+ errorBlockCalled = YES;
+ }];
+
+ [[expectFutureValue(@(completionBlockCalled)) shouldEventually] beTrue];
+ [[expectFutureValue(@(errorBlockCalled)) shouldEventually] beFalse];
+ });
+
+ it(@"error handler when there is an error", ^{
+ [MagicalRecord saveInBackgroundUsingCurrentContextWithBlock:^(NSManagedObjectContext *localContext) {
+ // Don't make any changes so that an error is triggered
+ } completion:^{
+ completionBlockCalled = YES;
+ } errorHandler:^(NSError *error) {
+ errorBlockCalled = YES;
+ }];
+
+ [[expectFutureValue(@(completionBlockCalled)) shouldEventually] beFalse];
+ [[expectFutureValue(@(errorBlockCalled)) shouldEventually] beTrue];
+ });
+ });
+
+ it(@"should save", ^{
+ __block NSError *saveError;
+ __block NSManagedObjectID *objectId;
+ __block NSManagedObject *fetchedObject;
+
+ [MagicalRecord saveInBackgroundUsingCurrentContextWithBlock:^(NSManagedObjectContext *localContext) {
+ NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:localContext];
+
+ [[@([inserted hasChanges])should] beTrue];
+
+ [localContext obtainPermanentIDsForObjects:@[inserted] error:nil];
+ objectId = [inserted objectID];
+ } completion:^{
+ [[objectId should] beNonNil];
+
+ fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
+ } errorHandler:^(NSError *error) {
+ saveError = error;
+ }];
+
+ [[expectFutureValue(objectId) shouldEventually] beNonNil];
+ [[expectFutureValue(saveError) shouldEventually] beNil];
+ [[expectFutureValue(fetchedObject) shouldEventually] beNonNil];
+ [[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beFalse];
+ });
+ });
+ });
+
+#pragma clang diagnostic pop // ignored "-Wdeprecated-declarations"
+
+});
+
+SPEC_END
View
528 Project Files/Mac Unit Tests/NSManagedObjectContext+MagicalSavesSpec.m
@@ -0,0 +1,528 @@
+#import "Kiwi.h"
+
+// Project
+#import "SingleEntityWithNoRelationships.h"
+
+SPEC_BEGIN(NSManagedObjectContextMagicalSavesSpec)
+
+describe(@"NSManagedObjectContext+MagicalSaves", ^{
+ beforeEach (^{
+ // Occurs before each enclosed "it" block
+ [MagicalRecord setDefaultModelFromClass:[self class]];
+ [MagicalRecord setupCoreDataStackWithInMemoryStore];
+ });
+
+ afterEach (^{
+ // Occurs after each enclosed "it" block
+ [MagicalRecord cleanUp];
+ });
+
+ context(@"be able to save to self only", ^{
+ __block NSManagedObjectContext *managedObjectContext;
+
+ beforeEach (^{
+ managedObjectContext = [NSManagedObjectContext MR_context];
+ });
+
+ afterEach (^{
+ [managedObjectContext reset];
+ managedObjectContext = nil;
+ });
+
+ context(@"synchronously", ^{
+ it(@"should save", ^{
+ NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
+
+ [[@([inserted hasChanges]) should] beTrue];
+
+ [managedObjectContext obtainPermanentIDsForObjects:@[inserted] error:nil];
+ NSManagedObjectID *objectId = [inserted objectID];
+
+ [managedObjectContext MR_saveOnlySelfAndWait];
+
+ NSManagedObject *rootFetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
+
+ [rootFetchedObject shouldBeNil];
+ [[@([rootFetchedObject hasChanges]) should] beFalse];
+
+ rootFetchedObject = [managedObjectContext objectRegisteredForID:objectId];
+
+ [rootFetchedObject shouldNotBeNil];
+ [[@([rootFetchedObject hasChanges]) should] beFalse];
+ });
+ });
+
+ context(@"asynchronously", ^{
+ it(@"and should call the completion block on the main thread", ^{
+ __block BOOL completionBlockCalled = NO;
+ __block BOOL completionBlockIsOnMainThread = NO;
+
+ [SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
+
+ [managedObjectContext MR_saveOnlySelfWithCompletion:^(BOOL success, NSError *error) {
+ completionBlockCalled = YES;
+ completionBlockIsOnMainThread = [NSThread isMainThread];
+ }];
+
+ [[expectFutureValue(@(completionBlockCalled)) shouldEventually] beTrue];
+ });
+
+ it(@"should save", ^{
+ __block NSManagedObjectID *objectId;
+ NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
+
+ [[@([inserted hasChanges]) should] beTrue];
+
+ [managedObjectContext MR_saveOnlySelfWithCompletion:^(BOOL success, NSError *error) {
+ [managedObjectContext obtainPermanentIDsForObjects:@[inserted] error:nil];
+ objectId = [inserted objectID];
+ }];
+
+ [[expectFutureValue(objectId) shouldEventually] beNonNil];
+
+ NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
+
+ [[expectFutureValue(fetchedObject) shouldEventually] beNil];
+ [[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beFalse];
+
+ fetchedObject = [managedObjectContext objectRegisteredForID:objectId];
+
+ [[expectFutureValue(fetchedObject) shouldEventually] beNonNil];
+ [[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beFalse];
+ });
+ });
+ });
+
+ context(@"be able to save to the persistent store", ^{
+ __block NSManagedObjectContext *managedObjectContext;
+
+ beforeEach (^{
+ managedObjectContext = [NSManagedObjectContext MR_context];
+ });
+
+ afterEach (^{
+ [managedObjectContext reset];
+ managedObjectContext = nil;
+ });
+
+ context(@"synchronously", ^{
+ it(@"and should save", ^{
+ NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
+
+ [[@([managedObjectContext hasChanges]) should] beTrue];
+ [[@([inserted hasChanges]) should] beTrue];
+
+ [managedObjectContext obtainPermanentIDsForObjects:@[inserted] error:nil];
+ NSManagedObjectID *objectId = [inserted objectID];
+
+ [managedObjectContext MR_saveToPersistentStoreAndWait];
+
+ NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
+
+ [fetchedObject shouldNotBeNil];
+ [[@([fetchedObject hasChanges]) should] beFalse];
+ });
+ });
+
+ context(@"asynchronously", ^{
+ it(@"and should call the completion block on the main thread", ^{
+ __block BOOL completionBlockCalled = NO;
+ __block BOOL completionBlockIsOnMainThread = NO;
+
+ [SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
+
+ [[@([managedObjectContext hasChanges]) should] beTrue];
+
+ [managedObjectContext MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
+ completionBlockCalled = YES;
+ completionBlockIsOnMainThread = [NSThread isMainThread];
+ }];
+
+ [[expectFutureValue(@(completionBlockCalled)) shouldEventually] beTrue];
+ });
+
+ it(@"and should save", ^{
+ __block NSManagedObjectID *objectId;
+
+ NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
+
+ [[@([managedObjectContext hasChanges]) should] beTrue];
+ [[@([inserted hasChanges]) should] beTrue];
+
+ [managedObjectContext MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
+ [managedObjectContext obtainPermanentIDsForObjects:@[inserted] error:nil];
+ objectId = [inserted objectID];
+ }];
+
+ [[expectFutureValue(objectId) shouldEventually] beNonNil];
+
+ NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
+
+ [[expectFutureValue(fetchedObject) shouldEventually] beNonNil];
+ [[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beFalse];
+ });
+ });
+ });
+
+ context(@"be able to save with options", ^{
+ __block NSManagedObjectContext *managedObjectContext;
+ __block NSManagedObjectID *permanentObjectID;
+ __block NSManagedObject *insertedObject;
+
+ beforeEach (^{
+ managedObjectContext = [NSManagedObjectContext MR_context];
+ insertedObject = [SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
+ [managedObjectContext obtainPermanentIDsForObjects:@[insertedObject] error:nil];
+ });
+
+ afterEach (^{
+ [managedObjectContext reset];
+
+ permanentObjectID = nil;
+ insertedObject = nil;
+ managedObjectContext = nil;
+ });
+
+ context(@"synchronously", ^{
+ beforeEach(^{
+ permanentObjectID = [insertedObject objectID];
+ [permanentObjectID shouldNotBeNil];
+ });
+
+ specify (^{
+ [[@([managedObjectContext hasChanges]) should] beTrue];
+ [[@([insertedObject hasChanges]) should] beTrue];
+ });
+
+ it(@"to self only", ^{
+ [managedObjectContext MR_saveWithOptions:MRSaveSynchronously completion:^(BOOL success, NSError *error) {
+ [[@(success) should] beTrue];
+ [error shouldBeNil];
+ }];
+
+ NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:permanentObjectID];
+ [fetchedObject shouldBeNil];
+ [[@([fetchedObject hasChanges]) should] beFalse];
+ });
+
+ it(@"to persistent store", ^{
+ [managedObjectContext MR_saveWithOptions:MRSaveSynchronously | MRSaveParentContexts completion:^(BOOL success, NSError *error) {
+ [[@(success) should] beTrue];
+ [error shouldBeNil];
+ }];
+
+ NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:permanentObjectID];
+ [fetchedObject shouldNotBeNil];
+ [[@([fetchedObject hasChanges]) should] beFalse];
+ });
+ });
+
+ context(@"asynchronously", ^{
+ it(@"to self only", ^{
+ [managedObjectContext MR_saveWithOptions:0 completion:^(BOOL success, NSError *error) {
+ [[@(success) should] beTrue];
+ [error shouldBeNil];
+
+ [managedObjectContext obtainPermanentIDsForObjects:@[insertedObject] error:nil];
+ permanentObjectID = [insertedObject objectID];
+ }];
+
+ [[expectFutureValue(permanentObjectID) shouldEventually] beNonNil];
+
+ NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:permanentObjectID];
+ [[expectFutureValue(fetchedObject) shouldEventually] beNil];
+ [[@([fetchedObject hasChanges]) should] beFalse];
+ });
+
+ it(@"to persistent store", ^{
+ [managedObjectContext MR_saveWithOptions:MRSaveParentContexts completion:^(BOOL success, NSError *error) {
+ [[@(success) should] beTrue];
+ [error shouldBeNil];
+
+ [managedObjectContext obtainPermanentIDsForObjects:@[insertedObject] error:nil];
+ permanentObjectID = [insertedObject objectID];
+ }];
+
+ [[expectFutureValue(permanentObjectID) shouldEventually] beNonNil];
+
+ NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:permanentObjectID];
+ [[expectFutureValue(fetchedObject) shouldEventually] beNonNil];
+ [[@([fetchedObject hasChanges]) should] beFalse];
+ });
+ });
+ });
+
+ // We're testing for deprecated method function — ignore the warnings
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+ context(@"deprecated method", ^{
+ __block NSManagedObjectContext *managedObjectContext;
+
+ beforeEach (^{
+ managedObjectContext = [NSManagedObjectContext MR_contextWithParent:[NSManagedObjectContext MR_defaultContext]];
+ });
+
+ afterEach (^{
+ [managedObjectContext reset];
+ managedObjectContext = nil;
+ });
+
+ context(@"MR_save", ^{
+ it(@"should save", ^{
+ NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
+
+ [[@([inserted hasChanges]) should] beTrue];
+
+ [managedObjectContext obtainPermanentIDsForObjects:@[inserted] error:nil];
+ NSManagedObjectID *objectId = [inserted objectID];
+
+ [managedObjectContext MR_save];
+
+ NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
+
+ [fetchedObject shouldNotBeNil];
+ [[@([fetchedObject hasChanges]) should] beFalse];
+ });
+ });
+
+ context(@"MR_saveWithErrorCallback", ^{
+ it(@"should call error handler on errors", ^{
+ __block BOOL errorHandlerCalled = NO;
+
+ [managedObjectContext MR_saveWithErrorCallback:^(NSError *error) {
+ errorHandlerCalled = YES;
+ }];
+
+ [[expectFutureValue(@(errorHandlerCalled)) shouldEventually] beTrue];
+ });
+
+ it(@"should save", ^{
+ NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
+
+ [[@([inserted hasChanges]) should] beTrue];
+
+ [managedObjectContext obtainPermanentIDsForObjects:@[inserted] error:nil];
+ NSManagedObjectID *objectId = [inserted objectID];
+
+ __block BOOL errorHandlerCalled = NO;
+ __block NSError *saveError;
+
+ [managedObjectContext MR_saveWithErrorCallback:^(NSError *error) {
+ saveError = error;
+ errorHandlerCalled = YES;
+ }];
+
+ [saveError shouldBeNil];
+ [[@(errorHandlerCalled) should] beFalse];
+
+ NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
+
+ [fetchedObject shouldNotBeNil];
+ [[@([fetchedObject hasChanges]) should] beFalse];
+ });
+ });
+
+ context(@"MR_saveInBackgroundErrorHandler", ^{
+ it(@"should call error handler on errors", ^{
+ __block BOOL errorHandlerCalled = NO;
+
+ [managedObjectContext MR_saveInBackgroundErrorHandler:^(NSError *error) {
+ errorHandlerCalled = YES;
+ }];
+
+ [[expectFutureValue(@(errorHandlerCalled)) shouldEventually] beTrue];
+ });
+
+ it(@"should save to self, and be present in parent context", ^{
+ NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
+
+ [[@([inserted hasChanges]) should] beTrue];
+
+ [managedObjectContext obtainPermanentIDsForObjects:@[inserted] error:nil];
+ NSManagedObjectID *objectId = [inserted objectID];
+
+ __block BOOL errorHandlerCalled = NO;
+ __block NSError *saveError;
+
+ [managedObjectContext MR_saveInBackgroundErrorHandler:^(NSError *error) {
+ saveError = error;
+ errorHandlerCalled = YES;
+ }];
+
+ [[expectFutureValue(@([inserted hasChanges])) shouldEventually] beFalse];
+
+ // There should be no errors
+ [[expectFutureValue(saveError) shouldEventually] beNil];
+ [[expectFutureValue(@(errorHandlerCalled)) shouldEventually] beFalse];
+
+ // Retrieve the object from the root saving context, and check that it's valid
+ NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
+
+ [[expectFutureValue(fetchedObject) shouldEventually] beNil];
+ [[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beFalse];
+
+ // Check that the object has been passed up to the parent context, but that the fetched object has unsaved changes
+ fetchedObject = [[managedObjectContext parentContext] objectRegisteredForID:objectId];
+
+ [[expectFutureValue(fetchedObject) shouldEventually] beNonNil];
+ [[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beTrue];
+ });
+ });
+
+ context(@"MR_saveInBackgroundErrorHandler", ^{
+ it(@"should call completion block", ^{
+ __block BOOL completionBlockCalled = NO;
+ __block BOOL errorHandlerCalled = NO;
+
+ [SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
+
+ [managedObjectContext MR_saveInBackgroundErrorHandler:^(NSError *error) {
+ errorHandlerCalled = YES;
+ } completion:^{
+ completionBlockCalled = YES;
+ }];
+
+ [[expectFutureValue(@(errorHandlerCalled)) shouldEventually] beFalse];
+ [[expectFutureValue(@(completionBlockCalled)) shouldEventually] beTrue];
+ });
+
+ it(@"should call error handler on errors", ^{
+ __block BOOL completionBlockCalled = NO;
+ __block BOOL errorHandlerCalled = NO;
+
+ [managedObjectContext MR_saveInBackgroundErrorHandler:^(NSError *error) {
+ errorHandlerCalled = YES;
+ } completion:^{
+ completionBlockCalled = YES;
+ }];
+
+ [[expectFutureValue(@(errorHandlerCalled)) shouldEventually] beTrue];
+ [[expectFutureValue(@(completionBlockCalled)) shouldEventually] beFalse];
+ });
+
+ it(@"should save to self, and be present in parent context", ^{
+ NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
+
+ [[@([inserted hasChanges]) should] beTrue];
+
+ [managedObjectContext obtainPermanentIDsForObjects:@[inserted] error:nil];
+ NSManagedObjectID *objectId = [inserted objectID];
+
+ __block BOOL errorHandlerCalled = NO;
+ __block NSError *saveError;
+
+ [managedObjectContext MR_saveInBackgroundErrorHandler:^(NSError *error) {
+ saveError = error;
+ errorHandlerCalled = YES;
+ }];
+
+ [[expectFutureValue(@([inserted hasChanges])) shouldEventually] beFalse];
+
+ // There should be no errors
+ [[expectFutureValue(saveError) shouldEventually] beNil];
+ [[expectFutureValue(@(errorHandlerCalled)) shouldEventually] beFalse];
+
+ // Retrieve the object from the root saving context, and check that it's valid
+ NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
+
+ [[expectFutureValue(fetchedObject) shouldEventually] beNil];
+ [[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beFalse];
+
+ // Check that the object has been passed up to the parent context, but that the fetched object has unsaved changes
+ fetchedObject = [[managedObjectContext parentContext] objectRegisteredForID:objectId];
+
+ [[expectFutureValue(fetchedObject) shouldEventually] beNonNil];
+ [[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beTrue];
+ });
+ });
+
+ context(@"MR_saveNestedContextsErrorHandler", ^{
+ it(@"should call error handler on errors", ^{
+ __block BOOL errorHandlerCalled = NO;
+
+ [managedObjectContext MR_saveNestedContextsErrorHandler:^(NSError *error) {
+ errorHandlerCalled = YES;
+ }];
+
+ [[expectFutureValue(@(errorHandlerCalled)) shouldEventually] beTrue];
+ });
+
+ it(@"should save", ^{
+ NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
+
+ [[@([inserted hasChanges]) should] beTrue];
+
+ [managedObjectContext obtainPermanentIDsForObjects:@[inserted] error:nil];
+ NSManagedObjectID *objectId = [inserted objectID];
+
+ __block BOOL errorHandlerCalled = NO;
+ __block NSError *saveError;
+
+ [managedObjectContext MR_saveNestedContextsErrorHandler:^(NSError *error) {
+ saveError = error;
+ errorHandlerCalled = YES;
+ }];
+
+ [[expectFutureValue(saveError) shouldEventually] beNil];
+ [[expectFutureValue(@(errorHandlerCalled)) shouldEventually] beFalse];
+
+ NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
+
+ [[expectFutureValue(fetchedObject) shouldEventually] beNonNil];
+ [[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beFalse];
+ });
+ });
+
+ context(@"MR_saveInBackgroundErrorHandler", ^{
+ it(@"should call error handler on errors", ^{
+ __block BOOL errorHandlerCalled = NO;
+
+ [managedObjectContext MR_saveInBackgroundErrorHandler:^(NSError *error) {
+ errorHandlerCalled = YES;
+ }];
+
+ [[expectFutureValue(@(errorHandlerCalled)) shouldEventually] beTrue];
+ });
+
+ it(@"should save to self, and be present in parent context", ^{
+ NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
+
+ [[@([inserted hasChanges]) should] beTrue];
+
+ [managedObjectContext obtainPermanentIDsForObjects:@[inserted] error:nil];
+ NSManagedObjectID *objectId = [inserted objectID];
+
+ __block BOOL errorHandlerCalled = NO;
+ __block NSError *saveError;
+
+ [managedObjectContext MR_saveInBackgroundErrorHandler:^(NSError *error) {
+ saveError = error;
+ errorHandlerCalled = YES;
+ }];
+
+ [[expectFutureValue(@([inserted hasChanges])) shouldEventually] beFalse];
+
+ // There should be no errors
+ [[expectFutureValue(saveError) shouldEventually] beNil];
+ [[expectFutureValue(@(errorHandlerCalled)) shouldEventually] beFalse];
+
+ // Retrieve the object from the root saving context, and check that it's valid
+ NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
+
+ [[expectFutureValue(fetchedObject) shouldEventually] beNil];
+ [[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beFalse];
+
+ // Check that the object has been passed up to the parent context, but that the fetched object has unsaved changes
+ fetchedObject = [[managedObjectContext parentContext] objectRegisteredForID:objectId];
+
+ [[expectFutureValue(fetchedObject) shouldEventually] beNonNil];
+ [[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beTrue];
+ });
+ });
+ });
+
+#pragma clang diagnostic pop // ignored "-Wdeprecated-declarations"
+});
+
+SPEC_END
View
547 Project Files/Magical Record.xcodeproj/project.pbxproj
@@ -7,64 +7,132 @@
objects = {
/* Begin PBXBuildFile section */
- 4B7116FD15F8EE4600B64426 /* EXPBackwardCompatibility.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116C215F8EE4600B64426 /* EXPBackwardCompatibility.m */; };
+ 4B7116FD15F8EE4600B64426 /* EXPBackwardCompatibility.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116C215F8EE4600B64426 /* EXPBackwardCompatibility.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
4B7116FE15F8EE4600B64426 /* EXPBackwardCompatibility.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116C215F8EE4600B64426 /* EXPBackwardCompatibility.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
- 4B7116FF15F8EE4600B64426 /* EXPBlockDefinedMatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116C415F8EE4600B64426 /* EXPBlockDefinedMatcher.m */; };
+ 4B7116FF15F8EE4600B64426 /* EXPBlockDefinedMatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116C415F8EE4600B64426 /* EXPBlockDefinedMatcher.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
4B71170015F8EE4600B64426 /* EXPBlockDefinedMatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116C415F8EE4600B64426 /* EXPBlockDefinedMatcher.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
- 4B71170115F8EE4600B64426 /* EXPDoubleTuple.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116C715F8EE4600B64426 /* EXPDoubleTuple.m */; };
+ 4B71170115F8EE4600B64426 /* EXPDoubleTuple.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116C715F8EE4600B64426 /* EXPDoubleTuple.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
4B71170215F8EE4600B64426 /* EXPDoubleTuple.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116C715F8EE4600B64426 /* EXPDoubleTuple.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
- 4B71170315F8EE4600B64426 /* Expecta.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116CA15F8EE4600B64426 /* Expecta.m */; };
+ 4B71170315F8EE4600B64426 /* Expecta.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116CA15F8EE4600B64426 /* Expecta.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
4B71170415F8EE4600B64426 /* Expecta.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116CA15F8EE4600B64426 /* Expecta.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
- 4B71170515F8EE4600B64426 /* ExpectaSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116CC15F8EE4600B64426 /* ExpectaSupport.m */; };
+ 4B71170515F8EE4600B64426 /* ExpectaSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116CC15F8EE4600B64426 /* ExpectaSupport.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
4B71170615F8EE4600B64426 /* ExpectaSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116CC15F8EE4600B64426 /* ExpectaSupport.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
- 4B71170715F8EE4600B64426 /* EXPExpect.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116CE15F8EE4600B64426 /* EXPExpect.m */; };
+ 4B71170715F8EE4600B64426 /* EXPExpect.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116CE15F8EE4600B64426 /* EXPExpect.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
4B71170815F8EE4600B64426 /* EXPExpect.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116CE15F8EE4600B64426 /* EXPExpect.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
- 4B71170915F8EE4600B64426 /* EXPFloatTuple.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116D015F8EE4600B64426 /* EXPFloatTuple.m */; };
+ 4B71170915F8EE4600B64426 /* EXPFloatTuple.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116D015F8EE4600B64426 /* EXPFloatTuple.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
4B71170A15F8EE4600B64426 /* EXPFloatTuple.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116D015F8EE4600B64426 /* EXPFloatTuple.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
- 4B71170B15F8EE4600B64426 /* EXPUnsupportedObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116D315F8EE4600B64426 /* EXPUnsupportedObject.m */; };
+ 4B71170B15F8EE4600B64426 /* EXPUnsupportedObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116D315F8EE4600B64426 /* EXPUnsupportedObject.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
4B71170C15F8EE4600B64426 /* EXPUnsupportedObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116D315F8EE4600B64426 /* EXPUnsupportedObject.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
- 4B71170D15F8EE4600B64426 /* EXPMatcherHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116D615F8EE4600B64426 /* EXPMatcherHelpers.m */; };
+ 4B71170D15F8EE4600B64426 /* EXPMatcherHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116D615F8EE4600B64426 /* EXPMatcherHelpers.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
4B71170E15F8EE4600B64426 /* EXPMatcherHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116D615F8EE4600B64426 /* EXPMatcherHelpers.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
- 4B71170F15F8EE4600B64426 /* EXPMatchers+beCloseTo.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116D815F8EE4600B64426 /* EXPMatchers+beCloseTo.m */; };
+ 4B71170F15F8EE4600B64426 /* EXPMatchers+beCloseTo.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116D815F8EE4600B64426 /* EXPMatchers+beCloseTo.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
4B71171015F8EE4600B64426 /* EXPMatchers+beCloseTo.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116D815F8EE4600B64426 /* EXPMatchers+beCloseTo.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
- 4B71171115F8EE4600B64426 /* EXPMatchers+beFalsy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116DA15F8EE4600B64426 /* EXPMatchers+beFalsy.m */; };
+ 4B71171115F8EE4600B64426 /* EXPMatchers+beFalsy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116DA15F8EE4600B64426 /* EXPMatchers+beFalsy.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
4B71171215F8EE4600B64426 /* EXPMatchers+beFalsy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116DA15F8EE4600B64426 /* EXPMatchers+beFalsy.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
- 4B71171315F8EE4600B64426 /* EXPMatchers+beGreaterThan.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116DC15F8EE4600B64426 /* EXPMatchers+beGreaterThan.m */; };
+ 4B71171315F8EE4600B64426 /* EXPMatchers+beGreaterThan.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116DC15F8EE4600B64426 /* EXPMatchers+beGreaterThan.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
4B71171415F8EE4600B64426 /* EXPMatchers+beGreaterThan.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116DC15F8EE4600B64426 /* EXPMatchers+beGreaterThan.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
- 4B71171515F8EE4600B64426 /* EXPMatchers+beGreaterThanOrEqualTo.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116DE15F8EE4600B64426 /* EXPMatchers+beGreaterThanOrEqualTo.m */; };
+ 4B71171515F8EE4600B64426 /* EXPMatchers+beGreaterThanOrEqualTo.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116DE15F8EE4600B64426 /* EXPMatchers+beGreaterThanOrEqualTo.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
4B71171615F8EE4600B64426 /* EXPMatchers+beGreaterThanOrEqualTo.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116DE15F8EE4600B64426 /* EXPMatchers+beGreaterThanOrEqualTo.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
- 4B71171715F8EE4600B64426 /* EXPMatchers+beIdenticalTo.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116E015F8EE4600B64426 /* EXPMatchers+beIdenticalTo.m */; };
+ 4B71171715F8EE4600B64426 /* EXPMatchers+beIdenticalTo.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116E015F8EE4600B64426 /* EXPMatchers+beIdenticalTo.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
4B71171815F8EE4600B64426 /* EXPMatchers+beIdenticalTo.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116E015F8EE4600B64426 /* EXPMatchers+beIdenticalTo.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
- 4B71171915F8EE4600B64426 /* EXPMatchers+beInstanceOf.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116E215F8EE4600B64426 /* EXPMatchers+beInstanceOf.m */; };
+ 4B71171915F8EE4600B64426 /* EXPMatchers+beInstanceOf.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116E215F8EE4600B64426 /* EXPMatchers+beInstanceOf.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
4B71171A15F8EE4600B64426 /* EXPMatchers+beInstanceOf.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116E215F8EE4600B64426 /* EXPMatchers+beInstanceOf.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
- 4B71171B15F8EE4600B64426 /* EXPMatchers+beInTheRangeOf.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116E415F8EE4600B64426 /* EXPMatchers+beInTheRangeOf.m */; };
+ 4B71171B15F8EE4600B64426 /* EXPMatchers+beInTheRangeOf.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116E415F8EE4600B64426 /* EXPMatchers+beInTheRangeOf.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
4B71171C15F8EE4600B64426 /* EXPMatchers+beInTheRangeOf.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116E415F8EE4600B64426 /* EXPMatchers+beInTheRangeOf.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
- 4B71171D15F8EE4600B64426 /* EXPMatchers+beKindOf.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116E615F8EE4600B64426 /* EXPMatchers+beKindOf.m */; };
+ 4B71171D15F8EE4600B64426 /* EXPMatchers+beKindOf.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116E615F8EE4600B64426 /* EXPMatchers+beKindOf.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
4B71171E15F8EE4600B64426 /* EXPMatchers+beKindOf.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116E615F8EE4600B64426 /* EXPMatchers+beKindOf.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
- 4B71171F15F8EE4600B64426 /* EXPMatchers+beLessThan.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116E815F8EE4600B64426 /* EXPMatchers+beLessThan.m */; };
+ 4B71171F15F8EE4600B64426 /* EXPMatchers+beLessThan.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116E815F8EE4600B64426 /* EXPMatchers+beLessThan.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
4B71172015F8EE4600B64426 /* EXPMatchers+beLessThan.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116E815F8EE4600B64426 /* EXPMatchers+beLessThan.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
- 4B71172115F8EE4600B64426 /* EXPMatchers+beLessThanOrEqualTo.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116EA15F8EE4600B64426 /* EXPMatchers+beLessThanOrEqualTo.m */; };
+ 4B71172115F8EE4600B64426 /* EXPMatchers+beLessThanOrEqualTo.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116EA15F8EE4600B64426 /* EXPMatchers+beLessThanOrEqualTo.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
4B71172215F8EE4600B64426 /* EXPMatchers+beLessThanOrEqualTo.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116EA15F8EE4600B64426 /* EXPMatchers+beLessThanOrEqualTo.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
- 4B71172315F8EE4600B64426 /* EXPMatchers+beNil.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116EC15F8EE4600B64426 /* EXPMatchers+beNil.m */; };
+ 4B71172315F8EE4600B64426 /* EXPMatchers+beNil.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116EC15F8EE4600B64426 /* EXPMatchers+beNil.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
4B71172415F8EE4600B64426 /* EXPMatchers+beNil.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116EC15F8EE4600B64426 /* EXPMatchers+beNil.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
- 4B71172515F8EE4600B64426 /* EXPMatchers+beSubclassOf.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116EE15F8EE4600B64426 /* EXPMatchers+beSubclassOf.m */; };
+ 4B71172515F8EE4600B64426 /* EXPMatchers+beSubclassOf.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116EE15F8EE4600B64426 /* EXPMatchers+beSubclassOf.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
4B71172615F8EE4600B64426 /* EXPMatchers+beSubclassOf.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116EE15F8EE4600B64426 /* EXPMatchers+beSubclassOf.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
- 4B71172715F8EE4600B64426 /* EXPMatchers+beTruthy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116F015F8EE4600B64426 /* EXPMatchers+beTruthy.m */; };
+ 4B71172715F8EE4600B64426 /* EXPMatchers+beTruthy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116F015F8EE4600B64426 /* EXPMatchers+beTruthy.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
4B71172815F8EE4600B64426 /* EXPMatchers+beTruthy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116F015F8EE4600B64426 /* EXPMatchers+beTruthy.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
- 4B71172915F8EE4600B64426 /* EXPMatchers+contain.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116F215F8EE4600B64426 /* EXPMatchers+contain.m */; };
+ 4B71172915F8EE4600B64426 /* EXPMatchers+contain.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116F215F8EE4600B64426 /* EXPMatchers+contain.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
4B71172A15F8EE4600B64426 /* EXPMatchers+contain.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116F215F8EE4600B64426 /* EXPMatchers+contain.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
- 4B71172B15F8EE4600B64426 /* EXPMatchers+equal.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116F415F8EE4600B64426 /* EXPMatchers+equal.m */; };
+ 4B71172B15F8EE4600B64426 /* EXPMatchers+equal.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116F415F8EE4600B64426 /* EXPMatchers+equal.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
4B71172C15F8EE4600B64426 /* EXPMatchers+equal.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116F415F8EE4600B64426 /* EXPMatchers+equal.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
- 4B71172D15F8EE4600B64426 /* EXPMatchers+haveCountOf.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116F615F8EE4600B64426 /* EXPMatchers+haveCountOf.m */; };
+ 4B71172D15F8EE4600B64426 /* EXPMatchers+haveCountOf.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116F615F8EE4600B64426 /* EXPMatchers+haveCountOf.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
4B71172E15F8EE4600B64426 /* EXPMatchers+haveCountOf.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116F615F8EE4600B64426 /* EXPMatchers+haveCountOf.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
- 4B71172F15F8EE4600B64426 /* EXPMatchers+raise.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116F815F8EE4600B64426 /* EXPMatchers+raise.m */; };
+ 4B71172F15F8EE4600B64426 /* EXPMatchers+raise.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116F815F8EE4600B64426 /* EXPMatchers+raise.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
4B71173015F8EE4600B64426 /* EXPMatchers+raise.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116F815F8EE4600B64426 /* EXPMatchers+raise.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
- 4B71173115F8EE4600B64426 /* NSValue+Expecta.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116FC15F8EE4600B64426 /* NSValue+Expecta.m */; };
+ 4B71173115F8EE4600B64426 /* NSValue+Expecta.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116FC15F8EE4600B64426 /* NSValue+Expecta.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
4B71173215F8EE4600B64426 /* NSValue+Expecta.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116FC15F8EE4600B64426 /* NSValue+Expecta.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
- 4B71173315F9149900B64426 /* SaveTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116BC15F8ED5A00B64426 /* SaveTests.m */; };
- 4B71173415F914A400B64426 /* SaveTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7116BC15F8ED5A00B64426 /* SaveTests.m */; };
4B93EA49160ECF1D00FB5676 /* TestModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 4B93EA47160ECF1D00FB5676 /* TestModel.xcdatamodeld */; };
4B93EA4A160ECF1D00FB5676 /* TestModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 4B93EA47160ECF1D00FB5676 /* TestModel.xcdatamodeld */; };
+ 900E1CC11676E246005FFF1C /* GHUnit.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = C7D2DC22155AFDF500B3A468 /* GHUnit.framework */; };
+ 900E1CC21676E246005FFF1C /* OCHamcrest.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = C7D2DC23155AFDF500B3A468 /* OCHamcrest.framework */; };
+ 900E1CC31676E246005FFF1C /* OCMock.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = C7D2DC24155AFDF500B3A468 /* OCMock.framework */; };
+ 900E1CC81676E27E005FFF1C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 900E1CC41676E25E005FFF1C /* CoreGraphics.framework */; };
+ 900E1CC91676E488005FFF1C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 900E1CC61676E275005FFF1C /* UIKit.framework */; };
+ 90DD2047167AA4630033BA25 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 90DD2045167AA45B0033BA25 /* SenTestingKit.framework */; };
+ 90DD204A167AA46D0033BA25 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 90DD2048167AA4670033BA25 /* Cocoa.framework */; };
+ 90DD204B167AA46F0033BA25 /* libKiwi-OSX.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 90DD203E167AA44D0033BA25 /* libKiwi-OSX.a */; };
+ 90DD204E167AA4E10033BA25 /* MagicalRecord+ActionsSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 90DD204D167AA4E10033BA25 /* MagicalRecord+ActionsSpec.m */; };
+ 90DD2054167AA6C80033BA25 /* MappedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = C784348E13F0FEE000463CEE /* MappedEntity.m */; };
+ 90DD2055167AA6C80033BA25 /* AbstractRelatedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = C7BD888313DBFA6200274567 /* AbstractRelatedEntity.m */; };
+ 90DD2056167AA6C80033BA25 /* ConcreteRelatedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = C7BD888513DBFA6200274567 /* ConcreteRelatedEntity.m */; };
+ 90DD2057167AA6C80033BA25 /* DifferentClassNameMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = C7BD888713DBFA6200274567 /* DifferentClassNameMapping.m */; };
+ 90DD2058167AA6C80033BA25 /* SingleEntityWithNoRelationships.m in Sources */ = {isa = PBXBuildFile; fileRef = C7BD888913DBFA6200274567 /* SingleEntityWithNoRelationships.m */; };
+ 90DD2059167AA6C80033BA25 /* SingleRelatedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = C7BD888B13DBFA6200274567 /* SingleRelatedEntity.m */; };
+ 90DD205A167AA6C80033BA25 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.m in Sources */ = {isa = PBXBuildFile; fileRef = C78F8FD913FDC3F400549DD8 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.m */; };
+ 90DD205B167AA6C80033BA25 /* SingleEntityRelatedToMappedEntityUsingDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = C7C9A38713F4524B002C5B0C /* SingleEntityRelatedToMappedEntityUsingDefaults.m */; };
+ 90DD205C167AA6C80033BA25 /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m in Sources */ = {isa = PBXBuildFile; fileRef = C7C9A38913F4524B002C5B0C /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m */; };
+ 90DD205D167AA6C80033BA25 /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m in Sources */ = {isa = PBXBuildFile; fileRef = C7913B9813FAEDF8007E09CC /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m */; };
+ 90DD205E167AA6C80033BA25 /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = C7913BA813FB1D2A007E09CC /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m */; };
+ 90DD205F167AA6CC0033BA25 /* TestModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 4B93EA47160ECF1D00FB5676 /* TestModel.xcdatamodeld */; };
+ 90DD2060167AA6D80033BA25 /* _SingleEntityRelatedToMappedEntityWithSecondaryMappings.m in Sources */ = {isa = PBXBuildFile; fileRef = C78F8FDC13FDC3FD00549DD8 /* _SingleEntityRelatedToMappedEntityWithSecondaryMappings.m */; };
+ 90DD2061167AA6D80033BA25 /* _AbstractRelatedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = C7BD887913DBFA6200274567 /* _AbstractRelatedEntity.m */; };
+ 90DD2062167AA6D80033BA25 /* _ConcreteRelatedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = C7BD887B13DBFA6200274567 /* _ConcreteRelatedEntity.m */; };
+ 90DD2063167AA6D80033BA25 /* _DifferentClassNameMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = C7BD887D13DBFA6200274567 /* _DifferentClassNameMapping.m */; };
+ 90DD2064167AA6D80033BA25 /* _SingleEntityWithNoRelationships.m in Sources */ = {isa = PBXBuildFile; fileRef = C7BD887F13DBFA6200274567 /* _SingleEntityWithNoRelationships.m */; };
+ 90DD2065167AA6D80033BA25 /* _SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m in Sources */ = {isa = PBXBuildFile; fileRef = C7913B9413FAEDE9007E09CC /* _SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m */; };
+ 90DD2066167AA6D80033BA25 /* _SingleRelatedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = C7BD888113DBFA6200274567 /* _SingleRelatedEntity.m */; };
+ 90DD2067167AA6D80033BA25 /* _MappedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = C784348C13F0FEE000463CEE /* _MappedEntity.m */; };
+ 90DD2068167AA6D80033BA25 /* _SingleEntityRelatedToMappedEntityUsingDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = C7C9A38113F45240002C5B0C /* _SingleEntityRelatedToMappedEntityUsingDefaults.m */; };
+ 90DD2069167AA6D80033BA25 /* _SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m in Sources */ = {isa = PBXBuildFile; fileRef = C7C9A38313F45240002C5B0C /* _SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m */; };
+ 90DD206A167AA6D80033BA25 /* _SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = C7913BA513FB1D17007E09CC /* _SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m */; };
+ 90DD206B167AA6DF0033BA25 /* SingleEntityWithNoRelationships.plist in Resources */ = {isa = PBXBuildFile; fileRef = C77E5FB213D0D1D100298F87 /* SingleEntityWithNoRelationships.plist */; };
+ 90DD206C167AA6DF0033BA25 /* SingleEntityWithNoRelationships.json in Resources */ = {isa = PBXBuildFile; fileRef = C7E736DE1402FE64005657C9 /* SingleEntityWithNoRelationships.json */; };
+ 90DD206D167AA6DF0033BA25 /* SampleJSONDataForImport.json in Resources */ = {isa = PBXBuildFile; fileRef = C77E5FB413D0D1EC00298F87 /* SampleJSONDataForImport.json */; };
+ 90DD206E167AA6DF0033BA25 /* SingleRelatedEntity.json in Resources */ = {isa = PBXBuildFile; fileRef = C76AF82913DBEE5A00CE2E05 /* SingleRelatedEntity.json */; };
+ 90DD206F167AA6DF0033BA25 /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json in Resources */ = {isa = PBXBuildFile; fileRef = C7C9A37C13F44B08002C5B0C /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json */; };
+ 90DD2070167AA6DF0033BA25 /* SingleEntityRelatedToMappedEntityUsingDefaults.json in Resources */ = {isa = PBXBuildFile; fileRef = C7C9A37E13F44B29002C5B0C /* SingleEntityRelatedToMappedEntityUsingDefaults.json */; };
+ 90DD2071167AA6DF0033BA25 /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json in Resources */ = {isa = PBXBuildFile; fileRef = C7B7379913FAE5D500EE4940 /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json */; };
+ 90DD2072167AA6DF0033BA25 /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json in Resources */ = {isa = PBXBuildFile; fileRef = C7913BAE13FB1E11007E09CC /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json */; };
+ 90DD2073167AA6DF0033BA25 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.json in Resources */ = {isa = PBXBuildFile; fileRef = C78F8FD213FDC2B600549DD8 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.json */; };
+ 90DD2074167AA6DF0033BA25 /* SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json in Resources */ = {isa = PBXBuildFile; fileRef = C7381275141037E80054EEF0 /* SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json */; };
+ 90DD2076167AA7050033BA25 /* MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72D2150F832A00216827 /* MagicalRecord.m */; };
+ 90DD2077167AA7050033BA25 /* MagicalRecord+Actions.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C6150F832A00216827 /* MagicalRecord+Actions.m */; };
+ 90DD2078167AA7050033BA25 /* MagicalRecord+ErrorHandling.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C8150F832A00216827 /* MagicalRecord+ErrorHandling.m */; };
+ 90DD2079167AA7050033BA25 /* MagicalRecord+iCloud.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72CA150F832A00216827 /* MagicalRecord+iCloud.m */; };
+ 90DD207A167AA7050033BA25 /* MagicalRecord+Options.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72CC150F832A00216827 /* MagicalRecord+Options.m */; };
+ 90DD207B167AA7050033BA25 /* MagicalRecord+Setup.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72CE150F832A00216827 /* MagicalRecord+Setup.m */; };
+ 90DD207C167AA7050033BA25 /* MagicalRecord+ShorthandSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72D0150F832A00216827 /* MagicalRecord+ShorthandSupport.m */; };
+ 90DD207D167AA7080033BA25 /* NSManagedObjectModel+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72BF150F832A00216827 /* NSManagedObjectModel+MagicalRecord.m */; };
+ 90DD207E167AA7080033BA25 /* NSPersistentStore+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C1150F832A00216827 /* NSPersistentStore+MagicalRecord.m */; };
+ 90DD207F167AA7080033BA25 /* NSPersistentStoreCoordinator+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C3150F832A00216827 /* NSPersistentStoreCoordinator+MagicalRecord.m */; };
+ 90DD2080167AA70E0033BA25 /* MagicalImportFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD729D150F832A00216827 /* MagicalImportFunctions.m */; };
+ 90DD2081167AA70E0033BA25 /* NSEntityDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A1150F832A00216827 /* NSEntityDescription+MagicalDataImport.m */; };
+ 90DD2082167AA70E0033BA25 /* NSAttributeDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD729F150F832A00216827 /* NSAttributeDescription+MagicalDataImport.m */; };
+ 90DD2083167AA70E0033BA25 /* NSRelationshipDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A7150F832A00216827 /* NSRelationshipDescription+MagicalDataImport.m */; };
+ 90DD2084167AA70E0033BA25 /* NSNumber+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A3150F832A00216827 /* NSNumber+MagicalDataImport.m */; };
+ 90DD2085167AA70E0033BA25 /* NSObject+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A5150F832A00216827 /* NSObject+MagicalDataImport.m */; };
+ 90DD2086167AA70E0033BA25 /* NSString+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A9150F832A00216827 /* NSString+MagicalDataImport.m */; };
+ 90DD2087167AA7130033BA25 /* NSManagedObject+MagicalAggregation.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72AC150F832A00216827 /* NSManagedObject+MagicalAggregation.m */; };
+ 90DD2088167AA7130033BA25 /* NSManagedObject+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72AE150F832A00216827 /* NSManagedObject+MagicalDataImport.m */; };
+ 90DD2089167AA7130033BA25 /* NSManagedObject+MagicalFinders.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B0150F832A00216827 /* NSManagedObject+MagicalFinders.m */; };
+ 90DD208A167AA7130033BA25 /* NSManagedObject+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B2150F832A00216827 /* NSManagedObject+MagicalRecord.m */; };
+ 90DD208B167AA7130033BA25 /* NSManagedObject+MagicalRequests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B4150F832A00216827 /* NSManagedObject+MagicalRequests.m */; };
+ 90DD208C167AA7180033BA25 /* NSManagedObjectContext+MagicalObserving.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B7150F832A00216827 /* NSManagedObjectContext+MagicalObserving.m */; };
+ 90DD208D167AA7180033BA25 /* NSManagedObjectContext+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B9150F832A00216827 /* NSManagedObjectContext+MagicalRecord.m */; };
+ 90DD208E167AA7180033BA25 /* NSManagedObjectContext+MagicalSaves.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72BB150F832A00216827 /* NSManagedObjectContext+MagicalSaves.m */; };
+ 90DD208F167AA7180033BA25 /* NSManagedObjectContext+MagicalThreading.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72BD150F832A00216827 /* NSManagedObjectContext+MagicalThreading.m */; };
+ 90DD2090167AA7590033BA25 /* generateShorthandFile.rb in Resources */ = {isa = PBXBuildFile; fileRef = C75C7D69147220D300D0C2FE /* generateShorthandFile.rb */; };
+ 90DD2093167AAEFA0033BA25 /* NSManagedObjectContext+MagicalSavesSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 90DD2092167AAEFA0033BA25 /* NSManagedObjectContext+MagicalSavesSpec.m */; };
C70B6E7113D0F62500709450 /* NSPersisentStoreHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C70B6E7013D0F62500709450 /* NSPersisentStoreHelperTests.m */; };
C70B6E7413D0F64000709450 /* NSPersistentStoreCoordinatorHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C70B6E7313D0F64000709450 /* NSPersistentStoreCoordinatorHelperTests.m */; };
C70B6E7713D0F66000709450 /* NSManagedObjectModelHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C70B6E7613D0F66000709450 /* NSManagedObjectModelHelperTests.m */; };
@@ -104,8 +172,6 @@
C76AF7FC13DBEB5500CE2E05 /* ImportSingleRelatedEntityTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C76AF7FA13DBEB5500CE2E05 /* ImportSingleRelatedEntityTests.m */; };
C76AF82A13DBEE5A00CE2E05 /* SingleRelatedEntity.json in Resources */ = {isa = PBXBuildFile; fileRef = C76AF82913DBEE5A00CE2E05 /* SingleRelatedEntity.json */; };
C76AF82B13DBEE5A00CE2E05 /* SingleRelatedEntity.json in Resources */ = {isa = PBXBuildFile; fileRef = C76AF82913DBEE5A00CE2E05 /* SingleRelatedEntity.json */; };
- C76D3EF715718EBC00B2D163 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C76D3EF615718EBC00B2D163 /* UIKit.framework */; };
- C76D3EF915718EC800B2D163 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C76D3EF815718EC800B2D163 /* CoreGraphics.framework */; };
C77E5F9B13D0CA0A00298F87 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C721C7E213D0C3A00097AB6F /* CoreData.framework */; };
C77E5FA813D0CBDE00298F87 /* MagicalRecordTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C77E5FA713D0CBDE00298F87 /* MagicalRecordTests.m */; };
C77E5FB313D0D1D100298F87 /* SingleEntityWithNoRelationships.plist in Resources */ = {isa = PBXBuildFile; fileRef = C77E5FB213D0D1D100298F87 /* SingleEntityWithNoRelationships.plist */; };
@@ -231,7 +297,6 @@
C7DD7307150F832B00216827 /* MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72D2150F832A00216827 /* MagicalRecord.m */; };
C7DD7308150F832B00216827 /* MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72D2150F832A00216827 /* MagicalRecord.m */; };
C7E736DF1402FE64005657C9 /* SingleEntityWithNoRelationships.json in Resources */ = {isa = PBXBuildFile; fileRef = C7E736DE1402FE64005657C9 /* SingleEntityWithNoRelationships.json */; };
- C7F5EEB2148DC76700964607 /* (null) in Sources */ = {isa = PBXBuildFile; };
FD73E54614AC4AC700922CA4 /* MagicalDataImportTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = C7913B9C13FAFC13007E09CC /* MagicalDataImportTestCase.m */; };
/* End PBXBuildFile section */
@@ -248,27 +313,45 @@
};
/* End PBXBuildRule section */
-/* Begin PBXCopyFilesBuildPhase section */
- C753897513DB6310002B2F57 /* Copy GHUnit into App Bundle */ = {
- isa = PBXCopyFilesBuildPhase;
- buildActionMask = 2147483647;
- dstPath = "";
- dstSubfolderSpec = 10;
- files = (
- );
- name = "Copy GHUnit into App Bundle";
- runOnlyForDeploymentPostprocessing = 0;
+/* Begin PBXContainerItemProxy section */
+ 90DD203B167AA44D0033BA25 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 90DD2033167AA44D0033BA25 /* Kiwi.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = F5015B9F11583A77002E9A98;
+ remoteInfo = Kiwi;
};
- C76AF7F313DBC33100CE2E05 /* Copy OCHamcrest into App Bundle */ = {
- isa = PBXCopyFilesBuildPhase;
- buildActionMask = 2147483647;
- dstPath = "";
- dstSubfolderSpec = 16;
- files = (
- );
- name = "Copy OCHamcrest into App Bundle";
- runOnlyForDeploymentPostprocessing = 0;
+ 90DD203D167AA44D0033BA25 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 90DD2033167AA44D0033BA25 /* Kiwi.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = 832C83C7157263B300F160D5;
+ remoteInfo = "Kiwi-OSX";
+ };
+ 90DD203F167AA44D0033BA25 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 90DD2033167AA44D0033BA25 /* Kiwi.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = F5015C9E11584017002E9A98;
+ remoteInfo = KiwiTests;
};
+ 90DD2041167AA44D0033BA25 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 90DD2033167AA44D0033BA25 /* Kiwi.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = A3B16542139967B800E9CC6E;
+ remoteInfo = KiwiExamples;
+ };
+ 90DD2043167AA4530033BA25 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 90DD2033167AA44D0033BA25 /* Kiwi.xcodeproj */;
+ proxyType = 1;
+ remoteGlobalIDString = 832C8323157263B300F160D5;
+ remoteInfo = "Kiwi-OSX";
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
C7E37A7B14157BE600CE9BF5 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
@@ -278,20 +361,22 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
- FD73E54714AC4D5200922CA4 /* CopyFiles */ = {
+ FD73E54714AC4D5200922CA4 /* Copy Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
+ 900E1CC11676E246005FFF1C /* GHUnit.framework in Copy Frameworks */,
+ 900E1CC21676E246005FFF1C /* OCHamcrest.framework in Copy Frameworks */,
+ 900E1CC31676E246005FFF1C /* OCMock.framework in Copy Frameworks */,
);
+ name = "Copy Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
- 4B7116BB15F8ED5A00B64426 /* SaveTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SaveTests.h; path = "Unit Tests/SaveTests.h"; sourceTree = "<group>"; };
- 4B7116BC15F8ED5A00B64426 /* SaveTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SaveTests.m; path = "Unit Tests/SaveTests.m"; sourceTree = "<group>"; };
4B7116C115F8EE4600B64426 /* EXPBackwardCompatibility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EXPBackwardCompatibility.h; sourceTree = "<group>"; };
4B7116C215F8EE4600B64426 /* EXPBackwardCompatibility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EXPBackwardCompatibility.m; sourceTree = "<group>"; };
4B7116C315F8EE4600B64426 /* EXPBlockDefinedMatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EXPBlockDefinedMatcher.h; sourceTree = "<group>"; };
@@ -352,6 +437,21 @@
4B7116FB15F8EE4600B64426 /* NSValue+Expecta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSValue+Expecta.h"; sourceTree = "<group>"; };
4B7116FC15F8EE4600B64426 /* NSValue+Expecta.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSValue+Expecta.m"; sourceTree = "<group>"; };
4B93EA48160ECF1D00FB5676 /* TestModel.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = TestModel.xcdatamodel; sourceTree = "<group>"; };
+ 900E1CC41676E25E005FFF1C /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk/System/Library/Frameworks/CoreGraphics.framework; sourceTree = DEVELOPER_DIR; };
+ 900E1CC61676E275005FFF1C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
+ 90DD201D167AA4350033BA25 /* Mac Unit Tests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Mac Unit Tests.octest"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 90DD201E167AA4350033BA25 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; };
+ 90DD2020167AA4350033BA25 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = Library/Frameworks/Cocoa.framework; sourceTree = DEVELOPER_DIR; };
+ 90DD2023167AA4350033BA25 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
+ 90DD2024167AA4350033BA25 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
+ 90DD2025167AA4350033BA25 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+ 90DD2028167AA4350033BA25 /* Mac Unit Tests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Mac Unit Tests-Info.plist"; sourceTree = "<group>"; };
+ 90DD202F167AA4350033BA25 /* Mac Unit Tests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Mac Unit Tests-Prefix.pch"; sourceTree = "<group>"; };
+ 90DD2033167AA44D0033BA25 /* Kiwi.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Kiwi.xcodeproj; path = "Third Party/Kiwi/Kiwi.xcodeproj"; sourceTree = "<group>"; };
+ 90DD2045167AA45B0033BA25 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; };
+ 90DD2048167AA4670033BA25 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/System/Library/Frameworks/Cocoa.framework; sourceTree = DEVELOPER_DIR; };
+ 90DD204D167AA4E10033BA25 /* MagicalRecord+ActionsSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+ActionsSpec.m"; sourceTree = "<group>"; };
+ 90DD2092167AAEFA0033BA25 /* NSManagedObjectContext+MagicalSavesSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectContext+MagicalSavesSpec.m"; sourceTree = "<group>"; };
C70B6E6F13D0F62500709450 /* NSPersisentStoreHelperTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NSPersisentStoreHelperTests.h; path = "Unit Tests/NSPersisentStoreHelperTests.h"; sourceTree = "<group>"; };
C70B6E7013D0F62500709450 /* NSPersisentStoreHelperTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NSPersisentStoreHelperTests.m; path = "Unit Tests/NSPersisentStoreHelperTests.m"; sourceTree = "<group>"; };
C70B6E7213D0F64000709450 /* NSPersistentStoreCoordinatorHelperTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NSPersistentStoreCoordinatorHelperTests.h; path = "Unit Tests/NSPersistentStoreCoordinatorHelperTests.h"; sourceTree = "<group>"; };
@@ -389,8 +489,6 @@
C763783113E10BEC0009A6CA /* GHUnitIOSTestMain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GHUnitIOSTestMain.m; sourceTree = "<group>"; };
C76AF7FA13DBEB5500CE2E05 /* ImportSingleRelatedEntityTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ImportSingleRelatedEntityTests.m; path = "Unit Tests/ImportSingleRelatedEntityTests.m"; sourceTree = "<group>"; };
C76AF82913DBEE5A00CE2E05 /* SingleRelatedEntity.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = SingleRelatedEntity.json; path = "Unit Tests/Fixtures/SingleRelatedEntity.json"; sourceTree = "<group>"; };
- C76D3EF615718EBC00B2D163 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
- C76D3EF815718EC800B2D163 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/System/Library/Frameworks/CoreGraphics.framework; sourceTree = DEVELOPER_DIR; };
C77E5FA613D0CBDE00298F87 /* MagicalRecordTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MagicalRecordTests.h; path = "Unit Tests/MagicalRecordTests.h"; sourceTree = "<group>"; };
C77E5FA713D0CBDE00298F87 /* MagicalRecordTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MagicalRecordTests.m; path = "Unit Tests/MagicalRecordTests.m"; sourceTree = "<group>"; };
C77E5FB213D0D1D100298F87 /* SingleEntityWithNoRelationships.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = SingleEntityWithNoRelationships.plist; path = "Unit Tests/Fixtures/SingleEntityWithNoRelationships.plist"; sourceTree = "<group>"; };
@@ -519,6 +617,16 @@
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
+ 90DD2019167AA4350033BA25 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 90DD204A167AA46D0033BA25 /* Cocoa.framework in Frameworks */,
+ 90DD2047167AA4630033BA25 /* SenTestingKit.framework in Frameworks */,
+ 90DD204B167AA46F0033BA25 /* libKiwi-OSX.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
C721C7D913D0C3A00097AB6F /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@@ -535,8 +643,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- C76D3EF915718EC800B2D163 /* CoreGraphics.framework in Frameworks */,
- C76D3EF715718EBC00B2D163 /* UIKit.framework in Frameworks */,
+ 900E1CC91676E488005FFF1C /* UIKit.framework in Frameworks */,
+ 900E1CC81676E27E005FFF1C /* CoreGraphics.framework in Frameworks */,
C721C82513D0C4660097AB6F /* Foundation.framework in Frameworks */,
C77E5F9B13D0CA0A00298F87 /* CoreData.framework in Frameworks */,
C74F8E611555E39D0008B054 /* OCHamcrestIOS.framework in Frameworks */,
@@ -623,6 +731,48 @@
path = matchers;
sourceTree = "<group>";
};
+ 90DD2022167AA4350033BA25 /* Other Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 90DD2023167AA4350033BA25 /* AppKit.framework */,
+ 90DD2024167AA4350033BA25 /* CoreData.framework */,
+ 90DD2025167AA4350033BA25 /* Foundation.framework */,
+ );
+ name = "Other Frameworks";
+ sourceTree = "<group>";
+ };
+ 90DD2026167AA4350033BA25 /* Mac Unit Tests */ = {
+ isa = PBXGroup;
+ children = (
+ 90DD2027167AA4350033BA25 /* Supporting Files */,
+ 90DD204D167AA4E10033BA25 /* MagicalRecord+ActionsSpec.m */,
+ 90DD2092167AAEFA0033BA25 /* NSManagedObjectContext+MagicalSavesSpec.m */,
+ );
+ path = "Mac Unit Tests";
+ sourceTree = "<group>";
+ };
+ 90DD2027167AA4350033BA25 /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ 90DD2048167AA4670033BA25 /* Cocoa.framework */,
+ 90DD2045167AA45B0033BA25 /* SenTestingKit.framework */,
+ 90DD2028167AA4350033BA25 /* Mac Unit Tests-Info.plist */,
+ 90DD202F167AA4350033BA25 /* Mac Unit Tests-Prefix.pch */,
+ );
+ name = "Supporting Files";
+ sourceTree = "<group>";
+ };
+ 90DD2034167AA44D0033BA25 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 90DD203C167AA44D0033BA25 /* libKiwi.a */,
+ 90DD203E167AA44D0033BA25 /* libKiwi-OSX.a */,
+ 90DD2040167AA44D0033BA25 /* KiwiTests.octest */,
+ 90DD2042167AA44D0033BA25 /* KiwiExamples.octest */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
C721C7A013D0A3750097AB6F = {
isa = PBXGroup;
children = (
@@ -632,6 +782,7 @@
C721C7E413D0C3A00097AB6F /* Mac App Unit Tests */,
C721C80213D0C3CD0097AB6F /* iOS App Unit Tests */,
C7C9A37013F43D3E002C5B0C /* Third Party */,
+ 90DD2026167AA4350033BA25 /* Mac Unit Tests */,
C721C7B313D0A3AF0097AB6F /* Frameworks */,
C721C7B113D0A3AF0097AB6F /* Products */,
);
@@ -642,6 +793,7 @@
children = (
C721C7DC13D0C3A00097AB6F /* Mac App Unit Tests.app */,
C721C7FD13D0C3CD0097AB6F /* iOS App Unit Tests.app */,
+ 90DD201D167AA4350033BA25 /* Mac Unit Tests.octest */,
);
name = Products;
sourceTree = "<group>";
@@ -651,6 +803,9 @@
children = (
C721C7E313D0C3A00097AB6F /* Foundation.framework */,
C721C7E213D0C3A00097AB6F /* CoreData.framework */,
+ 90DD201E167AA4350033BA25 /* SenTestingKit.framework */,
+ 90DD2020167AA4350033BA25 /* Cocoa.framework */,
+ 90DD2022167AA4350033BA25 /* Other Frameworks */,
);
name = Frameworks;
sourceTree = "<group>";
@@ -700,8 +855,8 @@
C721C82E13D0C6390097AB6F /* Frameworks */ = {
isa = PBXGroup;
children = (
- C76D3EF815718EC800B2D163 /* CoreGraphics.framework */,
- C76D3EF615718EBC00B2D163 /* UIKit.framework */,
+ 900E1CC61676E275005FFF1C /* UIKit.framework */,
+ 900E1CC41676E25E005FFF1C /* CoreGraphics.framework */,
C7D2DC29155AFE6D00B3A468 /* GHUnitIOS.framework */,
C74F8E551555E39D0008B054 /* OCHamcrestIOS.framework */,
C74F8E561555E39D0008B054 /* OCMockLibrary */,
@@ -877,6 +1032,7 @@
C7C9A37013F43D3E002C5B0C /* Third Party */ = {
isa = PBXGroup;
children = (
+ 90DD2033167AA44D0033BA25 /* Kiwi.xcodeproj */,
4B7116C015F8EE4600B64426 /* expecta */,
C7C9A37113F43D93002C5B0C /* JSONKit.h */,
C7C9A37213F43D93002C5B0C /* JSONKit.m */,
@@ -1001,8 +1157,6 @@
C70B6E7913D0F68400709450 /* NSManagedObjectContextHelperTests.m */,
C70B6E7B13D0F69A00709450 /* NSManagedObjectHelperTests.h */,
C70B6E7C13D0F69A00709450 /* NSManagedObjectHelperTests.m */,
- 4B7116BB15F8ED5A00B64426 /* SaveTests.h */,
- 4B7116BC15F8ED5A00B64426 /* SaveTests.m */,
);
name = "Core Tests";
sourceTree = "<group>";
@@ -1010,6 +1164,26 @@
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
+ 90DD201C167AA4350033BA25 /* Mac Unit Tests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 90DD2032167AA4350033BA25 /* Build configuration list for PBXNativeTarget "Mac Unit Tests" */;
+ buildPhases = (
+ 90DD2091167AA7700033BA25 /* Update Generated Core Data Entities */,
+ 90DD2018167AA4350033BA25 /* Sources */,
+ 90DD2019167AA4350033BA25 /* Frameworks */,
+ 90DD201A167AA4350033BA25 /* Resources */,
+ 90DD201B167AA4350033BA25 /* Run Unit Tests */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 90DD2044167AA4530033BA25 /* PBXTargetDependency */,
+ );
+ name = "Mac Unit Tests";
+ productName = "Mac Unit Tests";
+ productReference = 90DD201D167AA4350033BA25 /* Mac Unit Tests.octest */;
+ productType = "com.apple.product-type.bundle";
+ };
C721C7DB13D0C3A00097AB6F /* Mac App Unit Tests */ = {
isa = PBXNativeTarget;
buildConfigurationList = C721C7F613D0C3A00097AB6F /* Build configuration list for PBXNativeTarget "Mac App Unit Tests" */;
@@ -1018,9 +1192,7 @@
C721C7D813D0C3A00097AB6F /* Sources */,
C721C7D913D0C3A00097AB6F /* Frameworks */,
C721C7DA13D0C3A00097AB6F /* Resources */,
- C753897513DB6310002B2F57 /* Copy GHUnit into App Bundle */,
- C76AF7F313DBC33100CE2E05 /* Copy OCHamcrest into App Bundle */,
- FD73E54714AC4D5200922CA4 /* CopyFiles */,
+ FD73E54714AC4D5200922CA4 /* Copy Frameworks */,
);
buildRules = (
);
@@ -1058,7 +1230,7 @@
C721C7A213D0A3750097AB6F /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0450;
+ LastUpgradeCheck = 0460;
ORGANIZATIONNAME = "Magical Panda Software LLC";
};
buildConfigurationList = C721C7A513D0A3750097AB6F /* Build configuration list for PBXProject "Magical Record" */;
@@ -1071,15 +1243,71 @@
mainGroup = C721C7A013D0A3750097AB6F;
productRefGroup = C721C7B113D0A3AF0097AB6F /* Products */;
projectDirPath = "";
+ projectReferences = (
+ {
+ ProductGroup = 90DD2034167AA44D0033BA25 /* Products */;
+ ProjectRef = 90DD2033167AA44D0033BA25 /* Kiwi.xcodeproj */;
+ },
+ );
projectRoot = "";
targets = (
C721C7DB13D0C3A00097AB6F /* Mac App Unit Tests */,
C721C7FC13D0C3CD0097AB6F /* iOS App Unit Tests */,
+ 90DD201C167AA4350033BA25 /* Mac Unit Tests */,
);
};
/* End PBXProject section */
+/* Begin PBXReferenceProxy section */
+ 90DD203C167AA44D0033BA25 /* libKiwi.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = libKiwi.a;
+ remoteRef = 90DD203B167AA44D0033BA25 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ 90DD203E167AA44D0033BA25 /* libKiwi-OSX.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = "libKiwi-OSX.a";
+ remoteRef = 90DD203D167AA44D0033BA25 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ 90DD2040167AA44D0033BA25 /* KiwiTests.octest */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.cfbundle;
+ path = KiwiTests.octest;
+ remoteRef = 90DD203F167AA44D0033BA25 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ 90DD2042167AA44D0033BA25 /* KiwiExamples.octest */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.cfbundle;
+ path = KiwiExamples.octest;
+ remoteRef = 90DD2041167AA44D0033BA25 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+/* End PBXReferenceProxy section */
+
/* Begin PBXResourcesBuildPhase section */
+ 90DD201A167AA4350033BA25 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 90DD2090167AA7590033BA25 /* generateShorthandFile.rb in Resources */,
+ 90DD206B167AA6DF0033BA25 /* SingleEntityWithNoRelationships.plist in Resources */,
+ 90DD206C167AA6DF0033BA25 /* SingleEntityWithNoRelationships.json in Resources */,
+ 90DD206D167AA6DF0033BA25 /* SampleJSONDataForImport.json in Resources */,
+ 90DD206E167AA6DF0033BA25 /* SingleRelatedEntity.json in Resources */,
+ 90DD206F167AA6DF0033BA25 /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json in Resources */,
+ 90DD2070167AA6DF0033BA25 /* SingleEntityRelatedToMappedEntityUsingDefaults.json in Resources */,
+ 90DD2071167AA6DF0033BA25 /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json in Resources */,
+ 90DD2072167AA6DF0033BA25 /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json in Resources */,
+ 90DD2073167AA6DF0033BA25 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.json in Resources */,
+ 90DD2074167AA6DF0033BA25 /* SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
C721C7DA13D0C3A00097AB6F /* Resources */ = {
isa = PBXResourcesBuildPhase;