diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000..8e73b94cf --- /dev/null +++ b/.clang-format @@ -0,0 +1,13 @@ +BasedOnStyle: Chromium +AlignTrailingComments: true +BreakBeforeBraces: Allman +ColumnLimit: 0 +IndentWidth: 4 +KeepEmptyLinesAtTheStartOfBlocks: false +ObjCBlockIndentWidth: 4 +ObjCSpaceAfterProperty: true +ObjCSpaceBeforeProtocolList: true +PointerBindsToType: false +SpacesBeforeTrailingComments: 1 +TabWidth: 8 +UseTab: Never diff --git a/.cocoadocs.yml b/.cocoadocs.yml new file mode 100644 index 000000000..41ffd566a --- /dev/null +++ b/.cocoadocs.yml @@ -0,0 +1,12 @@ +additional_guides: + - https://github.com/magicalpanda/MagicalRecord/wiki/Installing-MagicalRecord + - https://github.com/magicalpanda/MagicalRecord/wiki/Getting-Started + - https://github.com/magicalpanda/MagicalRecord/wiki/Working-with-Managed-Object-Contexts + - https://github.com/magicalpanda/MagicalRecord/wiki/Creating-Entities + - https://github.com/magicalpanda/MagicalRecord/wiki/Deleting-Entities + - https://github.com/magicalpanda/MagicalRecord/wiki/Fetching-Entities + - https://github.com/magicalpanda/MagicalRecord/wiki/Saving + - https://github.com/magicalpanda/MagicalRecord/wiki/Usage-Patterns + - https://github.com/magicalpanda/MagicalRecord/wiki/Importing-Data + - https://github.com/magicalpanda/MagicalRecord/wiki/Logging + - https://github.com/magicalpanda/MagicalRecord/wiki/Upgrading-to-MagicalRecord-2.3 diff --git a/.gitignore b/.gitignore index c8f953d07..57b2bba39 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,5 @@ xcuserdata profile *.moved-aside +DerivedData +Carthage/Build diff --git a/.gitmodules b/.gitmodules index 3c22ed4c0..5048bacf6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "Project Files/Tests/Support/Vendor/Kiwi"] - path = Project Files/Tests/Support/Vendor/Kiwi - url = git://github.com/allending/Kiwi.git -[submodule "Project Files/Tests/Support/Vendor/Expecta"] - path = Project Files/Tests/Support/Vendor/Expecta - url = git@github.com:petejkim/expecta.git +[submodule "Carthage/Checkouts/expecta"] + path = Carthage/Checkouts/expecta + url = https://github.com/specta/expecta.git diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..1d7eb7148 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,7 @@ +language: objective-c +script: Support/Scripts/objc-build-scripts/cibuild +before_install: + - brew update + - if brew outdated | grep -qx xctool; then brew upgrade xctool; fi + +osx_image: xcode61 \ No newline at end of file diff --git a/Changelog.md b/CHANGELOG.md similarity index 92% rename from Changelog.md rename to CHANGELOG.md index 571b243ad..f1c383653 100644 --- a/Changelog.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog +## Version 2.3 +* Dynamic framework targets are provided for both OS X 10.8+ and iOS 8.0+ +* Logging is enabled by default, change the logging level using `+[MagicalRecord setLoggingLevel: MagicalRecordLogLevelOff];` — [see the documentation in the wiki](https://github.com/magicalpanda/MagicalRecord/wiki/Logging) +* CocoaLumberjack 2.0 support +* Enabling shorthand category method names can now be done by importing: + + ```objective-c + #import + #import + #import + ``` + Then calling `+[MagicalRecord enableShorthandMethods]`. + [See the documentation in the wiki](https://github.com/magicalpanda/MagicalRecord/wiki/Installing-MagicalRecord#shorthand-category-methods). + +* Support for running with Core Data's concurrency debugging checks enabled +* Many, many, many, many fixes to reported issues + ## Version 2.2 * Updated examples and fixed errors in README - [Tony Arnold](mailto:tony@thecocoabots.com) * Changes block saves to use child context of rootSavingContext so that large saves do not channel through the default context and block the main thread - r-peck @@ -51,7 +68,7 @@ * 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) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..57a363561 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,25 @@ +Thanks for contributing to this project! + +To make the process as easy as possible, we've got a few guidelines that we'd appreciate you following: + +## Filing Issues + +Before you file an issue, please ensure that: + +1. **It's a bug or a feature request** — if you're looking for help using MagicalRecord, please ask your question on [Stack Overflow](http://stackoverflow.com/). We monitor the [**MagicalRecord** tag](http://stackoverflow.com/questions/tagged/magicalrecord) so be sure to tag your question so that we see it +1. **Search for an existing issue** — there's a good chance you're not the only one experiencing the problem you've come to tell us about +2. **Include as much information as you can** — if we can't reproduce the problem you've filed, we can't fix it. Include crash logs, exception reports and code if you can. + +## We Prefer Pull Requests + +If you know exactly how to implement the feature being suggested or fix the bug being reported, please open a pull request instead of an issue. Pull requests are easier than patches or inline code blocks for discussing and merging the changes. Please ensure that you include tests in the Pull Request — we use XCTest with [Expecta](http://github.com/specta/expecta/). + +If you can't make the change yourself, please open an issue after making sure that one isn't already logged. + +## Contributing Code + +Fork this repository, make some great changes (preferably in a branch named for the topic of the changes you're making) and send a pull request! + +All code contributions should match our [coding conventions](/magicalpanda/MagicalRecord/wiki/Coding-Conventions). + +Thanks for reading the guidelines! diff --git a/Cartfile.private b/Cartfile.private new file mode 100644 index 000000000..1a41ee842 --- /dev/null +++ b/Cartfile.private @@ -0,0 +1 @@ +github "specta/expecta" ~> 1.0 diff --git a/Cartfile.resolved b/Cartfile.resolved new file mode 100644 index 000000000..51164a6b0 --- /dev/null +++ b/Cartfile.resolved @@ -0,0 +1 @@ +github "specta/expecta" "v1.0.1" diff --git a/Carthage/Checkouts/expecta b/Carthage/Checkouts/expecta new file mode 160000 index 000000000..9a4e64668 --- /dev/null +++ b/Carthage/Checkouts/expecta @@ -0,0 +1 @@ +Subproject commit 9a4e646685cd6a625b9fab95eef7d100f0e7cd95 diff --git a/Docs/Creating-Entities.md b/Docs/Creating-Entities.md new file mode 100644 index 000000000..d497e27ef --- /dev/null +++ b/Docs/Creating-Entities.md @@ -0,0 +1,13 @@ +# Creating Entities + +To create and insert a new instance of an Entity in the default context, you can use: + +```objective-c +Person *myPerson = [Person MR_createEntity]; +``` + +To create and insert an entity into specific context: + +```objective-c +Person *myPerson = [Person MR_createEntityInContext:otherContext]; +``` diff --git a/Docs/DefaultManagedObjectContext.md b/Docs/DefaultManagedObjectContext.md deleted file mode 100644 index 22453906e..000000000 --- a/Docs/DefaultManagedObjectContext.md +++ /dev/null @@ -1,26 +0,0 @@ - - -### Default Managed Object Context - -When using Core Data, you will deal with two types of objects the most: *NSManagedObject* and *NSManagedObjectContext*. MagicalRecord provides a single place for a default NSManagedObjectContext for use within your app. This is great for single threaded apps. You can easily get to this default context by calling: - - [NSManagedObjectContext MR_defaultContext]; - -This context will be used if a find or request method (described below) does not specify a specific context using the **inContext:** method overload. - -If you need to create a new Managed Object Context for use in other threads, based on the default persistent store that was creating using one of the setup methods, use: - - NSManagedObjectContext *myNewContext = [NSManagedObjectContext MR_context]; - -This will use the same object model and persistent store, but create an entirely new context for use with threads other than the main thread. - -And, if you want to make *myNewContext* the default for all fetch requests on the main thread: - - [NSManagedObjectContext MR_setDefaultContext:myNewContext]; - -MagicalRecord also has a helper method to hold on to a Managed Object Context in a thread's threadDictionary. This lets you access the correct NSManagedObjectContext instance no matter which thread you're calling from. This methods is: - - [NSManagedObjectContext MR_contextForCurrentThread]; - -**It is *highly* recommended that the default context is created and set using the main thread** - diff --git a/Docs/Deleting-Entities.md b/Docs/Deleting-Entities.md new file mode 100644 index 000000000..1c1715ba1 --- /dev/null +++ b/Docs/Deleting-Entities.md @@ -0,0 +1,25 @@ +# Deleting Entities + +To delete a single entity in the default context: + +```objective-c +[myPerson MR_deleteEntity]; +``` + +To delete the entity from a specific context: + +```objective-c +[myPerson MR_deleteEntityInContext:otherContext]; +``` + +To truncate all entities from the default context: + +```objective-c +[Person MR_truncateAll]; +``` + +To truncate all entities in a specific context: + +```objective-c +[Person MR_truncateAllInContext:otherContext]; +``` diff --git a/Docs/Fetching-Entities.md b/Docs/Fetching-Entities.md new file mode 100644 index 000000000..c21bbcc80 --- /dev/null +++ b/Docs/Fetching-Entities.md @@ -0,0 +1,129 @@ +# Fetching Entities + +#### Basic Finding + +Most methods in MagicalRecord return an `NSArray` of results. + +As an example, if you have an entity named *Person* related to a *Department* entity (as seen in many of [Apple's Core Data examples](.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdBasics.html#//apple_ref/doc/uid/TP40001650-TP1)), you can retrieve all of the *Person* entities from your persistent store using the following method: + +```objective-c +NSArray *people = [Person MR_findAll]; +``` + +To return the same entities sorted by a specific attribute: + +```objective-c +NSArray *peopleSorted = [Person MR_findAllSortedBy:@"LastName" + ascending:YES]; +``` + +To return the entities sorted by multiple attributes: + +```objective-c +NSArray *peopleSorted = [Person MR_findAllSortedBy:@"LastName,FirstName" + ascending:YES]; +``` + +To return the results sorted by multiple attributes with different values. If you don't provide a value for any attribute, it will default to whatever you've set in your model: + +```objective-c +NSArray *peopleSorted = [Person MR_findAllSortedBy:@"LastName:NO,FirstName" + ascending:YES]; + +// OR + +NSArray *peopleSorted = [Person MR_findAllSortedBy:@"LastName,FirstName:YES" + ascending:NO]; +``` + +If you have a unique way of retrieving a single object from your data store (such as an identifier attribute), you can use the following method: + +```objective-c +Person *person = [Person MR_findFirstByAttribute:@"FirstName" + withValue:@"Forrest"]; +``` + +#### Advanced Finding + +If you want to be more specific with your search, you can use a predicate: + +```objective-c +NSPredicate *peopleFilter = [NSPredicate predicateWithFormat:@"Department IN %@", @[dept1, dept2]]; +NSArray *people = [Person MR_findAllWithPredicate:peopleFilter]; +``` + +#### Returning an NSFetchRequest + +```objective-c +NSPredicate *peopleFilter = [NSPredicate predicateWithFormat:@"Department IN %@", departments]; +NSFetchRequest *people = [Person MR_requestAllWithPredicate:peopleFilter]; +``` + +For each of these single line calls, an `NSFetchRequest` and `NSSortDescriptor`s for any sorting criteria are created. + +#### Customizing the Request + +```objective-c +NSPredicate *peopleFilter = [NSPredicate predicateWithFormat:@"Department IN %@", departments]; + +NSFetchRequest *peopleRequest = [Person MR_requestAllWithPredicate:peopleFilter]; +[peopleRequest setReturnsDistinctResults:NO]; +[peopleRequest setReturnPropertiesNamed:@[@"FirstName", @"LastName"]]; + +NSArray *people = [Person MR_executeFetchRequest:peopleRequest]; +``` + +#### Find the number of entities + +You can also perform a count of all entities of a specific type in your persistent store: + +```objective-c +NSNumber *count = [Person MR_numberOfEntities]; +``` + +Or, if you're looking for a count of entities based on a predicate or some filter: + +```objective-c +NSNumber *count = [Person MR_numberOfEntitiesWithPredicate:...]; +``` + +There are also complementary methods which return `NSUInteger` rather than `NSNumber` instances: + +```objective-c ++ (NSUInteger) MR_countOfEntities; ++ (NSUInteger) MR_countOfEntitiesWithContext:(NSManagedObjectContext *)context; ++ (NSUInteger) MR_countOfEntitiesWithPredicate:(NSPredicate *)searchFilter; ++ (NSUInteger) MR_countOfEntitiesWithPredicate:(NSPredicate *)searchFilter + inContext:(NSManagedObjectContext *)context; +``` + +#### Aggregate Operations + +```objective-c +NSNumber *totalCalories = [CTFoodDiaryEntry MR_aggregateOperation:@"sum:" + onAttribute:@"calories" + withPredicate:predicate]; + +NSNumber *mostCalories = [CTFoodDiaryEntry MR_aggregateOperation:@"max:" + onAttribute:@"calories" + withPredicate:predicate]; + +NSArray *caloriesByMonth = [CTFoodDiaryEntry MR_aggregateOperation:@"sum:" + onAttribute:@"calories" + withPredicate:predicate + groupBy:@"month"]; +``` + +#### Finding entities in a specific context + +All find, fetch, and request methods have an `inContext:` method parameter that allows you to specify which managed object context you'd like to query: + +```objective-c +NSArray *peopleFromAnotherContext = [Person MR_findAllInContext:someOtherContext]; + +Person *personFromContext = [Person MR_findFirstByAttribute:@"lastName" + withValue:@"Gump" + inContext:someOtherContext]; + +NSUInteger count = [Person MR_numberOfEntitiesWithContext:someOtherContext]; +``` diff --git a/Docs/Fetching.md b/Docs/Fetching.md deleted file mode 100644 index f4640cb09..000000000 --- a/Docs/Fetching.md +++ /dev/null @@ -1,127 +0,0 @@ -### Fetching - -#### Basic Finding - -Most methods in MagicalRecord return an NSArray of results. So, if you have an Entity called Person, related to a Department (as seen in various Apple Core Data documentation), to get all the Person entities from your Persistent Store: - - //In order for this to work you need to add "#define MR_SHORTHAND" to your PCH file - NSArray *people = [Person findAll]; - - // Otherwise you can use the longer, namespaced version - NSArray *people = [Person MR_findAll]; - -Or, to have the results sorted by a property: - - NSArray *peopleSorted = [Person MR_findAllSortedBy:@"LastName" ascending:YES]; - -Or, to have the results sorted by multiple properties: - - NSArray *peopleSorted = [Person MR_findAllSortedBy:@"LastName,FirstName" ascending:YES]; - -If you have a unique way of retrieving a single object from your data store, you can get that object directly: - - Person *person = [Person MR_findFirstByAttribute:@"FirstName" withValue:@"Forrest"]; - -#### Advanced Finding - -If you want to be more specific with your search, you can send in a predicate: - - NSArray *departments = [NSArray arrayWithObjects:dept1, dept2, ..., nil]; - NSPredicate *peopleFilter = [NSPredicate predicateWithFormat:@"Department IN %@", departments]; - - NSArray *people = [Person MR_findAllWithPredicate:peopleFilter]; - -#### Returning an NSFetchRequest - - NSPredicate *peopleFilter = [NSPredicate predicateWithFormat:@"Department IN %@", departments]; - - NSArray *people = [Person MR_findAllWithPredicate:peopleFilter]; - -For each of these single line calls, the full stack of NSFetchRequest, NSSortDescriptors and a simple default error handling scheme (ie. logging to the console) is created. - -#### Customizing the Request - - NSPredicate *peopleFilter = [NSPredicate predicateWithFormat:@"Department IN %@", departments]; - - NSFetchRequest *peopleRequest = [Person MR_requestAllWithPredicate:peopleFilter]; - [peopleRequest setReturnsDistinctResults:NO]; - [peopleRequest setReturnPropertiesNamed:[NSArray arrayWithObjects:@"FirstName", @"LastName", nil]]; - ... - - NSArray *people = [Person MR_executeFetchRequest:peopleRequest]; - -#### Find the number of entities - -You can also perform a count of entities in your Store, that will be performed on the Store - - NSNumber *count = [Person MR_numberOfEntities]; - -Or, if you're looking for a count of entities based on a predicate or some filter: - - NSNumber *count = [Person MR_numberOfEntitiesWithPredicate:...]; - -There are also counterpart methods which return NSUInteger rather than NSNumbers: - -* countOfEntities -* countOfEntitiesWithContext:(NSManagedObjectContext *) -* countOfEntitiesWithPredicate:(NSPredicate *) -* countOfEntitiesWithPredicate:(NSPredicate *) inContext:(NSManagedObjectContext *) - -#### Aggregate Operations - - NSPredicate *predicate = [NSPredicate predicateWithFormat:@"diaryEntry.date == %@", today]; - int totalFat = [[CTFoodDiaryEntry MR_aggregateOperation:@"sum:" onAttribute:@"fatColories" withPredicate:predicate] intValue]; - int fattest = [[CTFoodDiaryEntry MR_aggregateOperation:@"max:" onAttribute:@"fatColories" withPredicate:predicate] intValue]; - -#### Finding from a different context - -All find, fetch, and request methods have an inContext: method parameter - - NSManagedObjectContext *someOtherContext = ...; - - NSArray *peopleFromAnotherContext = [Person MR_findAllInContext:someOtherContext]; - - ... - - Person *personFromContext = [Person MR_findFirstByAttribute:@"lastName" withValue:@"Gump" inContext:someOtherContext]; - - ... - - NSUInteger count = [Person MR_numberOfEntitiesWithContext:someOtherContext]; - - -## Creating new Entities - -When you need to create a new instance of an Entity, use: - - Person *myNewPersonInstance = [Person MR_createEntity]; - -or, to specify a context: - - NSManagedObjectContext *otherContext = ...; - - Person *myPerson = [Person MR_createInContext:otherContext]; - - -## Deleting Entities - -To delete a single entity: - - Person *p = ...; - [p MR_deleteEntity]; - -or, to specify a context: - - NSManagedObjectContext *otherContext = ...; - Person *deleteMe = ...; - - [deleteMe MR_deleteInContext:otherContext]; - -There is no delete *All Entities* or *truncate* operation in core data, so one is provided for you with Active Record for Core Data: - - [Person MR_truncateAll]; - -or, with a specific context: - - NSManagedObjectContext *otherContext = ...; - [Person MR_truncateAllInContext:otherContext]; \ No newline at end of file diff --git a/Docs/Getting-Started.md b/Docs/Getting-Started.md new file mode 100644 index 000000000..65334fd6c --- /dev/null +++ b/Docs/Getting-Started.md @@ -0,0 +1,84 @@ +To get started, import the `MagicalRecord.h` header file in your project's pch file. This will allow a global include of all the required headers. + +If you're using CocoaPods or MagicalRecord.framework, your import should look like: + +```objective-c +// Objective-C +#import +``` + +```swift +// Swift +import MagicalRecord +``` + +Otherwise, if you've added MagicalRecord's source files directly to your Objective-C project, your import should be: + +```objective-c +#import "MagicalRecord.h" +``` + +Next, somewhere in your app delegate, in either the `- applicationDidFinishLaunching: withOptions:` method, or `-awakeFromNib`, use **one** of the following setup calls with the **MagicalRecord** class: + +```objective-c ++ (void)setupCoreDataStack; ++ (void)setupAutoMigratingCoreDataStack; ++ (void)setupCoreDataStackWithInMemoryStore; ++ (void)setupCoreDataStackWithStoreNamed:(NSString *)storeName; ++ (void)setupCoreDataStackWithAutoMigratingSqliteStoreNamed:(NSString *)storeName; ++ (void)setupCoreDataStackWithStoreAtURL:(NSURL *)storeURL; ++ (void)setupCoreDataStackWithAutoMigratingSqliteStoreAtURL:(NSURL *)storeURL; +``` + +Each call instantiates one of each piece of the Core Data stack, and provides getter and setter methods for these instances. These well known instances to MagicalRecord, and are recognized as "defaults". + +When using the default SQLite data store with the `DEBUG` flag set, changing your model without creating a new model version will cause MagicalRecord to delete the old store and create a new one automatically. This can be a huge time saver — no more needing to uninstall and reinstall your app every time you make a change your data model! **Please be sure not to ship your app with `DEBUG` enabled: Deleting your app's data without telling the user about it is really bad form!** + +Before your app exits, you should call `+cleanUp` class method: + +```objective-c +[MagicalRecord cleanUp]; +``` + +This tidies up after MagicalRecord, tearing down our custom error handling and setting all of the Core Data stack created by MagicalRecord to nil. + +## iCloud-enabled Persistent Stores + +To take advantage of Apple's iCloud Core Data syncing, use **one** of the following setup methods in place of the standard methods listed in the previous section: + +```objective-c ++ (void)setupCoreDataStackWithiCloudContainer:(NSString *)containerID + localStoreNamed:(NSString *)localStore; + ++ (void)setupCoreDataStackWithiCloudContainer:(NSString *)containerID + contentNameKey:(NSString *)contentNameKey + localStoreNamed:(NSString *)localStoreName + cloudStorePathComponent:(NSString *)pathSubcomponent; + ++ (void)setupCoreDataStackWithiCloudContainer:(NSString *)containerID + contentNameKey:(NSString *)contentNameKey + localStoreNamed:(NSString *)localStoreName + cloudStorePathComponent:(NSString *)pathSubcomponent + completion:(void (^)(void))completion; + ++ (void)setupCoreDataStackWithiCloudContainer:(NSString *)containerID + localStoreAtURL:(NSURL *)storeURL; + ++ (void)setupCoreDataStackWithiCloudContainer:(NSString *)containerID + contentNameKey:(NSString *)contentNameKey + localStoreAtURL:(NSURL *)storeURL + cloudStorePathComponent:(NSString *)pathSubcomponent; + ++ (void)setupCoreDataStackWithiCloudContainer:(NSString *)containerID + contentNameKey:(NSString *)contentNameKey + localStoreAtURL:(NSURL *)storeURL + cloudStorePathComponent:(NSString *)pathSubcomponent + completion:(void (^)(void))completion; +``` + +For further details, please refer to [Apple's "iCloud Programming Guide for Core Data"](https://developer.apple.com/library/ios/documentation/DataManagement/Conceptual/UsingCoreDataWithiCloudPG/Introduction/Introduction.html#//apple_ref/doc/uid/TP40013491). + + +### Notes + +If you are managing multiple iCloud-enabled stores, we recommended that you use one of the longer setup methods that allows you to specify your own **contentNameKey**. The shorter setup methods automatically generate the **NSPersistentStoreUbiquitousContentNameKey** based on your app's bundle identifier (`CFBundleIdentifier`): diff --git a/Docs/GettingStarted.md b/Docs/GettingStarted.md deleted file mode 100644 index 3a241dc23..000000000 --- a/Docs/GettingStarted.md +++ /dev/null @@ -1,29 +0,0 @@ - -# Getting Started - -## Setting up the Core Data Stack - -To get started, first, import the header file *CoreData+MagicalRecord.h* in your project's pch file. This will allow a global include of all the required headers. -Next, somewhere in your app delegate, in either the applicationDidFinishLaunching:(UIApplication \*) withOptions:(NSDictionary \*) method, or awakeFromNib, use **one** of the following setup calls with the **MagicalRecord** class: - - + (void) setupCoreDataStack; - + (void) setupAutoMigratingDefaultCoreDataStack; - + (void) setupCoreDataStackWithInMemoryStore; - + (void) setupCoreDataStackWithStoreNamed:(NSString *)storeName; - + (void) setupCoreDataStackWithAutoMigratingSqliteStoreNamed:(NSString *)storeName; - -Each call instantiates one of each piece of the Core Data stack, and provides getter and setter methods for these instances. These well known instances to MagicalRecord, and are recognized as "defaults". - -When using the default sqlite data store with the DEBUG flag set, if you change your model without creating a new model version, Magical Record will delete the old store and create a new one automatically. No more uninstall/reinstall every time you make a change! - -And finally, before your app exits, you can use the clean up method: - - [MagicalRecord cleanUp]; - - -## Nested Contexts - -New in Core Data is support for related contexts. This is a super neat, and super fast feature. However, writing a wrapper that supports both is, frankly, more work that it's worth. However, the 1.8.3 version will be the last version that has dual support, and going forward, MagicalRecord will only work with the version of Core Data that supports nested managed object contexts. - -MagicalRecord provides a background saving queue so that saving all data is performed off the main thread, in the background. This means that it may be necessary to use *MR_saveNestedContexts* rather than the typical *MR_save* method in order to persist your changes all the way to your persistent store; - diff --git a/Docs/Importing-Data.md b/Docs/Importing-Data.md new file mode 100644 index 000000000..c66f88e95 --- /dev/null +++ b/Docs/Importing-Data.md @@ -0,0 +1,194 @@ +# Importing Data + +> We're working on updating this documentation — thanks for your patience. +> For the moment, please refer to [Importing Data Made Easy](http://www.cimgf.com/2012/05/29/importing-data-made-easy/) at [Cocoa Is My Girlfriend](http://www.cimgf.com/). Much of this document is based upon Saul's work in that original article. +> +> MagicalRecord Team + +MagicalRecord can help import data from standard NSObject instances such as NSArray and NSDictionary directly into your Core Data store. + +It's a two step process to import data from an external source into your persistent store using MagicalRecord: + +1. **Define how the data you're importing maps to your store** using your data model (it's pretty much codeless!) +2. **Perform the data import** + + +## Define Your Import + +Data from external sources can be wildly variable in quality and structure, so we've done our best to make MagicalRecord's import processes flexible. + +**MagicalRecord can import data from any Key-Value Coding (KVC) compliant object**. We usually find people work with `NSArray` and `NSDictionary` instances, but it works just fine with any KVC compliant `NSObject` subclass. + +MagicalRecord makes use of the Xcode data modeling tool's "**User Info**" values to allow configuration of import options and mappings possible without having to edit any code. + +

+Xcode's 'User Info' group in the data modeller +

+ +> **For reference**: The user info keys and values are held in an NSDictionary that is attached to every entity, attribute and relationship in your data model, and can be accessed via the `userInfo` method on your `NSEntityDescription` instances. + +Xcode's data modelling tools give you access to this dictionary via the Data Model Inspector's "User Info" group. When editing a data model, you can open this inspector using Xcode's menus — **View > Utilities > Show Data Model Inspector**, or press ⌥⌘3 on your keyboard. + +By default, MagicalRecord will automatically try to match attribute and relationship names with the keys in your imported data. **If an attribute or relationship name in your model matches a key in your data, you don't need to do anything — the value attached to the key will be imported automatically**. + +For example, if an attribute on an entity has the name 'firstName', MagicalRecord will assume the key in the data to import will also have a key of 'firstName' — if it does, your entity's `firstName` attribute will be set to the value of the `firstName` key in your data. + +More often than not, the keys and structure in the data you are importing will not match your entity's attributes and relationships. In this case, you will need to tell MagicalRecord how to map your import data's keys to the correct attribute or relationship in your data model. + + +Each of the three key objects we deal with in Core Data — Entities, Attributes and Relationships — have options that may need to be specified via user info keys: + +### Attributes + +| Key | Type | Purpose | +|-----|------|---------| +| **attributeValueClassName** | String | TBD | +| **dateFormat** | String | TBD. Defaults to `yyyy-MM-dd'T'HH:mm:ssz`. | +| **mappedKeyName** | String | Specifies the name of the keypath in your data to import the value from. Supports keypaths, delimited by `.`, eg. `location.latitude` | +| **mappedKeyName.[0-9]** | String | Specifies backup keypath names if the key specified by **mappedKeyName** doesn't exist. Supports the same syntax. | +| **useDefaultValueWhenNotPresent** | Boolean | If this is true, the default value for the attribute will be set on the imported instance if no value is found for any key. | + +### Entities + +| Key | Type | Purpose | +|-----|------|---------| +| **relatedByAttribute** | String | Specifies the attribute in the target of the relationship that links the two. | + +### Relationships + +| Key | Type | Purpose | +|-----|------|---------| +| **mappedKeyName** | String | Specifies the name of the keypath in your data to import the value from. Supports keypaths, delimited by `.`, eg. `location.latitude` | +| **mappedKeyName.[0-9]** | String | Specifies backup keypath names if the key specified by **mappedKeyName** doesn't exist. Supports the same syntax. | +| **relatedByAttribute** | String | Specifies the attribute in the target of the relationship that links the two. | +| **type** | String | TBD | + + +## Importing Objects + +To import data into your store using MagicalRecord, you need to know two things: + +1. The format of the data you're importing, and how it + +The basic idea behind MagicalRecord's importing is that you know the entity the data should be imported into, so you then write a single line of code tying this entity with the data to import. There are a couple of options to kick off the import process. + +To automatically create a new instance from the object, you can use the following, shorter approach: + +```objective-c +NSDictionary *contactInfo = // Result from JSON parser or some other source + +Person *importedPerson = [Person MR_importFromObject:contactInfo]; +``` + +You can also use a two-stage approach: + +```objective-c +NSDictionary *contactInfo = // Result from JSON parser or some other source + +Person *person = [Person MR_createEntity]; // This doesn't have to be a new entity +[person MR_importValuesForKeysWithObject:contactInfo]; +``` + +The two-stage approach can be helpful if you’re looking to update an existing object by overwriting its attributes. + +`+MR_importFromObject:` will look for an existing object based on the configured lookup value (see the _relatedByAttribute_ and _attributeNameID_). Also notice how this follows the built in paradigm of importing a list of key-value pairs in Cocoa, as well as following the safe way to import data. + +The `+MR_importFromObject:` class method provides a wrapper around creating a new object using the previously mentioned `-MR_importValuesForKeysWithObject:` instance method, and returns the newly created object filled with data. + +A key item of note is that both these methods are synchronous. While some imports will take longer than others, it’s still highly advisable to perform *all imports* in the background so as to not impact user interaction. As previously discussed, MagicalRecord provides a handy API to make using background threads more manageable: + +```objective-c +[MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *)localContext { + Person *importedPerson = [Person MR_importFromObject:personRecord inContext:localContext]; +}]; +``` + +## Importing Arrays + +It’s common for a list of data to be served using a JSON array, or you’re importing a large list of a single type of data. The details of importing such a list are taken care of in the `+MR_importFromArray:` class method. + +```objective-c +NSArray *arrayOfPeopleData = /// result from JSON parser +NSArray *people = [Person MR_importFromArray:arrayOfPeopleData]; +``` + +This method, like `+MR_importFromObject:` is also synchronous, so for background importing, use the previously mentioned helper method for performing blocks in the background. + +If your import data exactly matches your Core Data model, then read no further because the aforementioned methods are all you need to import your data into your Core Data store. However, if your data, like most, has little quirks and minor deviations, then read on, as we’ll walk through some of the features of MagicalRecord that will help you handle several commonly encountered deviations. + + +## Best Practice + +### Handling Bad Data When Importing + +APIs can often return data that has inconsistent formatting or values. The best way to handle this is to use the import category methods on your entity classes. There are three provided: + +Method | Purpose +--------------------------------|--------- +`- (BOOL) shouldImport;` | Called before an data is imported. Use this to cancel importing data on a specific instance of an entity by returning `NO`. +`- (void) willImport:(id)data;` | Called immediately before data is imported. +`- (void) didImport:(id)data;` | Called immediately after data has been imported. + + +Generally, if your data is bad you'll want to fix what the import did after an attempt has been made to import any values. + +A common scenario is importing JSON data where numeric strings can often be misinterpreted as an actual number. If you want to ensure that a value is imported as a string, you could do the following: + +```obj-c + +@interface MyGreatEntity + +@property(readwrite, nonatomic, copy) NSString *identifier; + +@end + +@implementation MyGreatEntity + +@dynamic identifier; + +- (void)didImport:(id)data +{ + if (NO == [data isKindOfClass:[NSDictionary class]]) { + return; + } + + NSDictionary *dataDictionary = (NSDictionary *)data; + + id identifierValue = dataDictionary[@"my_identifier"]; + + if ([identifierValue isKindOfClass:[NSNumber class]]) { + NSNumber *numberValue = (NSNumber *)identifierValue; + + self.identifier = [numberValue stringValue]; + } +} + +@end +``` + +### Deleting local records on import update + +Sometimes you will want to make sure that subsequent import operations not only update but also delete local records that are not included as part of the remote dataset. To do this, fetch all local records not included in this update via their `relatedByAttribute` (`id` in the example below) and remove them immediately before importing the new dataset. + +```objective-c +NSArray *arrayOfPeopleData = /// result from JSON parser +NSArray *people = [Person MR_importFromArray:arrayOfPeopleData]; +NSArray *idList = [arrayOfPeopleData valueForKey:@"id"]; +NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT(id IN %@)", idList]; +[Person MR_deleteAllMatchingPredicate:predicate]; +``` + +If you also want to make sure that related records are removed during this update, you can use similar logic as above but implement it in the `willImport:` method of `Person` + +```objective-c + +@implementation Person + +-(void)willImport:(id)data { + NSArray *idList = [data[@"posts"] valueForKey:@"id"]; + NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT(id IN %@) AND person.id == %@", idList, self.id]; + [Post MR_deleteAllMatchingPredicate:predicate]; +} +``` + +Source: http://stackoverflow.com/a/24252825/401092 diff --git a/Docs/Importing.md b/Docs/Importing.md deleted file mode 100644 index 70aee7919..000000000 --- a/Docs/Importing.md +++ /dev/null @@ -1,3 +0,0 @@ -# Data Import - -MagicalRecord will now import data from NSObjects into your Core Data store. [Documentation](https://github.com/magicalpanda/MagicalRecord/wiki/Data-Import) for this feature is forthcoming. diff --git a/Docs/Installation.md b/Docs/Installation.md deleted file mode 100644 index f20a98f4e..000000000 --- a/Docs/Installation.md +++ /dev/null @@ -1,21 +0,0 @@ -# Installation - -1. In your XCode Project, drag the *MagicalRecord* folder (under the main folder) into your project. -2. Add *CoreData+MagicalRecord.h* file to your PCH file or your AppDelegate file. -3. Optionally preceed the *CoreData+MagicalRecord.h* import with `#define MR_SHORTHAND` to your PCH file if you want to use MagicalRecord methods without the *MR_prefix* like `findAll` instead of `MR_findAll` -4. Start writing code! - -# Requirements - -MagicalRecord Platform Requirements: - -* iOS5.x or newer, or Mac OS 10.7 and newer -* ARC - -An iOS4 compatible version is available for use. Reference [tag 1.8.3](https://github.com/magicalpanda/MagicalRecord/tree/1.8.3). - -## ARC Support - -MagicalRecord fully supports ARC out of the box, there is no configuration necessary. -The last version to support manually managed memory is 1.8.3, and is available from the downloads page, or by switching to the 1.8.3 tag in the source. - diff --git a/Docs/Installing-MagicalRecord.md b/Docs/Installing-MagicalRecord.md new file mode 100644 index 000000000..61f3f6ec8 --- /dev/null +++ b/Docs/Installing-MagicalRecord.md @@ -0,0 +1,75 @@ +# Installing MagicalRecord + +**Adding MagicalRecord to your project is simple**: Just choose whichever method you're most comfortable with and follow the instructions below. + +## Using Carthage + +1. Add the following line to your `Cartfile`: + + ```yaml + github "MagicalPanda/MagicalRecord" + ``` + +2. Run `carthage update` in your project directory. +3. Drag the appropriate `MagicalRecord.framework` for your platform (located in `Carthage/Build/``) into your application’s Xcode project, and add it to the appropriate target(s). + + +## Using CocoaPods + +One of the easiest ways to integrate MagicalRecord in your project is to use [CocoaPods](http://cocoapods.org/): + +1. Add the following line to your `Podfile`: + + ````ruby + pod "MagicalRecord" + ```` + +2. In your project directory, run `pod update` +3. You should now be able to add `#import ` to any of your target's source files and begin using MagicalRecord! + +## Using an Xcode subproject + +Xcode sub-projects allow your project to use and build MagicalRecord as an implicit dependency. + +1. Add MagicalRecord to your project as a Git submodule: + + ```` + $ cd MyXcodeProjectFolder + $ git submodule add https://github.com/magicalpanda/MagicalRecord.git Vendor/MagicalRecord + $ git commit -m "Add MagicalRecord submodule" + ```` + +2. Drag `Vendor/MagicalRecord/MagicalRecord.xcproj` into your existing Xcode project +3. Navigate to your project's settings, then select the target you wish to add MagicalRecord to +4. Navigate to **Build Phases** and expand the **Link Binary With Libraries** section +5. Click the **+** and find the version of the MagicalRecord framework appropriate to your target's platform +6. You should now be able to add `#import ` to any of your target's source files and begin using MagicalRecord! + +> **Note** Please be aware that if you've set Xcode's **Link Frameworks Automatically** to **No** then you may need to add the CoreData.framework to your project on iOS, as UIKit does not include Core Data by default. On OS X, Cocoa includes Core Data. + +# Shorthand Category Methods + +By default, all of the category methods that MagicalRecord provides are prefixed with `MR_`. This is inline with [Apple's recommendation not to create unadorned category methods to avoid naming clashes](https://developer.apple.com/library/mac/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html#//apple_ref/doc/uid/TP40011210-CH6-SW4). + +If you like, you can include the following headers to use shorter, non-prefixed category methods: + +```objective-c +#import +#import +#import +``` + +If you're using Swift, you'll need to add these imports to your target's Objective-C bridging header. + +Once you've included the headers, you should call the `+[MagicalRecord enableShorthandMethods]` class method _before_ you setup/use MagicalRecord: + +```objective-c +- (void)theMethodWhereYouSetupMagicalRecord +{ + [MagicalRecord enableShorthandMethods]; + + // Setup MagicalRecord as per usual +} +``` + +**Please note that we do not offer support for this feature**. If it doesn't work, [please file an issue](https://github.com/magicalpanda/MagicalRecord/issues/new) and we'll fix it when we can. diff --git a/Docs/Logging.md b/Docs/Logging.md index ec6fb0267..5d75fbc0e 100644 --- a/Docs/Logging.md +++ b/Docs/Logging.md @@ -1,6 +1,44 @@ ## Logging -MagicalRecord has logging built in to every fetch request and other Core Data operation. When errors occur when fetching or saving data, these errors are captured by MagicalRecord. By default, these logs use NSLog to present logging information. However, if you have CocoaLumberjack installed in your project, MagicalRecord will use CocoaLumberjack and it's configuration to send logs to their proper output. -All logging in MagicalRecord can be disabled by placing this define preprocessor statement prior to the main import of CoreData+MagicalRecord.h +MagicalRecord has logging built in to most of its interactions with Core Data. When errors occur during fetching or saving data, these errors are captured and (if you've enabled them) logged to the console. - #define MR_ENABLE_ACTIVE_RECORD_LOGGING 0 +Logging is configured to output debugging messages (**MagicalRecordLoggingLevelDebug**) by default in debug builds, and will output error messages (**MagicalRecordLoggingLevelError**) in release builds. + +Logging can be configured by calling `[MagicalRecord setLoggingLevel:];` using one of the predefined logging levels: + +- **MagicalRecordLogLevelOff**: Don't log anything +- **MagicalRecordLoggingLevelError**: Log all errors +- **MagicalRecordLoggingLevelWarn**: Log warnings and errors +- **MagicalRecordLoggingLevelInfo**: Log informative, warning and error messages +- **MagicalRecordLoggingLevelDebug**: Log all debug, informative, warning and error messages +- **MagicalRecordLoggingLevelVerbose**: Log verbose diagnostic, informative, warning and error messages + +The logging level defaults to `MagicalRecordLoggingLevelWarn`. + +## CocoaLumberjack + +If it's available, MagicalRecord will direct its logs to [CocoaLumberjack](https://github.com/CocoaLumberjack/CocoaLumberjack). All you need to do is make sure you've imported CocoaLumberjack before you import MagicalRecord, like so: + +```objective-c +// Objective-C +#import +#import +``` + +```swift +// Swift +import CocoaLumberjack +import MagicalRecord +``` + +## Disabling Logging Completely + +For most people this should be unnecessary. Setting the logging level to **MagicalRecordLogLevelOff** will ensure that no logs are printed. + +Even when using `MagicalRecordLogLevelOff`, a very quick check may be performed whenever a log call is made. If you absolutely need to disable the logging, you will need to define the following when compiling MagicalRecord: + +```objective-c +#define MR_LOGGING_DISABLED 1 +``` + +Please note that this will only work if you've added MagicalRecord's source to your own project. You can also add this to the MagicalRecord project's `OTHER_CFLAGS` as `-DMR_LOGGING_DISABLED=1`. diff --git a/Docs/Resources.md b/Docs/Other-Resources.md similarity index 83% rename from Docs/Resources.md rename to Docs/Other-Resources.md index ee297233b..8a918d54a 100644 --- a/Docs/Resources.md +++ b/Docs/Other-Resources.md @@ -1,7 +1,6 @@ - # Resources -## Third Party Blog Entries -The following blog entries highlight how to install and use aspects of Magical Record. + +The following articles highlight how to install and use aspects of MagicalRecord: * [How to make Programming with Core Data Pleasant](http://yannickloriot.com/2012/03/magicalrecord-how-to-make-programming-with-core-data-pleasant/) * [Using Core Data with MagicalRecord](http://ablfx.com/blog/2012/03/using-coredata-magicalrecord/) diff --git a/Docs/Saving-Entities.md b/Docs/Saving-Entities.md new file mode 100644 index 000000000..a8f70e822 --- /dev/null +++ b/Docs/Saving-Entities.md @@ -0,0 +1,148 @@ +# Saving Entities + +## When should I save? + +In general, your app should save to it's persistent store(s) when data changes. Some applications choose to save on application termination, however this shouldn't be necessary in most circumstances — in fact, **if you're only saving when your app terminates, you're risking data loss**! What happens if your app crashes? The user will lose all the changes they've made — that's a terrible experience, and easily avoided. + +If you find that saving is taking a long time, there are a couple of things you should consider doing: + +1. **Save in a background thread**: MagicalRecord provides a simple, clean API for making changes to your entities and subsequently saving them in a background thread — for example: + ````objective-c + [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) { + + // Do your work to be saved here, against the `localContext` instance + // Everything you do in this block will occur on a background thread + + } completion:^(BOOL success, NSError *error) { + [application endBackgroundTask:bgTask]; + bgTask = UIBackgroundTaskInvalid; + }]; + ```` + +2. **Break the task down into smaller saves**: tasks like importing large amounts of data should always be broken down into smaller chunks. There's no one-size-fits all rule for how much data you should be saving in one go, so you'll need to measure your application's performance using a tool like Apple's Instruments and tune appropriately. + + +## Handling Long-running Saves + +### On iOS + +When an application terminates on iOS, it is given a small window of opportunity to tidy up and save any data to disk. If you know that a save operation is likely to take a while, the best approach is to request an extension to your application's expiration, like so: + +````objective-c +UIApplication *application = [UIApplication sharedApplication]; + +__block UIBackgroundTaskIdentifier bgTask = [application beginBackgroundTaskWithExpirationHandler:^{ + [application endBackgroundTask:bgTask]; + bgTask = UIBackgroundTaskInvalid; +}]; + +[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) { + + // Do your work to be saved here + +} completion:^(BOOL success, NSError *error) { + [application endBackgroundTask:bgTask]; + bgTask = UIBackgroundTaskInvalid; +}]; +```` + +Be sure to carefully [read the documentation for `beginBackgroundTaskWithExpirationHandler`](https://developer.apple.com/library/iOS/documentation/UIKit/Reference/UIApplication_Class/Reference/Reference.html#//apple_ref/occ/instm/UIApplication/beginBackgroundTaskWithExpirationHandler:), as inappropriately or unnecessarily extending your application's lifetime may earn your app a rejection from the App Store. + +### On OS X + +On OS X Mavericks (10.9) and later, App Nap can cause your application to act as though it is effectively terminated when it is in the background. If you know that a save operation is likely to take a while, the best approach is to disable automatic and sudden termination temporarily (assuming that your app supports these features): + +````objective-c +NSProcessInfo *processInfo = [NSProcessInfo processInfo]; + +[processInfo disableSuddenTermination]; +[processInfo disableAutomaticTermination:@"Application is currently saving to persistent store"]; + +[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) { + + // Do your work to be saved here + +} completion:^(BOOL success, NSError *error) { + [processInfo enableSuddenTermination]; + [processInfo enableAutomaticTermination:@"Application has finished saving to the persistent store"]; +}]; +```` + +As with the iOS approach, be sure to [read the documentation on NSProcessInfo](https://developer.apple.com/library/mac/documentation/cocoa/reference/foundation/Classes/NSProcessInfo_Class/Reference/Reference.html) before implementing this approach in your app. + +--- + +## Changes to saving in MagicalRecord 2.3.0 + +### Context For Current Thread Deprecation + +In earlier releases of MagicalRecord, we provided methods to retrieve the managed object context for the thread that the method was called on. Unfortunately, **it's not possible to return the context for the currently executing thread in a reliable manner** anymore. Grand Central Dispatch (GCD) makes no guarantees that a queue will be executed on a single thread, and our approach was based upon the older NSThread API while CoreData has transitioned to use GCD. For more details, please see Saul's post "[Why contextForCurrentThread Doesn't Work in MagicalRecord](http://saulmora.com/2013/09/15/why-contextforcurrentthread-doesn-t-work-in-magicalrecord/)". + +In MagicalRecord 2.3.0, we continue to use `+MR_contextForCurrentThread` internally in a few places to maintain compatibility with older releases. These methods are deprecated, and you will be warned if you use them. + +In particular, **do not use `+MR_contextForCurrentThread` from within any of the `+[MagicalRecord saveWithBlock:…]` methods — the returned context may not be correct!** + +If you'd like to begin preparing for the change now, please use the method variants that accept a "context" parameter, and use the context that's passed to you in the `+[MagicalRecord saveWithBlock:…]` method block. Instead of: + +```objective-c +[MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) { + NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createEntity]; + // … +}]; +``` + +You should now use: + +```objective-c +[MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) { + NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createEntityInContext:localContext]; + // … +}]; +``` + +**When MagicalRecord 3.0 is released, the context for current thread methods will be removed entirely**. The methods that do not accept a "context" parameter will move to using the default context of the default stack — please see the MagicalRecord 3.0 release notes for more details. + +--- + +## Changes to saving in MagicalRecord 2.2.0 + +In MagicalRecord 2.2, the APIs for saving were revised to behave more consistently, and also to follow naming patterns present in Core Data. Extensive work has gone into adding automated tests that ensure the save methods (both new and deprecated) continue to work as expected through future updates. + +`MR_save` has been temporarily restored to it's original state of running synchronously on the current thread, and saving to the persistent store. However, the __`MR_save` method is marked as deprecated and will be removed in the next major release of MagicalRecord (version 3.0)__. You should use `MR_saveToPersistentStoreAndWait` if you want the same behaviour in future versions of the library. + +### New Methods +The following methods have been added: + +#### NSManagedObjectContext+MagicalSaves +- `- (void) MR_saveOnlySelfWithCompletion:(MRSaveCompletionHandler)completion;` +- `- (void) MR_saveToPersistentStoreWithCompletion:(MRSaveCompletionHandler)completion;` +- `- (void) MR_saveOnlySelfAndWait;` +- `- (void) MR_saveToPersistentStoreAndWait;` +- `- (void) MR_saveWithOptions:(MRSaveContextOptions)mask completion:(MRSaveCompletionHandler)completion;` + +#### __MagicalRecord+Actions__ +- `+ (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block;` +- `+ (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block completion:(MRSaveCompletionHandler)completion;` +- `+ (void) saveWithBlockAndWait:(void(^)(NSManagedObjectContext *localContext))block;` +- `+ (void) saveUsingCurrentThreadContextWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(MRSaveCompletionHandler)completion;` +- `+ (void) saveUsingCurrentThreadContextWithBlockAndWait:(void (^)(NSManagedObjectContext *localContext))block;` + +### Deprecations + +The following methods have been deprecated in favour of newer alternatives, and will be removed in MagicalRecord 3.0: + +#### NSManagedObjectContext+MagicalSaves +- `- (void) MR_save;` +- `- (void) MR_saveWithErrorCallback:(void(^)(NSError *error))errorCallback;` +- `- (void) MR_saveInBackgroundCompletion:(void (^)(void))completion;` +- `- (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback;` +- `- (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion;` +- `- (void) MR_saveNestedContexts;` +- `- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback;` +- `- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion;` + +### MagicalRecord+Actions +- `+ (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block;` +- `+ (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block;` +- `+ (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block completion:(void(^)(void))completion;` +- `+ (void) saveInBackgroundUsingCurrentContextWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(void (^)(void))completion errorHandler:(void (^)(NSError *error))errorHandler;` diff --git a/Docs/Saving.md b/Docs/Saving.md deleted file mode 100644 index 8b5e10718..000000000 --- a/Docs/Saving.md +++ /dev/null @@ -1,44 +0,0 @@ -### Changes to saving - -The APIs for saving have been revised to behave more consistently, and also to follow naming patterns present in Core Data. Extensive work has gone into adding automated tests that ensure the save methods (both new and deprecated) continue to work as expected through future updates. - -`MR_save` has been temporarily restored to it's original state of running synchronously on the current thread, and saving to the persistent store. However, the __`MR_save` method is marked as deprecated and will be removed in the next major release of MagicalRecord (version 3.0)__. You should use `MR_saveToPersistentStoreAndWait` if you want the same behaviour in future versions of the library. - -### New Methods -The following methods have been added: - -#### NSManagedObjectContext+MagicalSaves -- `- (void) MR_saveOnlySelfWithCompletion:(MRSaveCompletionHandler)completion;` -- `- (void) MR_saveToPersistentStoreWithCompletion:(MRSaveCompletionHandler)completion;` -- `- (void) MR_saveOnlySelfAndWait;` -- `- (void) MR_saveToPersistentStoreAndWait;` -- `- (void) MR_saveWithOptions:(MRSaveContextOptions)mask completion:(MRSaveCompletionHandler)completion;` - -#### __MagicalRecord+Actions__ -- `+ (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block;` -- `+ (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block completion:(MRSaveCompletionHandler)completion;` -- `+ (void) saveWithBlockAndWait:(void(^)(NSManagedObjectContext *localContext))block;` -- `+ (void) saveUsingCurrentThreadContextWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(MRSaveCompletionHandler)completion;` -- `+ (void) saveUsingCurrentThreadContextWithBlockAndWait:(void (^)(NSManagedObjectContext *localContext))block;` - -### Deprecations - -The following methods have been deprecated in favour of newer alternatives, and will be removed in MagicalRecord 3.0: - -#### NSManagedObjectContext+MagicalSaves -- `- (void) MR_save;` -- `- (void) MR_saveWithErrorCallback:(void(^)(NSError *error))errorCallback;` -- `- (void) MR_saveInBackgroundCompletion:(void (^)(void))completion;` -- `- (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback;` -- `- (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion;` -- `- (void) MR_saveNestedContexts;` -- `- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback;` -- `- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion;` - -### MagicalRecord+Actions -- `+ (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block;` -- `+ (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block;` -- `+ (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block completion:(void(^)(void))completion;` -- `+ (void) saveInBackgroundUsingCurrentContextWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(void (^)(void))completion errorHandler:(void (^)(NSError *error))errorHandler;` - - diff --git a/Docs/Support.md b/Docs/Support.md deleted file mode 100644 index 634bdf728..000000000 --- a/Docs/Support.md +++ /dev/null @@ -1,44 +0,0 @@ -##License - - Copyright (c) 2010-2013, Magical Panda Software, LLC - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, - copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following - conditions: - - -- Provide attribution to Magical Panda Software, LLC and (optionally) link to the MagicalRecord open source repository - - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - - -## Support - -MagicalRecord is provided free of charge. For Support, you have a few choices: - - -* Ask your support question on [Stackoverflow.com](http://stackoverflow.com), and tag your question with **MagicalRecord**. The core team will be notified of your question only if you mark your question with this tag. The general Stack Overflow community is provided the opportunity to answer the question to help you faster, and to reap the reputation points. If the community is unable to answer, we'll try to step in and answer your question. -* If you believe you have found a bug in MagicalRecord, please submit a support ticket on the [Github Issues page for MagicalRecord](http://github.com/magicalpanda/magicalrecord/issues). We'll get to them as soon as we can. Please do **NOT** as general questions on the issue tracker. All questions will be immedialy closed and unanswered. -* For more personal or immediate support, [MagicalPanda](http://magicalpanda.com) is available for hire to consult on your project. - - -## Twitter - -Follow [@MagicalRecord](http://twitter.com/magicalrecord) on twitter to stay up to date on twitter with the latest updates to MagicalRecord. - diff --git a/Docs/Threads.md b/Docs/Threads.md index 00eee0ea7..63e861f74 100644 --- a/Docs/Threads.md +++ b/Docs/Threads.md @@ -1,40 +1,64 @@ - - ## Performing Core Data operations on Threads MagicalRecord also provides some handy methods to set up background context for use with threading. The background saving operations are inspired by the UIView animation block methods, with few minor differences: * The block in which you add your data saving code will never be on the main thread. -* a single NSManagedObjectContext is provided for your operations. +* a single NSManagedObjectContext is provided for your operations. For example, if we have Person entity, and we need to set the firstName and lastName fields, this is how you would use MagicalRecord to setup a background context for your use: - Person *person = ...; - [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext){ - - Person *localPerson = [person MR_inContext:localContext]; +```objective-c +Person *person; // Retrieve person entity +[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) { + + Person *localPerson = [person MR_inContext:localContext]; + + localPerson.firstName = @"John"; + localPerson.lastName = @"Appleseed"; + +}]; +``` - localPerson.firstName = @"John"; - localPerson.lastName = @"Appleseed"; - - }]; - In this method, the specified block provides you with the proper context in which to perform your operations, you don't need to worry about setting up the context so that it tells the Default Context that it's done, and should update because changes were performed on another thread. To perform an action after this save block is completed, you can fill in a completion block: - Person *person = ...; - [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext){ - - Person *localPerson = [person MR_inContext:localContext]; - - localPerson.firstName = @"John"; - localPerson.lastName = @"Appleseed"; - - } completion:^(BOOL success, NSError *error) { - - self.everyoneInTheDepartment = [Person findAll]; - - }]; - -This completion block is called on the main thread (queue), so this is also safe for triggering UI updates. \ No newline at end of file +```objective-c +Person *person; // Retrieve person entity +[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext){ + + Person *localPerson = [person MR_inContext:localContext]; + + localPerson.firstName = @"John"; + localPerson.lastName = @"Appleseed"; + +} completion:^(BOOL success, NSError *error) { + + self.everyoneInTheDepartment = [Person findAll]; + +}]; +``` + +This completion block is called on the main thread (queue), so this is also safe for triggering UI updates. + +### Perform blocks synchronously + +If you want to have your code wait until the save block is done, use `[MagicalRecord saveWithBlockAndWait:]`. + +## Creating custom contexts + +If you need to create a custom context, you can do so by using `[NSManagedObjectContext MR_context];`. This will return a new context of type `NSPrivateQueueConcurrencyType`, with the root saving context as it's parent. + +To perform operations on the context's queue, use `[context performBlock:]` or `[context performBlockAndWait:]`. + +To save the context, you can use one of the following: + +* `[context MR_saveOnlySelfWithCompletion:]` - Save asynchronously to self and it's parent, but not to the persistent store +* `[context MR_saveToPersistentStoreWithCompletion:]` - Save asynchronously all the way down to the persistent store +* `[context MR_saveOnlySelfAndWait]` - Save synchronously to self and it's parent, but not to the persistent store +* `[context MR_saveToPersistentStoreAndWait]` - Save synchronously all the way down to the persistent store + +## Debugging Core Data threading-related issues +You can enable core data threading assertions by adding `-com.apple.CoreData.ConcurrencyDebug 1` to your scheme's launch parameters. This will stop your app and open the debugger every time your app tries to do a context operation on the wrong thread. This is very helpful, especially in finding bugs that are rare and hard to reproduce. + +More info on this can be found in the "225 - What's New in Core Data" session from WWDC 2014. diff --git a/Docs/Working-with-Managed-Object-Contexts.md b/Docs/Working-with-Managed-Object-Contexts.md new file mode 100644 index 000000000..e2bb5d767 --- /dev/null +++ b/Docs/Working-with-Managed-Object-Contexts.md @@ -0,0 +1,85 @@ +# Working with Managed Object Contexts + +## Creating New Contexts + +A variety of simple class methods are provided to help you create new contexts: + +- `+ [NSManagedObjectContext MR_newContext]`: Sets the default context as it's parent context. Has a concurrency type of **NSPrivateQueueConcurrencyType**. +- `+ [NSManagedObjectContext MR_newMainQueueContext]`: Has a concurrency type of ** NSMainQueueConcurrencyType**. +- `+ [NSManagedObjectContext MR_newPrivateQueueContext]`: Has a concurrency type of **NSPrivateQueueConcurrencyType**. +- `+ [NSManagedObjectContext MR_newContextWithParent:…]`: Allows you to specify the parent context that will be set. Has a concurrency type of **NSPrivateQueueConcurrencyType**. +- `+ [NSManagedObjectContext MR_newContextWithStoreCoordinator:…]`: Allows you to specify the persistent store coordinator for the new context. Has a concurrency type of **NSPrivateQueueConcurrencyType**. + +## The Default Context + +When working with Core Data, you will regularly deal with two main objects: `NSManagedObject` and `NSManagedObjectContext`. + +MagicalRecord provides a simple class method to retrieve a default `NSManagedObjectContext` that can be used throughout your app. This context operates on the main thread, and is great for simple, single-threaded apps. + +To access the default context, call: + +```objective-c +NSManagedObjectContext *defaultContext = [NSManagedObjectContext MR_defaultContext]; +``` + +This context will be used throughout MagicalRecord in any method that uses a context, but does not provde a specific managed object context parameter. + +If you need to create a new managed object context for use in non-main threads, use the following method: + +```objective-c +NSManagedObjectContext *myNewContext = [NSManagedObjectContext MR_newContext]; +``` + +This will create a new managed object context which has the same object model and persistent store as the default context, but is safe for use on another thread. It automatically sets the default context as it's parent context. + +If you'd like to make your `myNewContext` instance the default for all fetch requests, use the following class method: + +```objective-c +[NSManagedObjectContext MR_setDefaultContext:myNewContext]; +``` + +> **NOTE:** It is *highly* recommended that the default context is created and set on the main thread using a managed object context with a concurrency type of `NSMainQueueConcurrencyType`. + + +## Performing Work on Background Threads + +MagicalRecord provides methods to set up and work with contexts for use in background threads. The background saving operations are inspired by the UIView animation block methods, with a few minor differences: + +* The block in which you make changes to your entities will never be executed on the main thread. +* A single **NSManagedObjectContext** is provided for you within these blocks. + +For example, if we have Person entity, and we need to set the firstName and lastName fields, this is how you would use MagicalRecord to setup a background context for your use: + +```objective-c +Person *person = ...; + +[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext){ + + Person *localPerson = [person MR_inContext:localContext]; + localPerson.firstName = @"John"; + localPerson.lastName = @"Appleseed"; + +}]; +``` + +In this method, the specified block provides you with the proper context in which to perform your operations, you don't need to worry about setting up the context so that it tells the Default Context that it's done, and should update because changes were performed on another thread. + +To perform an action after this save block is completed, you can fill in a completion block: + +```objective-c +Person *person = ...; + +[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext){ + + Person *localPerson = [person MR_inContext:localContext]; + localPerson.firstName = @"John"; + localPerson.lastName = @"Appleseed"; + +} completion:^(BOOL success, NSError *error) { + + self.everyoneInTheDepartment = [Person findAll]; + +}]; +``` + +This completion block is called on the main thread (queue), so this is also safe for triggering UI updates. diff --git a/Docs/iCloud.md b/Docs/iCloud.md deleted file mode 100644 index c0cbd2d86..000000000 --- a/Docs/iCloud.md +++ /dev/null @@ -1,14 +0,0 @@ - -## iCloud Support - - Apps built for iOS5+ and OSX Lion 10.7.2+ can take advantage of iCloud to sync Core Data stores. To implement this functionality with MagicalRecord, use **one** of the following setup calls instead of those listed in the previous section: - - + (void) setupCoreDataStackWithiCloudContainer:(NSString *)icloudBucket localStoreNamed:(NSString *)localStore; - + (void) setupCoreDataStackWithiCloudContainer:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)pathSubcomponent; - + (void) setupCoreDataStackWithiCloudContainer:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)pathSubcomponent completion:(void(^)(void))completion; - -For further details, and to ensure that your application is suitable for iCloud, please see [Apple's iCloud Notes](https://developer.apple.com/library/ios/#releasenotes/DataManagement/RN-iCloudCoreData/_index.html). - -In particular note that the first helper method, + (void) setupCoreDataStackWithiCloudContainer:(NSString \*)icloudBucket localStoreNamed:(NSString \*)localStore, automatically generates the **NSPersistentStoreUbiquitousContentNameKey** based on your application's Bundle Identifier. - -If you are managing multiple different iCloud stores it is highly recommended that you use one of the other helper methods to specify your own **contentNameKey** diff --git a/LICENSE b/LICENSE index 4b9553cd8..287f101c1 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ - Copyright (c) 2010, Magical Panda Software, LLC + Copyright (c) 2010-2015, Magical Panda Software, LLC Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation @@ -8,10 +8,14 @@ copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + * Link to the MagicalRecord Repository at http:/github.com/magicalpanda/magicalrecord in the credits section of your application The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + This software license is in accordance with the standard MIT License. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND diff --git a/MagicalRecord.podspec b/MagicalRecord.podspec index 69f8a434f..89e2015ea 100644 --- a/MagicalRecord.podspec +++ b/MagicalRecord.podspec @@ -1,20 +1,22 @@ Pod::Spec.new do |s| s.name = 'MagicalRecord' - s.version = '2.2.0' + s.version = '2.3.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',:branch=>'develop', :tag => '2.2' } + s.author = { 'Saul Mora' => 'saul@magicalpanda.com', 'Tony Arnold' => 'tony@thecocoabots.com' } + s.source = { :git => 'https://github.com/magicalpanda/MagicalRecord.git', :tag => "v#{s.version}" } s.description = 'Handy fetching, threading and data import helpers to make Core Data a little easier to use.' - s.source_files = 'MagicalRecord/**/*.{h,m}' - s.framework = 'CoreData' s.requires_arc = true + s.ios.deployment_target = '6.1' + s.osx.deployment_target = '10.8' + + s.framework = 'CoreData' + s.header_dir = 'MagicalRecord' + s.source_files = 'MagicalRecord/**/*.{h,m}' + s.prefix_header_contents = <<-EOS +#import +#import +EOS - def s.post_install(target) - prefix_header = config.project_pods_root + target.prefix_header_filename - prefix_header.open('a') do |file| - file.puts(%{#ifdef __OBJC__\n#define MR_SHORTHAND\n#import "CoreData+MagicalRecord.h"\n#endif}) - end - end end diff --git a/MagicalRecord.xcodeproj/project.pbxproj b/MagicalRecord.xcodeproj/project.pbxproj new file mode 100644 index 000000000..0f09a2dd5 --- /dev/null +++ b/MagicalRecord.xcodeproj/project.pbxproj @@ -0,0 +1,2663 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1352E5841B175E6200182E53 /* MagicalRecord.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C7DD72D4150F832A00216827 /* MagicalRecord.h */; }; + 1352E5851B175E6200182E53 /* MagicalImportFunctions.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C7DD729C150F832A00216827 /* MagicalImportFunctions.h */; }; + 1352E5861B175E6200182E53 /* NSAttributeDescription+MagicalDataImport.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C7DD729E150F832A00216827 /* NSAttributeDescription+MagicalDataImport.h */; }; + 1352E5871B175E6200182E53 /* NSEntityDescription+MagicalDataImport.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C7DD72A0150F832A00216827 /* NSEntityDescription+MagicalDataImport.h */; }; + 1352E5881B175E6200182E53 /* NSNumber+MagicalDataImport.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C7DD72A2150F832A00216827 /* NSNumber+MagicalDataImport.h */; }; + 1352E5891B175E6200182E53 /* NSObject+MagicalDataImport.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C7DD72A4150F832A00216827 /* NSObject+MagicalDataImport.h */; }; + 1352E58A1B175E6200182E53 /* NSRelationshipDescription+MagicalDataImport.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C7DD72A6150F832A00216827 /* NSRelationshipDescription+MagicalDataImport.h */; }; + 1352E58B1B175E6200182E53 /* NSString+MagicalDataImport.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C7DD72A8150F832A00216827 /* NSString+MagicalDataImport.h */; }; + 1352E58C1B175E6200182E53 /* NSManagedObject+MagicalAggregation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C7DD72AB150F832A00216827 /* NSManagedObject+MagicalAggregation.h */; }; + 1352E58D1B175E6200182E53 /* NSManagedObject+MagicalDataImport.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C7DD72AD150F832A00216827 /* NSManagedObject+MagicalDataImport.h */; }; + 1352E58E1B175E6200182E53 /* NSManagedObject+MagicalFinders.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C7DD72AF150F832A00216827 /* NSManagedObject+MagicalFinders.h */; }; + 1352E58F1B175E6200182E53 /* NSManagedObject+MagicalRecord.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C7DD72B1150F832A00216827 /* NSManagedObject+MagicalRecord.h */; }; + 1352E5901B175E6200182E53 /* NSManagedObject+MagicalRequests.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C7DD72B3150F832A00216827 /* NSManagedObject+MagicalRequests.h */; }; + 1352E5911B175E6200182E53 /* NSManagedObjectContext+MagicalChainSave.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9BB566891A2C44C4004174B3 /* NSManagedObjectContext+MagicalChainSave.h */; }; + 1352E5921B175E6200182E53 /* NSManagedObjectContext+MagicalObserving.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C7DD72B6150F832A00216827 /* NSManagedObjectContext+MagicalObserving.h */; }; + 1352E5931B175E6200182E53 /* NSManagedObjectContext+MagicalRecord.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C7DD72B8150F832A00216827 /* NSManagedObjectContext+MagicalRecord.h */; }; + 1352E5941B175E6200182E53 /* NSManagedObjectContext+MagicalSaves.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C7DD72BA150F832A00216827 /* NSManagedObjectContext+MagicalSaves.h */; }; + 1352E5951B175E6200182E53 /* NSManagedObjectContext+MagicalThreading.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C7DD72BC150F832A00216827 /* NSManagedObjectContext+MagicalThreading.h */; }; + 1352E5961B175E6200182E53 /* NSManagedObjectModel+MagicalRecord.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C7DD72BE150F832A00216827 /* NSManagedObjectModel+MagicalRecord.h */; }; + 1352E5971B175E6200182E53 /* NSPersistentStore+MagicalRecord.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C7DD72C0150F832A00216827 /* NSPersistentStore+MagicalRecord.h */; }; + 1352E5981B175E6200182E53 /* NSPersistentStoreCoordinator+MagicalRecord.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C7DD72C2150F832A00216827 /* NSPersistentStoreCoordinator+MagicalRecord.h */; }; + 1352E5991B175E6200182E53 /* MagicalRecord+Actions.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C7DD72C5150F832A00216827 /* MagicalRecord+Actions.h */; }; + 1352E59A1B175E6200182E53 /* MagicalRecord+ErrorHandling.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C7DD72C7150F832A00216827 /* MagicalRecord+ErrorHandling.h */; }; + 1352E59B1B175E6200182E53 /* MagicalRecord+iCloud.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C7DD72C9150F832A00216827 /* MagicalRecord+iCloud.h */; }; + 1352E59C1B175E6200182E53 /* MagicalRecord+Options.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C7DD72CB150F832A00216827 /* MagicalRecord+Options.h */; }; + 1352E59D1B175E6200182E53 /* MagicalRecord+Setup.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C7DD72CD150F832A00216827 /* MagicalRecord+Setup.h */; }; + 1352E59E1B175E6200182E53 /* MagicalRecord+ShorthandMethods.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 90B05B891B02452A00354056 /* MagicalRecord+ShorthandMethods.h */; }; + 1352E59F1B175E6200182E53 /* MagicalRecordDeprecationMacros.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 902CE11E18F6133E0024F47C /* MagicalRecordDeprecationMacros.h */; }; + 1352E5A01B175E6200182E53 /* MagicalRecordInternal.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C7DD72D1150F832A00216827 /* MagicalRecordInternal.h */; }; + 1352E5A11B175E6200182E53 /* MagicalRecordLogging.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 90FEC08B18F42DEA002FFC2F /* MagicalRecordLogging.h */; }; + 1352E5A21B175E6200182E53 /* MagicalRecordShorthandMethodAliases.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 90B05B851B02450900354056 /* MagicalRecordShorthandMethodAliases.h */; }; + 1352E5F21B176AF600182E53 /* MagicalRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72D4150F832A00216827 /* MagicalRecord.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1352E5F31B176AF600182E53 /* MagicalImportFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD729C150F832A00216827 /* MagicalImportFunctions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1352E5F41B176AF600182E53 /* NSAttributeDescription+MagicalDataImport.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD729E150F832A00216827 /* NSAttributeDescription+MagicalDataImport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1352E5F51B176AF600182E53 /* NSEntityDescription+MagicalDataImport.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72A0150F832A00216827 /* NSEntityDescription+MagicalDataImport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1352E5F61B176AF600182E53 /* NSNumber+MagicalDataImport.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72A2150F832A00216827 /* NSNumber+MagicalDataImport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1352E5F71B176AF600182E53 /* NSObject+MagicalDataImport.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72A4150F832A00216827 /* NSObject+MagicalDataImport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1352E5F81B176AF600182E53 /* NSRelationshipDescription+MagicalDataImport.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72A6150F832A00216827 /* NSRelationshipDescription+MagicalDataImport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1352E5F91B176AF600182E53 /* NSString+MagicalDataImport.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72A8150F832A00216827 /* NSString+MagicalDataImport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1352E5FA1B176AF600182E53 /* NSManagedObject+MagicalAggregation.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72AB150F832A00216827 /* NSManagedObject+MagicalAggregation.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1352E5FB1B176AF600182E53 /* NSManagedObject+MagicalDataImport.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72AD150F832A00216827 /* NSManagedObject+MagicalDataImport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1352E5FC1B176AF600182E53 /* NSManagedObject+MagicalFinders.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72AF150F832A00216827 /* NSManagedObject+MagicalFinders.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1352E5FD1B176AF600182E53 /* NSManagedObject+MagicalRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72B1150F832A00216827 /* NSManagedObject+MagicalRecord.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1352E5FE1B176AF600182E53 /* NSManagedObject+MagicalRequests.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72B3150F832A00216827 /* NSManagedObject+MagicalRequests.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1352E5FF1B176AF600182E53 /* NSManagedObjectContext+MagicalChainSave.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BB566891A2C44C4004174B3 /* NSManagedObjectContext+MagicalChainSave.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1352E6001B176AF600182E53 /* NSManagedObjectContext+MagicalObserving.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72B6150F832A00216827 /* NSManagedObjectContext+MagicalObserving.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1352E6011B176AF600182E53 /* NSManagedObjectContext+MagicalRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72B8150F832A00216827 /* NSManagedObjectContext+MagicalRecord.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1352E6021B176AF600182E53 /* NSManagedObjectContext+MagicalSaves.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72BA150F832A00216827 /* NSManagedObjectContext+MagicalSaves.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1352E6031B176AF600182E53 /* NSManagedObjectContext+MagicalThreading.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72BC150F832A00216827 /* NSManagedObjectContext+MagicalThreading.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1352E6041B176AF600182E53 /* NSManagedObjectModel+MagicalRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72BE150F832A00216827 /* NSManagedObjectModel+MagicalRecord.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1352E6051B176AF600182E53 /* NSPersistentStore+MagicalRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72C0150F832A00216827 /* NSPersistentStore+MagicalRecord.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1352E6061B176AF600182E53 /* NSPersistentStoreCoordinator+MagicalRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72C2150F832A00216827 /* NSPersistentStoreCoordinator+MagicalRecord.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1352E6071B176AF600182E53 /* MagicalRecord+Actions.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72C5150F832A00216827 /* MagicalRecord+Actions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1352E6081B176AF600182E53 /* MagicalRecord+ErrorHandling.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72C7150F832A00216827 /* MagicalRecord+ErrorHandling.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1352E6091B176AF600182E53 /* MagicalRecord+iCloud.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72C9150F832A00216827 /* MagicalRecord+iCloud.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1352E60A1B176AF600182E53 /* MagicalRecord+Options.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72CB150F832A00216827 /* MagicalRecord+Options.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1352E60B1B176AF600182E53 /* MagicalRecord+Setup.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72CD150F832A00216827 /* MagicalRecord+Setup.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1352E60C1B176AF600182E53 /* MagicalRecord+ShorthandMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = 90B05B891B02452A00354056 /* MagicalRecord+ShorthandMethods.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1352E60D1B176AF600182E53 /* MagicalRecordDeprecationMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 902CE11E18F6133E0024F47C /* MagicalRecordDeprecationMacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1352E60E1B176AF700182E53 /* MagicalRecordInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72D1150F832A00216827 /* MagicalRecordInternal.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1352E60F1B176AF700182E53 /* MagicalRecordLogging.h in Headers */ = {isa = PBXBuildFile; fileRef = 90FEC08B18F42DEA002FFC2F /* MagicalRecordLogging.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1352E6101B176AF700182E53 /* MagicalRecordShorthandMethodAliases.h in Headers */ = {isa = PBXBuildFile; fileRef = 90B05B851B02450900354056 /* MagicalRecordShorthandMethodAliases.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 581ECBF7187F660B00084FEE /* MultipleEntitiesWithNoPrimaryKey.json in Resources */ = {isa = PBXBuildFile; fileRef = 581ECBF6187F660B00084FEE /* MultipleEntitiesWithNoPrimaryKey.json */; }; + 581ECBF8187F660B00084FEE /* MultipleEntitiesWithNoPrimaryKey.json in Resources */ = {isa = PBXBuildFile; fileRef = 581ECBF6187F660B00084FEE /* MultipleEntitiesWithNoPrimaryKey.json */; }; + 581ECBF9187F663100084FEE /* ImportMultipleEntitiesWithNoPrimaryKeyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 581ECBEB187F63FF00084FEE /* ImportMultipleEntitiesWithNoPrimaryKeyTests.m */; }; + 581ECBFA187F663200084FEE /* ImportMultipleEntitiesWithNoPrimaryKeyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 581ECBEB187F63FF00084FEE /* ImportMultipleEntitiesWithNoPrimaryKeyTests.m */; }; + 9004F4DE1A94C76A00A61312 /* libMagicalRecord.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = C7CF97BB1749843F008D9D13 /* libMagicalRecord.dylib */; }; + 9004F4DF1A94C76E00A61312 /* libMagicalRecord.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C7CF97AB17498414008D9D13 /* libMagicalRecord.a */; }; + 9004F4E21A94CBCF00A61312 /* DifferentClassNameMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492817C2F42100BC2B5C /* DifferentClassNameMapping.m */; }; + 9004F4E31A94CBCF00A61312 /* _AbstractRelatedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099490E17C2F42100BC2B5C /* _AbstractRelatedEntity.m */; }; + 9004F4E41A94CBCF00A61312 /* SingleRelatedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099493817C2F42100BC2B5C /* SingleRelatedEntity.m */; }; + 9004F4E51A94CBCF00A61312 /* _SingleEntityRelatedToMappedEntityWithSecondaryMappings.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491E17C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityWithSecondaryMappings.m */; }; + 9004F4E61A94CBCF00A61312 /* NSManagedObjectContext+ChainSaveTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BB566931A2C47B3004174B3 /* NSManagedObjectContext+ChainSaveTests.m */; }; + 9004F4E71A94CBCF00A61312 /* _SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491617C2F42100BC2B5C /* _SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m */; }; + 9004F4E81A94CBCF00A61312 /* NSPersistentStoreHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF977017498275008D9D13 /* NSPersistentStoreHelperTests.m */; }; + 9004F4E91A94CBCF00A61312 /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099493017C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m */; }; + 9004F4EA1A94CBCF00A61312 /* _SingleEntityRelatedToMappedEntityUsingDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491817C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityUsingDefaults.m */; }; + 9004F4EB1A94CBCF00A61312 /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099493217C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m */; }; + 9004F4EC1A94CBCF00A61312 /* NSManagedObjectHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF976C17498275008D9D13 /* NSManagedObjectHelperTests.m */; }; + 9004F4ED1A94CBCF00A61312 /* ConcreteRelatedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492617C2F42100BC2B5C /* ConcreteRelatedEntity.m */; }; + 9004F4EE1A94CBCF00A61312 /* MagicalDataImportTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF978E174982AD008D9D13 /* MagicalDataImportTestCase.m */; }; + 9004F4EF1A94CBCF00A61312 /* AbstractRelatedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492417C2F42100BC2B5C /* AbstractRelatedEntity.m */; }; + 9004F4F01A94CBCF00A61312 /* MappedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492A17C2F42100BC2B5C /* MappedEntity.m */; }; + 9004F4F11A94CBCF00A61312 /* MagicalRecordTestBase.m in Sources */ = {isa = PBXBuildFile; fileRef = 90BB1C4518651539001BBFBB /* MagicalRecordTestBase.m */; }; + 9004F4F21A94CBCF00A61312 /* _SingleRelatedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492217C2F42100BC2B5C /* _SingleRelatedEntity.m */; }; + 9004F4F31A94CBCF00A61312 /* ImportSingleEntityWithNoRelationshipsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF978B174982AD008D9D13 /* ImportSingleEntityWithNoRelationshipsTests.m */; }; + 9004F4F41A94CBCF00A61312 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099493417C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.m */; }; + 9004F4F51A94CBCF00A61312 /* EntityWithoutEntityNameMethod.m in Sources */ = {isa = PBXBuildFile; fileRef = 90AA772418F79CCC00D49377 /* EntityWithoutEntityNameMethod.m */; }; + 9004F4F61A94CBCF00A61312 /* ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9787174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m */; }; + 9004F4F71A94CBCF00A61312 /* ImportMultipleEntitiesWithNoPrimaryKeyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 581ECBEB187F63FF00084FEE /* ImportMultipleEntitiesWithNoPrimaryKeyTests.m */; }; + 9004F4F81A94CBCF00A61312 /* ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9789174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m */; }; + 9004F4F91A94CBCF00A61312 /* NSPersistentStoreCoordinatorHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF977217498275008D9D13 /* NSPersistentStoreCoordinatorHelperTests.m */; }; + 9004F4FA1A94CBCF00A61312 /* NSManagedObjectContextHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF976A17498275008D9D13 /* NSManagedObjectContextHelperTests.m */; }; + 9004F4FB1A94CBCF00A61312 /* ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9788174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m */; }; + 9004F4FC1A94CBCF00A61312 /* _SingleEntityWithNoRelationships.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492017C2F42100BC2B5C /* _SingleEntityWithNoRelationships.m */; }; + 9004F4FD1A94CBCF00A61312 /* FixtureHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9B6C17498B5C008D9D13 /* FixtureHelpers.m */; }; + 9004F4FE1A94CBCF00A61312 /* ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF978A174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m */; }; + 9004F4FF1A94CBCF00A61312 /* TestModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 9099490817C2F3D400BC2B5C /* TestModel.xcdatamodeld */; }; + 9004F5001A94CBCF00A61312 /* NSManagedObjectContext+MagicalSavesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 902CE13818F61E410024F47C /* NSManagedObjectContext+MagicalSavesTests.m */; }; + 9004F5011A94CBCF00A61312 /* SingleEntityRelatedToMappedEntityUsingDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492E17C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityUsingDefaults.m */; }; + 9004F5021A94CBCF00A61312 /* _SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491A17C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m */; }; + 9004F5031A94CBCF00A61312 /* ImportSingleRelatedEntityTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 90BB1C3E1864F662001BBFBB /* ImportSingleRelatedEntityTests.m */; }; + 9004F5041A94CBCF00A61312 /* MagicalRecord+ActionsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 902CE12B18F61A2F0024F47C /* MagicalRecord+ActionsTests.m */; }; + 9004F5051A94CBCF00A61312 /* NSManagedObject+MagicalRecordTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 90AA771718F79A3300D49377 /* NSManagedObject+MagicalRecordTests.m */; }; + 9004F5061A94CBCF00A61312 /* ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9786174982AD008D9D13 /* ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m */; }; + 9004F5071A94CBCF00A61312 /* _SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491C17C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m */; }; + 9004F5081A94CBCF00A61312 /* MagicalRecord+StackTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF976817498275008D9D13 /* MagicalRecord+StackTests.m */; }; + 9004F5091A94CBCF00A61312 /* _MappedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491417C2F42100BC2B5C /* _MappedEntity.m */; }; + 9004F50A1A94CBCF00A61312 /* _DifferentClassNameMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491217C2F42100BC2B5C /* _DifferentClassNameMapping.m */; }; + 9004F50B1A94CBCF00A61312 /* _ConcreteRelatedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491017C2F42100BC2B5C /* _ConcreteRelatedEntity.m */; }; + 9004F50C1A94CBCF00A61312 /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492C17C2F42100BC2B5C /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m */; }; + 9004F50D1A94CBCF00A61312 /* SingleEntityWithNoRelationships.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099493617C2F42100BC2B5C /* SingleEntityWithNoRelationships.m */; }; + 9004F5121A94CBCF00A61312 /* TestModel.xcdatamodeld in Resources */ = {isa = PBXBuildFile; fileRef = 9099490817C2F3D400BC2B5C /* TestModel.xcdatamodeld */; }; + 9004F5131A94CBCF00A61312 /* SampleJSONDataForImport.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4917498985008D9D13 /* SampleJSONDataForImport.json */; }; + 9004F5141A94CBCF00A61312 /* SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4A17498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json */; }; + 9004F5151A94CBCF00A61312 /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4B17498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json */; }; + 9004F5161A94CBCF00A61312 /* MultipleEntitiesWithNoPrimaryKey.json in Resources */ = {isa = PBXBuildFile; fileRef = 581ECBF6187F660B00084FEE /* MultipleEntitiesWithNoPrimaryKey.json */; }; + 9004F5171A94CBCF00A61312 /* SingleEntityRelatedToMappedEntityUsingDefaults.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4C17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingDefaults.json */; }; + 9004F5181A94CBCF00A61312 /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4D17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json */; }; + 9004F5191A94CBCF00A61312 /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4E17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json */; }; + 9004F51A1A94CBCF00A61312 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4F17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.json */; }; + 9004F51B1A94CBCF00A61312 /* SingleEntityWithNoRelationships.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B5017498985008D9D13 /* SingleEntityWithNoRelationships.json */; }; + 9004F51C1A94CBCF00A61312 /* SingleEntityWithNoRelationships.plist in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B5117498985008D9D13 /* SingleEntityWithNoRelationships.plist */; }; + 9004F51D1A94CBCF00A61312 /* SingleRelatedEntity.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B5217498985008D9D13 /* SingleRelatedEntity.json */; }; + 9004F5231A94CBF300A61312 /* MagicalRecord.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 905D07181A63DE190076B54E /* MagicalRecord.framework */; }; + 9004F5271A94CBF900A61312 /* DifferentClassNameMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492817C2F42100BC2B5C /* DifferentClassNameMapping.m */; }; + 9004F5281A94CBF900A61312 /* _AbstractRelatedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099490E17C2F42100BC2B5C /* _AbstractRelatedEntity.m */; }; + 9004F5291A94CBF900A61312 /* SingleRelatedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099493817C2F42100BC2B5C /* SingleRelatedEntity.m */; }; + 9004F52A1A94CBF900A61312 /* _SingleEntityRelatedToMappedEntityWithSecondaryMappings.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491E17C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityWithSecondaryMappings.m */; }; + 9004F52B1A94CBF900A61312 /* NSManagedObjectContext+ChainSaveTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BB566931A2C47B3004174B3 /* NSManagedObjectContext+ChainSaveTests.m */; }; + 9004F52C1A94CBF900A61312 /* _SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491617C2F42100BC2B5C /* _SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m */; }; + 9004F52D1A94CBF900A61312 /* NSPersistentStoreHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF977017498275008D9D13 /* NSPersistentStoreHelperTests.m */; }; + 9004F52E1A94CBF900A61312 /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099493017C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m */; }; + 9004F52F1A94CBF900A61312 /* _SingleEntityRelatedToMappedEntityUsingDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491817C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityUsingDefaults.m */; }; + 9004F5301A94CBF900A61312 /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099493217C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m */; }; + 9004F5311A94CBF900A61312 /* NSManagedObjectHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF976C17498275008D9D13 /* NSManagedObjectHelperTests.m */; }; + 9004F5321A94CBF900A61312 /* ConcreteRelatedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492617C2F42100BC2B5C /* ConcreteRelatedEntity.m */; }; + 9004F5331A94CBF900A61312 /* MagicalDataImportTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF978E174982AD008D9D13 /* MagicalDataImportTestCase.m */; }; + 9004F5341A94CBF900A61312 /* AbstractRelatedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492417C2F42100BC2B5C /* AbstractRelatedEntity.m */; }; + 9004F5351A94CBF900A61312 /* MappedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492A17C2F42100BC2B5C /* MappedEntity.m */; }; + 9004F5361A94CBF900A61312 /* MagicalRecordTestBase.m in Sources */ = {isa = PBXBuildFile; fileRef = 90BB1C4518651539001BBFBB /* MagicalRecordTestBase.m */; }; + 9004F5371A94CBF900A61312 /* _SingleRelatedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492217C2F42100BC2B5C /* _SingleRelatedEntity.m */; }; + 9004F5381A94CBF900A61312 /* ImportSingleEntityWithNoRelationshipsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF978B174982AD008D9D13 /* ImportSingleEntityWithNoRelationshipsTests.m */; }; + 9004F5391A94CBF900A61312 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099493417C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.m */; }; + 9004F53A1A94CBF900A61312 /* EntityWithoutEntityNameMethod.m in Sources */ = {isa = PBXBuildFile; fileRef = 90AA772418F79CCC00D49377 /* EntityWithoutEntityNameMethod.m */; }; + 9004F53B1A94CBF900A61312 /* ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9787174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m */; }; + 9004F53C1A94CBF900A61312 /* ImportMultipleEntitiesWithNoPrimaryKeyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 581ECBEB187F63FF00084FEE /* ImportMultipleEntitiesWithNoPrimaryKeyTests.m */; }; + 9004F53D1A94CBF900A61312 /* ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9789174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m */; }; + 9004F53E1A94CBF900A61312 /* NSPersistentStoreCoordinatorHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF977217498275008D9D13 /* NSPersistentStoreCoordinatorHelperTests.m */; }; + 9004F53F1A94CBF900A61312 /* NSManagedObjectContextHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF976A17498275008D9D13 /* NSManagedObjectContextHelperTests.m */; }; + 9004F5401A94CBF900A61312 /* ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9788174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m */; }; + 9004F5411A94CBF900A61312 /* _SingleEntityWithNoRelationships.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492017C2F42100BC2B5C /* _SingleEntityWithNoRelationships.m */; }; + 9004F5421A94CBF900A61312 /* FixtureHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9B6C17498B5C008D9D13 /* FixtureHelpers.m */; }; + 9004F5431A94CBF900A61312 /* ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF978A174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m */; }; + 9004F5441A94CBF900A61312 /* TestModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 9099490817C2F3D400BC2B5C /* TestModel.xcdatamodeld */; }; + 9004F5451A94CBF900A61312 /* NSManagedObjectContext+MagicalSavesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 902CE13818F61E410024F47C /* NSManagedObjectContext+MagicalSavesTests.m */; }; + 9004F5461A94CBF900A61312 /* SingleEntityRelatedToMappedEntityUsingDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492E17C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityUsingDefaults.m */; }; + 9004F5471A94CBF900A61312 /* _SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491A17C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m */; }; + 9004F5481A94CBF900A61312 /* ImportSingleRelatedEntityTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 90BB1C3E1864F662001BBFBB /* ImportSingleRelatedEntityTests.m */; }; + 9004F5491A94CBF900A61312 /* MagicalRecord+ActionsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 902CE12B18F61A2F0024F47C /* MagicalRecord+ActionsTests.m */; }; + 9004F54A1A94CBF900A61312 /* NSManagedObject+MagicalRecordTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 90AA771718F79A3300D49377 /* NSManagedObject+MagicalRecordTests.m */; }; + 9004F54B1A94CBF900A61312 /* ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9786174982AD008D9D13 /* ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m */; }; + 9004F54C1A94CBF900A61312 /* _SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491C17C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m */; }; + 9004F54D1A94CBF900A61312 /* MagicalRecord+StackTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF976817498275008D9D13 /* MagicalRecord+StackTests.m */; }; + 9004F54E1A94CBF900A61312 /* _MappedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491417C2F42100BC2B5C /* _MappedEntity.m */; }; + 9004F54F1A94CBF900A61312 /* _DifferentClassNameMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491217C2F42100BC2B5C /* _DifferentClassNameMapping.m */; }; + 9004F5501A94CBF900A61312 /* _ConcreteRelatedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491017C2F42100BC2B5C /* _ConcreteRelatedEntity.m */; }; + 9004F5511A94CBF900A61312 /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492C17C2F42100BC2B5C /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m */; }; + 9004F5521A94CBF900A61312 /* SingleEntityWithNoRelationships.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099493617C2F42100BC2B5C /* SingleEntityWithNoRelationships.m */; }; + 9004F5571A94CBF900A61312 /* TestModel.xcdatamodeld in Resources */ = {isa = PBXBuildFile; fileRef = 9099490817C2F3D400BC2B5C /* TestModel.xcdatamodeld */; }; + 9004F5581A94CBF900A61312 /* SampleJSONDataForImport.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4917498985008D9D13 /* SampleJSONDataForImport.json */; }; + 9004F5591A94CBF900A61312 /* SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4A17498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json */; }; + 9004F55A1A94CBF900A61312 /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4B17498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json */; }; + 9004F55B1A94CBF900A61312 /* MultipleEntitiesWithNoPrimaryKey.json in Resources */ = {isa = PBXBuildFile; fileRef = 581ECBF6187F660B00084FEE /* MultipleEntitiesWithNoPrimaryKey.json */; }; + 9004F55C1A94CBF900A61312 /* SingleEntityRelatedToMappedEntityUsingDefaults.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4C17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingDefaults.json */; }; + 9004F55D1A94CBF900A61312 /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4D17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json */; }; + 9004F55E1A94CBF900A61312 /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4E17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json */; }; + 9004F55F1A94CBF900A61312 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4F17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.json */; }; + 9004F5601A94CBF900A61312 /* SingleEntityWithNoRelationships.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B5017498985008D9D13 /* SingleEntityWithNoRelationships.json */; }; + 9004F5611A94CBF900A61312 /* SingleEntityWithNoRelationships.plist in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B5117498985008D9D13 /* SingleEntityWithNoRelationships.plist */; }; + 9004F5621A94CBF900A61312 /* SingleRelatedEntity.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B5217498985008D9D13 /* SingleRelatedEntity.json */; }; + 9004F5681A94CC0E00A61312 /* MagicalRecord.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 905D073B1A63DE690076B54E /* MagicalRecord.framework */; }; + 9004F57A1A94D7D300A61312 /* MagicalRecord.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 905D07181A63DE190076B54E /* MagicalRecord.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9004F57D1A94D7F100A61312 /* MagicalRecord.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 905D073B1A63DE690076B54E /* MagicalRecord.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 90171E1B17C329CC00E7084A /* FixtureHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9B6C17498B5C008D9D13 /* FixtureHelpers.m */; }; + 90171E1C17C329CD00E7084A /* FixtureHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9B6C17498B5C008D9D13 /* FixtureHelpers.m */; }; + 90171E1D17C32ACE00E7084A /* TestModel.xcdatamodeld in Resources */ = {isa = PBXBuildFile; fileRef = 9099490817C2F3D400BC2B5C /* TestModel.xcdatamodeld */; }; + 90171E1E17C32AD300E7084A /* TestModel.xcdatamodeld in Resources */ = {isa = PBXBuildFile; fileRef = 9099490817C2F3D400BC2B5C /* TestModel.xcdatamodeld */; }; + 9021D9E31AFB34D6001C80BA /* MagicalRecordTestHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 9021D9E21AFB34D6001C80BA /* MagicalRecordTestHelpers.m */; }; + 9021D9E41AFB34D6001C80BA /* MagicalRecordTestHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 9021D9E21AFB34D6001C80BA /* MagicalRecordTestHelpers.m */; }; + 9021D9E51AFB34D6001C80BA /* MagicalRecordTestHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 9021D9E21AFB34D6001C80BA /* MagicalRecordTestHelpers.m */; }; + 9021D9E61AFB34D6001C80BA /* MagicalRecordTestHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 9021D9E21AFB34D6001C80BA /* MagicalRecordTestHelpers.m */; }; + 902CE12C18F61A2F0024F47C /* MagicalRecord+ActionsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 902CE12B18F61A2F0024F47C /* MagicalRecord+ActionsTests.m */; }; + 902CE12D18F61A2F0024F47C /* MagicalRecord+ActionsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 902CE12B18F61A2F0024F47C /* MagicalRecord+ActionsTests.m */; }; + 902CE13918F61E410024F47C /* NSManagedObjectContext+MagicalSavesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 902CE13818F61E410024F47C /* NSManagedObjectContext+MagicalSavesTests.m */; }; + 902CE13A18F61E410024F47C /* NSManagedObjectContext+MagicalSavesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 902CE13818F61E410024F47C /* NSManagedObjectContext+MagicalSavesTests.m */; }; + 903125A11B10384A000E8841 /* Expecta.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 903125941B103812000E8841 /* Expecta.framework */; }; + 903125A21B103860000E8841 /* Expecta.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 903125921B103812000E8841 /* Expecta.framework */; }; + 903125A31B103881000E8841 /* libExpecta.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9031259A1B103812000E8841 /* libExpecta.a */; }; + 903125A41B103886000E8841 /* libExpecta.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9031259C1B103812000E8841 /* libExpecta.a */; }; + 90542E121863F20900916224 /* MagicalDataImportTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF978E174982AD008D9D13 /* MagicalDataImportTestCase.m */; }; + 90542E131863F20900916224 /* MagicalDataImportTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF978E174982AD008D9D13 /* MagicalDataImportTestCase.m */; }; + 90542E141863F20C00916224 /* ImportSingleEntityWithNoRelationshipsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF978B174982AD008D9D13 /* ImportSingleEntityWithNoRelationshipsTests.m */; }; + 90542E151863F20C00916224 /* ImportSingleEntityWithNoRelationshipsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF978B174982AD008D9D13 /* ImportSingleEntityWithNoRelationshipsTests.m */; }; + 90542E181864438900916224 /* ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF978A174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m */; }; + 90542E191864438A00916224 /* ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF978A174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m */; }; + 90542E1A1864688100916224 /* ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9789174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m */; }; + 90542E1B1864688100916224 /* ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9789174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m */; }; + 90542E1C1864691E00916224 /* ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9788174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m */; }; + 90542E1D1864691E00916224 /* ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9788174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m */; }; + 90542E1E1864853900916224 /* MagicalRecord+StackTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF976817498275008D9D13 /* MagicalRecord+StackTests.m */; }; + 90542E1F1864853A00916224 /* MagicalRecord+StackTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF976817498275008D9D13 /* MagicalRecord+StackTests.m */; }; + 90542E201864855500916224 /* NSManagedObjectContextHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF976A17498275008D9D13 /* NSManagedObjectContextHelperTests.m */; }; + 90542E211864855500916224 /* NSManagedObjectContextHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF976A17498275008D9D13 /* NSManagedObjectContextHelperTests.m */; }; + 90542E221864861100916224 /* NSManagedObjectHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF976C17498275008D9D13 /* NSManagedObjectHelperTests.m */; }; + 90542E231864861200916224 /* NSManagedObjectHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF976C17498275008D9D13 /* NSManagedObjectHelperTests.m */; }; + 90542E241864894D00916224 /* NSPersistentStoreHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF977017498275008D9D13 /* NSPersistentStoreHelperTests.m */; }; + 90542E251864894D00916224 /* NSPersistentStoreHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF977017498275008D9D13 /* NSPersistentStoreHelperTests.m */; }; + 90542E2618648AAF00916224 /* NSPersistentStoreCoordinatorHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF977217498275008D9D13 /* NSPersistentStoreCoordinatorHelperTests.m */; }; + 90542E2718648AB000916224 /* NSPersistentStoreCoordinatorHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF977217498275008D9D13 /* NSPersistentStoreCoordinatorHelperTests.m */; }; + 905D07551A63DEF40076B54E /* MagicalImportFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD729C150F832A00216827 /* MagicalImportFunctions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07561A63DEF40076B54E /* NSEntityDescription+MagicalDataImport.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72A0150F832A00216827 /* NSEntityDescription+MagicalDataImport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07571A63DEF40076B54E /* NSAttributeDescription+MagicalDataImport.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD729E150F832A00216827 /* NSAttributeDescription+MagicalDataImport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07581A63DEF40076B54E /* NSRelationshipDescription+MagicalDataImport.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72A6150F832A00216827 /* NSRelationshipDescription+MagicalDataImport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07591A63DEF40076B54E /* NSNumber+MagicalDataImport.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72A2150F832A00216827 /* NSNumber+MagicalDataImport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D075A1A63DEF40076B54E /* NSObject+MagicalDataImport.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72A4150F832A00216827 /* NSObject+MagicalDataImport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D075B1A63DEF40076B54E /* NSString+MagicalDataImport.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72A8150F832A00216827 /* NSString+MagicalDataImport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D075C1A63DEF40076B54E /* NSManagedObject+MagicalAggregation.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72AB150F832A00216827 /* NSManagedObject+MagicalAggregation.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D075D1A63DEF40076B54E /* NSManagedObject+MagicalDataImport.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72AD150F832A00216827 /* NSManagedObject+MagicalDataImport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D075E1A63DEF40076B54E /* NSManagedObject+MagicalFinders.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72AF150F832A00216827 /* NSManagedObject+MagicalFinders.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D075F1A63DEF40076B54E /* NSManagedObject+MagicalRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72B1150F832A00216827 /* NSManagedObject+MagicalRecord.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07601A63DEF40076B54E /* NSManagedObject+MagicalRequests.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72B3150F832A00216827 /* NSManagedObject+MagicalRequests.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07611A63DEF40076B54E /* NSManagedObjectContext+MagicalChainSave.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BB566891A2C44C4004174B3 /* NSManagedObjectContext+MagicalChainSave.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07621A63DEF40076B54E /* NSManagedObjectContext+MagicalObserving.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72B6150F832A00216827 /* NSManagedObjectContext+MagicalObserving.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07631A63DEF40076B54E /* NSManagedObjectContext+MagicalRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72B8150F832A00216827 /* NSManagedObjectContext+MagicalRecord.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07641A63DEF40076B54E /* NSManagedObjectContext+MagicalSaves.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72BA150F832A00216827 /* NSManagedObjectContext+MagicalSaves.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07651A63DEF40076B54E /* NSManagedObjectContext+MagicalThreading.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72BC150F832A00216827 /* NSManagedObjectContext+MagicalThreading.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07661A63DEF40076B54E /* NSManagedObjectModel+MagicalRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72BE150F832A00216827 /* NSManagedObjectModel+MagicalRecord.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07671A63DEF40076B54E /* NSPersistentStore+MagicalRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72C0150F832A00216827 /* NSPersistentStore+MagicalRecord.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07681A63DEF40076B54E /* NSPersistentStoreCoordinator+MagicalRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72C2150F832A00216827 /* NSPersistentStoreCoordinator+MagicalRecord.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07691A63DEF40076B54E /* MagicalRecordInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72D1150F832A00216827 /* MagicalRecordInternal.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D076A1A63DEF40076B54E /* MagicalRecord+Actions.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72C5150F832A00216827 /* MagicalRecord+Actions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D076B1A63DEF40076B54E /* MagicalRecord+ErrorHandling.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72C7150F832A00216827 /* MagicalRecord+ErrorHandling.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D076C1A63DEF40076B54E /* MagicalRecord+iCloud.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72C9150F832A00216827 /* MagicalRecord+iCloud.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D076D1A63DEF40076B54E /* MagicalRecord+Options.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72CB150F832A00216827 /* MagicalRecord+Options.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D076E1A63DEF40076B54E /* MagicalRecord+Setup.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72CD150F832A00216827 /* MagicalRecord+Setup.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07701A63DEF40076B54E /* MagicalRecordLogging.h in Headers */ = {isa = PBXBuildFile; fileRef = 90FEC08B18F42DEA002FFC2F /* MagicalRecordLogging.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07721A63DEF40076B54E /* MagicalRecordDeprecationMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 902CE11E18F6133E0024F47C /* MagicalRecordDeprecationMacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07731A63DEF40076B54E /* MagicalRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72D4150F832A00216827 /* MagicalRecord.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07741A63DEF40076B54E /* MagicalImportFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD729C150F832A00216827 /* MagicalImportFunctions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07751A63DEF40076B54E /* NSEntityDescription+MagicalDataImport.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72A0150F832A00216827 /* NSEntityDescription+MagicalDataImport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07761A63DEF40076B54E /* NSAttributeDescription+MagicalDataImport.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD729E150F832A00216827 /* NSAttributeDescription+MagicalDataImport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07771A63DEF40076B54E /* NSRelationshipDescription+MagicalDataImport.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72A6150F832A00216827 /* NSRelationshipDescription+MagicalDataImport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07781A63DEF40076B54E /* NSNumber+MagicalDataImport.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72A2150F832A00216827 /* NSNumber+MagicalDataImport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07791A63DEF40076B54E /* NSObject+MagicalDataImport.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72A4150F832A00216827 /* NSObject+MagicalDataImport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D077A1A63DEF40076B54E /* NSString+MagicalDataImport.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72A8150F832A00216827 /* NSString+MagicalDataImport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D077B1A63DEF40076B54E /* NSManagedObject+MagicalAggregation.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72AB150F832A00216827 /* NSManagedObject+MagicalAggregation.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D077C1A63DEF40076B54E /* NSManagedObject+MagicalDataImport.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72AD150F832A00216827 /* NSManagedObject+MagicalDataImport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D077D1A63DEF40076B54E /* NSManagedObject+MagicalFinders.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72AF150F832A00216827 /* NSManagedObject+MagicalFinders.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D077E1A63DEF40076B54E /* NSManagedObject+MagicalRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72B1150F832A00216827 /* NSManagedObject+MagicalRecord.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D077F1A63DEF40076B54E /* NSManagedObject+MagicalRequests.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72B3150F832A00216827 /* NSManagedObject+MagicalRequests.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07801A63DEF40076B54E /* NSManagedObjectContext+MagicalChainSave.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BB566891A2C44C4004174B3 /* NSManagedObjectContext+MagicalChainSave.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07811A63DEF40076B54E /* NSManagedObjectContext+MagicalObserving.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72B6150F832A00216827 /* NSManagedObjectContext+MagicalObserving.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07821A63DEF40076B54E /* NSManagedObjectContext+MagicalRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72B8150F832A00216827 /* NSManagedObjectContext+MagicalRecord.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07831A63DEF40076B54E /* NSManagedObjectContext+MagicalSaves.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72BA150F832A00216827 /* NSManagedObjectContext+MagicalSaves.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07841A63DEF40076B54E /* NSManagedObjectContext+MagicalThreading.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72BC150F832A00216827 /* NSManagedObjectContext+MagicalThreading.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07851A63DEF40076B54E /* NSManagedObjectModel+MagicalRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72BE150F832A00216827 /* NSManagedObjectModel+MagicalRecord.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07861A63DEF40076B54E /* NSPersistentStore+MagicalRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72C0150F832A00216827 /* NSPersistentStore+MagicalRecord.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07871A63DEF40076B54E /* NSPersistentStoreCoordinator+MagicalRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72C2150F832A00216827 /* NSPersistentStoreCoordinator+MagicalRecord.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07881A63DEF40076B54E /* MagicalRecordInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72D1150F832A00216827 /* MagicalRecordInternal.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07891A63DEF40076B54E /* MagicalRecord+Actions.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72C5150F832A00216827 /* MagicalRecord+Actions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D078A1A63DEF40076B54E /* MagicalRecord+ErrorHandling.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72C7150F832A00216827 /* MagicalRecord+ErrorHandling.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D078B1A63DEF40076B54E /* MagicalRecord+iCloud.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72C9150F832A00216827 /* MagicalRecord+iCloud.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D078C1A63DEF40076B54E /* MagicalRecord+Options.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72CB150F832A00216827 /* MagicalRecord+Options.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D078D1A63DEF40076B54E /* MagicalRecord+Setup.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72CD150F832A00216827 /* MagicalRecord+Setup.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D078F1A63DEF40076B54E /* MagicalRecordLogging.h in Headers */ = {isa = PBXBuildFile; fileRef = 90FEC08B18F42DEA002FFC2F /* MagicalRecordLogging.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07911A63DEF40076B54E /* MagicalRecordDeprecationMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 902CE11E18F6133E0024F47C /* MagicalRecordDeprecationMacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07921A63DEF40076B54E /* MagicalRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = C7DD72D4150F832A00216827 /* MagicalRecord.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905D07931A63DF120076B54E /* MagicalImportFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD729D150F832A00216827 /* MagicalImportFunctions.m */; }; + 905D07941A63DF120076B54E /* NSEntityDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A1150F832A00216827 /* NSEntityDescription+MagicalDataImport.m */; }; + 905D07951A63DF120076B54E /* NSAttributeDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD729F150F832A00216827 /* NSAttributeDescription+MagicalDataImport.m */; }; + 905D07961A63DF120076B54E /* NSRelationshipDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A7150F832A00216827 /* NSRelationshipDescription+MagicalDataImport.m */; }; + 905D07971A63DF120076B54E /* NSNumber+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A3150F832A00216827 /* NSNumber+MagicalDataImport.m */; }; + 905D07981A63DF120076B54E /* NSObject+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A5150F832A00216827 /* NSObject+MagicalDataImport.m */; }; + 905D07991A63DF120076B54E /* NSString+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A9150F832A00216827 /* NSString+MagicalDataImport.m */; }; + 905D079A1A63DF120076B54E /* NSManagedObject+MagicalAggregation.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72AC150F832A00216827 /* NSManagedObject+MagicalAggregation.m */; }; + 905D079B1A63DF120076B54E /* NSManagedObject+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72AE150F832A00216827 /* NSManagedObject+MagicalDataImport.m */; }; + 905D079C1A63DF120076B54E /* NSManagedObject+MagicalFinders.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B0150F832A00216827 /* NSManagedObject+MagicalFinders.m */; }; + 905D079D1A63DF120076B54E /* NSManagedObject+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B2150F832A00216827 /* NSManagedObject+MagicalRecord.m */; }; + 905D079E1A63DF120076B54E /* NSManagedObject+MagicalRequests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B4150F832A00216827 /* NSManagedObject+MagicalRequests.m */; }; + 905D079F1A63DF120076B54E /* NSManagedObjectContext+MagicalChainSave.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BB5668A1A2C44C4004174B3 /* NSManagedObjectContext+MagicalChainSave.m */; }; + 905D07A01A63DF120076B54E /* NSManagedObjectContext+MagicalObserving.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B7150F832A00216827 /* NSManagedObjectContext+MagicalObserving.m */; }; + 905D07A11A63DF120076B54E /* NSManagedObjectContext+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B9150F832A00216827 /* NSManagedObjectContext+MagicalRecord.m */; }; + 905D07A21A63DF120076B54E /* NSManagedObjectContext+MagicalSaves.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72BB150F832A00216827 /* NSManagedObjectContext+MagicalSaves.m */; }; + 905D07A31A63DF120076B54E /* NSManagedObjectContext+MagicalThreading.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72BD150F832A00216827 /* NSManagedObjectContext+MagicalThreading.m */; }; + 905D07A41A63DF120076B54E /* NSManagedObjectModel+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72BF150F832A00216827 /* NSManagedObjectModel+MagicalRecord.m */; }; + 905D07A51A63DF120076B54E /* NSPersistentStore+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C1150F832A00216827 /* NSPersistentStore+MagicalRecord.m */; }; + 905D07A61A63DF120076B54E /* NSPersistentStoreCoordinator+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C3150F832A00216827 /* NSPersistentStoreCoordinator+MagicalRecord.m */; }; + 905D07A71A63DF120076B54E /* MagicalRecordInternal.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72D2150F832A00216827 /* MagicalRecordInternal.m */; }; + 905D07A81A63DF120076B54E /* MagicalRecord+Actions.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C6150F832A00216827 /* MagicalRecord+Actions.m */; }; + 905D07A91A63DF120076B54E /* MagicalRecord+ErrorHandling.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C8150F832A00216827 /* MagicalRecord+ErrorHandling.m */; }; + 905D07AA1A63DF120076B54E /* MagicalRecord+iCloud.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72CA150F832A00216827 /* MagicalRecord+iCloud.m */; }; + 905D07AB1A63DF120076B54E /* MagicalRecord+Options.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72CC150F832A00216827 /* MagicalRecord+Options.m */; }; + 905D07AC1A63DF120076B54E /* MagicalRecord+Setup.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72CE150F832A00216827 /* MagicalRecord+Setup.m */; }; + 905D07AE1A63DF130076B54E /* MagicalImportFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD729D150F832A00216827 /* MagicalImportFunctions.m */; }; + 905D07AF1A63DF130076B54E /* NSEntityDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A1150F832A00216827 /* NSEntityDescription+MagicalDataImport.m */; }; + 905D07B01A63DF130076B54E /* NSAttributeDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD729F150F832A00216827 /* NSAttributeDescription+MagicalDataImport.m */; }; + 905D07B11A63DF130076B54E /* NSRelationshipDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A7150F832A00216827 /* NSRelationshipDescription+MagicalDataImport.m */; }; + 905D07B21A63DF130076B54E /* NSNumber+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A3150F832A00216827 /* NSNumber+MagicalDataImport.m */; }; + 905D07B31A63DF130076B54E /* NSObject+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A5150F832A00216827 /* NSObject+MagicalDataImport.m */; }; + 905D07B41A63DF130076B54E /* NSString+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A9150F832A00216827 /* NSString+MagicalDataImport.m */; }; + 905D07B51A63DF130076B54E /* NSManagedObject+MagicalAggregation.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72AC150F832A00216827 /* NSManagedObject+MagicalAggregation.m */; }; + 905D07B61A63DF130076B54E /* NSManagedObject+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72AE150F832A00216827 /* NSManagedObject+MagicalDataImport.m */; }; + 905D07B71A63DF130076B54E /* NSManagedObject+MagicalFinders.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B0150F832A00216827 /* NSManagedObject+MagicalFinders.m */; }; + 905D07B81A63DF130076B54E /* NSManagedObject+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B2150F832A00216827 /* NSManagedObject+MagicalRecord.m */; }; + 905D07B91A63DF130076B54E /* NSManagedObject+MagicalRequests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B4150F832A00216827 /* NSManagedObject+MagicalRequests.m */; }; + 905D07BA1A63DF130076B54E /* NSManagedObjectContext+MagicalChainSave.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BB5668A1A2C44C4004174B3 /* NSManagedObjectContext+MagicalChainSave.m */; }; + 905D07BB1A63DF130076B54E /* NSManagedObjectContext+MagicalObserving.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B7150F832A00216827 /* NSManagedObjectContext+MagicalObserving.m */; }; + 905D07BC1A63DF130076B54E /* NSManagedObjectContext+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B9150F832A00216827 /* NSManagedObjectContext+MagicalRecord.m */; }; + 905D07BD1A63DF130076B54E /* NSManagedObjectContext+MagicalSaves.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72BB150F832A00216827 /* NSManagedObjectContext+MagicalSaves.m */; }; + 905D07BE1A63DF130076B54E /* NSManagedObjectContext+MagicalThreading.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72BD150F832A00216827 /* NSManagedObjectContext+MagicalThreading.m */; }; + 905D07BF1A63DF130076B54E /* NSManagedObjectModel+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72BF150F832A00216827 /* NSManagedObjectModel+MagicalRecord.m */; }; + 905D07C01A63DF130076B54E /* NSPersistentStore+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C1150F832A00216827 /* NSPersistentStore+MagicalRecord.m */; }; + 905D07C11A63DF130076B54E /* NSPersistentStoreCoordinator+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C3150F832A00216827 /* NSPersistentStoreCoordinator+MagicalRecord.m */; }; + 905D07C21A63DF130076B54E /* MagicalRecordInternal.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72D2150F832A00216827 /* MagicalRecordInternal.m */; }; + 905D07C31A63DF130076B54E /* MagicalRecord+Actions.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C6150F832A00216827 /* MagicalRecord+Actions.m */; }; + 905D07C41A63DF130076B54E /* MagicalRecord+ErrorHandling.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C8150F832A00216827 /* MagicalRecord+ErrorHandling.m */; }; + 905D07C51A63DF130076B54E /* MagicalRecord+iCloud.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72CA150F832A00216827 /* MagicalRecord+iCloud.m */; }; + 905D07C61A63DF130076B54E /* MagicalRecord+Options.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72CC150F832A00216827 /* MagicalRecord+Options.m */; }; + 905D07C71A63DF130076B54E /* MagicalRecord+Setup.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72CE150F832A00216827 /* MagicalRecord+Setup.m */; }; + 9088CFC61B1043F500E51758 /* Expecta.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 903125921B103812000E8841 /* Expecta.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9088CFC71B10440800E51758 /* Expecta.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 903125941B103812000E8841 /* Expecta.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9099490A17C2F3D400BC2B5C /* TestModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 9099490817C2F3D400BC2B5C /* TestModel.xcdatamodeld */; }; + 9099490B17C2F3D400BC2B5C /* TestModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 9099490817C2F3D400BC2B5C /* TestModel.xcdatamodeld */; }; + 9099493917C2F42100BC2B5C /* _AbstractRelatedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099490E17C2F42100BC2B5C /* _AbstractRelatedEntity.m */; }; + 9099493A17C2F42100BC2B5C /* _AbstractRelatedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099490E17C2F42100BC2B5C /* _AbstractRelatedEntity.m */; }; + 9099493B17C2F42100BC2B5C /* _ConcreteRelatedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491017C2F42100BC2B5C /* _ConcreteRelatedEntity.m */; }; + 9099493C17C2F42100BC2B5C /* _ConcreteRelatedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491017C2F42100BC2B5C /* _ConcreteRelatedEntity.m */; }; + 9099493D17C2F42100BC2B5C /* _DifferentClassNameMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491217C2F42100BC2B5C /* _DifferentClassNameMapping.m */; }; + 9099493E17C2F42100BC2B5C /* _DifferentClassNameMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491217C2F42100BC2B5C /* _DifferentClassNameMapping.m */; }; + 9099493F17C2F42100BC2B5C /* _MappedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491417C2F42100BC2B5C /* _MappedEntity.m */; }; + 9099494017C2F42100BC2B5C /* _MappedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491417C2F42100BC2B5C /* _MappedEntity.m */; }; + 9099494117C2F42100BC2B5C /* _SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491617C2F42100BC2B5C /* _SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m */; }; + 9099494217C2F42100BC2B5C /* _SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491617C2F42100BC2B5C /* _SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m */; }; + 9099494317C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityUsingDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491817C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityUsingDefaults.m */; }; + 9099494417C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityUsingDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491817C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityUsingDefaults.m */; }; + 9099494517C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491A17C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m */; }; + 9099494617C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491A17C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m */; }; + 9099494717C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491C17C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m */; }; + 9099494817C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491C17C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m */; }; + 9099494917C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityWithSecondaryMappings.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491E17C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityWithSecondaryMappings.m */; }; + 9099494A17C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityWithSecondaryMappings.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099491E17C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityWithSecondaryMappings.m */; }; + 9099494B17C2F42100BC2B5C /* _SingleEntityWithNoRelationships.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492017C2F42100BC2B5C /* _SingleEntityWithNoRelationships.m */; }; + 9099494C17C2F42100BC2B5C /* _SingleEntityWithNoRelationships.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492017C2F42100BC2B5C /* _SingleEntityWithNoRelationships.m */; }; + 9099494D17C2F42100BC2B5C /* _SingleRelatedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492217C2F42100BC2B5C /* _SingleRelatedEntity.m */; }; + 9099494E17C2F42100BC2B5C /* _SingleRelatedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492217C2F42100BC2B5C /* _SingleRelatedEntity.m */; }; + 9099494F17C2F42100BC2B5C /* AbstractRelatedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492417C2F42100BC2B5C /* AbstractRelatedEntity.m */; }; + 9099495017C2F42100BC2B5C /* AbstractRelatedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492417C2F42100BC2B5C /* AbstractRelatedEntity.m */; }; + 9099495117C2F42100BC2B5C /* ConcreteRelatedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492617C2F42100BC2B5C /* ConcreteRelatedEntity.m */; }; + 9099495217C2F42100BC2B5C /* ConcreteRelatedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492617C2F42100BC2B5C /* ConcreteRelatedEntity.m */; }; + 9099495317C2F42100BC2B5C /* DifferentClassNameMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492817C2F42100BC2B5C /* DifferentClassNameMapping.m */; }; + 9099495417C2F42100BC2B5C /* DifferentClassNameMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492817C2F42100BC2B5C /* DifferentClassNameMapping.m */; }; + 9099495517C2F42100BC2B5C /* MappedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492A17C2F42100BC2B5C /* MappedEntity.m */; }; + 9099495617C2F42100BC2B5C /* MappedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492A17C2F42100BC2B5C /* MappedEntity.m */; }; + 9099495717C2F42100BC2B5C /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492C17C2F42100BC2B5C /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m */; }; + 9099495817C2F42100BC2B5C /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492C17C2F42100BC2B5C /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m */; }; + 9099495917C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityUsingDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492E17C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityUsingDefaults.m */; }; + 9099495A17C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityUsingDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099492E17C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityUsingDefaults.m */; }; + 9099495B17C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099493017C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m */; }; + 9099495C17C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099493017C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m */; }; + 9099495D17C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099493217C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m */; }; + 9099495E17C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099493217C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m */; }; + 9099495F17C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099493417C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.m */; }; + 9099496017C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099493417C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.m */; }; + 9099496117C2F42100BC2B5C /* SingleEntityWithNoRelationships.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099493617C2F42100BC2B5C /* SingleEntityWithNoRelationships.m */; }; + 9099496217C2F42100BC2B5C /* SingleEntityWithNoRelationships.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099493617C2F42100BC2B5C /* SingleEntityWithNoRelationships.m */; }; + 9099496317C2F42100BC2B5C /* SingleRelatedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099493817C2F42100BC2B5C /* SingleRelatedEntity.m */; }; + 9099496417C2F42100BC2B5C /* SingleRelatedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9099493817C2F42100BC2B5C /* SingleRelatedEntity.m */; }; + 90AA771818F79A3300D49377 /* NSManagedObject+MagicalRecordTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 90AA771718F79A3300D49377 /* NSManagedObject+MagicalRecordTests.m */; }; + 90AA771918F79A3300D49377 /* NSManagedObject+MagicalRecordTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 90AA771718F79A3300D49377 /* NSManagedObject+MagicalRecordTests.m */; }; + 90AA772518F79CCC00D49377 /* EntityWithoutEntityNameMethod.m in Sources */ = {isa = PBXBuildFile; fileRef = 90AA772418F79CCC00D49377 /* EntityWithoutEntityNameMethod.m */; }; + 90AA772618F79CCC00D49377 /* EntityWithoutEntityNameMethod.m in Sources */ = {isa = PBXBuildFile; fileRef = 90AA772418F79CCC00D49377 /* EntityWithoutEntityNameMethod.m */; }; + 90B05B861B02450900354056 /* MagicalRecordShorthandMethodAliases.h in Headers */ = {isa = PBXBuildFile; fileRef = 90B05B851B02450900354056 /* MagicalRecordShorthandMethodAliases.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 90B05B871B02450900354056 /* MagicalRecordShorthandMethodAliases.h in Headers */ = {isa = PBXBuildFile; fileRef = 90B05B851B02450900354056 /* MagicalRecordShorthandMethodAliases.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 90B05B8B1B02452A00354056 /* MagicalRecord+ShorthandMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = 90B05B891B02452A00354056 /* MagicalRecord+ShorthandMethods.h */; }; + 90B05B8C1B02452A00354056 /* MagicalRecord+ShorthandMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = 90B05B891B02452A00354056 /* MagicalRecord+ShorthandMethods.h */; }; + 90B05B8E1B02452A00354056 /* MagicalRecord+ShorthandMethods.m in Sources */ = {isa = PBXBuildFile; fileRef = 90B05B8A1B02452A00354056 /* MagicalRecord+ShorthandMethods.m */; }; + 90B05B8F1B02452A00354056 /* MagicalRecord+ShorthandMethods.m in Sources */ = {isa = PBXBuildFile; fileRef = 90B05B8A1B02452A00354056 /* MagicalRecord+ShorthandMethods.m */; }; + 90B05B901B02452A00354056 /* MagicalRecord+ShorthandMethods.m in Sources */ = {isa = PBXBuildFile; fileRef = 90B05B8A1B02452A00354056 /* MagicalRecord+ShorthandMethods.m */; }; + 90B05B911B02452A00354056 /* MagicalRecord+ShorthandMethods.m in Sources */ = {isa = PBXBuildFile; fileRef = 90B05B8A1B02452A00354056 /* MagicalRecord+ShorthandMethods.m */; }; + 90BB1C3A1864F341001BBFBB /* ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9787174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m */; }; + 90BB1C3B1864F341001BBFBB /* ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9787174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m */; }; + 90BB1C3C1864F3E9001BBFBB /* ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9786174982AD008D9D13 /* ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m */; }; + 90BB1C3D1864F3E9001BBFBB /* ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9786174982AD008D9D13 /* ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m */; }; + 90BB1C3F1864F662001BBFBB /* ImportSingleRelatedEntityTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 90BB1C3E1864F662001BBFBB /* ImportSingleRelatedEntityTests.m */; }; + 90BB1C401864F662001BBFBB /* ImportSingleRelatedEntityTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 90BB1C3E1864F662001BBFBB /* ImportSingleRelatedEntityTests.m */; }; + 90BB1C491865159A001BBFBB /* MagicalRecordTestBase.m in Sources */ = {isa = PBXBuildFile; fileRef = 90BB1C4518651539001BBFBB /* MagicalRecordTestBase.m */; }; + 90BB1C4A1865159A001BBFBB /* MagicalRecordTestBase.m in Sources */ = {isa = PBXBuildFile; fileRef = 90BB1C4518651539001BBFBB /* MagicalRecordTestBase.m */; }; + 9BB5668C1A2C44C4004174B3 /* NSManagedObjectContext+MagicalChainSave.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BB5668A1A2C44C4004174B3 /* NSManagedObjectContext+MagicalChainSave.m */; }; + 9BB5668D1A2C44C4004174B3 /* NSManagedObjectContext+MagicalChainSave.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BB5668A1A2C44C4004174B3 /* NSManagedObjectContext+MagicalChainSave.m */; }; + 9BB566981A2EA8F8004174B3 /* NSManagedObjectContext+ChainSaveTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BB566931A2C47B3004174B3 /* NSManagedObjectContext+ChainSaveTests.m */; }; + 9BB566991A2EA8FF004174B3 /* NSManagedObjectContext+ChainSaveTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BB566931A2C47B3004174B3 /* NSManagedObjectContext+ChainSaveTests.m */; }; + C7CF97C617498493008D9D13 /* MagicalImportFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD729D150F832A00216827 /* MagicalImportFunctions.m */; }; + C7CF97C717498493008D9D13 /* NSEntityDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A1150F832A00216827 /* NSEntityDescription+MagicalDataImport.m */; }; + C7CF97C817498493008D9D13 /* NSAttributeDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD729F150F832A00216827 /* NSAttributeDescription+MagicalDataImport.m */; }; + C7CF97C917498493008D9D13 /* NSRelationshipDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A7150F832A00216827 /* NSRelationshipDescription+MagicalDataImport.m */; }; + C7CF97CA17498493008D9D13 /* NSNumber+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A3150F832A00216827 /* NSNumber+MagicalDataImport.m */; }; + C7CF97CB17498493008D9D13 /* NSObject+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A5150F832A00216827 /* NSObject+MagicalDataImport.m */; }; + C7CF97CC17498493008D9D13 /* NSString+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A9150F832A00216827 /* NSString+MagicalDataImport.m */; }; + C7CF97CD17498493008D9D13 /* NSManagedObject+MagicalAggregation.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72AC150F832A00216827 /* NSManagedObject+MagicalAggregation.m */; }; + C7CF97CE17498493008D9D13 /* NSManagedObject+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72AE150F832A00216827 /* NSManagedObject+MagicalDataImport.m */; }; + C7CF97CF17498493008D9D13 /* NSManagedObject+MagicalFinders.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B0150F832A00216827 /* NSManagedObject+MagicalFinders.m */; }; + C7CF97D017498493008D9D13 /* NSManagedObject+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B2150F832A00216827 /* NSManagedObject+MagicalRecord.m */; }; + C7CF97D117498493008D9D13 /* NSManagedObject+MagicalRequests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B4150F832A00216827 /* NSManagedObject+MagicalRequests.m */; }; + C7CF97D217498493008D9D13 /* NSManagedObjectContext+MagicalObserving.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B7150F832A00216827 /* NSManagedObjectContext+MagicalObserving.m */; }; + C7CF97D317498493008D9D13 /* NSManagedObjectContext+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B9150F832A00216827 /* NSManagedObjectContext+MagicalRecord.m */; }; + C7CF97D417498493008D9D13 /* NSManagedObjectContext+MagicalSaves.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72BB150F832A00216827 /* NSManagedObjectContext+MagicalSaves.m */; }; + C7CF97D517498493008D9D13 /* NSManagedObjectContext+MagicalThreading.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72BD150F832A00216827 /* NSManagedObjectContext+MagicalThreading.m */; }; + C7CF97D617498493008D9D13 /* NSManagedObjectModel+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72BF150F832A00216827 /* NSManagedObjectModel+MagicalRecord.m */; }; + C7CF97D717498493008D9D13 /* NSPersistentStore+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C1150F832A00216827 /* NSPersistentStore+MagicalRecord.m */; }; + C7CF97D817498493008D9D13 /* NSPersistentStoreCoordinator+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C3150F832A00216827 /* NSPersistentStoreCoordinator+MagicalRecord.m */; }; + C7CF97D917498493008D9D13 /* MagicalRecordInternal.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72D2150F832A00216827 /* MagicalRecordInternal.m */; }; + C7CF97DA17498493008D9D13 /* MagicalRecord+Actions.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C6150F832A00216827 /* MagicalRecord+Actions.m */; }; + C7CF97DB17498493008D9D13 /* MagicalRecord+ErrorHandling.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C8150F832A00216827 /* MagicalRecord+ErrorHandling.m */; }; + C7CF97DC17498493008D9D13 /* MagicalRecord+iCloud.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72CA150F832A00216827 /* MagicalRecord+iCloud.m */; }; + C7CF97DD17498493008D9D13 /* MagicalRecord+Options.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72CC150F832A00216827 /* MagicalRecord+Options.m */; }; + C7CF97DE17498493008D9D13 /* MagicalRecord+Setup.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72CE150F832A00216827 /* MagicalRecord+Setup.m */; }; + C7CF97E0174984A5008D9D13 /* MagicalImportFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD729D150F832A00216827 /* MagicalImportFunctions.m */; }; + C7CF97E1174984A5008D9D13 /* NSEntityDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A1150F832A00216827 /* NSEntityDescription+MagicalDataImport.m */; }; + C7CF97E2174984A5008D9D13 /* NSAttributeDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD729F150F832A00216827 /* NSAttributeDescription+MagicalDataImport.m */; }; + C7CF97E3174984A5008D9D13 /* NSRelationshipDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A7150F832A00216827 /* NSRelationshipDescription+MagicalDataImport.m */; }; + C7CF97E4174984A5008D9D13 /* NSNumber+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A3150F832A00216827 /* NSNumber+MagicalDataImport.m */; }; + C7CF97E5174984A5008D9D13 /* NSObject+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A5150F832A00216827 /* NSObject+MagicalDataImport.m */; }; + C7CF97E6174984A5008D9D13 /* NSString+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A9150F832A00216827 /* NSString+MagicalDataImport.m */; }; + C7CF97E7174984A5008D9D13 /* NSManagedObject+MagicalAggregation.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72AC150F832A00216827 /* NSManagedObject+MagicalAggregation.m */; }; + C7CF97E8174984A5008D9D13 /* NSManagedObject+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72AE150F832A00216827 /* NSManagedObject+MagicalDataImport.m */; }; + C7CF97E9174984A5008D9D13 /* NSManagedObject+MagicalFinders.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B0150F832A00216827 /* NSManagedObject+MagicalFinders.m */; }; + C7CF97EA174984A5008D9D13 /* NSManagedObject+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B2150F832A00216827 /* NSManagedObject+MagicalRecord.m */; }; + C7CF97EB174984A5008D9D13 /* NSManagedObject+MagicalRequests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B4150F832A00216827 /* NSManagedObject+MagicalRequests.m */; }; + C7CF97EC174984A5008D9D13 /* NSManagedObjectContext+MagicalObserving.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B7150F832A00216827 /* NSManagedObjectContext+MagicalObserving.m */; }; + C7CF97ED174984A5008D9D13 /* NSManagedObjectContext+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B9150F832A00216827 /* NSManagedObjectContext+MagicalRecord.m */; }; + C7CF97EE174984A5008D9D13 /* NSManagedObjectContext+MagicalSaves.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72BB150F832A00216827 /* NSManagedObjectContext+MagicalSaves.m */; }; + C7CF97EF174984A5008D9D13 /* NSManagedObjectContext+MagicalThreading.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72BD150F832A00216827 /* NSManagedObjectContext+MagicalThreading.m */; }; + C7CF97F0174984A5008D9D13 /* NSManagedObjectModel+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72BF150F832A00216827 /* NSManagedObjectModel+MagicalRecord.m */; }; + C7CF97F1174984A5008D9D13 /* NSPersistentStore+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C1150F832A00216827 /* NSPersistentStore+MagicalRecord.m */; }; + C7CF97F2174984A5008D9D13 /* NSPersistentStoreCoordinator+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C3150F832A00216827 /* NSPersistentStoreCoordinator+MagicalRecord.m */; }; + C7CF97F3174984A5008D9D13 /* MagicalRecordInternal.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72D2150F832A00216827 /* MagicalRecordInternal.m */; }; + C7CF97F4174984A5008D9D13 /* MagicalRecord+Actions.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C6150F832A00216827 /* MagicalRecord+Actions.m */; }; + C7CF97F5174984A5008D9D13 /* MagicalRecord+ErrorHandling.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C8150F832A00216827 /* MagicalRecord+ErrorHandling.m */; }; + C7CF97F6174984A5008D9D13 /* MagicalRecord+iCloud.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72CA150F832A00216827 /* MagicalRecord+iCloud.m */; }; + C7CF97F7174984A5008D9D13 /* MagicalRecord+Options.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72CC150F832A00216827 /* MagicalRecord+Options.m */; }; + C7CF97F8174984A5008D9D13 /* MagicalRecord+Setup.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72CE150F832A00216827 /* MagicalRecord+Setup.m */; }; + C7CF9B5317498985008D9D13 /* SampleJSONDataForImport.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4917498985008D9D13 /* SampleJSONDataForImport.json */; }; + C7CF9B5417498985008D9D13 /* SampleJSONDataForImport.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4917498985008D9D13 /* SampleJSONDataForImport.json */; }; + C7CF9B5517498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4A17498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json */; }; + C7CF9B5617498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4A17498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json */; }; + C7CF9B5717498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4B17498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json */; }; + C7CF9B5817498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4B17498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json */; }; + C7CF9B5917498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingDefaults.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4C17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingDefaults.json */; }; + C7CF9B5A17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingDefaults.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4C17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingDefaults.json */; }; + C7CF9B5B17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4D17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json */; }; + C7CF9B5C17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4D17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json */; }; + C7CF9B5D17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4E17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json */; }; + C7CF9B5E17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4E17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json */; }; + C7CF9B5F17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4F17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.json */; }; + C7CF9B6017498985008D9D13 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4F17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.json */; }; + C7CF9B6117498985008D9D13 /* SingleEntityWithNoRelationships.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B5017498985008D9D13 /* SingleEntityWithNoRelationships.json */; }; + C7CF9B6217498985008D9D13 /* SingleEntityWithNoRelationships.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B5017498985008D9D13 /* SingleEntityWithNoRelationships.json */; }; + C7CF9B6317498986008D9D13 /* SingleEntityWithNoRelationships.plist in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B5117498985008D9D13 /* SingleEntityWithNoRelationships.plist */; }; + C7CF9B6417498986008D9D13 /* SingleEntityWithNoRelationships.plist in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B5117498985008D9D13 /* SingleEntityWithNoRelationships.plist */; }; + C7CF9B6517498986008D9D13 /* SingleRelatedEntity.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B5217498985008D9D13 /* SingleRelatedEntity.json */; }; + C7CF9B6617498986008D9D13 /* SingleRelatedEntity.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B5217498985008D9D13 /* SingleRelatedEntity.json */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 903125911B103812000E8841 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 903125861B103812000E8841 /* Expecta.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 908379791A8B972C009844DA; + remoteInfo = Expecta; + }; + 903125931B103812000E8841 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 903125861B103812000E8841 /* Expecta.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 908379111A8B9660009844DA; + remoteInfo = "Expecta-iOS"; + }; + 903125951B103812000E8841 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 903125861B103812000E8841 /* Expecta.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 3A0A598C1AD4418C003DA3E4; + remoteInfo = ExpectaTests; + }; + 903125971B103812000E8841 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 903125861B103812000E8841 /* Expecta.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 3A0A59BF1AD441CB003DA3E4; + remoteInfo = "Expecta-iOSTests"; + }; + 903125991B103812000E8841 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 903125861B103812000E8841 /* Expecta.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = E9ACDF0C13B2DD520010F4D7; + remoteInfo = libExpecta; + }; + 9031259B1B103812000E8841 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 903125861B103812000E8841 /* Expecta.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = E93067CE13B2E6D100EA26FF; + remoteInfo = "libExpecta-iOS"; + }; + 9031259D1B103812000E8841 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 903125861B103812000E8841 /* Expecta.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 9C4416F917FF3F4A00978F09; + remoteInfo = libExpectaTests; + }; + 9031259F1B103812000E8841 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 903125861B103812000E8841 /* Expecta.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = E93067DA13B2E6D100EA26FF; + remoteInfo = "libExpecta-iOSTests"; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9004F5791A94D7C500A61312 /* Copy Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 9088CFC71B10440800E51758 /* Expecta.framework in Copy Frameworks */, + 9004F57A1A94D7D300A61312 /* MagicalRecord.framework in Copy Frameworks */, + ); + name = "Copy Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + 9004F57B1A94D7DC00A61312 /* Copy Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 9088CFC61B1043F500E51758 /* Expecta.framework in Copy Frameworks */, + 9004F57D1A94D7F100A61312 /* MagicalRecord.framework in Copy Frameworks */, + ); + name = "Copy Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + 907DAC031AFB24A5003D7BB4 /* Copy Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Copy Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + 907DAC051AFB24B8003D7BB4 /* Copy Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Copy Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + C7CF97A917498414008D9D13 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "include/${PRODUCT_NAME}"; + dstSubfolderSpec = 16; + files = ( + 1352E5841B175E6200182E53 /* MagicalRecord.h in CopyFiles */, + 1352E5851B175E6200182E53 /* MagicalImportFunctions.h in CopyFiles */, + 1352E5861B175E6200182E53 /* NSAttributeDescription+MagicalDataImport.h in CopyFiles */, + 1352E5871B175E6200182E53 /* NSEntityDescription+MagicalDataImport.h in CopyFiles */, + 1352E5881B175E6200182E53 /* NSNumber+MagicalDataImport.h in CopyFiles */, + 1352E5891B175E6200182E53 /* NSObject+MagicalDataImport.h in CopyFiles */, + 1352E58A1B175E6200182E53 /* NSRelationshipDescription+MagicalDataImport.h in CopyFiles */, + 1352E58B1B175E6200182E53 /* NSString+MagicalDataImport.h in CopyFiles */, + 1352E58C1B175E6200182E53 /* NSManagedObject+MagicalAggregation.h in CopyFiles */, + 1352E58D1B175E6200182E53 /* NSManagedObject+MagicalDataImport.h in CopyFiles */, + 1352E58E1B175E6200182E53 /* NSManagedObject+MagicalFinders.h in CopyFiles */, + 1352E58F1B175E6200182E53 /* NSManagedObject+MagicalRecord.h in CopyFiles */, + 1352E5901B175E6200182E53 /* NSManagedObject+MagicalRequests.h in CopyFiles */, + 1352E5911B175E6200182E53 /* NSManagedObjectContext+MagicalChainSave.h in CopyFiles */, + 1352E5921B175E6200182E53 /* NSManagedObjectContext+MagicalObserving.h in CopyFiles */, + 1352E5931B175E6200182E53 /* NSManagedObjectContext+MagicalRecord.h in CopyFiles */, + 1352E5941B175E6200182E53 /* NSManagedObjectContext+MagicalSaves.h in CopyFiles */, + 1352E5951B175E6200182E53 /* NSManagedObjectContext+MagicalThreading.h in CopyFiles */, + 1352E5961B175E6200182E53 /* NSManagedObjectModel+MagicalRecord.h in CopyFiles */, + 1352E5971B175E6200182E53 /* NSPersistentStore+MagicalRecord.h in CopyFiles */, + 1352E5981B175E6200182E53 /* NSPersistentStoreCoordinator+MagicalRecord.h in CopyFiles */, + 1352E5991B175E6200182E53 /* MagicalRecord+Actions.h in CopyFiles */, + 1352E59A1B175E6200182E53 /* MagicalRecord+ErrorHandling.h in CopyFiles */, + 1352E59B1B175E6200182E53 /* MagicalRecord+iCloud.h in CopyFiles */, + 1352E59C1B175E6200182E53 /* MagicalRecord+Options.h in CopyFiles */, + 1352E59D1B175E6200182E53 /* MagicalRecord+Setup.h in CopyFiles */, + 1352E59E1B175E6200182E53 /* MagicalRecord+ShorthandMethods.h in CopyFiles */, + 1352E59F1B175E6200182E53 /* MagicalRecordDeprecationMacros.h in CopyFiles */, + 1352E5A01B175E6200182E53 /* MagicalRecordInternal.h in CopyFiles */, + 1352E5A11B175E6200182E53 /* MagicalRecordLogging.h in CopyFiles */, + 1352E5A21B175E6200182E53 /* MagicalRecordShorthandMethodAliases.h in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 581ECBEB187F63FF00084FEE /* ImportMultipleEntitiesWithNoPrimaryKeyTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImportMultipleEntitiesWithNoPrimaryKeyTests.m; sourceTree = ""; }; + 581ECBF6187F660B00084FEE /* MultipleEntitiesWithNoPrimaryKey.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = MultipleEntitiesWithNoPrimaryKey.json; path = Fixtures/MultipleEntitiesWithNoPrimaryKey.json; sourceTree = ""; }; + 9004F5211A94CBCF00A61312 /* MagicalRecord for iOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "MagicalRecord for iOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 9004F5661A94CBF900A61312 /* MagicalRecord for OS X Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "MagicalRecord for OS X Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 9021D9E11AFB34D6001C80BA /* MagicalRecordTestHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MagicalRecordTestHelpers.h; path = Tests/Support/MagicalRecordTestHelpers.h; sourceTree = SOURCE_ROOT; }; + 9021D9E21AFB34D6001C80BA /* MagicalRecordTestHelpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MagicalRecordTestHelpers.m; path = Tests/Support/MagicalRecordTestHelpers.m; sourceTree = SOURCE_ROOT; }; + 902CE11E18F6133E0024F47C /* MagicalRecordDeprecationMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MagicalRecordDeprecationMacros.h; sourceTree = ""; }; + 902CE12B18F61A2F0024F47C /* MagicalRecord+ActionsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+ActionsTests.m"; sourceTree = ""; }; + 902CE13818F61E410024F47C /* NSManagedObjectContext+MagicalSavesTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectContext+MagicalSavesTests.m"; sourceTree = ""; }; + 903125861B103812000E8841 /* Expecta.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Expecta.xcodeproj; path = Carthage/Checkouts/expecta/Expecta.xcodeproj; sourceTree = SOURCE_ROOT; }; + 90425379187103D00066DA41 /* MagicalRecordTests-iOS-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "MagicalRecordTests-iOS-Info.plist"; sourceTree = ""; }; + 9042537A187103D00066DA41 /* MagicalRecordTests-iOS-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MagicalRecordTests-iOS-Prefix.pch"; sourceTree = ""; }; + 9042537B187103D00066DA41 /* MagicalRecordTests-OSX-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "MagicalRecordTests-OSX-Info.plist"; sourceTree = ""; }; + 9042537C187103D00066DA41 /* MagicalRecordTests-OSX-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MagicalRecordTests-OSX-Prefix.pch"; sourceTree = ""; }; + 905D07181A63DE190076B54E /* MagicalRecord.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MagicalRecord.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 905D073B1A63DE690076B54E /* MagicalRecord.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MagicalRecord.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 905D07C91A63DFED0076B54E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9099490917C2F3D400BC2B5C /* TestModel.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = TestModel.xcdatamodel; sourceTree = ""; }; + 9099490D17C2F42100BC2B5C /* _AbstractRelatedEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _AbstractRelatedEntity.h; sourceTree = ""; }; + 9099490E17C2F42100BC2B5C /* _AbstractRelatedEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = _AbstractRelatedEntity.m; sourceTree = ""; }; + 9099490F17C2F42100BC2B5C /* _ConcreteRelatedEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _ConcreteRelatedEntity.h; sourceTree = ""; }; + 9099491017C2F42100BC2B5C /* _ConcreteRelatedEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = _ConcreteRelatedEntity.m; sourceTree = ""; }; + 9099491117C2F42100BC2B5C /* _DifferentClassNameMapping.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _DifferentClassNameMapping.h; sourceTree = ""; }; + 9099491217C2F42100BC2B5C /* _DifferentClassNameMapping.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = _DifferentClassNameMapping.m; sourceTree = ""; }; + 9099491317C2F42100BC2B5C /* _MappedEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _MappedEntity.h; sourceTree = ""; }; + 9099491417C2F42100BC2B5C /* _MappedEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = _MappedEntity.m; sourceTree = ""; }; + 9099491517C2F42100BC2B5C /* _SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.h; sourceTree = ""; }; + 9099491617C2F42100BC2B5C /* _SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = _SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m; sourceTree = ""; }; + 9099491717C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityUsingDefaults.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _SingleEntityRelatedToMappedEntityUsingDefaults.h; sourceTree = ""; }; + 9099491817C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityUsingDefaults.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = _SingleEntityRelatedToMappedEntityUsingDefaults.m; sourceTree = ""; }; + 9099491917C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.h; sourceTree = ""; }; + 9099491A17C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = _SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m; sourceTree = ""; }; + 9099491B17C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.h; sourceTree = ""; }; + 9099491C17C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = _SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m; sourceTree = ""; }; + 9099491D17C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityWithSecondaryMappings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _SingleEntityRelatedToMappedEntityWithSecondaryMappings.h; sourceTree = ""; }; + 9099491E17C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityWithSecondaryMappings.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = _SingleEntityRelatedToMappedEntityWithSecondaryMappings.m; sourceTree = ""; }; + 9099491F17C2F42100BC2B5C /* _SingleEntityWithNoRelationships.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _SingleEntityWithNoRelationships.h; sourceTree = ""; }; + 9099492017C2F42100BC2B5C /* _SingleEntityWithNoRelationships.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = _SingleEntityWithNoRelationships.m; sourceTree = ""; }; + 9099492117C2F42100BC2B5C /* _SingleRelatedEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _SingleRelatedEntity.h; sourceTree = ""; }; + 9099492217C2F42100BC2B5C /* _SingleRelatedEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = _SingleRelatedEntity.m; sourceTree = ""; }; + 9099492317C2F42100BC2B5C /* AbstractRelatedEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AbstractRelatedEntity.h; sourceTree = ""; }; + 9099492417C2F42100BC2B5C /* AbstractRelatedEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AbstractRelatedEntity.m; sourceTree = ""; }; + 9099492517C2F42100BC2B5C /* ConcreteRelatedEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConcreteRelatedEntity.h; sourceTree = ""; }; + 9099492617C2F42100BC2B5C /* ConcreteRelatedEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConcreteRelatedEntity.m; sourceTree = ""; }; + 9099492717C2F42100BC2B5C /* DifferentClassNameMapping.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DifferentClassNameMapping.h; sourceTree = ""; }; + 9099492817C2F42100BC2B5C /* DifferentClassNameMapping.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DifferentClassNameMapping.m; sourceTree = ""; }; + 9099492917C2F42100BC2B5C /* MappedEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MappedEntity.h; sourceTree = ""; }; + 9099492A17C2F42100BC2B5C /* MappedEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MappedEntity.m; sourceTree = ""; }; + 9099492B17C2F42100BC2B5C /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.h; sourceTree = ""; }; + 9099492C17C2F42100BC2B5C /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m; sourceTree = ""; }; + 9099492D17C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityUsingDefaults.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SingleEntityRelatedToMappedEntityUsingDefaults.h; sourceTree = ""; }; + 9099492E17C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityUsingDefaults.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SingleEntityRelatedToMappedEntityUsingDefaults.m; sourceTree = ""; }; + 9099492F17C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.h; sourceTree = ""; }; + 9099493017C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m; sourceTree = ""; }; + 9099493117C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.h; sourceTree = ""; }; + 9099493217C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m; sourceTree = ""; }; + 9099493317C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SingleEntityRelatedToMappedEntityWithSecondaryMappings.h; sourceTree = ""; }; + 9099493417C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SingleEntityRelatedToMappedEntityWithSecondaryMappings.m; sourceTree = ""; }; + 9099493517C2F42100BC2B5C /* SingleEntityWithNoRelationships.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SingleEntityWithNoRelationships.h; sourceTree = ""; }; + 9099493617C2F42100BC2B5C /* SingleEntityWithNoRelationships.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SingleEntityWithNoRelationships.m; sourceTree = ""; }; + 9099493717C2F42100BC2B5C /* SingleRelatedEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SingleRelatedEntity.h; sourceTree = ""; }; + 9099493817C2F42100BC2B5C /* SingleRelatedEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SingleRelatedEntity.m; sourceTree = ""; }; + 90AA771718F79A3300D49377 /* NSManagedObject+MagicalRecordTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+MagicalRecordTests.m"; sourceTree = ""; }; + 90AA772318F79CCC00D49377 /* EntityWithoutEntityNameMethod.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EntityWithoutEntityNameMethod.h; sourceTree = ""; }; + 90AA772418F79CCC00D49377 /* EntityWithoutEntityNameMethod.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EntityWithoutEntityNameMethod.m; sourceTree = ""; }; + 90B05B851B02450900354056 /* MagicalRecordShorthandMethodAliases.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MagicalRecordShorthandMethodAliases.h; sourceTree = ""; }; + 90B05B891B02452A00354056 /* MagicalRecord+ShorthandMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord+ShorthandMethods.h"; sourceTree = ""; }; + 90B05B8A1B02452A00354056 /* MagicalRecord+ShorthandMethods.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+ShorthandMethods.m"; sourceTree = ""; }; + 90BB1C3E1864F662001BBFBB /* ImportSingleRelatedEntityTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImportSingleRelatedEntityTests.m; sourceTree = ""; }; + 90BB1C4518651539001BBFBB /* MagicalRecordTestBase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MagicalRecordTestBase.m; sourceTree = ""; }; + 90BB1C481865155B001BBFBB /* MagicalRecordTestBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MagicalRecordTestBase.h; sourceTree = ""; }; + 90FEC08B18F42DEA002FFC2F /* MagicalRecordLogging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MagicalRecordLogging.h; sourceTree = ""; }; + 9BB566891A2C44C4004174B3 /* NSManagedObjectContext+MagicalChainSave.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObjectContext+MagicalChainSave.h"; sourceTree = ""; }; + 9BB5668A1A2C44C4004174B3 /* NSManagedObjectContext+MagicalChainSave.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectContext+MagicalChainSave.m"; sourceTree = ""; }; + 9BB566931A2C47B3004174B3 /* NSManagedObjectContext+ChainSaveTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectContext+ChainSaveTests.m"; sourceTree = ""; }; + C7CF976817498275008D9D13 /* MagicalRecord+StackTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+StackTests.m"; sourceTree = ""; }; + C7CF976A17498275008D9D13 /* NSManagedObjectContextHelperTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSManagedObjectContextHelperTests.m; sourceTree = ""; }; + C7CF976C17498275008D9D13 /* NSManagedObjectHelperTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSManagedObjectHelperTests.m; sourceTree = ""; }; + C7CF977017498275008D9D13 /* NSPersistentStoreHelperTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSPersistentStoreHelperTests.m; sourceTree = ""; }; + C7CF977217498275008D9D13 /* NSPersistentStoreCoordinatorHelperTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSPersistentStoreCoordinatorHelperTests.m; sourceTree = ""; }; + C7CF9786174982AD008D9D13 /* ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m; sourceTree = ""; }; + C7CF9787174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m; sourceTree = ""; }; + C7CF9788174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m; sourceTree = ""; }; + C7CF9789174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m; sourceTree = ""; }; + C7CF978A174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m; sourceTree = ""; }; + C7CF978B174982AD008D9D13 /* ImportSingleEntityWithNoRelationshipsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImportSingleEntityWithNoRelationshipsTests.m; sourceTree = ""; }; + C7CF978D174982AD008D9D13 /* MagicalDataImportTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MagicalDataImportTestCase.h; sourceTree = ""; }; + C7CF978E174982AD008D9D13 /* MagicalDataImportTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MagicalDataImportTestCase.m; sourceTree = ""; }; + C7CF97AB17498414008D9D13 /* libMagicalRecord.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libMagicalRecord.a; sourceTree = BUILT_PRODUCTS_DIR; }; + C7CF97BB1749843F008D9D13 /* libMagicalRecord.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libMagicalRecord.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; + C7CF97FF174984CA008D9D13 /* libMagicalRecord for iOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "libMagicalRecord for iOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + C7CF9816174984E4008D9D13 /* libMagicalRecord for OS X Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "libMagicalRecord for OS X Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + C7CF9B4917498985008D9D13 /* SampleJSONDataForImport.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = SampleJSONDataForImport.json; path = Fixtures/SampleJSONDataForImport.json; sourceTree = ""; }; + C7CF9B4A17498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json; path = Fixtures/SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json; sourceTree = ""; }; + C7CF9B4B17498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json; path = Fixtures/SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json; sourceTree = ""; }; + C7CF9B4C17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingDefaults.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = SingleEntityRelatedToMappedEntityUsingDefaults.json; path = Fixtures/SingleEntityRelatedToMappedEntityUsingDefaults.json; sourceTree = ""; }; + C7CF9B4D17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json; path = Fixtures/SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json; sourceTree = ""; }; + C7CF9B4E17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json; path = Fixtures/SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json; sourceTree = ""; }; + C7CF9B4F17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = SingleEntityRelatedToMappedEntityWithSecondaryMappings.json; path = Fixtures/SingleEntityRelatedToMappedEntityWithSecondaryMappings.json; sourceTree = ""; }; + C7CF9B5017498985008D9D13 /* SingleEntityWithNoRelationships.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = SingleEntityWithNoRelationships.json; path = Fixtures/SingleEntityWithNoRelationships.json; sourceTree = ""; }; + C7CF9B5117498985008D9D13 /* SingleEntityWithNoRelationships.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = SingleEntityWithNoRelationships.plist; path = Fixtures/SingleEntityWithNoRelationships.plist; sourceTree = ""; }; + C7CF9B5217498985008D9D13 /* SingleRelatedEntity.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = SingleRelatedEntity.json; path = Fixtures/SingleRelatedEntity.json; sourceTree = ""; }; + C7CF9B6B17498B5C008D9D13 /* FixtureHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FixtureHelpers.h; path = Fixtures/FixtureHelpers.h; sourceTree = ""; }; + C7CF9B6C17498B5C008D9D13 /* FixtureHelpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FixtureHelpers.m; path = Fixtures/FixtureHelpers.m; sourceTree = ""; }; + C7DD729C150F832A00216827 /* MagicalImportFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MagicalImportFunctions.h; sourceTree = ""; }; + C7DD729D150F832A00216827 /* MagicalImportFunctions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MagicalImportFunctions.m; sourceTree = ""; }; + C7DD729E150F832A00216827 /* NSAttributeDescription+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSAttributeDescription+MagicalDataImport.h"; sourceTree = ""; }; + C7DD729F150F832A00216827 /* NSAttributeDescription+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSAttributeDescription+MagicalDataImport.m"; sourceTree = ""; }; + C7DD72A0150F832A00216827 /* NSEntityDescription+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSEntityDescription+MagicalDataImport.h"; sourceTree = ""; }; + C7DD72A1150F832A00216827 /* NSEntityDescription+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSEntityDescription+MagicalDataImport.m"; sourceTree = ""; }; + C7DD72A2150F832A00216827 /* NSNumber+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSNumber+MagicalDataImport.h"; sourceTree = ""; }; + C7DD72A3150F832A00216827 /* NSNumber+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSNumber+MagicalDataImport.m"; sourceTree = ""; }; + C7DD72A4150F832A00216827 /* NSObject+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+MagicalDataImport.h"; sourceTree = ""; }; + C7DD72A5150F832A00216827 /* NSObject+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+MagicalDataImport.m"; sourceTree = ""; }; + C7DD72A6150F832A00216827 /* NSRelationshipDescription+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSRelationshipDescription+MagicalDataImport.h"; sourceTree = ""; }; + C7DD72A7150F832A00216827 /* NSRelationshipDescription+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSRelationshipDescription+MagicalDataImport.m"; sourceTree = ""; }; + C7DD72A8150F832A00216827 /* NSString+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+MagicalDataImport.h"; sourceTree = ""; }; + C7DD72A9150F832A00216827 /* NSString+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+MagicalDataImport.m"; sourceTree = ""; }; + C7DD72AB150F832A00216827 /* NSManagedObject+MagicalAggregation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+MagicalAggregation.h"; sourceTree = ""; }; + C7DD72AC150F832A00216827 /* NSManagedObject+MagicalAggregation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+MagicalAggregation.m"; sourceTree = ""; }; + C7DD72AD150F832A00216827 /* NSManagedObject+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+MagicalDataImport.h"; sourceTree = ""; }; + C7DD72AE150F832A00216827 /* NSManagedObject+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+MagicalDataImport.m"; sourceTree = ""; }; + C7DD72AF150F832A00216827 /* NSManagedObject+MagicalFinders.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+MagicalFinders.h"; sourceTree = ""; }; + C7DD72B0150F832A00216827 /* NSManagedObject+MagicalFinders.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+MagicalFinders.m"; sourceTree = ""; }; + C7DD72B1150F832A00216827 /* NSManagedObject+MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+MagicalRecord.h"; sourceTree = ""; }; + C7DD72B2150F832A00216827 /* NSManagedObject+MagicalRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+MagicalRecord.m"; sourceTree = ""; }; + C7DD72B3150F832A00216827 /* NSManagedObject+MagicalRequests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+MagicalRequests.h"; sourceTree = ""; }; + C7DD72B4150F832A00216827 /* NSManagedObject+MagicalRequests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+MagicalRequests.m"; sourceTree = ""; }; + C7DD72B6150F832A00216827 /* NSManagedObjectContext+MagicalObserving.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObjectContext+MagicalObserving.h"; sourceTree = ""; }; + C7DD72B7150F832A00216827 /* NSManagedObjectContext+MagicalObserving.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectContext+MagicalObserving.m"; sourceTree = ""; }; + C7DD72B8150F832A00216827 /* NSManagedObjectContext+MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObjectContext+MagicalRecord.h"; sourceTree = ""; }; + C7DD72B9150F832A00216827 /* NSManagedObjectContext+MagicalRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectContext+MagicalRecord.m"; sourceTree = ""; }; + C7DD72BA150F832A00216827 /* NSManagedObjectContext+MagicalSaves.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObjectContext+MagicalSaves.h"; sourceTree = ""; }; + C7DD72BB150F832A00216827 /* NSManagedObjectContext+MagicalSaves.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectContext+MagicalSaves.m"; sourceTree = ""; }; + C7DD72BC150F832A00216827 /* NSManagedObjectContext+MagicalThreading.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObjectContext+MagicalThreading.h"; sourceTree = ""; }; + C7DD72BD150F832A00216827 /* NSManagedObjectContext+MagicalThreading.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectContext+MagicalThreading.m"; sourceTree = ""; }; + C7DD72BE150F832A00216827 /* NSManagedObjectModel+MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObjectModel+MagicalRecord.h"; sourceTree = ""; }; + C7DD72BF150F832A00216827 /* NSManagedObjectModel+MagicalRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectModel+MagicalRecord.m"; sourceTree = ""; }; + C7DD72C0150F832A00216827 /* NSPersistentStore+MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSPersistentStore+MagicalRecord.h"; sourceTree = ""; }; + C7DD72C1150F832A00216827 /* NSPersistentStore+MagicalRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSPersistentStore+MagicalRecord.m"; sourceTree = ""; }; + C7DD72C2150F832A00216827 /* NSPersistentStoreCoordinator+MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSPersistentStoreCoordinator+MagicalRecord.h"; sourceTree = ""; }; + C7DD72C3150F832A00216827 /* NSPersistentStoreCoordinator+MagicalRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSPersistentStoreCoordinator+MagicalRecord.m"; sourceTree = ""; }; + C7DD72C5150F832A00216827 /* MagicalRecord+Actions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord+Actions.h"; sourceTree = ""; }; + C7DD72C6150F832A00216827 /* MagicalRecord+Actions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+Actions.m"; sourceTree = ""; }; + C7DD72C7150F832A00216827 /* MagicalRecord+ErrorHandling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord+ErrorHandling.h"; sourceTree = ""; }; + C7DD72C8150F832A00216827 /* MagicalRecord+ErrorHandling.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+ErrorHandling.m"; sourceTree = ""; }; + C7DD72C9150F832A00216827 /* MagicalRecord+iCloud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord+iCloud.h"; sourceTree = ""; }; + C7DD72CA150F832A00216827 /* MagicalRecord+iCloud.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+iCloud.m"; sourceTree = ""; }; + C7DD72CB150F832A00216827 /* MagicalRecord+Options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord+Options.h"; sourceTree = ""; }; + C7DD72CC150F832A00216827 /* MagicalRecord+Options.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+Options.m"; sourceTree = ""; }; + C7DD72CD150F832A00216827 /* MagicalRecord+Setup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord+Setup.h"; sourceTree = ""; }; + C7DD72CE150F832A00216827 /* MagicalRecord+Setup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+Setup.m"; sourceTree = ""; }; + C7DD72D1150F832A00216827 /* MagicalRecordInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MagicalRecordInternal.h; sourceTree = ""; }; + C7DD72D2150F832A00216827 /* MagicalRecordInternal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MagicalRecordInternal.m; sourceTree = ""; }; + C7DD72D4150F832A00216827 /* MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MagicalRecord.h; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 9004F50E1A94CBCF00A61312 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9004F5231A94CBF300A61312 /* MagicalRecord.framework in Frameworks */, + 903125A11B10384A000E8841 /* Expecta.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9004F5531A94CBF900A61312 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 903125A21B103860000E8841 /* Expecta.framework in Frameworks */, + 9004F5681A94CC0E00A61312 /* MagicalRecord.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 905D07141A63DE190076B54E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 905D07371A63DE690076B54E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C7CF97A817498414008D9D13 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C7CF97B81749843F008D9D13 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C7CF97FB174984CA008D9D13 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 903125A41B103886000E8841 /* libExpecta.a in Frameworks */, + 9004F4DF1A94C76E00A61312 /* libMagicalRecord.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C7CF9812174984E4008D9D13 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 903125A31B103881000E8841 /* libExpecta.a in Frameworks */, + 9004F4DE1A94C76A00A61312 /* libMagicalRecord.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 902CE13718F61E170024F47C /* Abstract */ = { + isa = PBXGroup; + children = ( + 90BB1C481865155B001BBFBB /* MagicalRecordTestBase.h */, + 90BB1C4518651539001BBFBB /* MagicalRecordTestBase.m */, + ); + name = Abstract; + sourceTree = ""; + }; + 903125871B103812000E8841 /* Products */ = { + isa = PBXGroup; + children = ( + 903125921B103812000E8841 /* Expecta.framework */, + 903125941B103812000E8841 /* Expecta.framework */, + 903125961B103812000E8841 /* ExpectaTests.xctest */, + 903125981B103812000E8841 /* Expecta-iOSTests.xctest */, + 9031259A1B103812000E8841 /* libExpecta.a */, + 9031259C1B103812000E8841 /* libExpecta.a */, + 9031259E1B103812000E8841 /* libExpectaTests.xctest */, + 903125A01B103812000E8841 /* libExpecta-iOSTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 90425374187102DC0066DA41 /* Support */ = { + isa = PBXGroup; + children = ( + 905D07C91A63DFED0076B54E /* Info.plist */, + ); + path = Support; + sourceTree = ""; + }; + 90425378187103D00066DA41 /* Support */ = { + isa = PBXGroup; + children = ( + 9021D9E11AFB34D6001C80BA /* MagicalRecordTestHelpers.h */, + 9021D9E21AFB34D6001C80BA /* MagicalRecordTestHelpers.m */, + 90425379187103D00066DA41 /* MagicalRecordTests-iOS-Info.plist */, + 9042537A187103D00066DA41 /* MagicalRecordTests-iOS-Prefix.pch */, + 9042537B187103D00066DA41 /* MagicalRecordTests-OSX-Info.plist */, + 9042537C187103D00066DA41 /* MagicalRecordTests-OSX-Prefix.pch */, + ); + path = Support; + sourceTree = ""; + }; + 907DABF31AFB204D003D7BB4 /* Vendor */ = { + isa = PBXGroup; + children = ( + 903125861B103812000E8841 /* Expecta.xcodeproj */, + ); + name = Vendor; + sourceTree = ""; + }; + 9099490C17C2F42100BC2B5C /* TestModel */ = { + isa = PBXGroup; + children = ( + 9099490D17C2F42100BC2B5C /* _AbstractRelatedEntity.h */, + 9099490E17C2F42100BC2B5C /* _AbstractRelatedEntity.m */, + 9099490F17C2F42100BC2B5C /* _ConcreteRelatedEntity.h */, + 9099491017C2F42100BC2B5C /* _ConcreteRelatedEntity.m */, + 9099491117C2F42100BC2B5C /* _DifferentClassNameMapping.h */, + 9099491217C2F42100BC2B5C /* _DifferentClassNameMapping.m */, + 9099491317C2F42100BC2B5C /* _MappedEntity.h */, + 9099491417C2F42100BC2B5C /* _MappedEntity.m */, + 9099491517C2F42100BC2B5C /* _SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.h */, + 9099491617C2F42100BC2B5C /* _SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m */, + 9099491717C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityUsingDefaults.h */, + 9099491817C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityUsingDefaults.m */, + 9099491917C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.h */, + 9099491A17C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m */, + 9099491B17C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.h */, + 9099491C17C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m */, + 9099491D17C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityWithSecondaryMappings.h */, + 9099491E17C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityWithSecondaryMappings.m */, + 9099491F17C2F42100BC2B5C /* _SingleEntityWithNoRelationships.h */, + 9099492017C2F42100BC2B5C /* _SingleEntityWithNoRelationships.m */, + 9099492117C2F42100BC2B5C /* _SingleRelatedEntity.h */, + 9099492217C2F42100BC2B5C /* _SingleRelatedEntity.m */, + 9099492317C2F42100BC2B5C /* AbstractRelatedEntity.h */, + 9099492417C2F42100BC2B5C /* AbstractRelatedEntity.m */, + 9099492517C2F42100BC2B5C /* ConcreteRelatedEntity.h */, + 9099492617C2F42100BC2B5C /* ConcreteRelatedEntity.m */, + 9099492717C2F42100BC2B5C /* DifferentClassNameMapping.h */, + 9099492817C2F42100BC2B5C /* DifferentClassNameMapping.m */, + 90AA772318F79CCC00D49377 /* EntityWithoutEntityNameMethod.h */, + 90AA772418F79CCC00D49377 /* EntityWithoutEntityNameMethod.m */, + 9099492917C2F42100BC2B5C /* MappedEntity.h */, + 9099492A17C2F42100BC2B5C /* MappedEntity.m */, + 9099492B17C2F42100BC2B5C /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.h */, + 9099492C17C2F42100BC2B5C /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m */, + 9099492D17C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityUsingDefaults.h */, + 9099492E17C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityUsingDefaults.m */, + 9099492F17C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.h */, + 9099493017C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m */, + 9099493117C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.h */, + 9099493217C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m */, + 9099493317C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.h */, + 9099493417C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.m */, + 9099493517C2F42100BC2B5C /* SingleEntityWithNoRelationships.h */, + 9099493617C2F42100BC2B5C /* SingleEntityWithNoRelationships.m */, + 9099493717C2F42100BC2B5C /* SingleRelatedEntity.h */, + 9099493817C2F42100BC2B5C /* SingleRelatedEntity.m */, + ); + name = TestModel; + path = Fixtures/TestModel; + sourceTree = ""; + }; + 90CE059118F62B5B008CC79A /* Abstract */ = { + isa = PBXGroup; + children = ( + C7CF978D174982AD008D9D13 /* MagicalDataImportTestCase.h */, + C7CF978E174982AD008D9D13 /* MagicalDataImportTestCase.m */, + ); + name = Abstract; + sourceTree = ""; + }; + C721C7A013D0A3750097AB6F = { + isa = PBXGroup; + children = ( + C7DD7299150F832A00216827 /* MagicalRecord */, + C77E5FA513D0CBA600298F87 /* Tests */, + 90425374187102DC0066DA41 /* Support */, + C721C7B113D0A3AF0097AB6F /* Products */, + ); + sourceTree = ""; + }; + C721C7B113D0A3AF0097AB6F /* Products */ = { + isa = PBXGroup; + children = ( + C7CF97AB17498414008D9D13 /* libMagicalRecord.a */, + C7CF97BB1749843F008D9D13 /* libMagicalRecord.dylib */, + C7CF97FF174984CA008D9D13 /* libMagicalRecord for iOS Tests.xctest */, + C7CF9816174984E4008D9D13 /* libMagicalRecord for OS X Tests.xctest */, + 905D07181A63DE190076B54E /* MagicalRecord.framework */, + 905D073B1A63DE690076B54E /* MagicalRecord.framework */, + 9004F5211A94CBCF00A61312 /* MagicalRecord for iOS Tests.xctest */, + 9004F5661A94CBF900A61312 /* MagicalRecord for OS X Tests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + C77E5FA513D0CBA600298F87 /* Tests */ = { + isa = PBXGroup; + children = ( + C7CF976617498275008D9D13 /* Core */, + C7CF9785174982AD008D9D13 /* DataImport */, + C77E5FA913D0CBE300298F87 /* Fixtures */, + 90425378187103D00066DA41 /* Support */, + 907DABF31AFB204D003D7BB4 /* Vendor */, + ); + path = Tests; + sourceTree = ""; + }; + C77E5FA913D0CBE300298F87 /* Fixtures */ = { + isa = PBXGroup; + children = ( + C7CF9B6B17498B5C008D9D13 /* FixtureHelpers.h */, + C7CF9B6C17498B5C008D9D13 /* FixtureHelpers.m */, + C77E5FB113D0D18D00298F87 /* Sample Data Files */, + C77E5FB013D0D18000298F87 /* Sample Models */, + ); + name = Fixtures; + sourceTree = ""; + }; + C77E5FB013D0D18000298F87 /* Sample Models */ = { + isa = PBXGroup; + children = ( + 9099490817C2F3D400BC2B5C /* TestModel.xcdatamodeld */, + 9099490C17C2F42100BC2B5C /* TestModel */, + ); + name = "Sample Models"; + sourceTree = ""; + }; + C77E5FB113D0D18D00298F87 /* Sample Data Files */ = { + isa = PBXGroup; + children = ( + C7CF9B4917498985008D9D13 /* SampleJSONDataForImport.json */, + C7CF9B4A17498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json */, + C7CF9B4B17498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json */, + C7CF9B4C17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingDefaults.json */, + C7CF9B4D17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json */, + C7CF9B4E17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json */, + C7CF9B4F17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.json */, + C7CF9B5017498985008D9D13 /* SingleEntityWithNoRelationships.json */, + 581ECBF6187F660B00084FEE /* MultipleEntitiesWithNoPrimaryKey.json */, + C7CF9B5117498985008D9D13 /* SingleEntityWithNoRelationships.plist */, + C7CF9B5217498985008D9D13 /* SingleRelatedEntity.json */, + ); + name = "Sample Data Files"; + sourceTree = ""; + }; + C7CF976617498275008D9D13 /* Core */ = { + isa = PBXGroup; + children = ( + 902CE13718F61E170024F47C /* Abstract */, + 902CE12B18F61A2F0024F47C /* MagicalRecord+ActionsTests.m */, + C7CF976817498275008D9D13 /* MagicalRecord+StackTests.m */, + 90AA771718F79A3300D49377 /* NSManagedObject+MagicalRecordTests.m */, + 9BB566931A2C47B3004174B3 /* NSManagedObjectContext+ChainSaveTests.m */, + 902CE13818F61E410024F47C /* NSManagedObjectContext+MagicalSavesTests.m */, + C7CF976A17498275008D9D13 /* NSManagedObjectContextHelperTests.m */, + C7CF976C17498275008D9D13 /* NSManagedObjectHelperTests.m */, + C7CF977217498275008D9D13 /* NSPersistentStoreCoordinatorHelperTests.m */, + C7CF977017498275008D9D13 /* NSPersistentStoreHelperTests.m */, + ); + path = Core; + sourceTree = ""; + }; + C7CF9785174982AD008D9D13 /* DataImport */ = { + isa = PBXGroup; + children = ( + 90CE059118F62B5B008CC79A /* Abstract */, + 581ECBEB187F63FF00084FEE /* ImportMultipleEntitiesWithNoPrimaryKeyTests.m */, + C7CF9786174982AD008D9D13 /* ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m */, + C7CF9787174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m */, + C7CF9788174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m */, + C7CF9789174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m */, + C7CF978A174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m */, + C7CF978B174982AD008D9D13 /* ImportSingleEntityWithNoRelationshipsTests.m */, + 90BB1C3E1864F662001BBFBB /* ImportSingleRelatedEntityTests.m */, + ); + path = DataImport; + sourceTree = ""; + }; + C7DD7299150F832A00216827 /* MagicalRecord */ = { + isa = PBXGroup; + children = ( + C7DD72D4150F832A00216827 /* MagicalRecord.h */, + C7DD729A150F832A00216827 /* Categories */, + C7DD72C4150F832A00216827 /* Core */, + ); + path = MagicalRecord; + sourceTree = ""; + }; + C7DD729A150F832A00216827 /* Categories */ = { + isa = PBXGroup; + children = ( + C7DD729B150F832A00216827 /* DataImport */, + C7DD72AA150F832A00216827 /* NSManagedObject */, + C7DD72B5150F832A00216827 /* NSManagedObjectContext */, + C7DD72BE150F832A00216827 /* NSManagedObjectModel+MagicalRecord.h */, + C7DD72BF150F832A00216827 /* NSManagedObjectModel+MagicalRecord.m */, + C7DD72C0150F832A00216827 /* NSPersistentStore+MagicalRecord.h */, + C7DD72C1150F832A00216827 /* NSPersistentStore+MagicalRecord.m */, + C7DD72C2150F832A00216827 /* NSPersistentStoreCoordinator+MagicalRecord.h */, + C7DD72C3150F832A00216827 /* NSPersistentStoreCoordinator+MagicalRecord.m */, + ); + path = Categories; + sourceTree = ""; + }; + C7DD729B150F832A00216827 /* DataImport */ = { + isa = PBXGroup; + children = ( + C7DD729C150F832A00216827 /* MagicalImportFunctions.h */, + C7DD729D150F832A00216827 /* MagicalImportFunctions.m */, + C7DD729E150F832A00216827 /* NSAttributeDescription+MagicalDataImport.h */, + C7DD729F150F832A00216827 /* NSAttributeDescription+MagicalDataImport.m */, + C7DD72A0150F832A00216827 /* NSEntityDescription+MagicalDataImport.h */, + C7DD72A1150F832A00216827 /* NSEntityDescription+MagicalDataImport.m */, + C7DD72A2150F832A00216827 /* NSNumber+MagicalDataImport.h */, + C7DD72A3150F832A00216827 /* NSNumber+MagicalDataImport.m */, + C7DD72A4150F832A00216827 /* NSObject+MagicalDataImport.h */, + C7DD72A5150F832A00216827 /* NSObject+MagicalDataImport.m */, + C7DD72A6150F832A00216827 /* NSRelationshipDescription+MagicalDataImport.h */, + C7DD72A7150F832A00216827 /* NSRelationshipDescription+MagicalDataImport.m */, + C7DD72A8150F832A00216827 /* NSString+MagicalDataImport.h */, + C7DD72A9150F832A00216827 /* NSString+MagicalDataImport.m */, + ); + path = DataImport; + sourceTree = ""; + }; + C7DD72AA150F832A00216827 /* NSManagedObject */ = { + isa = PBXGroup; + children = ( + C7DD72AB150F832A00216827 /* NSManagedObject+MagicalAggregation.h */, + C7DD72AC150F832A00216827 /* NSManagedObject+MagicalAggregation.m */, + C7DD72AD150F832A00216827 /* NSManagedObject+MagicalDataImport.h */, + C7DD72AE150F832A00216827 /* NSManagedObject+MagicalDataImport.m */, + C7DD72AF150F832A00216827 /* NSManagedObject+MagicalFinders.h */, + C7DD72B0150F832A00216827 /* NSManagedObject+MagicalFinders.m */, + C7DD72B1150F832A00216827 /* NSManagedObject+MagicalRecord.h */, + C7DD72B2150F832A00216827 /* NSManagedObject+MagicalRecord.m */, + C7DD72B3150F832A00216827 /* NSManagedObject+MagicalRequests.h */, + C7DD72B4150F832A00216827 /* NSManagedObject+MagicalRequests.m */, + ); + path = NSManagedObject; + sourceTree = ""; + }; + C7DD72B5150F832A00216827 /* NSManagedObjectContext */ = { + isa = PBXGroup; + children = ( + 9BB566891A2C44C4004174B3 /* NSManagedObjectContext+MagicalChainSave.h */, + 9BB5668A1A2C44C4004174B3 /* NSManagedObjectContext+MagicalChainSave.m */, + C7DD72B6150F832A00216827 /* NSManagedObjectContext+MagicalObserving.h */, + C7DD72B7150F832A00216827 /* NSManagedObjectContext+MagicalObserving.m */, + C7DD72B8150F832A00216827 /* NSManagedObjectContext+MagicalRecord.h */, + C7DD72B9150F832A00216827 /* NSManagedObjectContext+MagicalRecord.m */, + C7DD72BA150F832A00216827 /* NSManagedObjectContext+MagicalSaves.h */, + C7DD72BB150F832A00216827 /* NSManagedObjectContext+MagicalSaves.m */, + C7DD72BC150F832A00216827 /* NSManagedObjectContext+MagicalThreading.h */, + C7DD72BD150F832A00216827 /* NSManagedObjectContext+MagicalThreading.m */, + ); + path = NSManagedObjectContext; + sourceTree = ""; + }; + C7DD72C4150F832A00216827 /* Core */ = { + isa = PBXGroup; + children = ( + C7DD72C5150F832A00216827 /* MagicalRecord+Actions.h */, + C7DD72C6150F832A00216827 /* MagicalRecord+Actions.m */, + C7DD72C7150F832A00216827 /* MagicalRecord+ErrorHandling.h */, + C7DD72C8150F832A00216827 /* MagicalRecord+ErrorHandling.m */, + C7DD72C9150F832A00216827 /* MagicalRecord+iCloud.h */, + C7DD72CA150F832A00216827 /* MagicalRecord+iCloud.m */, + C7DD72CB150F832A00216827 /* MagicalRecord+Options.h */, + C7DD72CC150F832A00216827 /* MagicalRecord+Options.m */, + C7DD72CD150F832A00216827 /* MagicalRecord+Setup.h */, + C7DD72CE150F832A00216827 /* MagicalRecord+Setup.m */, + 90B05B891B02452A00354056 /* MagicalRecord+ShorthandMethods.h */, + 90B05B8A1B02452A00354056 /* MagicalRecord+ShorthandMethods.m */, + 902CE11E18F6133E0024F47C /* MagicalRecordDeprecationMacros.h */, + C7DD72D1150F832A00216827 /* MagicalRecordInternal.h */, + C7DD72D2150F832A00216827 /* MagicalRecordInternal.m */, + 90FEC08B18F42DEA002FFC2F /* MagicalRecordLogging.h */, + 90B05B851B02450900354056 /* MagicalRecordShorthandMethodAliases.h */, + ); + path = Core; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 905D07151A63DE190076B54E /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 905D07641A63DEF40076B54E /* NSManagedObjectContext+MagicalSaves.h in Headers */, + 905D075B1A63DEF40076B54E /* NSString+MagicalDataImport.h in Headers */, + 90B05B8B1B02452A00354056 /* MagicalRecord+ShorthandMethods.h in Headers */, + 905D076B1A63DEF40076B54E /* MagicalRecord+ErrorHandling.h in Headers */, + 905D075A1A63DEF40076B54E /* NSObject+MagicalDataImport.h in Headers */, + 905D07551A63DEF40076B54E /* MagicalImportFunctions.h in Headers */, + 905D07581A63DEF40076B54E /* NSRelationshipDescription+MagicalDataImport.h in Headers */, + 905D07731A63DEF40076B54E /* MagicalRecord.h in Headers */, + 905D076C1A63DEF40076B54E /* MagicalRecord+iCloud.h in Headers */, + 905D07561A63DEF40076B54E /* NSEntityDescription+MagicalDataImport.h in Headers */, + 905D07681A63DEF40076B54E /* NSPersistentStoreCoordinator+MagicalRecord.h in Headers */, + 905D07671A63DEF40076B54E /* NSPersistentStore+MagicalRecord.h in Headers */, + 905D075F1A63DEF40076B54E /* NSManagedObject+MagicalRecord.h in Headers */, + 905D076A1A63DEF40076B54E /* MagicalRecord+Actions.h in Headers */, + 905D07651A63DEF40076B54E /* NSManagedObjectContext+MagicalThreading.h in Headers */, + 905D07601A63DEF40076B54E /* NSManagedObject+MagicalRequests.h in Headers */, + 905D07611A63DEF40076B54E /* NSManagedObjectContext+MagicalChainSave.h in Headers */, + 905D07591A63DEF40076B54E /* NSNumber+MagicalDataImport.h in Headers */, + 905D076D1A63DEF40076B54E /* MagicalRecord+Options.h in Headers */, + 905D07691A63DEF40076B54E /* MagicalRecordInternal.h in Headers */, + 90B05B861B02450900354056 /* MagicalRecordShorthandMethodAliases.h in Headers */, + 905D07571A63DEF40076B54E /* NSAttributeDescription+MagicalDataImport.h in Headers */, + 905D07621A63DEF40076B54E /* NSManagedObjectContext+MagicalObserving.h in Headers */, + 905D075E1A63DEF40076B54E /* NSManagedObject+MagicalFinders.h in Headers */, + 905D07661A63DEF40076B54E /* NSManagedObjectModel+MagicalRecord.h in Headers */, + 905D075D1A63DEF40076B54E /* NSManagedObject+MagicalDataImport.h in Headers */, + 905D076E1A63DEF40076B54E /* MagicalRecord+Setup.h in Headers */, + 905D07631A63DEF40076B54E /* NSManagedObjectContext+MagicalRecord.h in Headers */, + 905D075C1A63DEF40076B54E /* NSManagedObject+MagicalAggregation.h in Headers */, + 905D07701A63DEF40076B54E /* MagicalRecordLogging.h in Headers */, + 905D07721A63DEF40076B54E /* MagicalRecordDeprecationMacros.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 905D07381A63DE690076B54E /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 905D07831A63DEF40076B54E /* NSManagedObjectContext+MagicalSaves.h in Headers */, + 905D077A1A63DEF40076B54E /* NSString+MagicalDataImport.h in Headers */, + 90B05B8C1B02452A00354056 /* MagicalRecord+ShorthandMethods.h in Headers */, + 905D078A1A63DEF40076B54E /* MagicalRecord+ErrorHandling.h in Headers */, + 905D07791A63DEF40076B54E /* NSObject+MagicalDataImport.h in Headers */, + 905D07741A63DEF40076B54E /* MagicalImportFunctions.h in Headers */, + 905D078F1A63DEF40076B54E /* MagicalRecordLogging.h in Headers */, + 905D07771A63DEF40076B54E /* NSRelationshipDescription+MagicalDataImport.h in Headers */, + 905D07921A63DEF40076B54E /* MagicalRecord.h in Headers */, + 905D078B1A63DEF40076B54E /* MagicalRecord+iCloud.h in Headers */, + 905D07751A63DEF40076B54E /* NSEntityDescription+MagicalDataImport.h in Headers */, + 905D07871A63DEF40076B54E /* NSPersistentStoreCoordinator+MagicalRecord.h in Headers */, + 905D07861A63DEF40076B54E /* NSPersistentStore+MagicalRecord.h in Headers */, + 905D077E1A63DEF40076B54E /* NSManagedObject+MagicalRecord.h in Headers */, + 905D07891A63DEF40076B54E /* MagicalRecord+Actions.h in Headers */, + 905D07841A63DEF40076B54E /* NSManagedObjectContext+MagicalThreading.h in Headers */, + 905D077F1A63DEF40076B54E /* NSManagedObject+MagicalRequests.h in Headers */, + 905D07801A63DEF40076B54E /* NSManagedObjectContext+MagicalChainSave.h in Headers */, + 905D07781A63DEF40076B54E /* NSNumber+MagicalDataImport.h in Headers */, + 905D078C1A63DEF40076B54E /* MagicalRecord+Options.h in Headers */, + 90B05B871B02450900354056 /* MagicalRecordShorthandMethodAliases.h in Headers */, + 905D07881A63DEF40076B54E /* MagicalRecordInternal.h in Headers */, + 905D07761A63DEF40076B54E /* NSAttributeDescription+MagicalDataImport.h in Headers */, + 905D07811A63DEF40076B54E /* NSManagedObjectContext+MagicalObserving.h in Headers */, + 905D077D1A63DEF40076B54E /* NSManagedObject+MagicalFinders.h in Headers */, + 905D07851A63DEF40076B54E /* NSManagedObjectModel+MagicalRecord.h in Headers */, + 905D077C1A63DEF40076B54E /* NSManagedObject+MagicalDataImport.h in Headers */, + 905D078D1A63DEF40076B54E /* MagicalRecord+Setup.h in Headers */, + 905D07821A63DEF40076B54E /* NSManagedObjectContext+MagicalRecord.h in Headers */, + 905D077B1A63DEF40076B54E /* NSManagedObject+MagicalAggregation.h in Headers */, + 905D07911A63DEF40076B54E /* MagicalRecordDeprecationMacros.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C7CF97B91749843F008D9D13 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 1352E5F21B176AF600182E53 /* MagicalRecord.h in Headers */, + 1352E5F31B176AF600182E53 /* MagicalImportFunctions.h in Headers */, + 1352E5F41B176AF600182E53 /* NSAttributeDescription+MagicalDataImport.h in Headers */, + 1352E5F51B176AF600182E53 /* NSEntityDescription+MagicalDataImport.h in Headers */, + 1352E5F61B176AF600182E53 /* NSNumber+MagicalDataImport.h in Headers */, + 1352E5F71B176AF600182E53 /* NSObject+MagicalDataImport.h in Headers */, + 1352E5F81B176AF600182E53 /* NSRelationshipDescription+MagicalDataImport.h in Headers */, + 1352E5F91B176AF600182E53 /* NSString+MagicalDataImport.h in Headers */, + 1352E5FA1B176AF600182E53 /* NSManagedObject+MagicalAggregation.h in Headers */, + 1352E5FB1B176AF600182E53 /* NSManagedObject+MagicalDataImport.h in Headers */, + 1352E5FC1B176AF600182E53 /* NSManagedObject+MagicalFinders.h in Headers */, + 1352E5FD1B176AF600182E53 /* NSManagedObject+MagicalRecord.h in Headers */, + 1352E5FE1B176AF600182E53 /* NSManagedObject+MagicalRequests.h in Headers */, + 1352E5FF1B176AF600182E53 /* NSManagedObjectContext+MagicalChainSave.h in Headers */, + 1352E6001B176AF600182E53 /* NSManagedObjectContext+MagicalObserving.h in Headers */, + 1352E6011B176AF600182E53 /* NSManagedObjectContext+MagicalRecord.h in Headers */, + 1352E6021B176AF600182E53 /* NSManagedObjectContext+MagicalSaves.h in Headers */, + 1352E6031B176AF600182E53 /* NSManagedObjectContext+MagicalThreading.h in Headers */, + 1352E6041B176AF600182E53 /* NSManagedObjectModel+MagicalRecord.h in Headers */, + 1352E6051B176AF600182E53 /* NSPersistentStore+MagicalRecord.h in Headers */, + 1352E6061B176AF600182E53 /* NSPersistentStoreCoordinator+MagicalRecord.h in Headers */, + 1352E6071B176AF600182E53 /* MagicalRecord+Actions.h in Headers */, + 1352E6081B176AF600182E53 /* MagicalRecord+ErrorHandling.h in Headers */, + 1352E6091B176AF600182E53 /* MagicalRecord+iCloud.h in Headers */, + 1352E60A1B176AF600182E53 /* MagicalRecord+Options.h in Headers */, + 1352E60B1B176AF600182E53 /* MagicalRecord+Setup.h in Headers */, + 1352E60C1B176AF600182E53 /* MagicalRecord+ShorthandMethods.h in Headers */, + 1352E60D1B176AF600182E53 /* MagicalRecordDeprecationMacros.h in Headers */, + 1352E60E1B176AF700182E53 /* MagicalRecordInternal.h in Headers */, + 1352E60F1B176AF700182E53 /* MagicalRecordLogging.h in Headers */, + 1352E6101B176AF700182E53 /* MagicalRecordShorthandMethodAliases.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 9004F4E01A94CBCF00A61312 /* MagicalRecord for iOS Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9004F51E1A94CBCF00A61312 /* Build configuration list for PBXNativeTarget "MagicalRecord for iOS Tests" */; + buildPhases = ( + 9004F4E11A94CBCF00A61312 /* Sources */, + 9004F50E1A94CBCF00A61312 /* Frameworks */, + 9004F5111A94CBCF00A61312 /* Resources */, + 9004F5791A94D7C500A61312 /* Copy Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "MagicalRecord for iOS Tests"; + productName = MagicalRecordTests; + productReference = 9004F5211A94CBCF00A61312 /* MagicalRecord for iOS Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 9004F5251A94CBF900A61312 /* MagicalRecord for OS X Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9004F5631A94CBF900A61312 /* Build configuration list for PBXNativeTarget "MagicalRecord for OS X Tests" */; + buildPhases = ( + 9004F5261A94CBF900A61312 /* Sources */, + 9004F5531A94CBF900A61312 /* Frameworks */, + 9004F5561A94CBF900A61312 /* Resources */, + 9004F57B1A94D7DC00A61312 /* Copy Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "MagicalRecord for OS X Tests"; + productName = "MagicalRecordTests-OSX"; + productReference = 9004F5661A94CBF900A61312 /* MagicalRecord for OS X Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 905D07171A63DE190076B54E /* MagicalRecord for iOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = 905D07341A63DE190076B54E /* Build configuration list for PBXNativeTarget "MagicalRecord for iOS" */; + buildPhases = ( + 905D07131A63DE190076B54E /* Sources */, + 905D07141A63DE190076B54E /* Frameworks */, + 905D07151A63DE190076B54E /* Headers */, + 905D07161A63DE190076B54E /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "MagicalRecord for iOS"; + productName = MagicalRecord; + productReference = 905D07181A63DE190076B54E /* MagicalRecord.framework */; + productType = "com.apple.product-type.framework"; + }; + 905D073A1A63DE690076B54E /* MagicalRecord for OS X */ = { + isa = PBXNativeTarget; + buildConfigurationList = 905D074E1A63DE690076B54E /* Build configuration list for PBXNativeTarget "MagicalRecord for OS X" */; + buildPhases = ( + 905D07361A63DE690076B54E /* Sources */, + 905D07371A63DE690076B54E /* Frameworks */, + 905D07381A63DE690076B54E /* Headers */, + 905D07391A63DE690076B54E /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "MagicalRecord for OS X"; + productName = "MagicalRecord OS X"; + productReference = 905D073B1A63DE690076B54E /* MagicalRecord.framework */; + productType = "com.apple.product-type.framework"; + }; + C7CF97AA17498414008D9D13 /* libMagicalRecord for iOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = C7CF97B417498414008D9D13 /* Build configuration list for PBXNativeTarget "libMagicalRecord for iOS" */; + buildPhases = ( + C7CF97A717498414008D9D13 /* Sources */, + C7CF97A817498414008D9D13 /* Frameworks */, + C7CF97A917498414008D9D13 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "libMagicalRecord for iOS"; + productName = libMagicalRecord; + productReference = C7CF97AB17498414008D9D13 /* libMagicalRecord.a */; + productType = "com.apple.product-type.library.static"; + }; + C7CF97BA1749843F008D9D13 /* libMagicalRecord for OS X */ = { + isa = PBXNativeTarget; + buildConfigurationList = C7CF97C31749843F008D9D13 /* Build configuration list for PBXNativeTarget "libMagicalRecord for OS X" */; + buildPhases = ( + C7CF97B71749843F008D9D13 /* Sources */, + C7CF97B81749843F008D9D13 /* Frameworks */, + C7CF97B91749843F008D9D13 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "libMagicalRecord for OS X"; + productName = libMagicalRecord; + productReference = C7CF97BB1749843F008D9D13 /* libMagicalRecord.dylib */; + productType = "com.apple.product-type.library.dynamic"; + }; + C7CF97FE174984CA008D9D13 /* libMagicalRecord for iOS Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = C7CF980E174984CA008D9D13 /* Build configuration list for PBXNativeTarget "libMagicalRecord for iOS Tests" */; + buildPhases = ( + C7CF97FA174984CA008D9D13 /* Sources */, + C7CF97FB174984CA008D9D13 /* Frameworks */, + C7CF97FC174984CA008D9D13 /* Resources */, + 907DAC031AFB24A5003D7BB4 /* Copy Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "libMagicalRecord for iOS Tests"; + productName = MagicalRecordTests; + productReference = C7CF97FF174984CA008D9D13 /* libMagicalRecord for iOS Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + C7CF9815174984E4008D9D13 /* libMagicalRecord for OS X Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = C7CF9823174984E4008D9D13 /* Build configuration list for PBXNativeTarget "libMagicalRecord for OS X Tests" */; + buildPhases = ( + C7CF9811174984E4008D9D13 /* Sources */, + C7CF9812174984E4008D9D13 /* Frameworks */, + C7CF9813174984E4008D9D13 /* Resources */, + 907DAC051AFB24B8003D7BB4 /* Copy Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "libMagicalRecord for OS X Tests"; + productName = "MagicalRecordTests-OSX"; + productReference = C7CF9816174984E4008D9D13 /* libMagicalRecord for OS X Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + C721C7A213D0A3750097AB6F /* Project object */ = { + isa = PBXProject; + attributes = { + CLASSPREFIX = MR; + LastUpgradeCheck = 0610; + ORGANIZATIONNAME = "Magical Panda Software LLC"; + TargetAttributes = { + 905D07171A63DE190076B54E = { + CreatedOnToolsVersion = 6.2; + }; + 905D073A1A63DE690076B54E = { + CreatedOnToolsVersion = 6.2; + }; + }; + }; + buildConfigurationList = C721C7A513D0A3750097AB6F /* Build configuration list for PBXProject "MagicalRecord" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = C721C7A013D0A3750097AB6F; + productRefGroup = C721C7B113D0A3AF0097AB6F /* Products */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 903125871B103812000E8841 /* Products */; + ProjectRef = 903125861B103812000E8841 /* Expecta.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + 905D07171A63DE190076B54E /* MagicalRecord for iOS */, + 9004F4E01A94CBCF00A61312 /* MagicalRecord for iOS Tests */, + 905D073A1A63DE690076B54E /* MagicalRecord for OS X */, + 9004F5251A94CBF900A61312 /* MagicalRecord for OS X Tests */, + C7CF97AA17498414008D9D13 /* libMagicalRecord for iOS */, + C7CF97FE174984CA008D9D13 /* libMagicalRecord for iOS Tests */, + C7CF97BA1749843F008D9D13 /* libMagicalRecord for OS X */, + C7CF9815174984E4008D9D13 /* libMagicalRecord for OS X Tests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 903125921B103812000E8841 /* Expecta.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = Expecta.framework; + remoteRef = 903125911B103812000E8841 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 903125941B103812000E8841 /* Expecta.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = Expecta.framework; + remoteRef = 903125931B103812000E8841 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 903125961B103812000E8841 /* ExpectaTests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = ExpectaTests.xctest; + remoteRef = 903125951B103812000E8841 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 903125981B103812000E8841 /* Expecta-iOSTests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = "Expecta-iOSTests.xctest"; + remoteRef = 903125971B103812000E8841 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 9031259A1B103812000E8841 /* libExpecta.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libExpecta.a; + remoteRef = 903125991B103812000E8841 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 9031259C1B103812000E8841 /* libExpecta.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libExpecta.a; + remoteRef = 9031259B1B103812000E8841 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 9031259E1B103812000E8841 /* libExpectaTests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = libExpectaTests.xctest; + remoteRef = 9031259D1B103812000E8841 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 903125A01B103812000E8841 /* libExpecta-iOSTests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = "libExpecta-iOSTests.xctest"; + remoteRef = 9031259F1B103812000E8841 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXResourcesBuildPhase section */ + 9004F5111A94CBCF00A61312 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9004F5121A94CBCF00A61312 /* TestModel.xcdatamodeld in Resources */, + 9004F5131A94CBCF00A61312 /* SampleJSONDataForImport.json in Resources */, + 9004F5141A94CBCF00A61312 /* SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json in Resources */, + 9004F5151A94CBCF00A61312 /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json in Resources */, + 9004F5161A94CBCF00A61312 /* MultipleEntitiesWithNoPrimaryKey.json in Resources */, + 9004F5171A94CBCF00A61312 /* SingleEntityRelatedToMappedEntityUsingDefaults.json in Resources */, + 9004F5181A94CBCF00A61312 /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json in Resources */, + 9004F5191A94CBCF00A61312 /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json in Resources */, + 9004F51A1A94CBCF00A61312 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.json in Resources */, + 9004F51B1A94CBCF00A61312 /* SingleEntityWithNoRelationships.json in Resources */, + 9004F51C1A94CBCF00A61312 /* SingleEntityWithNoRelationships.plist in Resources */, + 9004F51D1A94CBCF00A61312 /* SingleRelatedEntity.json in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9004F5561A94CBF900A61312 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9004F5571A94CBF900A61312 /* TestModel.xcdatamodeld in Resources */, + 9004F5581A94CBF900A61312 /* SampleJSONDataForImport.json in Resources */, + 9004F5591A94CBF900A61312 /* SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json in Resources */, + 9004F55A1A94CBF900A61312 /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json in Resources */, + 9004F55B1A94CBF900A61312 /* MultipleEntitiesWithNoPrimaryKey.json in Resources */, + 9004F55C1A94CBF900A61312 /* SingleEntityRelatedToMappedEntityUsingDefaults.json in Resources */, + 9004F55D1A94CBF900A61312 /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json in Resources */, + 9004F55E1A94CBF900A61312 /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json in Resources */, + 9004F55F1A94CBF900A61312 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.json in Resources */, + 9004F5601A94CBF900A61312 /* SingleEntityWithNoRelationships.json in Resources */, + 9004F5611A94CBF900A61312 /* SingleEntityWithNoRelationships.plist in Resources */, + 9004F5621A94CBF900A61312 /* SingleRelatedEntity.json in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 905D07161A63DE190076B54E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 905D07391A63DE690076B54E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C7CF97FC174984CA008D9D13 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 90171E1D17C32ACE00E7084A /* TestModel.xcdatamodeld in Resources */, + C7CF9B5317498985008D9D13 /* SampleJSONDataForImport.json in Resources */, + C7CF9B5517498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json in Resources */, + C7CF9B5717498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json in Resources */, + 581ECBF7187F660B00084FEE /* MultipleEntitiesWithNoPrimaryKey.json in Resources */, + C7CF9B5917498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingDefaults.json in Resources */, + C7CF9B5B17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json in Resources */, + C7CF9B5D17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json in Resources */, + C7CF9B5F17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.json in Resources */, + C7CF9B6117498985008D9D13 /* SingleEntityWithNoRelationships.json in Resources */, + C7CF9B6317498986008D9D13 /* SingleEntityWithNoRelationships.plist in Resources */, + C7CF9B6517498986008D9D13 /* SingleRelatedEntity.json in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C7CF9813174984E4008D9D13 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 90171E1E17C32AD300E7084A /* TestModel.xcdatamodeld in Resources */, + C7CF9B5417498985008D9D13 /* SampleJSONDataForImport.json in Resources */, + C7CF9B5617498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json in Resources */, + C7CF9B5817498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json in Resources */, + 581ECBF8187F660B00084FEE /* MultipleEntitiesWithNoPrimaryKey.json in Resources */, + C7CF9B5A17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingDefaults.json in Resources */, + C7CF9B5C17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json in Resources */, + C7CF9B5E17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json in Resources */, + C7CF9B6017498985008D9D13 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.json in Resources */, + C7CF9B6217498985008D9D13 /* SingleEntityWithNoRelationships.json in Resources */, + C7CF9B6417498986008D9D13 /* SingleEntityWithNoRelationships.plist in Resources */, + C7CF9B6617498986008D9D13 /* SingleRelatedEntity.json in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 9004F4E11A94CBCF00A61312 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9004F4E21A94CBCF00A61312 /* DifferentClassNameMapping.m in Sources */, + 9004F4E31A94CBCF00A61312 /* _AbstractRelatedEntity.m in Sources */, + 9004F4E41A94CBCF00A61312 /* SingleRelatedEntity.m in Sources */, + 9004F4E51A94CBCF00A61312 /* _SingleEntityRelatedToMappedEntityWithSecondaryMappings.m in Sources */, + 9004F4E61A94CBCF00A61312 /* NSManagedObjectContext+ChainSaveTests.m in Sources */, + 9004F4E71A94CBCF00A61312 /* _SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m in Sources */, + 9004F4E81A94CBCF00A61312 /* NSPersistentStoreHelperTests.m in Sources */, + 9004F4E91A94CBCF00A61312 /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m in Sources */, + 9004F4EA1A94CBCF00A61312 /* _SingleEntityRelatedToMappedEntityUsingDefaults.m in Sources */, + 9004F4EB1A94CBCF00A61312 /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m in Sources */, + 9004F4EC1A94CBCF00A61312 /* NSManagedObjectHelperTests.m in Sources */, + 9004F4ED1A94CBCF00A61312 /* ConcreteRelatedEntity.m in Sources */, + 9004F4EE1A94CBCF00A61312 /* MagicalDataImportTestCase.m in Sources */, + 9021D9E31AFB34D6001C80BA /* MagicalRecordTestHelpers.m in Sources */, + 9004F4EF1A94CBCF00A61312 /* AbstractRelatedEntity.m in Sources */, + 9004F4F01A94CBCF00A61312 /* MappedEntity.m in Sources */, + 9004F4F11A94CBCF00A61312 /* MagicalRecordTestBase.m in Sources */, + 9004F4F21A94CBCF00A61312 /* _SingleRelatedEntity.m in Sources */, + 9004F4F31A94CBCF00A61312 /* ImportSingleEntityWithNoRelationshipsTests.m in Sources */, + 9004F4F41A94CBCF00A61312 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.m in Sources */, + 9004F4F51A94CBCF00A61312 /* EntityWithoutEntityNameMethod.m in Sources */, + 9004F4F61A94CBCF00A61312 /* ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m in Sources */, + 9004F4F71A94CBCF00A61312 /* ImportMultipleEntitiesWithNoPrimaryKeyTests.m in Sources */, + 9004F4F81A94CBCF00A61312 /* ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m in Sources */, + 9004F4F91A94CBCF00A61312 /* NSPersistentStoreCoordinatorHelperTests.m in Sources */, + 9004F4FA1A94CBCF00A61312 /* NSManagedObjectContextHelperTests.m in Sources */, + 9004F4FB1A94CBCF00A61312 /* ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m in Sources */, + 9004F4FC1A94CBCF00A61312 /* _SingleEntityWithNoRelationships.m in Sources */, + 9004F4FD1A94CBCF00A61312 /* FixtureHelpers.m in Sources */, + 9004F4FE1A94CBCF00A61312 /* ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m in Sources */, + 9004F4FF1A94CBCF00A61312 /* TestModel.xcdatamodeld in Sources */, + 9004F5001A94CBCF00A61312 /* NSManagedObjectContext+MagicalSavesTests.m in Sources */, + 9004F5011A94CBCF00A61312 /* SingleEntityRelatedToMappedEntityUsingDefaults.m in Sources */, + 9004F5021A94CBCF00A61312 /* _SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m in Sources */, + 9004F5031A94CBCF00A61312 /* ImportSingleRelatedEntityTests.m in Sources */, + 9004F5041A94CBCF00A61312 /* MagicalRecord+ActionsTests.m in Sources */, + 9004F5051A94CBCF00A61312 /* NSManagedObject+MagicalRecordTests.m in Sources */, + 9004F5061A94CBCF00A61312 /* ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m in Sources */, + 9004F5071A94CBCF00A61312 /* _SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m in Sources */, + 9004F5081A94CBCF00A61312 /* MagicalRecord+StackTests.m in Sources */, + 9004F5091A94CBCF00A61312 /* _MappedEntity.m in Sources */, + 9004F50A1A94CBCF00A61312 /* _DifferentClassNameMapping.m in Sources */, + 9004F50B1A94CBCF00A61312 /* _ConcreteRelatedEntity.m in Sources */, + 9004F50C1A94CBCF00A61312 /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m in Sources */, + 9004F50D1A94CBCF00A61312 /* SingleEntityWithNoRelationships.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9004F5261A94CBF900A61312 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9004F5271A94CBF900A61312 /* DifferentClassNameMapping.m in Sources */, + 9004F5281A94CBF900A61312 /* _AbstractRelatedEntity.m in Sources */, + 9004F5291A94CBF900A61312 /* SingleRelatedEntity.m in Sources */, + 9004F52A1A94CBF900A61312 /* _SingleEntityRelatedToMappedEntityWithSecondaryMappings.m in Sources */, + 9004F52B1A94CBF900A61312 /* NSManagedObjectContext+ChainSaveTests.m in Sources */, + 9004F52C1A94CBF900A61312 /* _SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m in Sources */, + 9004F52D1A94CBF900A61312 /* NSPersistentStoreHelperTests.m in Sources */, + 9004F52E1A94CBF900A61312 /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m in Sources */, + 9004F52F1A94CBF900A61312 /* _SingleEntityRelatedToMappedEntityUsingDefaults.m in Sources */, + 9004F5301A94CBF900A61312 /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m in Sources */, + 9004F5311A94CBF900A61312 /* NSManagedObjectHelperTests.m in Sources */, + 9004F5321A94CBF900A61312 /* ConcreteRelatedEntity.m in Sources */, + 9004F5331A94CBF900A61312 /* MagicalDataImportTestCase.m in Sources */, + 9021D9E41AFB34D6001C80BA /* MagicalRecordTestHelpers.m in Sources */, + 9004F5341A94CBF900A61312 /* AbstractRelatedEntity.m in Sources */, + 9004F5351A94CBF900A61312 /* MappedEntity.m in Sources */, + 9004F5361A94CBF900A61312 /* MagicalRecordTestBase.m in Sources */, + 9004F5371A94CBF900A61312 /* _SingleRelatedEntity.m in Sources */, + 9004F5381A94CBF900A61312 /* ImportSingleEntityWithNoRelationshipsTests.m in Sources */, + 9004F5391A94CBF900A61312 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.m in Sources */, + 9004F53A1A94CBF900A61312 /* EntityWithoutEntityNameMethod.m in Sources */, + 9004F53B1A94CBF900A61312 /* ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m in Sources */, + 9004F53C1A94CBF900A61312 /* ImportMultipleEntitiesWithNoPrimaryKeyTests.m in Sources */, + 9004F53D1A94CBF900A61312 /* ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m in Sources */, + 9004F53E1A94CBF900A61312 /* NSPersistentStoreCoordinatorHelperTests.m in Sources */, + 9004F53F1A94CBF900A61312 /* NSManagedObjectContextHelperTests.m in Sources */, + 9004F5401A94CBF900A61312 /* ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m in Sources */, + 9004F5411A94CBF900A61312 /* _SingleEntityWithNoRelationships.m in Sources */, + 9004F5421A94CBF900A61312 /* FixtureHelpers.m in Sources */, + 9004F5431A94CBF900A61312 /* ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m in Sources */, + 9004F5441A94CBF900A61312 /* TestModel.xcdatamodeld in Sources */, + 9004F5451A94CBF900A61312 /* NSManagedObjectContext+MagicalSavesTests.m in Sources */, + 9004F5461A94CBF900A61312 /* SingleEntityRelatedToMappedEntityUsingDefaults.m in Sources */, + 9004F5471A94CBF900A61312 /* _SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m in Sources */, + 9004F5481A94CBF900A61312 /* ImportSingleRelatedEntityTests.m in Sources */, + 9004F5491A94CBF900A61312 /* MagicalRecord+ActionsTests.m in Sources */, + 9004F54A1A94CBF900A61312 /* NSManagedObject+MagicalRecordTests.m in Sources */, + 9004F54B1A94CBF900A61312 /* ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m in Sources */, + 9004F54C1A94CBF900A61312 /* _SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m in Sources */, + 9004F54D1A94CBF900A61312 /* MagicalRecord+StackTests.m in Sources */, + 9004F54E1A94CBF900A61312 /* _MappedEntity.m in Sources */, + 9004F54F1A94CBF900A61312 /* _DifferentClassNameMapping.m in Sources */, + 9004F5501A94CBF900A61312 /* _ConcreteRelatedEntity.m in Sources */, + 9004F5511A94CBF900A61312 /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m in Sources */, + 9004F5521A94CBF900A61312 /* SingleEntityWithNoRelationships.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 905D07131A63DE190076B54E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 905D079F1A63DF120076B54E /* NSManagedObjectContext+MagicalChainSave.m in Sources */, + 905D07AA1A63DF120076B54E /* MagicalRecord+iCloud.m in Sources */, + 905D07951A63DF120076B54E /* NSAttributeDescription+MagicalDataImport.m in Sources */, + 905D07AC1A63DF120076B54E /* MagicalRecord+Setup.m in Sources */, + 905D07961A63DF120076B54E /* NSRelationshipDescription+MagicalDataImport.m in Sources */, + 905D07A41A63DF120076B54E /* NSManagedObjectModel+MagicalRecord.m in Sources */, + 905D07A71A63DF120076B54E /* MagicalRecordInternal.m in Sources */, + 905D07A81A63DF120076B54E /* MagicalRecord+Actions.m in Sources */, + 905D07AB1A63DF120076B54E /* MagicalRecord+Options.m in Sources */, + 905D07A11A63DF120076B54E /* NSManagedObjectContext+MagicalRecord.m in Sources */, + 905D07971A63DF120076B54E /* NSNumber+MagicalDataImport.m in Sources */, + 905D07A91A63DF120076B54E /* MagicalRecord+ErrorHandling.m in Sources */, + 905D07A21A63DF120076B54E /* NSManagedObjectContext+MagicalSaves.m in Sources */, + 90B05B8E1B02452A00354056 /* MagicalRecord+ShorthandMethods.m in Sources */, + 905D07A51A63DF120076B54E /* NSPersistentStore+MagicalRecord.m in Sources */, + 905D07941A63DF120076B54E /* NSEntityDescription+MagicalDataImport.m in Sources */, + 905D07931A63DF120076B54E /* MagicalImportFunctions.m in Sources */, + 905D079D1A63DF120076B54E /* NSManagedObject+MagicalRecord.m in Sources */, + 905D07A31A63DF120076B54E /* NSManagedObjectContext+MagicalThreading.m in Sources */, + 905D079A1A63DF120076B54E /* NSManagedObject+MagicalAggregation.m in Sources */, + 905D079B1A63DF120076B54E /* NSManagedObject+MagicalDataImport.m in Sources */, + 905D07A61A63DF120076B54E /* NSPersistentStoreCoordinator+MagicalRecord.m in Sources */, + 905D07991A63DF120076B54E /* NSString+MagicalDataImport.m in Sources */, + 905D079C1A63DF120076B54E /* NSManagedObject+MagicalFinders.m in Sources */, + 905D079E1A63DF120076B54E /* NSManagedObject+MagicalRequests.m in Sources */, + 905D07A01A63DF120076B54E /* NSManagedObjectContext+MagicalObserving.m in Sources */, + 905D07981A63DF120076B54E /* NSObject+MagicalDataImport.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 905D07361A63DE690076B54E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 905D07BA1A63DF130076B54E /* NSManagedObjectContext+MagicalChainSave.m in Sources */, + 905D07C51A63DF130076B54E /* MagicalRecord+iCloud.m in Sources */, + 905D07B01A63DF130076B54E /* NSAttributeDescription+MagicalDataImport.m in Sources */, + 905D07C71A63DF130076B54E /* MagicalRecord+Setup.m in Sources */, + 905D07B11A63DF130076B54E /* NSRelationshipDescription+MagicalDataImport.m in Sources */, + 905D07BF1A63DF130076B54E /* NSManagedObjectModel+MagicalRecord.m in Sources */, + 905D07C21A63DF130076B54E /* MagicalRecordInternal.m in Sources */, + 905D07C31A63DF130076B54E /* MagicalRecord+Actions.m in Sources */, + 905D07C61A63DF130076B54E /* MagicalRecord+Options.m in Sources */, + 905D07BC1A63DF130076B54E /* NSManagedObjectContext+MagicalRecord.m in Sources */, + 905D07B21A63DF130076B54E /* NSNumber+MagicalDataImport.m in Sources */, + 905D07C41A63DF130076B54E /* MagicalRecord+ErrorHandling.m in Sources */, + 905D07BD1A63DF130076B54E /* NSManagedObjectContext+MagicalSaves.m in Sources */, + 90B05B8F1B02452A00354056 /* MagicalRecord+ShorthandMethods.m in Sources */, + 905D07C01A63DF130076B54E /* NSPersistentStore+MagicalRecord.m in Sources */, + 905D07AF1A63DF130076B54E /* NSEntityDescription+MagicalDataImport.m in Sources */, + 905D07AE1A63DF130076B54E /* MagicalImportFunctions.m in Sources */, + 905D07B81A63DF130076B54E /* NSManagedObject+MagicalRecord.m in Sources */, + 905D07BE1A63DF130076B54E /* NSManagedObjectContext+MagicalThreading.m in Sources */, + 905D07B51A63DF130076B54E /* NSManagedObject+MagicalAggregation.m in Sources */, + 905D07B61A63DF130076B54E /* NSManagedObject+MagicalDataImport.m in Sources */, + 905D07C11A63DF130076B54E /* NSPersistentStoreCoordinator+MagicalRecord.m in Sources */, + 905D07B41A63DF130076B54E /* NSString+MagicalDataImport.m in Sources */, + 905D07B71A63DF130076B54E /* NSManagedObject+MagicalFinders.m in Sources */, + 905D07B91A63DF130076B54E /* NSManagedObject+MagicalRequests.m in Sources */, + 905D07BB1A63DF130076B54E /* NSManagedObjectContext+MagicalObserving.m in Sources */, + 905D07B31A63DF130076B54E /* NSObject+MagicalDataImport.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C7CF97A717498414008D9D13 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C7CF97C617498493008D9D13 /* MagicalImportFunctions.m in Sources */, + C7CF97C717498493008D9D13 /* NSEntityDescription+MagicalDataImport.m in Sources */, + C7CF97C817498493008D9D13 /* NSAttributeDescription+MagicalDataImport.m in Sources */, + C7CF97C917498493008D9D13 /* NSRelationshipDescription+MagicalDataImport.m in Sources */, + C7CF97CA17498493008D9D13 /* NSNumber+MagicalDataImport.m in Sources */, + C7CF97CB17498493008D9D13 /* NSObject+MagicalDataImport.m in Sources */, + C7CF97CC17498493008D9D13 /* NSString+MagicalDataImport.m in Sources */, + C7CF97CD17498493008D9D13 /* NSManagedObject+MagicalAggregation.m in Sources */, + C7CF97CE17498493008D9D13 /* NSManagedObject+MagicalDataImport.m in Sources */, + C7CF97CF17498493008D9D13 /* NSManagedObject+MagicalFinders.m in Sources */, + C7CF97D017498493008D9D13 /* NSManagedObject+MagicalRecord.m in Sources */, + C7CF97D117498493008D9D13 /* NSManagedObject+MagicalRequests.m in Sources */, + C7CF97D217498493008D9D13 /* NSManagedObjectContext+MagicalObserving.m in Sources */, + 90B05B901B02452A00354056 /* MagicalRecord+ShorthandMethods.m in Sources */, + C7CF97D317498493008D9D13 /* NSManagedObjectContext+MagicalRecord.m in Sources */, + C7CF97D417498493008D9D13 /* NSManagedObjectContext+MagicalSaves.m in Sources */, + C7CF97D517498493008D9D13 /* NSManagedObjectContext+MagicalThreading.m in Sources */, + C7CF97D617498493008D9D13 /* NSManagedObjectModel+MagicalRecord.m in Sources */, + 9BB5668C1A2C44C4004174B3 /* NSManagedObjectContext+MagicalChainSave.m in Sources */, + C7CF97D717498493008D9D13 /* NSPersistentStore+MagicalRecord.m in Sources */, + C7CF97D817498493008D9D13 /* NSPersistentStoreCoordinator+MagicalRecord.m in Sources */, + C7CF97D917498493008D9D13 /* MagicalRecordInternal.m in Sources */, + C7CF97DA17498493008D9D13 /* MagicalRecord+Actions.m in Sources */, + C7CF97DB17498493008D9D13 /* MagicalRecord+ErrorHandling.m in Sources */, + C7CF97DC17498493008D9D13 /* MagicalRecord+iCloud.m in Sources */, + C7CF97DD17498493008D9D13 /* MagicalRecord+Options.m in Sources */, + C7CF97DE17498493008D9D13 /* MagicalRecord+Setup.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C7CF97B71749843F008D9D13 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C7CF97E0174984A5008D9D13 /* MagicalImportFunctions.m in Sources */, + C7CF97E1174984A5008D9D13 /* NSEntityDescription+MagicalDataImport.m in Sources */, + C7CF97E2174984A5008D9D13 /* NSAttributeDescription+MagicalDataImport.m in Sources */, + C7CF97E3174984A5008D9D13 /* NSRelationshipDescription+MagicalDataImport.m in Sources */, + C7CF97E4174984A5008D9D13 /* NSNumber+MagicalDataImport.m in Sources */, + C7CF97E5174984A5008D9D13 /* NSObject+MagicalDataImport.m in Sources */, + C7CF97E6174984A5008D9D13 /* NSString+MagicalDataImport.m in Sources */, + C7CF97E7174984A5008D9D13 /* NSManagedObject+MagicalAggregation.m in Sources */, + C7CF97E8174984A5008D9D13 /* NSManagedObject+MagicalDataImport.m in Sources */, + C7CF97E9174984A5008D9D13 /* NSManagedObject+MagicalFinders.m in Sources */, + C7CF97EA174984A5008D9D13 /* NSManagedObject+MagicalRecord.m in Sources */, + C7CF97EB174984A5008D9D13 /* NSManagedObject+MagicalRequests.m in Sources */, + C7CF97EC174984A5008D9D13 /* NSManagedObjectContext+MagicalObserving.m in Sources */, + 90B05B911B02452A00354056 /* MagicalRecord+ShorthandMethods.m in Sources */, + C7CF97ED174984A5008D9D13 /* NSManagedObjectContext+MagicalRecord.m in Sources */, + C7CF97EE174984A5008D9D13 /* NSManagedObjectContext+MagicalSaves.m in Sources */, + C7CF97EF174984A5008D9D13 /* NSManagedObjectContext+MagicalThreading.m in Sources */, + C7CF97F0174984A5008D9D13 /* NSManagedObjectModel+MagicalRecord.m in Sources */, + 9BB5668D1A2C44C4004174B3 /* NSManagedObjectContext+MagicalChainSave.m in Sources */, + C7CF97F1174984A5008D9D13 /* NSPersistentStore+MagicalRecord.m in Sources */, + C7CF97F2174984A5008D9D13 /* NSPersistentStoreCoordinator+MagicalRecord.m in Sources */, + C7CF97F3174984A5008D9D13 /* MagicalRecordInternal.m in Sources */, + C7CF97F4174984A5008D9D13 /* MagicalRecord+Actions.m in Sources */, + C7CF97F5174984A5008D9D13 /* MagicalRecord+ErrorHandling.m in Sources */, + C7CF97F6174984A5008D9D13 /* MagicalRecord+iCloud.m in Sources */, + C7CF97F7174984A5008D9D13 /* MagicalRecord+Options.m in Sources */, + C7CF97F8174984A5008D9D13 /* MagicalRecord+Setup.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C7CF97FA174984CA008D9D13 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9099495317C2F42100BC2B5C /* DifferentClassNameMapping.m in Sources */, + 9099493917C2F42100BC2B5C /* _AbstractRelatedEntity.m in Sources */, + 9099496317C2F42100BC2B5C /* SingleRelatedEntity.m in Sources */, + 9099494917C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityWithSecondaryMappings.m in Sources */, + 9BB566991A2EA8FF004174B3 /* NSManagedObjectContext+ChainSaveTests.m in Sources */, + 9099494117C2F42100BC2B5C /* _SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m in Sources */, + 90542E241864894D00916224 /* NSPersistentStoreHelperTests.m in Sources */, + 9099495B17C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m in Sources */, + 9099494317C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityUsingDefaults.m in Sources */, + 9099495D17C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m in Sources */, + 90542E221864861100916224 /* NSManagedObjectHelperTests.m in Sources */, + 9099495117C2F42100BC2B5C /* ConcreteRelatedEntity.m in Sources */, + 90542E121863F20900916224 /* MagicalDataImportTestCase.m in Sources */, + 9021D9E51AFB34D6001C80BA /* MagicalRecordTestHelpers.m in Sources */, + 9099494F17C2F42100BC2B5C /* AbstractRelatedEntity.m in Sources */, + 9099495517C2F42100BC2B5C /* MappedEntity.m in Sources */, + 90BB1C491865159A001BBFBB /* MagicalRecordTestBase.m in Sources */, + 9099494D17C2F42100BC2B5C /* _SingleRelatedEntity.m in Sources */, + 90542E141863F20C00916224 /* ImportSingleEntityWithNoRelationshipsTests.m in Sources */, + 9099495F17C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.m in Sources */, + 90AA772518F79CCC00D49377 /* EntityWithoutEntityNameMethod.m in Sources */, + 90BB1C3A1864F341001BBFBB /* ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m in Sources */, + 581ECBF9187F663100084FEE /* ImportMultipleEntitiesWithNoPrimaryKeyTests.m in Sources */, + 90542E1A1864688100916224 /* ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m in Sources */, + 90542E2618648AAF00916224 /* NSPersistentStoreCoordinatorHelperTests.m in Sources */, + 90542E201864855500916224 /* NSManagedObjectContextHelperTests.m in Sources */, + 90542E1C1864691E00916224 /* ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m in Sources */, + 9099494B17C2F42100BC2B5C /* _SingleEntityWithNoRelationships.m in Sources */, + 90171E1B17C329CC00E7084A /* FixtureHelpers.m in Sources */, + 90542E181864438900916224 /* ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m in Sources */, + 9099490A17C2F3D400BC2B5C /* TestModel.xcdatamodeld in Sources */, + 902CE13918F61E410024F47C /* NSManagedObjectContext+MagicalSavesTests.m in Sources */, + 9099495917C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityUsingDefaults.m in Sources */, + 9099494517C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m in Sources */, + 90BB1C3F1864F662001BBFBB /* ImportSingleRelatedEntityTests.m in Sources */, + 902CE12C18F61A2F0024F47C /* MagicalRecord+ActionsTests.m in Sources */, + 90AA771818F79A3300D49377 /* NSManagedObject+MagicalRecordTests.m in Sources */, + 90BB1C3C1864F3E9001BBFBB /* ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m in Sources */, + 9099494717C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m in Sources */, + 90542E1E1864853900916224 /* MagicalRecord+StackTests.m in Sources */, + 9099493F17C2F42100BC2B5C /* _MappedEntity.m in Sources */, + 9099493D17C2F42100BC2B5C /* _DifferentClassNameMapping.m in Sources */, + 9099493B17C2F42100BC2B5C /* _ConcreteRelatedEntity.m in Sources */, + 9099495717C2F42100BC2B5C /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m in Sources */, + 9099496117C2F42100BC2B5C /* SingleEntityWithNoRelationships.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C7CF9811174984E4008D9D13 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9099495417C2F42100BC2B5C /* DifferentClassNameMapping.m in Sources */, + 9099493A17C2F42100BC2B5C /* _AbstractRelatedEntity.m in Sources */, + 9099496417C2F42100BC2B5C /* SingleRelatedEntity.m in Sources */, + 9099494A17C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityWithSecondaryMappings.m in Sources */, + 9BB566981A2EA8F8004174B3 /* NSManagedObjectContext+ChainSaveTests.m in Sources */, + 9099494217C2F42100BC2B5C /* _SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m in Sources */, + 90542E251864894D00916224 /* NSPersistentStoreHelperTests.m in Sources */, + 9099495C17C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m in Sources */, + 9099494417C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityUsingDefaults.m in Sources */, + 9099495E17C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m in Sources */, + 90542E231864861200916224 /* NSManagedObjectHelperTests.m in Sources */, + 9099495217C2F42100BC2B5C /* ConcreteRelatedEntity.m in Sources */, + 90542E131863F20900916224 /* MagicalDataImportTestCase.m in Sources */, + 9021D9E61AFB34D6001C80BA /* MagicalRecordTestHelpers.m in Sources */, + 9099495017C2F42100BC2B5C /* AbstractRelatedEntity.m in Sources */, + 9099495617C2F42100BC2B5C /* MappedEntity.m in Sources */, + 90BB1C4A1865159A001BBFBB /* MagicalRecordTestBase.m in Sources */, + 9099494E17C2F42100BC2B5C /* _SingleRelatedEntity.m in Sources */, + 90542E151863F20C00916224 /* ImportSingleEntityWithNoRelationshipsTests.m in Sources */, + 9099496017C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.m in Sources */, + 90AA772618F79CCC00D49377 /* EntityWithoutEntityNameMethod.m in Sources */, + 90BB1C3B1864F341001BBFBB /* ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m in Sources */, + 581ECBFA187F663200084FEE /* ImportMultipleEntitiesWithNoPrimaryKeyTests.m in Sources */, + 90542E1B1864688100916224 /* ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m in Sources */, + 90542E2718648AB000916224 /* NSPersistentStoreCoordinatorHelperTests.m in Sources */, + 90542E211864855500916224 /* NSManagedObjectContextHelperTests.m in Sources */, + 90542E1D1864691E00916224 /* ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m in Sources */, + 9099494C17C2F42100BC2B5C /* _SingleEntityWithNoRelationships.m in Sources */, + 90171E1C17C329CD00E7084A /* FixtureHelpers.m in Sources */, + 90542E191864438A00916224 /* ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m in Sources */, + 9099490B17C2F3D400BC2B5C /* TestModel.xcdatamodeld in Sources */, + 902CE13A18F61E410024F47C /* NSManagedObjectContext+MagicalSavesTests.m in Sources */, + 9099495A17C2F42100BC2B5C /* SingleEntityRelatedToMappedEntityUsingDefaults.m in Sources */, + 9099494617C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m in Sources */, + 90BB1C401864F662001BBFBB /* ImportSingleRelatedEntityTests.m in Sources */, + 902CE12D18F61A2F0024F47C /* MagicalRecord+ActionsTests.m in Sources */, + 90AA771918F79A3300D49377 /* NSManagedObject+MagicalRecordTests.m in Sources */, + 90BB1C3D1864F3E9001BBFBB /* ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m in Sources */, + 9099494817C2F42100BC2B5C /* _SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m in Sources */, + 90542E1F1864853A00916224 /* MagicalRecord+StackTests.m in Sources */, + 9099494017C2F42100BC2B5C /* _MappedEntity.m in Sources */, + 9099493E17C2F42100BC2B5C /* _DifferentClassNameMapping.m in Sources */, + 9099493C17C2F42100BC2B5C /* _ConcreteRelatedEntity.m in Sources */, + 9099495817C2F42100BC2B5C /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m in Sources */, + 9099496217C2F42100BC2B5C /* SingleEntityWithNoRelationships.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 9004F51F1A94CBCF00A61312 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_MODULES = YES; + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/Developer/Library/Frameworks", + "$(DEVELOPER_FRAMEWORKS_DIR)", + ); + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + INFOPLIST_FILE = "Tests/Support/MagicalRecordTests-iOS-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MOMC_NO_INVERSE_RELATIONSHIP_WARNINGS = YES; + OTHER_LDFLAGS = ( + "$(inherited)", + "-ObjC", + "-all_load", + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + WRAPPER_EXTENSION = xctest; + }; + name = Debug; + }; + 9004F5201A94CBCF00A61312 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_MODULES = YES; + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/Developer/Library/Frameworks", + "$(DEVELOPER_FRAMEWORKS_DIR)", + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + INFOPLIST_FILE = "Tests/Support/MagicalRecordTests-iOS-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MOMC_NO_INVERSE_RELATIONSHIP_WARNINGS = YES; + OTHER_LDFLAGS = ( + "$(inherited)", + "-ObjC", + "-all_load", + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + WRAPPER_EXTENSION = xctest; + }; + name = Release; + }; + 9004F5641A94CBF900A61312 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_MODULES = YES; + COMBINE_HIDPI_IMAGES = YES; + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(DEVELOPER_FRAMEWORKS_DIR)", + ); + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + INFOPLIST_FILE = "Tests/Support/MagicalRecordTests-OSX-Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MOMC_NO_INVERSE_RELATIONSHIP_WARNINGS = YES; + OTHER_LDFLAGS = ( + "$(inherited)", + "-framework", + XCTest, + "-ObjC", + "-all_load", + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + WRAPPER_EXTENSION = xctest; + }; + name = Debug; + }; + 9004F5651A94CBF900A61312 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_MODULES = YES; + COMBINE_HIDPI_IMAGES = YES; + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(DEVELOPER_FRAMEWORKS_DIR)", + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + INFOPLIST_FILE = "Tests/Support/MagicalRecordTests-OSX-Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MOMC_NO_INVERSE_RELATIONSHIP_WARNINGS = YES; + OTHER_LDFLAGS = ( + "$(inherited)", + "-framework", + XCTest, + "-ObjC", + "-all_load", + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + WRAPPER_EXTENSION = xctest; + }; + name = Release; + }; + 905D072B1A63DE190076B54E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEFINES_MODULE = YES; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + INFOPLIST_FILE = Support/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_NAME = "$(PROJECT_NAME)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 905D072C1A63DE190076B54E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEFINES_MODULE = YES; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + INFOPLIST_FILE = Support/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = "$(PROJECT_NAME)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; + 905D074F1A63DE690076B54E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + COMBINE_HIDPI_IMAGES = YES; + COPY_PHASE_STRIP = NO; + DEFINES_MODULE = YES; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_VERSION = A; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_GENERATE_TEST_COVERAGE_FILES = YES; + GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + INFOPLIST_FILE = Support/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_NAME = "$(PROJECT_NAME)"; + SDKROOT = macosx; + SKIP_INSTALL = YES; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 905D07501A63DE690076B54E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + COMBINE_HIDPI_IMAGES = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_VERSION = A; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_GENERATE_TEST_COVERAGE_FILES = YES; + GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + INFOPLIST_FILE = Support/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = "$(PROJECT_NAME)"; + SDKROOT = macosx; + SKIP_INSTALL = YES; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; + C721C7A713D0A3750097AB6F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CURRENT_PROJECT_VERSION = 2.2.99; + DYLIB_COMPATIBILITY_VERSION = 2.0; + DYLIB_CURRENT_VERSION = "$(CURRENT_PROJECT_VERSION)"; + GCC_TREAT_WARNINGS_AS_ERRORS = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; + GCC_WARN_ABOUT_MISSING_NEWLINE = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_STRICT_SELECTOR_MATCH = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 6.1; + MACOSX_DEPLOYMENT_TARGET = 10.8; + ONLY_ACTIVE_ARCH = YES; + OTHER_CFLAGS = "-DDEBUG"; + }; + name = Debug; + }; + C721C7A813D0A3750097AB6F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CURRENT_PROJECT_VERSION = 2.2.99; + DYLIB_COMPATIBILITY_VERSION = 2.0; + DYLIB_CURRENT_VERSION = "$(CURRENT_PROJECT_VERSION)"; + GCC_TREAT_WARNINGS_AS_ERRORS = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; + GCC_WARN_ABOUT_MISSING_NEWLINE = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_STRICT_SELECTOR_MATCH = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 6.1; + MACOSX_DEPLOYMENT_TARGET = 10.8; + OTHER_CFLAGS = "-DNEBUG"; + }; + name = Release; + }; + C7CF97B517498414008D9D13 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + DSTROOT = /tmp/libMagicalRecord.dst; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/Developer/Library/Frameworks", + "$(PROJECT_DIR)/Tests", + ); + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + IPHONEOS_DEPLOYMENT_TARGET = 6.1; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = "$(PROJECT_NAME)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + C7CF97B617498414008D9D13 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + DSTROOT = /tmp/libMagicalRecord.dst; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/Developer/Library/Frameworks", + "$(PROJECT_DIR)/Tests", + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREPROCESSOR_DEFINITIONS = NDEBUG; + IPHONEOS_DEPLOYMENT_TARGET = 6.1; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = "$(PROJECT_NAME)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; + C7CF97C41749843F008D9D13 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COMBINE_HIDPI_IMAGES = YES; + COPY_PHASE_STRIP = NO; + EXECUTABLE_PREFIX = lib; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + PRODUCT_NAME = "$(PROJECT_NAME)"; + SDKROOT = macosx; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + C7CF97C51749843F008D9D13 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COMBINE_HIDPI_IMAGES = YES; + COPY_PHASE_STRIP = YES; + EXECUTABLE_PREFIX = lib; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + PRODUCT_NAME = "$(PROJECT_NAME)"; + SDKROOT = macosx; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; + C7CF980F174984CA008D9D13 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_MODULES = YES; + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/Developer/Library/Frameworks", + "$(DEVELOPER_FRAMEWORKS_DIR)", + ); + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + INFOPLIST_FILE = "Tests/Support/MagicalRecordTests-iOS-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 6.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; + MOMC_NO_INVERSE_RELATIONSHIP_WARNINGS = YES; + OTHER_LDFLAGS = ( + "$(inherited)", + "-ObjC", + "-all_load", + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + WRAPPER_EXTENSION = xctest; + }; + name = Debug; + }; + C7CF9810174984CA008D9D13 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_MODULES = YES; + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/Developer/Library/Frameworks", + "$(DEVELOPER_FRAMEWORKS_DIR)", + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + INFOPLIST_FILE = "Tests/Support/MagicalRecordTests-iOS-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 6.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; + MOMC_NO_INVERSE_RELATIONSHIP_WARNINGS = YES; + OTHER_LDFLAGS = ( + "$(inherited)", + "-ObjC", + "-all_load", + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + WRAPPER_EXTENSION = xctest; + }; + name = Release; + }; + C7CF9824174984E4008D9D13 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_MODULES = YES; + COMBINE_HIDPI_IMAGES = YES; + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(DEVELOPER_FRAMEWORKS_DIR)", + ); + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + INFOPLIST_FILE = "Tests/Support/MagicalRecordTests-OSX-Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MOMC_NO_INVERSE_RELATIONSHIP_WARNINGS = YES; + OTHER_LDFLAGS = ( + "$(inherited)", + "-framework", + XCTest, + "-ObjC", + "-all_load", + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + WRAPPER_EXTENSION = xctest; + }; + name = Debug; + }; + C7CF9825174984E4008D9D13 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_MODULES = YES; + COMBINE_HIDPI_IMAGES = YES; + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(DEVELOPER_FRAMEWORKS_DIR)", + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + INFOPLIST_FILE = "Tests/Support/MagicalRecordTests-OSX-Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MOMC_NO_INVERSE_RELATIONSHIP_WARNINGS = YES; + OTHER_LDFLAGS = ( + "$(inherited)", + "-framework", + XCTest, + "-ObjC", + "-all_load", + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + WRAPPER_EXTENSION = xctest; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 9004F51E1A94CBCF00A61312 /* Build configuration list for PBXNativeTarget "MagicalRecord for iOS Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9004F51F1A94CBCF00A61312 /* Debug */, + 9004F5201A94CBCF00A61312 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 9004F5631A94CBF900A61312 /* Build configuration list for PBXNativeTarget "MagicalRecord for OS X Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9004F5641A94CBF900A61312 /* Debug */, + 9004F5651A94CBF900A61312 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 905D07341A63DE190076B54E /* Build configuration list for PBXNativeTarget "MagicalRecord for iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 905D072B1A63DE190076B54E /* Debug */, + 905D072C1A63DE190076B54E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 905D074E1A63DE690076B54E /* Build configuration list for PBXNativeTarget "MagicalRecord for OS X" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 905D074F1A63DE690076B54E /* Debug */, + 905D07501A63DE690076B54E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C721C7A513D0A3750097AB6F /* Build configuration list for PBXProject "MagicalRecord" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C721C7A713D0A3750097AB6F /* Debug */, + C721C7A813D0A3750097AB6F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C7CF97B417498414008D9D13 /* Build configuration list for PBXNativeTarget "libMagicalRecord for iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C7CF97B517498414008D9D13 /* Debug */, + C7CF97B617498414008D9D13 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C7CF97C31749843F008D9D13 /* Build configuration list for PBXNativeTarget "libMagicalRecord for OS X" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C7CF97C41749843F008D9D13 /* Debug */, + C7CF97C51749843F008D9D13 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C7CF980E174984CA008D9D13 /* Build configuration list for PBXNativeTarget "libMagicalRecord for iOS Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C7CF980F174984CA008D9D13 /* Debug */, + C7CF9810174984CA008D9D13 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C7CF9823174984E4008D9D13 /* Build configuration list for PBXNativeTarget "libMagicalRecord for OS X Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C7CF9824174984E4008D9D13 /* Debug */, + C7CF9825174984E4008D9D13 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCVersionGroup section */ + 9099490817C2F3D400BC2B5C /* TestModel.xcdatamodeld */ = { + isa = XCVersionGroup; + children = ( + 9099490917C2F3D400BC2B5C /* TestModel.xcdatamodel */, + ); + currentVersion = 9099490917C2F3D400BC2B5C /* TestModel.xcdatamodel */; + name = TestModel.xcdatamodeld; + path = Fixtures/TestModel.xcdatamodeld; + sourceTree = ""; + versionGroupType = wrapper.xcdatamodel; + }; +/* End XCVersionGroup section */ + }; + rootObject = C721C7A213D0A3750097AB6F /* Project object */; +} diff --git a/Project Files/MagicalRecord.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/MagicalRecord.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from Project Files/MagicalRecord.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to MagicalRecord.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/MagicalRecord.xcodeproj/xcshareddata/xcschemes/MagicalRecord for OS X.xcscheme b/MagicalRecord.xcodeproj/xcshareddata/xcschemes/MagicalRecord for OS X.xcscheme new file mode 100644 index 000000000..4bceba4f0 --- /dev/null +++ b/MagicalRecord.xcodeproj/xcshareddata/xcschemes/MagicalRecord for OS X.xcscheme @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MagicalRecord.xcodeproj/xcshareddata/xcschemes/MagicalRecord for iOS.xcscheme b/MagicalRecord.xcodeproj/xcshareddata/xcschemes/MagicalRecord for iOS.xcscheme new file mode 100644 index 000000000..edb90233d --- /dev/null +++ b/MagicalRecord.xcodeproj/xcshareddata/xcschemes/MagicalRecord for iOS.xcscheme @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MagicalRecord.xcodeproj/xcshareddata/xcschemes/libMagicalRecord for OS X.xcscheme b/MagicalRecord.xcodeproj/xcshareddata/xcschemes/libMagicalRecord for OS X.xcscheme new file mode 100644 index 000000000..9af683e58 --- /dev/null +++ b/MagicalRecord.xcodeproj/xcshareddata/xcschemes/libMagicalRecord for OS X.xcscheme @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MagicalRecord.xcodeproj/xcshareddata/xcschemes/libMagicalRecord for iOS.xcscheme b/MagicalRecord.xcodeproj/xcshareddata/xcschemes/libMagicalRecord for iOS.xcscheme new file mode 100644 index 000000000..9f8b07dc8 --- /dev/null +++ b/MagicalRecord.xcodeproj/xcshareddata/xcschemes/libMagicalRecord for iOS.xcscheme @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MagicalRecord/Categories/DataImport/MagicalImportFunctions.h b/MagicalRecord/Categories/DataImport/MagicalImportFunctions.h index f7d52da0a..fc71f49a0 100644 --- a/MagicalRecord/Categories/DataImport/MagicalImportFunctions.h +++ b/MagicalRecord/Categories/DataImport/MagicalImportFunctions.h @@ -8,21 +8,19 @@ #import - -NSDate * adjustDateForDST(NSDate *date); -NSDate * dateFromString(NSString *value, NSString *format); -NSNumber * numberFromString(NSString *value); -NSString * attributeNameFromString(NSString *value); -NSString * primaryKeyNameFromString(NSString *value); +NSDate * MR_adjustDateForDST(NSDate *date); +NSDate * MR_dateFromString(NSString *value, NSString *format); +NSDate * MR_dateFromNumber(NSNumber *value, BOOL milliseconds); +NSNumber * MR_numberFromString(NSString *value); +NSString * MR_attributeNameFromString(NSString *value); +NSString * MR_primaryKeyNameFromString(NSString *value); #if TARGET_OS_IPHONE #import -UIColor * UIColorFromString(NSString *serializedColor); - +UIColor * MR_colorFromString(NSString *serializedColor); #else #import -NSColor * NSColorFromString(NSString *serializedColor); - +NSColor * MR_colorFromString(NSString *serializedColor); #endif -extern id (*colorFromString)(NSString *); +NSInteger* MR_newColorComponentsFromString(NSString *serializedColor); diff --git a/MagicalRecord/Categories/DataImport/MagicalImportFunctions.m b/MagicalRecord/Categories/DataImport/MagicalImportFunctions.m index 0f4f1962d..bfd31a956 100644 --- a/MagicalRecord/Categories/DataImport/MagicalImportFunctions.m +++ b/MagicalRecord/Categories/DataImport/MagicalImportFunctions.m @@ -11,19 +11,19 @@ #pragma mark - Data import helper functions -NSString * attributeNameFromString(NSString *value) +NSString * MR_attributeNameFromString(NSString *value) { NSString *firstCharacter = [[value substringToIndex:1] capitalizedString]; return [firstCharacter stringByAppendingString:[value substringFromIndex:1]]; } -NSString * primaryKeyNameFromString(NSString *value) +NSString * MR_primaryKeyNameFromString(NSString *value) { NSString *firstCharacter = [[value substringToIndex:1] lowercaseString]; return [firstCharacter stringByAppendingFormat:@"%@ID", [value substringFromIndex:1]]; } -NSDate * adjustDateForDST(NSDate *date) +NSDate * MR_adjustDateForDST(NSDate *date) { NSTimeInterval dstOffset = [[NSTimeZone localTimeZone] daylightSavingTimeOffsetForDate:date]; NSDate *actualDate = [date dateByAddingTimeInterval:dstOffset]; @@ -31,10 +31,10 @@ return actualDate; } -NSDate * dateFromString(NSString *value, NSString *format) +NSDate * MR_dateFromString(NSString *value, NSString *format) { NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; - [formatter setTimeZone:[NSTimeZone localTimeZone]]; + [formatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; [formatter setLocale:[NSLocale currentLocale]]; [formatter setDateFormat:format]; @@ -43,18 +43,31 @@ return parsedDate; } -NSNumber * numberFromString(NSString *value) { +NSDate * MR_dateFromNumber(NSNumber *value, BOOL milliseconds) +{ + NSTimeInterval timeInterval = [value doubleValue]; + if (milliseconds) { + timeInterval = timeInterval / 1000.00; + } + return [NSDate dateWithTimeIntervalSince1970:timeInterval]; +} + +NSNumber * MR_numberFromString(NSString *value) { return [NSNumber numberWithDouble:[value doubleValue]]; } -NSInteger* newColorComponentsFromString(NSString *serializedColor); -NSInteger* newColorComponentsFromString(NSString *serializedColor) +NSInteger* MR_newColorComponentsFromString(NSString *serializedColor) { NSScanner *colorScanner = [NSScanner scannerWithString:serializedColor]; NSString *colorType; [colorScanner scanUpToString:@"(" intoString:&colorType]; NSInteger *componentValues = malloc(4 * sizeof(NSInteger)); + if (componentValues == NULL) + { + return NULL; + } + if ([colorType hasPrefix:@"rgba"]) { NSCharacterSet *rgbaCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@"(,)"]; @@ -67,16 +80,20 @@ componentValue++; } } - //else if ([colorType hasPrefix:@"hsba"]) - //else if ([colorType hasPrefix:@""]) + return componentValues; } #if TARGET_OS_IPHONE -UIColor * UIColorFromString(NSString *serializedColor) +UIColor * MR_colorFromString(NSString *serializedColor) { - NSInteger *componentValues = newColorComponentsFromString(serializedColor); + NSInteger *componentValues = MR_newColorComponentsFromString(serializedColor); + if (componentValues == NULL) + { + return nil; + } + UIColor *color = [UIColor colorWithRed:(componentValues[0] / 255.0f) green:(componentValues[1] / 255.0f) blue:(componentValues[2] / 255.0f) @@ -85,13 +102,17 @@ free(componentValues); return color; } -id (*colorFromString)(NSString *) = UIColorFromString; #else -NSColor * NSColorFromString(NSString *serializedColor) +NSColor * MR_colorFromString(NSString *serializedColor) { - NSInteger *componentValues = newColorComponentsFromString(serializedColor); + NSInteger *componentValues = MR_newColorComponentsFromString(serializedColor); + if (componentValues == NULL) + { + return nil; + } + NSColor *color = [NSColor colorWithDeviceRed:(componentValues[0] / 255.0f) green:(componentValues[1] / 255.0f) blue:(componentValues[2] / 255.0f) @@ -99,7 +120,5 @@ free(componentValues); return color; } -id (*colorFromString)(NSString *) = NSColorFromString; - #endif diff --git a/MagicalRecord/Categories/DataImport/NSAttributeDescription+MagicalDataImport.m b/MagicalRecord/Categories/DataImport/NSAttributeDescription+MagicalDataImport.m index a0395025a..b79f414ee 100644 --- a/MagicalRecord/Categories/DataImport/NSAttributeDescription+MagicalDataImport.m +++ b/MagicalRecord/Categories/DataImport/NSAttributeDescription+MagicalDataImport.m @@ -27,7 +27,7 @@ - (id) MR_valueForKeyPath:(NSString *)keyPath fromObjectData:(id)objectData; { if ([desiredAttributeType hasSuffix:@"Color"]) { - value = colorFromString(value); + value = MR_colorFromString(value); } } else @@ -37,9 +37,13 @@ - (id) MR_valueForKeyPath:(NSString *)keyPath fromObjectData:(id)objectData; if (![value isKindOfClass:[NSDate class]]) { NSString *dateFormat = [[self userInfo] valueForKey:kMagicalRecordImportCustomDateFormatKey]; - value = dateFromString([value description], dateFormat ?: kMagicalRecordImportDefaultDateFormatString); + if ([value isKindOfClass:[NSNumber class]]) { + value = MR_dateFromNumber(value, [dateFormat isEqualToString:kMagicalRecordImportUnixTimeString]); + } + else { + value = MR_dateFromString([value description], dateFormat ?: kMagicalRecordImportDefaultDateFormatString); + } } - // value = adjustDateForDST(value); } else if (attributeType == NSInteger16AttributeType || attributeType == NSInteger32AttributeType || @@ -48,7 +52,17 @@ - (id) MR_valueForKeyPath:(NSString *)keyPath fromObjectData:(id)objectData; attributeType == NSDoubleAttributeType || attributeType == NSFloatAttributeType) { if (![value isKindOfClass:[NSNumber class]] && value != [NSNull null]) { - value = numberFromString([value description]); + value = MR_numberFromString([value description]); + } + } + else if (attributeType == NSBooleanAttributeType) { + if (![value isKindOfClass:[NSNumber class]] && value != [NSNull null]) { + value = [NSNumber numberWithBool:[value boolValue]]; + } + } + else if (attributeType == NSStringAttributeType) { + if (![value isKindOfClass:[NSString class]] && value != [NSNull null]) { + value = [value description]; } } } diff --git a/MagicalRecord/Categories/DataImport/NSEntityDescription+MagicalDataImport.h b/MagicalRecord/Categories/DataImport/NSEntityDescription+MagicalDataImport.h index 0e89ba6af..078ab304b 100644 --- a/MagicalRecord/Categories/DataImport/NSEntityDescription+MagicalDataImport.h +++ b/MagicalRecord/Categories/DataImport/NSEntityDescription+MagicalDataImport.h @@ -6,10 +6,22 @@ // Copyright 2011 Magical Panda Software LLC. All rights reserved. // +#import @interface NSEntityDescription (MagicalRecord_DataImport) - (NSAttributeDescription *) MR_primaryAttributeToRelateBy; - (NSManagedObject *) MR_createInstanceInContext:(NSManagedObjectContext *)context; +/** + * Safely returns an attribute description for the given name, otherwise returns nil. In certain circumstances, the keys of the dictionary returned by `attributesByName` are not standard NSStrings and won't match using object subscripting or standard `objectForKey:` lookups. + * + * There may be performance implications to using this method if your entity has hundreds or thousands of attributes. + * + * @param name Name of the attribute description in the `attributesByName` dictionary on this instance + * + * @return The attribute description for the given name, otherwise nil + */ +- (NSAttributeDescription *) MR_attributeDescriptionForName:(NSString *)name; + @end diff --git a/MagicalRecord/Categories/DataImport/NSEntityDescription+MagicalDataImport.m b/MagicalRecord/Categories/DataImport/NSEntityDescription+MagicalDataImport.m index 8ce691c91..33d7dca11 100644 --- a/MagicalRecord/Categories/DataImport/NSEntityDescription+MagicalDataImport.m +++ b/MagicalRecord/Categories/DataImport/NSEntityDescription+MagicalDataImport.m @@ -6,29 +6,47 @@ // Copyright 2011 Magical Panda Software LLC. All rights reserved. // -#import "CoreData+MagicalRecord.h" +#import "NSEntityDescription+MagicalDataImport.h" +#import "NSManagedObject+MagicalDataImport.h" +#import "NSManagedObject+MagicalRecord.h" +#import "MagicalImportFunctions.h" @implementation NSEntityDescription (MagicalRecord_DataImport) - (NSAttributeDescription *) MR_primaryAttributeToRelateBy; { - NSString *lookupKey = [[self userInfo] valueForKey:kMagicalRecordImportRelationshipLinkedByKey] ?: primaryKeyNameFromString([self name]); - NSDictionary *attributesByName = [self attributesByName]; - - if ([attributesByName count] == 0) return nil; - - NSAttributeDescription *primaryAttribute = [attributesByName objectForKey:lookupKey]; + NSString *lookupKey = [[self userInfo] valueForKey:kMagicalRecordImportRelationshipLinkedByKey] ?: MR_primaryKeyNameFromString([self name]); - return primaryAttribute; + return [self MR_attributeDescriptionForName:lookupKey]; } - (NSManagedObject *) MR_createInstanceInContext:(NSManagedObjectContext *)context; { Class relatedClass = NSClassFromString([self managedObjectClassName]); - NSManagedObject *newInstance = [relatedClass MR_createInContext:context]; + NSManagedObject *newInstance = [relatedClass MR_createEntityInContext:context]; return newInstance; } +- (NSAttributeDescription *) MR_attributeDescriptionForName:(NSString *)name; +{ + __block NSAttributeDescription *attributeDescription; + + NSDictionary *attributesByName = [self attributesByName]; + + if ([attributesByName count] == 0) { + return nil; + } + + [attributesByName enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { + if ([key isEqualToString:name]) { + attributeDescription = obj; + + *stop = YES; + } + }]; + + return attributeDescription; +} @end diff --git a/MagicalRecord/Categories/DataImport/NSNumber+MagicalDataImport.h b/MagicalRecord/Categories/DataImport/NSNumber+MagicalDataImport.h index fc1736e64..5da2b915c 100644 --- a/MagicalRecord/Categories/DataImport/NSNumber+MagicalDataImport.h +++ b/MagicalRecord/Categories/DataImport/NSNumber+MagicalDataImport.h @@ -7,6 +7,7 @@ // #import +#import @interface NSNumber (MagicalRecord_DataImport) diff --git a/MagicalRecord/Categories/DataImport/NSObject+MagicalDataImport.h b/MagicalRecord/Categories/DataImport/NSObject+MagicalDataImport.h index e22aa8bb8..80c1765de 100644 --- a/MagicalRecord/Categories/DataImport/NSObject+MagicalDataImport.h +++ b/MagicalRecord/Categories/DataImport/NSObject+MagicalDataImport.h @@ -7,6 +7,7 @@ // #import +#import @interface NSObject (MagicalRecord_DataImport) diff --git a/MagicalRecord/Categories/DataImport/NSObject+MagicalDataImport.m b/MagicalRecord/Categories/DataImport/NSObject+MagicalDataImport.m index 900d78f80..ece3c59a3 100644 --- a/MagicalRecord/Categories/DataImport/NSObject+MagicalDataImport.m +++ b/MagicalRecord/Categories/DataImport/NSObject+MagicalDataImport.m @@ -7,21 +7,17 @@ // #import "NSObject+MagicalDataImport.h" +#import "NSAttributeDescription+MagicalDataImport.h" +#import "NSEntityDescription+MagicalDataImport.h" #import "NSManagedObject+MagicalDataImport.h" -#import "MagicalRecord.h" -#import "CoreData+MagicalRecord.h" +#import "NSRelationshipDescription+MagicalDataImport.h" +#import "MagicalRecordLogging.h" NSUInteger const kMagicalRecordImportMaximumAttributeFailoverDepth = 10; @implementation NSObject (MagicalRecord_DataImport) -//#warning If you implement valueForUndefinedKey: in any NSObject in your code, this may be the problem if something broke -- (id) MR_valueForUndefinedKey:(NSString *)key -{ - return nil; -} - - (NSString *) MR_lookupKeyForAttribute:(NSAttributeDescription *)attributeInfo; { NSString *attributeName = [attributeInfo name]; @@ -54,15 +50,14 @@ - (NSString *) MR_lookupKeyForRelationship:(NSRelationshipDescription *)relation NSEntityDescription *destinationEntity = [relationshipInfo destinationEntity]; if (destinationEntity == nil) { - MRLog(@"Unable to find entity for type '%@'", [self valueForKey:kMagicalRecordImportRelationshipTypeKey]); + MRLogError(@"Unable to find entity for type '%@'", [self valueForKey:kMagicalRecordImportRelationshipTypeKey]); return nil; } - NSString *primaryKeyName = [relationshipInfo MR_primaryKey]; - - NSAttributeDescription *primaryKeyAttribute = [[destinationEntity attributesByName] valueForKey:primaryKeyName]; - NSString *lookupKey = [[primaryKeyAttribute userInfo] valueForKey:kMagicalRecordImportAttributeKeyMapKey] ?: [primaryKeyAttribute name]; - + NSString *primaryKeyName = [relationshipInfo MR_primaryKey]; + NSAttributeDescription *primaryKeyAttribute = [destinationEntity MR_attributeDescriptionForName:primaryKeyName]; + NSString *lookupKey = [self MR_lookupKeyForAttribute:primaryKeyAttribute] ?: [primaryKeyAttribute name]; + return lookupKey; } diff --git a/MagicalRecord/Categories/DataImport/NSRelationshipDescription+MagicalDataImport.m b/MagicalRecord/Categories/DataImport/NSRelationshipDescription+MagicalDataImport.m index 770d14c6a..a6adbe0ec 100644 --- a/MagicalRecord/Categories/DataImport/NSRelationshipDescription+MagicalDataImport.m +++ b/MagicalRecord/Categories/DataImport/NSRelationshipDescription+MagicalDataImport.m @@ -9,14 +9,13 @@ #import "NSRelationshipDescription+MagicalDataImport.h" #import "NSManagedObject+MagicalDataImport.h" #import "MagicalImportFunctions.h" -#import "MagicalRecord.h" @implementation NSRelationshipDescription (MagicalRecord_DataImport) - (NSString *) MR_primaryKey; { NSString *primaryKeyName = [[self userInfo] valueForKey:kMagicalRecordImportRelationshipLinkedByKey] ?: - primaryKeyNameFromString([[self destinationEntity] name]); + MR_primaryKeyNameFromString([[self destinationEntity] name]); return primaryKeyName; } diff --git a/MagicalRecord/Categories/DataImport/NSString+MagicalDataImport.h b/MagicalRecord/Categories/DataImport/NSString+MagicalDataImport.h index 09da58a6b..3d3778a93 100644 --- a/MagicalRecord/Categories/DataImport/NSString+MagicalDataImport.h +++ b/MagicalRecord/Categories/DataImport/NSString+MagicalDataImport.h @@ -7,6 +7,7 @@ // #import +#import @interface NSString (MagicalRecord_DataImport) diff --git a/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalAggregation.h b/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalAggregation.h index 1e68eb78b..046482a90 100644 --- a/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalAggregation.h +++ b/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalAggregation.h @@ -23,10 +23,46 @@ + (BOOL) MR_hasAtLeastOneEntity; + (BOOL) MR_hasAtLeastOneEntityInContext:(NSManagedObjectContext *)context; -+ (NSNumber *)MR_aggregateOperation:(NSString *)function onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate inContext:(NSManagedObjectContext *)context; -+ (NSNumber *)MR_aggregateOperation:(NSString *)function onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate; +- (id) MR_minValueFor:(NSString *)property; +- (id) MR_maxValueFor:(NSString *)property; -- (id) MR_objectWithMinValueFor:(NSString *)property; -- (id) MR_objectWithMinValueFor:(NSString *)property inContext:(NSManagedObjectContext *)context; ++ (id) MR_aggregateOperation:(NSString *)function onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate inContext:(NSManagedObjectContext *)context; ++ (id) MR_aggregateOperation:(NSString *)function onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate; + +/** + * Supports aggregating values using a key-value collection operator that can be grouped by an attribute. + * See https://developer.apple.com/library/ios/documentation/cocoa/conceptual/KeyValueCoding/Articles/CollectionOperators.html for a list of valid collection operators. + * + * @since 2.3.0 + * + * @param collectionOperator Collection operator + * @param attributeName Entity attribute to apply the collection operator to + * @param predicate Predicate to filter results + * @param groupingKeyPath Key path to group results by + * @param context Context to perform the request in + * + * @return Results of the collection operator, filtered by the provided predicate and grouped by the provided key path + */ ++ (NSArray *) MR_aggregateOperation:(NSString *)collectionOperator onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate groupBy:(NSString*)groupingKeyPath inContext:(NSManagedObjectContext *)context; + +/** + * Supports aggregating values using a key-value collection operator that can be grouped by an attribute. + * See https://developer.apple.com/library/ios/documentation/cocoa/conceptual/KeyValueCoding/Articles/CollectionOperators.html for a list of valid collection operators. + * + * This method is run against the default MagicalRecordStack's context. + * + * @since 2.3.0 + * + * @param collectionOperator Collection operator + * @param attributeName Entity attribute to apply the collection operator to + * @param predicate Predicate to filter results + * @param groupingKeyPath Key path to group results by + * + * @return Results of the collection operator, filtered by the provided predicate and grouped by the provided key path + */ ++ (NSArray *) MR_aggregateOperation:(NSString *)collectionOperator onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate groupBy:(NSString*)groupingKeyPath; + +- (instancetype) MR_objectWithMinValueFor:(NSString *)property; +- (instancetype) MR_objectWithMinValueFor:(NSString *)property inContext:(NSManagedObjectContext *)context; @end diff --git a/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalAggregation.m b/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalAggregation.m index 1d4644b11..e7324a3ad 100644 --- a/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalAggregation.m +++ b/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalAggregation.m @@ -7,6 +7,7 @@ // #import "NSManagedObject+MagicalAggregation.h" +#import "NSEntityDescription+MagicalDataImport.h" #import "NSManagedObjectContext+MagicalRecord.h" #import "NSManagedObjectContext+MagicalThreading.h" #import "NSManagedObject+MagicalRequests.h" @@ -26,45 +27,56 @@ + (NSNumber *) MR_numberOfEntitiesWithContext:(NSManagedObjectContext *)context + (NSNumber *) MR_numberOfEntities { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [self MR_numberOfEntitiesWithContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } + (NSNumber *) MR_numberOfEntitiesWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context { - return [NSNumber numberWithUnsignedInteger:[self MR_countOfEntitiesWithPredicate:searchTerm inContext:context]]; } + (NSNumber *) MR_numberOfEntitiesWithPredicate:(NSPredicate *)searchTerm; { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [self MR_numberOfEntitiesWithPredicate:searchTerm inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } + (NSUInteger) MR_countOfEntities; { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [self MR_countOfEntitiesWithContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } + (NSUInteger) MR_countOfEntitiesWithContext:(NSManagedObjectContext *)context; { - NSError *error = nil; - NSUInteger count = [context countForFetchRequest:[self MR_createFetchRequestInContext:context] error:&error]; - [MagicalRecord handleErrors:error]; - - return count; + return [self MR_countOfEntitiesWithPredicate:nil inContext:context]; } + (NSUInteger) MR_countOfEntitiesWithPredicate:(NSPredicate *)searchFilter; { - return [self MR_countOfEntitiesWithPredicate:searchFilter inContext:[NSManagedObjectContext MR_defaultContext]]; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + return [self MR_countOfEntitiesWithPredicate:searchFilter inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } + (NSUInteger) MR_countOfEntitiesWithPredicate:(NSPredicate *)searchFilter inContext:(NSManagedObjectContext *)context; { NSError *error = nil; NSFetchRequest *request = [self MR_createFetchRequestInContext:context]; - [request setPredicate:searchFilter]; + + if (searchFilter) + { + [request setPredicate:searchFilter]; + } NSUInteger count = [context countForFetchRequest:request error:&error]; [MagicalRecord handleErrors:error]; @@ -74,7 +86,10 @@ + (NSUInteger) MR_countOfEntitiesWithPredicate:(NSPredicate *)searchFilter inCon + (BOOL) MR_hasAtLeastOneEntity { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [self MR_hasAtLeastOneEntityInContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } + (BOOL) MR_hasAtLeastOneEntityInContext:(NSManagedObjectContext *)context @@ -82,11 +97,19 @@ + (BOOL) MR_hasAtLeastOneEntityInContext:(NSManagedObjectContext *)context return [[self MR_numberOfEntitiesWithContext:context] intValue] > 0; } -- (NSNumber *) MR_maxValueFor:(NSString *)property +- (id) MR_minValueFor:(NSString *)property +{ + NSManagedObject *obj = [[self class] MR_findFirstByAttribute:property + withValue:[NSString stringWithFormat:@"min(%@)", property]]; + + return [obj valueForKey:property]; +} + +- (id) MR_maxValueFor:(NSString *)property { NSManagedObject *obj = [[self class] MR_findFirstByAttribute:property withValue:[NSString stringWithFormat:@"max(%@)", property]]; - + return [obj valueForKey:property]; } @@ -105,7 +128,7 @@ - (id) MR_objectWithMinValueFor:(NSString *)property return [self MR_objectWithMinValueFor:property inContext:[self managedObjectContext]]; } -+ (NSNumber *) MR_aggregateOperation:(NSString *)function onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate inContext:(NSManagedObjectContext *)context ++ (id) MR_aggregateOperation:(NSString *)function onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate inContext:(NSManagedObjectContext *)context { NSExpression *ex = [NSExpression expressionForFunction:function arguments:[NSArray arrayWithObject:[NSExpression expressionForKeyPath:attributeName]]]; @@ -115,7 +138,7 @@ + (NSNumber *) MR_aggregateOperation:(NSString *)function onAttribute:(NSString [ed setExpression:ex]; // determine the type of attribute, required to set the expression return type - NSAttributeDescription *attributeDescription = [[[self MR_entityDescription] attributesByName] objectForKey:attributeName]; + NSAttributeDescription *attributeDescription = [[self MR_entityDescriptionInContext:context] MR_attributeDescriptionForName:attributeName]; [ed setExpressionResultType:[attributeDescription attributeType]]; NSArray *properties = [NSArray arrayWithObject:ed]; @@ -124,17 +147,53 @@ + (NSNumber *) MR_aggregateOperation:(NSString *)function onAttribute:(NSString [request setResultType:NSDictionaryResultType]; NSDictionary *resultsDictionary = [self MR_executeFetchRequestAndReturnFirstObject:request inContext:context]; - NSNumber *resultValue = [resultsDictionary objectForKey:@"result"]; - return resultValue; + return [resultsDictionary objectForKey:@"result"]; } -+ (NSNumber *) MR_aggregateOperation:(NSString *)function onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate ++ (id) MR_aggregateOperation:(NSString *)function onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate { - return [self MR_aggregateOperation:function +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + return [self MR_aggregateOperation:function onAttribute:attributeName withPredicate:predicate - inContext:[NSManagedObjectContext MR_defaultContext]]; + inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop +} + ++ (NSArray *) MR_aggregateOperation:(NSString *)collectionOperator onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate groupBy:(NSString *)groupingKeyPath inContext:(NSManagedObjectContext *)context; +{ + NSExpression *expression = [NSExpression expressionForFunction:collectionOperator arguments:[NSArray arrayWithObject:[NSExpression expressionForKeyPath:attributeName]]]; + + NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init]; + + [expressionDescription setName:@"result"]; + [expressionDescription setExpression:expression]; + + NSAttributeDescription *attributeDescription = [[[self MR_entityDescriptionInContext:context] attributesByName] objectForKey:attributeName]; + [expressionDescription setExpressionResultType:[attributeDescription attributeType]]; + NSArray *properties = [NSArray arrayWithObjects:groupingKeyPath, expressionDescription, nil]; + + NSFetchRequest *fetchRequest = [self MR_requestAllWithPredicate:predicate inContext:context]; + [fetchRequest setPropertiesToFetch:properties]; + [fetchRequest setResultType:NSDictionaryResultType]; + [fetchRequest setPropertiesToGroupBy:[NSArray arrayWithObject:groupingKeyPath]]; + + NSArray *results = [self MR_executeFetchRequest:fetchRequest inContext:context]; + + return results; +} + ++ (NSArray *) MR_aggregateOperation:(NSString *)collectionOperator onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate groupBy:(NSString *)groupingKeyPath; +{ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + return [self MR_aggregateOperation:collectionOperator + onAttribute:attributeName + withPredicate:predicate groupBy:groupingKeyPath + inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } @end diff --git a/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalDataImport.h b/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalDataImport.h index c5376305d..c42533d03 100644 --- a/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalDataImport.h +++ b/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalDataImport.h @@ -9,6 +9,7 @@ extern NSString * const kMagicalRecordImportCustomDateFormatKey; extern NSString * const kMagicalRecordImportDefaultDateFormatString; +extern NSString * const kMagicalRecordImportUnixTimeString; extern NSString * const kMagicalRecordImportAttributeKeyMapKey; extern NSString * const kMagicalRecordImportAttributeValueClassNameKey; @@ -16,12 +17,21 @@ extern NSString * const kMagicalRecordImportRelationshipMapKey; extern NSString * const kMagicalRecordImportRelationshipLinkedByKey; extern NSString * const kMagicalRecordImportRelationshipTypeKey; -@interface NSManagedObject (MagicalRecord_DataImport) +@protocol MagicalRecordDataImportProtocol + +@optional +- (BOOL) shouldImport:(id)data; +- (void) willImport:(id)data; +- (void) didImport:(id)data; + +@end + +@interface NSManagedObject (MagicalRecord_DataImport) - (BOOL) MR_importValuesForKeysWithObject:(id)objectData; -+ (id) MR_importFromObject:(id)data; -+ (id) MR_importFromObject:(id)data inContext:(NSManagedObjectContext *)context; ++ (instancetype) MR_importFromObject:(id)data; ++ (instancetype) MR_importFromObject:(id)data inContext:(NSManagedObjectContext *)context; + (NSArray *) MR_importFromArray:(NSArray *)listOfObjectData; + (NSArray *) MR_importFromArray:(NSArray *)listOfObjectData inContext:(NSManagedObjectContext *)context; diff --git a/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalDataImport.m b/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalDataImport.m index 4e5fb5c01..22fd9c693 100644 --- a/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalDataImport.m +++ b/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalDataImport.m @@ -5,13 +5,22 @@ // Copyright 2011 Magical Panda Software LLC. All rights reserved. // -#import "CoreData+MagicalRecord.h" +#import "NSObject+MagicalDataImport.h" +#import "NSAttributeDescription+MagicalDataImport.h" +#import "NSEntityDescription+MagicalDataImport.h" +#import "NSManagedObjectContext+MagicalThreading.h" +#import "NSManagedObject+MagicalDataImport.h" +#import "NSManagedObject+MagicalFinders.h" +#import "NSManagedObject+MagicalRecord.h" +#import "NSRelationshipDescription+MagicalDataImport.h" +#import "NSString+MagicalDataImport.h" +#import "MagicalImportFunctions.h" +#import "MagicalRecordLogging.h" #import -void MR_swapMethodsFromClass(Class c, SEL orig, SEL new); - NSString * const kMagicalRecordImportCustomDateFormatKey = @"dateFormat"; -NSString * const kMagicalRecordImportDefaultDateFormatString = @"yyyy-MM-dd'T'HH:mm:ss'Z'"; +NSString * const kMagicalRecordImportDefaultDateFormatString = @"yyyy-MM-dd'T'HH:mm:ssz"; +NSString * const kMagicalRecordImportUnixTimeString = @"UnixTime"; NSString * const kMagicalRecordImportAttributeKeyMapKey = @"mappedKeyName"; NSString * const kMagicalRecordImportAttributeValueClassNameKey = @"attributeValueClassName"; @@ -22,20 +31,26 @@ NSString * const kMagicalRecordImportAttributeUseDefaultValueWhenNotPresent = @"useDefaultValueWhenNotPresent"; -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Warc-performSelector-leaks" - @implementation NSManagedObject (MagicalRecord_DataImport) - (BOOL) MR_importValue:(id)value forKey:(NSString *)key { NSString *selectorString = [NSString stringWithFormat:@"import%@:", [key MR_capitalizedFirstCharacterString]]; SEL selector = NSSelectorFromString(selectorString); + if ([self respondsToSelector:selector]) { - [self performSelector:selector withObject:value]; - return YES; + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:selector]]; + [invocation setTarget:self]; + [invocation setSelector:selector]; + [invocation setArgument:&value atIndex:2]; + [invocation invoke]; + + BOOL returnValue = YES; + [invocation getReturnValue:&returnValue]; + return returnValue; } + return NO; } @@ -72,25 +87,41 @@ - (NSManagedObject *) MR_findObjectForRelationship:(NSRelationshipDescription *) { NSEntityDescription *destinationEntity = [relationshipInfo destinationEntity]; NSManagedObject *objectForRelationship = nil; - id relatedValue = [singleRelatedObjectData MR_relatedValueForRelationship:relationshipInfo]; - if (relatedValue) + id relatedValue; + + // if its a primitive class, than handle singleRelatedObjectData as the key for relationship + if ([singleRelatedObjectData isKindOfClass:[NSString class]] || + [singleRelatedObjectData isKindOfClass:[NSNumber class]]) + { + relatedValue = singleRelatedObjectData; + } + else if ([singleRelatedObjectData isKindOfClass:[NSDictionary class]]) + { + relatedValue = [singleRelatedObjectData MR_relatedValueForRelationship:relationshipInfo]; + } + else + { + relatedValue = singleRelatedObjectData; + } + + if (relatedValue) { NSManagedObjectContext *context = [self managedObjectContext]; Class managedObjectClass = NSClassFromString([destinationEntity managedObjectClassName]); NSString *primaryKey = [relationshipInfo MR_primaryKey]; objectForRelationship = [managedObjectClass MR_findFirstByAttribute:primaryKey - withValue:relatedValue - inContext:context]; + withValue:relatedValue + inContext:context]; } - + return objectForRelationship; } - (void) MR_addObject:(NSManagedObject *)relatedObject forRelationship:(NSRelationshipDescription *)relationshipInfo { NSAssert2(relatedObject != nil, @"Cannot add nil to %@ for attribute %@", NSStringFromClass([self class]), [relationshipInfo name]); - NSAssert2([relatedObject entity] == [relationshipInfo destinationEntity], @"related object entity %@ not same as destination entity %@", [relatedObject entity], [relationshipInfo destinationEntity]); + NSAssert2([[relatedObject entity] isKindOfEntity:[relationshipInfo destinationEntity]], @"related object entity %@ not same as destination entity %@", [relatedObject entity], [relationshipInfo destinationEntity]); //add related object to set NSString *addRelationMessageFormat = @"set%@:"; @@ -102,68 +133,93 @@ - (void) MR_addObject:(NSManagedObject *)relatedObject forRelationship:(NSRelati { //Need to get the ordered set NSString *selectorName = [[relationshipInfo name] stringByAppendingString:@"Set"]; + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" relationshipSource = [self performSelector:NSSelectorFromString(selectorName)]; +#pragma clang diagnostic pop addRelationMessageFormat = @"addObject:"; } } - NSString *addRelatedObjectToSetMessage = [NSString stringWithFormat:addRelationMessageFormat, attributeNameFromString([relationshipInfo name])]; + NSString *addRelatedObjectToSetMessage = [NSString stringWithFormat:addRelationMessageFormat, MR_attributeNameFromString([relationshipInfo name])]; SEL selector = NSSelectorFromString(addRelatedObjectToSetMessage); - - @try + + @try { - [relationshipSource performSelector:selector withObject:relatedObject]; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + [relationshipSource performSelector:selector withObject:relatedObject]; +#pragma clang diagnostic pop } - @catch (NSException *exception) + @catch (NSException *exception) { - MRLog(@"Adding object for relationship failed: %@\n", relationshipInfo); - MRLog(@"relatedObject.entity %@", [relatedObject entity]); - MRLog(@"relationshipInfo.destinationEntity %@", [relationshipInfo destinationEntity]); - MRLog(@"Add Relationship Selector: %@", addRelatedObjectToSetMessage); - MRLog(@"perform selector error: %@", exception); + MRLogError(@"Adding object for relationship failed: %@\n", relationshipInfo); + MRLogError(@"relatedObject.entity %@", [relatedObject entity]); + MRLogError(@"relationshipInfo.destinationEntity %@", [relationshipInfo destinationEntity]); + MRLogError(@"Add Relationship Selector: %@", addRelatedObjectToSetMessage); + MRLogError(@"perform selector error: %@", exception); } } -- (void) MR_setRelationships:(NSDictionary *)relationships forKeysWithObject:(id)relationshipData withBlock:(void(^)(NSRelationshipDescription *,id))setRelationshipBlock +- (void)MR_setRelationships:(NSDictionary *)relationships forKeysWithObject:(id)relationshipData withBlock:(void (^)(NSRelationshipDescription *, id))setRelationshipBlock { - for (NSString *relationshipName in relationships) + for (NSString *relationshipName in relationships) { - if ([self MR_importValue:relationshipData forKey:relationshipName]) - { - continue; - } - + SEL shouldImportSelector = NSSelectorFromString([NSString stringWithFormat:@"shouldImport%@:", [relationshipName MR_capitalizedFirstCharacterString]]); + BOOL implementsShouldImport = (BOOL)[self respondsToSelector:shouldImportSelector]; + NSRelationshipDescription *relationshipInfo = [relationships valueForKey:relationshipName]; - + NSString *lookupKey = [[relationshipInfo userInfo] valueForKey:kMagicalRecordImportRelationshipMapKey] ?: relationshipName; - id relatedObjectData = [relationshipData valueForKeyPath:lookupKey]; - - if (relatedObjectData == nil || [relatedObjectData isEqual:[NSNull null]]) + + id relatedObjectData; + + @try { - continue; + relatedObjectData = [relationshipData valueForKeyPath:lookupKey]; } - - SEL shouldImportSelector = NSSelectorFromString([NSString stringWithFormat:@"shouldImport%@:", [relationshipName MR_capitalizedFirstCharacterString]]); - BOOL implementsShouldImport = (BOOL)[self respondsToSelector:shouldImportSelector]; - void (^establishRelationship)(NSRelationshipDescription *, id) = ^(NSRelationshipDescription *blockInfo, id blockData) + @catch (NSException *exception) + { + MRLogWarn(@"Looking up a key for relationship failed while importing: %@\n", relationshipInfo); + MRLogWarn(@"lookupKey: %@", lookupKey); + MRLogWarn(@"relationshipInfo.destinationEntity %@", [relationshipInfo destinationEntity]); + MRLogWarn(@"relationshipData: %@", relationshipData); + MRLogWarn(@"Exception:\n%@: %@", [exception name], [exception reason]); + } + @finally { - if (!(implementsShouldImport && !(BOOL)[self performSelector:shouldImportSelector withObject:relatedObjectData])) + if (relatedObjectData == nil || [relatedObjectData isEqual:[NSNull null]]) { - setRelationshipBlock(blockInfo, blockData); + continue; } - }; - + } + +#pragma clang diagnostic push +#pragma clang diagnostic ignored \ + "-Warc-performSelector-leaks" + if (implementsShouldImport && !(BOOL)[self performSelector:shouldImportSelector withObject:relatedObjectData]) + { + continue; + } +#pragma clang diagnostic pop + // Different values provided to the -shouldImport and -import methods?? + if ([self MR_importValue:relationshipData forKey:relationshipName]) + { + continue; + } + if ([relationshipInfo isToMany] && [relatedObjectData isKindOfClass:[NSArray class]]) { - for (id singleRelatedObjectData in relatedObjectData) + for (id singleRelatedObjectData in relatedObjectData) { - establishRelationship(relationshipInfo, singleRelatedObjectData); + setRelationshipBlock(relationshipInfo, singleRelatedObjectData); } } else { - establishRelationship(relationshipInfo, relatedObjectData); + setRelationshipBlock(relationshipInfo, relatedObjectData); } } } @@ -172,7 +228,7 @@ - (BOOL) MR_preImport:(id)objectData; { if ([self respondsToSelector:@selector(shouldImport:)]) { - BOOL shouldImport = (BOOL)[self performSelector:@selector(shouldImport:) withObject:objectData]; + BOOL shouldImport = (BOOL)[self shouldImport:objectData]; if (!shouldImport) { return NO; @@ -181,19 +237,19 @@ - (BOOL) MR_preImport:(id)objectData; if ([self respondsToSelector:@selector(willImport:)]) { - [self performSelector:@selector(willImport:) withObject:objectData]; + [self willImport:objectData]; } - MR_swapMethodsFromClass([objectData class], @selector(valueForUndefinedKey:), @selector(MR_valueForUndefinedKey:)); + return YES; } - (BOOL) MR_postImport:(id)objectData; { - MR_swapMethodsFromClass([objectData class], @selector(valueForUndefinedKey:), @selector(MR_valueForUndefinedKey:)); if ([self respondsToSelector:@selector(didImport:)]) { [self performSelector:@selector(didImport:) withObject:objectData]; } + return YES; } @@ -211,88 +267,94 @@ - (BOOL) MR_performDataImportFromObject:(id)objectData relationshipBlock:(void(^ return [self MR_postImport:objectData]; } -- (BOOL) MR_importValuesForKeysWithObject:(id)objectData +- (BOOL)MR_importValuesForKeysWithObject:(id)objectData { - typeof(self) weakself = self; + __weak typeof(self) weakself = self; return [self MR_performDataImportFromObject:objectData relationshipBlock:^(NSRelationshipDescription *relationshipInfo, id localObjectData) { - - NSManagedObject *relatedObject = [weakself MR_findObjectForRelationship:relationshipInfo withData:localObjectData]; - - if (relatedObject == nil) - { - NSEntityDescription *entityDescription = [relationshipInfo destinationEntity]; - relatedObject = [entityDescription MR_createInstanceInContext:[weakself managedObjectContext]]; - } - [relatedObject MR_importValuesForKeysWithObject:localObjectData]; - - [weakself MR_addObject:relatedObject forRelationship:relationshipInfo]; - } ]; + + NSManagedObject *relatedObject = [weakself MR_findObjectForRelationship:relationshipInfo withData:localObjectData]; + + if (relatedObject == nil) + { + NSEntityDescription *entityDescription = [relationshipInfo destinationEntity]; + relatedObject = [entityDescription MR_createInstanceInContext:[weakself managedObjectContext]]; + } + if ([localObjectData isKindOfClass:[NSDictionary class]]) + { + [relatedObject MR_importValuesForKeysWithObject:localObjectData]; + } + else if (localObjectData) + { + NSString *relatedByAttribute = [[relationshipInfo userInfo] objectForKey:kMagicalRecordImportRelationshipLinkedByKey] ?: MR_primaryKeyNameFromString([[relationshipInfo destinationEntity] name]); + + if (relatedByAttribute) + { + if (![relatedObject MR_importValue:localObjectData forKey:relatedByAttribute]) + { + [relatedObject setValue:localObjectData forKey:relatedByAttribute]; + } + } + } + + [weakself MR_addObject:relatedObject forRelationship:relationshipInfo]; + }]; } + (id) MR_importFromObject:(id)objectData inContext:(NSManagedObjectContext *)context; { - NSAttributeDescription *primaryAttribute = [[self MR_entityDescription] MR_primaryAttributeToRelateBy]; - - id value = [objectData MR_valueForAttribute:primaryAttribute]; - - NSManagedObject *managedObject = [self MR_findFirstByAttribute:[primaryAttribute name] withValue:value inContext:context]; - if (managedObject == nil) - { - managedObject = [self MR_createInContext:context]; - } + __block NSManagedObject *managedObject; + + [context performBlockAndWait:^{ + NSAttributeDescription *primaryAttribute = [[self MR_entityDescriptionInContext:context] MR_primaryAttributeToRelateBy]; + + id value = [objectData MR_valueForAttribute:primaryAttribute]; + + if (primaryAttribute != nil) + { + managedObject = [self MR_findFirstByAttribute:[primaryAttribute name] withValue:value inContext:context]; + } + if (managedObject == nil) + { + managedObject = [self MR_createEntityInContext:context]; + } - [managedObject MR_importValuesForKeysWithObject:objectData]; + [managedObject MR_importValuesForKeysWithObject:objectData]; + }]; return managedObject; } + (id) MR_importFromObject:(id)objectData { - return [self MR_importFromObject:objectData inContext:[NSManagedObjectContext MR_defaultContext]]; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + return [self MR_importFromObject:objectData inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } + (NSArray *) MR_importFromArray:(NSArray *)listOfObjectData { - return [self MR_importFromArray:listOfObjectData inContext:[NSManagedObjectContext MR_defaultContext]]; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + return [self MR_importFromArray:listOfObjectData inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } + (NSArray *) MR_importFromArray:(NSArray *)listOfObjectData inContext:(NSManagedObjectContext *)context { - NSMutableArray *objectIDs = [NSMutableArray array]; - - [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) - { - [listOfObjectData enumerateObjectsWithOptions:0 usingBlock:^(id obj, NSUInteger idx, BOOL *stop) - { - NSDictionary *objectData = (NSDictionary *)obj; + NSMutableArray *dataObjects = [NSMutableArray array]; + + [listOfObjectData enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) + { + NSDictionary *objectData = (NSDictionary *)obj; - NSManagedObject *dataObject = [self MR_importFromObject:objectData inContext:localContext]; + NSManagedObject *dataObject = [self MR_importFromObject:objectData inContext:context]; - if ([context obtainPermanentIDsForObjects:[NSArray arrayWithObject:dataObject] error:nil]) - { - [objectIDs addObject:[dataObject objectID]]; - } - }]; + [dataObjects addObject:dataObject]; }]; - - return [self MR_findAllWithPredicate:[NSPredicate predicateWithFormat:@"self IN %@", objectIDs] inContext:context]; + + return dataObjects; } @end - -#pragma clang diagnostic pop - -void MR_swapMethodsFromClass(Class c, SEL orig, SEL new) -{ - Method origMethod = class_getInstanceMethod(c, orig); - Method newMethod = class_getInstanceMethod(c, new); - if (class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) - { - class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod)); - } - else - { - method_exchangeImplementations(origMethod, newMethod); - } -} diff --git a/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalFinders.h b/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalFinders.h index 02aadc037..41633257b 100644 --- a/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalFinders.h +++ b/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalFinders.h @@ -20,20 +20,23 @@ + (NSArray *) MR_findAllWithPredicate:(NSPredicate *)searchTerm; + (NSArray *) MR_findAllWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context; -+ (id) MR_findFirst; -+ (id) MR_findFirstInContext:(NSManagedObjectContext *)context; -+ (id) MR_findFirstWithPredicate:(NSPredicate *)searchTerm; -+ (id) MR_findFirstWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context; -+ (id) MR_findFirstWithPredicate:(NSPredicate *)searchterm sortedBy:(NSString *)property ascending:(BOOL)ascending; -+ (id) MR_findFirstWithPredicate:(NSPredicate *)searchterm sortedBy:(NSString *)property ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context; -+ (id) MR_findFirstWithPredicate:(NSPredicate *)searchTerm andRetrieveAttributes:(NSArray *)attributes; -+ (id) MR_findFirstWithPredicate:(NSPredicate *)searchTerm andRetrieveAttributes:(NSArray *)attributes inContext:(NSManagedObjectContext *)context; -+ (id) MR_findFirstWithPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortBy ascending:(BOOL)ascending andRetrieveAttributes:(id)attributes, ...; -+ (id) MR_findFirstWithPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortBy ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context andRetrieveAttributes:(id)attributes, ...; -+ (id) MR_findFirstByAttribute:(NSString *)attribute withValue:(id)searchValue; -+ (id) MR_findFirstByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context; -+ (id) MR_findFirstOrderedByAttribute:(NSString *)attribute ascending:(BOOL)ascending; -+ (id) MR_findFirstOrderedByAttribute:(NSString *)attribute ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context; ++ (instancetype) MR_findFirst; ++ (instancetype) MR_findFirstInContext:(NSManagedObjectContext *)context; ++ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchTerm; ++ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context; ++ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchterm sortedBy:(NSString *)property ascending:(BOOL)ascending; ++ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchterm sortedBy:(NSString *)property ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context; ++ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchTerm andRetrieveAttributes:(NSArray *)attributes; ++ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchTerm andRetrieveAttributes:(NSArray *)attributes inContext:(NSManagedObjectContext *)context; ++ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortBy ascending:(BOOL)ascending andRetrieveAttributes:(id)attributes, ...; ++ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortBy ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context andRetrieveAttributes:(id)attributes, ...; ++ (instancetype) MR_findFirstByAttribute:(NSString *)attribute withValue:(id)searchValue; ++ (instancetype) MR_findFirstByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context; ++ (instancetype) MR_findFirstOrderedByAttribute:(NSString *)attribute ascending:(BOOL)ascending; ++ (instancetype) MR_findFirstOrderedByAttribute:(NSString *)attribute ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context; + ++ (instancetype) MR_findFirstOrCreateByAttribute:(NSString *)attribute withValue:(id)searchValue; ++ (instancetype) MR_findFirstOrCreateByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context; + (NSArray *) MR_findByAttribute:(NSString *)attribute withValue:(id)searchValue; + (NSArray *) MR_findByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context; @@ -42,6 +45,8 @@ #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR ++ (NSFetchedResultsController *) MR_fetchController:(NSFetchRequest *)request delegate:(id)delegate useFileCache:(BOOL)useFileCache groupedBy:(NSString *)groupKeyPath inContext:(NSManagedObjectContext *)context; + + (NSFetchedResultsController *) MR_fetchAllWithDelegate:(id)delegate; + (NSFetchedResultsController *) MR_fetchAllWithDelegate:(id)delegate inContext:(NSManagedObjectContext *)context; diff --git a/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalFinders.m b/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalFinders.m index a298385fe..99ee98668 100644 --- a/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalFinders.m +++ b/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalFinders.m @@ -23,7 +23,10 @@ + (NSArray *) MR_findAllInContext:(NSManagedObjectContext *)context + (NSArray *) MR_findAll { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [self MR_findAllInContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } + (NSArray *) MR_findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context @@ -35,9 +38,12 @@ + (NSArray *) MR_findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending + (NSArray *) MR_findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [self MR_findAllSortedBy:sortTerm ascending:ascending inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } + (NSArray *) MR_findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context @@ -52,10 +58,13 @@ + (NSArray *) MR_findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending + (NSArray *) MR_findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [self MR_findAllSortedBy:sortTerm ascending:ascending withPredicate:searchTerm inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } @@ -70,38 +79,45 @@ + (NSArray *) MR_findAllWithPredicate:(NSPredicate *)searchTerm inContext:(NSMan + (NSArray *) MR_findAllWithPredicate:(NSPredicate *)searchTerm { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [self MR_findAllWithPredicate:searchTerm inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } -+ (id) MR_findFirstInContext:(NSManagedObjectContext *)context ++ (instancetype) MR_findFirstInContext:(NSManagedObjectContext *)context { NSFetchRequest *request = [self MR_createFetchRequestInContext:context]; return [self MR_executeFetchRequestAndReturnFirstObject:request inContext:context]; } -+ (id) MR_findFirst ++ (instancetype) MR_findFirst { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [self MR_findFirstInContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } -+ (id) MR_findFirstByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context ++ (instancetype) MR_findFirstByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context { NSFetchRequest *request = [self MR_requestFirstByAttribute:attribute withValue:searchValue inContext:context]; - // [request setPropertiesToFetch:[NSArray arrayWithObject:attribute]]; - return [self MR_executeFetchRequestAndReturnFirstObject:request inContext:context]; } -+ (id) MR_findFirstByAttribute:(NSString *)attribute withValue:(id)searchValue ++ (instancetype) MR_findFirstByAttribute:(NSString *)attribute withValue:(id)searchValue { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [self MR_findFirstByAttribute:attribute withValue:searchValue inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } -+ (id) MR_findFirstOrderedByAttribute:(NSString *)attribute ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context; ++ (instancetype) MR_findFirstOrderedByAttribute:(NSString *)attribute ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context; { NSFetchRequest *request = [self MR_requestAllSortedBy:attribute ascending:ascending inContext:context]; [request setFetchLimit:1]; @@ -109,41 +125,76 @@ + (id) MR_findFirstOrderedByAttribute:(NSString *)attribute ascending:(BOOL)asce return [self MR_executeFetchRequestAndReturnFirstObject:request inContext:context]; } -+ (id) MR_findFirstOrderedByAttribute:(NSString *)attribute ascending:(BOOL)ascending; ++ (instancetype) MR_findFirstOrderedByAttribute:(NSString *)attribute ascending:(BOOL)ascending; { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [self MR_findFirstOrderedByAttribute:attribute ascending:ascending inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop +} + ++ (instancetype) MR_findFirstOrCreateByAttribute:(NSString *)attribute withValue:(id)searchValue +{ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + return [self MR_findFirstOrCreateByAttribute:attribute + withValue:searchValue + inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } -+ (id) MR_findFirstWithPredicate:(NSPredicate *)searchTerm ++ (instancetype) MR_findFirstOrCreateByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context { + id result = [self MR_findFirstByAttribute:attribute + withValue:searchValue + inContext:context]; + + if (result != nil) { + return result; + } + + result = [self MR_createEntityInContext:context]; + [result setValue:searchValue forKey:attribute]; + + return result; +} + ++ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchTerm +{ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [self MR_findFirstWithPredicate:searchTerm inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } -+ (id) MR_findFirstWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context ++ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context { NSFetchRequest *request = [self MR_requestFirstWithPredicate:searchTerm inContext:context]; return [self MR_executeFetchRequestAndReturnFirstObject:request inContext:context]; } -+ (id) MR_findFirstWithPredicate:(NSPredicate *)searchterm sortedBy:(NSString *)property ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context ++ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchterm sortedBy:(NSString *)property ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context { NSFetchRequest *request = [self MR_requestAllSortedBy:property ascending:ascending withPredicate:searchterm inContext:context]; return [self MR_executeFetchRequestAndReturnFirstObject:request inContext:context]; } -+ (id) MR_findFirstWithPredicate:(NSPredicate *)searchterm sortedBy:(NSString *)property ascending:(BOOL)ascending ++ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchterm sortedBy:(NSString *)property ascending:(BOOL)ascending { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [self MR_findFirstWithPredicate:searchterm sortedBy:property ascending:ascending inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } -+ (id) MR_findFirstWithPredicate:(NSPredicate *)searchTerm andRetrieveAttributes:(NSArray *)attributes inContext:(NSManagedObjectContext *)context ++ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchTerm andRetrieveAttributes:(NSArray *)attributes inContext:(NSManagedObjectContext *)context { NSFetchRequest *request = [self MR_createFetchRequestInContext:context]; [request setPredicate:searchTerm]; @@ -152,31 +203,37 @@ + (id) MR_findFirstWithPredicate:(NSPredicate *)searchTerm andRetrieveAttributes return [self MR_executeFetchRequestAndReturnFirstObject:request inContext:context]; } -+ (id) MR_findFirstWithPredicate:(NSPredicate *)searchTerm andRetrieveAttributes:(NSArray *)attributes ++ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchTerm andRetrieveAttributes:(NSArray *)attributes { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [self MR_findFirstWithPredicate:searchTerm andRetrieveAttributes:attributes inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } -+ (id) MR_findFirstWithPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortBy ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context andRetrieveAttributes:(id)attributes, ... ++ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortBy ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context andRetrieveAttributes:(id)attributes, ... { NSFetchRequest *request = [self MR_requestAllSortedBy:sortBy ascending:ascending withPredicate:searchTerm inContext:context]; - [request setPropertiesToFetch:[self MR_propertiesNamed:attributes]]; + [request setPropertiesToFetch:[self MR_propertiesNamed:attributes inContext:context]]; return [self MR_executeFetchRequestAndReturnFirstObject:request inContext:context]; } -+ (id) MR_findFirstWithPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortBy ascending:(BOOL)ascending andRetrieveAttributes:(id)attributes, ... ++ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortBy ascending:(BOOL)ascending andRetrieveAttributes:(id)attributes, ... { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [self MR_findFirstWithPredicate:searchTerm sortedBy:sortBy ascending:ascending inContext:[NSManagedObjectContext MR_contextForCurrentThread] andRetrieveAttributes:attributes]; +#pragma clang diagnostic pop } + (NSArray *) MR_findByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context @@ -188,9 +245,12 @@ + (NSArray *) MR_findByAttribute:(NSString *)attribute withValue:(id)searchValue + (NSArray *) MR_findByAttribute:(NSString *)attribute withValue:(id)searchValue { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [self MR_findByAttribute:attribute withValue:searchValue inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } + (NSArray *) MR_findByAttribute:(NSString *)attribute withValue:(id)searchValue andOrderBy:(NSString *)sortTerm ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context @@ -203,11 +263,14 @@ + (NSArray *) MR_findByAttribute:(NSString *)attribute withValue:(id)searchValue + (NSArray *) MR_findByAttribute:(NSString *)attribute withValue:(id)searchValue andOrderBy:(NSString *)sortTerm ascending:(BOOL)ascending { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [self MR_findByAttribute:attribute withValue:searchValue andOrderBy:sortTerm ascending:ascending inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } @@ -217,7 +280,7 @@ + (NSArray *) MR_findByAttribute:(NSString *)attribute withValue:(id)searchValue #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR -+ (NSFetchedResultsController *) MR_fetchController:(NSFetchRequest *)request delegate:(id)delegate useFileCache:(BOOL)useFileCache groupedBy:(NSString *)groupKeyPath inContext:(NSManagedObjectContext *)context ++ (NSFetchedResultsController *) MR_fetchController:(NSFetchRequest *)request delegate:(id)delegate useFileCache:(BOOL)useFileCache groupedBy:(NSString *)groupKeyPath inContext:(NSManagedObjectContext *)context; { NSString *cacheName = useFileCache ? [NSString stringWithFormat:@"MagicalRecord-Cache-%@", NSStringFromClass([self class])] : nil; @@ -233,7 +296,10 @@ + (NSFetchedResultsController *) MR_fetchController:(NSFetchRequest *)request de + (NSFetchedResultsController *) MR_fetchAllWithDelegate:(id)delegate; { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [self MR_fetchAllWithDelegate:delegate inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } + (NSFetchedResultsController *) MR_fetchAllWithDelegate:(id)delegate inContext:(NSManagedObjectContext *)context; @@ -264,12 +330,15 @@ + (NSFetchedResultsController *) MR_fetchAllGroupedBy:(NSString *)group withPred + (NSFetchedResultsController *) MR_fetchAllGroupedBy:(NSString *)group withPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortTerm ascending:(BOOL)ascending delegate:(id)delegate { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [self MR_fetchAllGroupedBy:group withPredicate:searchTerm sortedBy:sortTerm ascending:ascending delegate:delegate inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } + (NSFetchedResultsController *) MR_fetchAllGroupedBy:(NSString *)group withPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortTerm ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context; @@ -284,11 +353,14 @@ + (NSFetchedResultsController *) MR_fetchAllGroupedBy:(NSString *)group withPred + (NSFetchedResultsController *) MR_fetchAllGroupedBy:(NSString *)group withPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortTerm ascending:(BOOL)ascending { - return [self MR_fetchAllGroupedBy:group +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + return [self MR_fetchAllGroupedBy:group withPredicate:searchTerm sortedBy:sortTerm ascending:ascending inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } @@ -298,47 +370,49 @@ + (NSFetchedResultsController *) MR_fetchAllSortedBy:(NSString *)sortTerm ascend ascending:ascending withPredicate:searchTerm inContext:context]; - - NSFetchedResultsController *controller = [self MR_fetchController:request + NSFetchedResultsController *controller = [self MR_fetchController:request delegate:nil useFileCache:NO groupedBy:groupingKeyPath - inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; - + inContext:context]; + [self MR_performFetch:controller]; return controller; } + (NSFetchedResultsController *) MR_fetchAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm groupBy:(NSString *)groupingKeyPath; { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [self MR_fetchAllSortedBy:sortTerm ascending:ascending withPredicate:searchTerm groupBy:groupingKeyPath inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } + (NSFetchedResultsController *) MR_fetchAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm groupBy:(NSString *)groupingKeyPath delegate:(id)delegate inContext:(NSManagedObjectContext *)context { - NSFetchedResultsController *controller = [self MR_fetchAllGroupedBy:groupingKeyPath - withPredicate:searchTerm - sortedBy:sortTerm - ascending:ascending - delegate:delegate - inContext:context]; - - [self MR_performFetch:controller]; - return controller; + return [self MR_fetchAllGroupedBy:groupingKeyPath + withPredicate:searchTerm + sortedBy:sortTerm + ascending:ascending + delegate:delegate + inContext:context]; } + (NSFetchedResultsController *) MR_fetchAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm groupBy:(NSString *)groupingKeyPath delegate:(id)delegate { - return [self MR_fetchAllSortedBy:sortTerm +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + return [self MR_fetchAllSortedBy:sortTerm ascending:ascending withPredicate:searchTerm groupBy:groupingKeyPath delegate:delegate inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } #endif diff --git a/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalRecord.h b/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalRecord.h index bf7a8c9c2..b1b70dec4 100644 --- a/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalRecord.h +++ b/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalRecord.h @@ -5,34 +5,42 @@ // #import -#import "MagicalRecord.h" - -#define kMagicalRecordDefaultBatchSize 20 +#import @interface NSManagedObject (MagicalRecord) +/** + * If the NSManagedObject subclass calling this method has implemented the `entityName` method, then the return value of that will be used. + * If `entityName` is not implemented, then the name of the class is returned. If the class is written in Swift, the module name will be removed. + * + * @return String based name for the entity + */ ++ (NSString *) MR_entityName; + + (NSUInteger) MR_defaultBatchSize; + (void) MR_setDefaultBatchSize:(NSUInteger)newBatchSize; + (NSArray *) MR_executeFetchRequest:(NSFetchRequest *)request; + (NSArray *) MR_executeFetchRequest:(NSFetchRequest *)request inContext:(NSManagedObjectContext *)context; -+ (id) MR_executeFetchRequestAndReturnFirstObject:(NSFetchRequest *)request; -+ (id) MR_executeFetchRequestAndReturnFirstObject:(NSFetchRequest *)request inContext:(NSManagedObjectContext *)context; ++ (instancetype) MR_executeFetchRequestAndReturnFirstObject:(NSFetchRequest *)request; ++ (instancetype) MR_executeFetchRequestAndReturnFirstObject:(NSFetchRequest *)request inContext:(NSManagedObjectContext *)context; #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR -+ (void) MR_performFetch:(NSFetchedResultsController *)controller; ++ (BOOL) MR_performFetch:(NSFetchedResultsController *)controller; #endif + (NSEntityDescription *) MR_entityDescription; + (NSEntityDescription *) MR_entityDescriptionInContext:(NSManagedObjectContext *)context; + (NSArray *) MR_propertiesNamed:(NSArray *)properties; ++ (NSArray *) MR_propertiesNamed:(NSArray *)properties inContext:(NSManagedObjectContext *)context; + ++ (instancetype) MR_createEntity; ++ (instancetype) MR_createEntityInContext:(NSManagedObjectContext *)context; -+ (id) MR_createEntity; -+ (id) MR_createInContext:(NSManagedObjectContext *)context; - (BOOL) MR_deleteEntity; -- (BOOL) MR_deleteInContext:(NSManagedObjectContext *)context; +- (BOOL) MR_deleteEntityInContext:(NSManagedObjectContext *)context; + (BOOL) MR_deleteAllMatchingPredicate:(NSPredicate *)predicate; + (BOOL) MR_deleteAllMatchingPredicate:(NSPredicate *)predicate inContext:(NSManagedObjectContext *)context; @@ -43,8 +51,24 @@ + (NSArray *) MR_ascendingSortDescriptors:(NSArray *)attributesToSortBy; + (NSArray *) MR_descendingSortDescriptors:(NSArray *)attributesToSortBy; -- (id) MR_inContext:(NSManagedObjectContext *)otherContext; -- (id) MR_inThreadContext; +- (instancetype) MR_inContext:(NSManagedObjectContext *)otherContext; +- (instancetype) MR_inThreadContext; + +@end + +@protocol MagicalRecord_MOGenerator + +@optional ++ (NSString *)entityName; +- (instancetype) entityInManagedObjectContext:(NSManagedObjectContext *)object; +- (instancetype) insertInManagedObjectContext:(NSManagedObjectContext *)object; @end +#pragma mark - Deprecated Methods — DO NOT USE +@interface NSManagedObject (MagicalRecordDeprecated) + ++ (instancetype) MR_createInContext:(NSManagedObjectContext *)context MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("4.0", "MR_createEntityInContext:"); +- (BOOL) MR_deleteInContext:(NSManagedObjectContext *)context MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("4.0", "MR_deleteEntityInContext:"); + +@end diff --git a/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalRecord.m b/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalRecord.m index 8bd7a8efd..9cb172ad5 100644 --- a/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalRecord.m +++ b/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalRecord.m @@ -3,24 +3,45 @@ // Copyright 2010 Magical Panda Software, LLC All rights reserved. // -#import "CoreData+MagicalRecord.h" - -static NSUInteger defaultBatchSize = kMagicalRecordDefaultBatchSize; +#import "NSManagedObject+MagicalRecord.h" +#import "NSManagedObject+MagicalRequests.h" +#import "NSManagedObjectContext+MagicalThreading.h" +#import "MagicalRecord+ErrorHandling.h" +#import "MagicalRecordLogging.h" +static NSUInteger kMagicalRecordDefaultBatchSize = 20; @implementation NSManagedObject (MagicalRecord) ++ (NSString *) MR_entityName; +{ + NSString *entityName; + + if ([self respondsToSelector:@selector(entityName)]) + { + entityName = [self performSelector:@selector(entityName)]; + } + + if ([entityName length] == 0) + { + // Remove module prefix from Swift subclasses + entityName = [NSStringFromClass(self) componentsSeparatedByString:@"."].lastObject; + } + + return entityName; +} + + (void) MR_setDefaultBatchSize:(NSUInteger)newBatchSize { @synchronized(self) { - defaultBatchSize = newBatchSize; + kMagicalRecordDefaultBatchSize = newBatchSize; } } + (NSUInteger) MR_defaultBatchSize { - return defaultBatchSize; + return kMagicalRecordDefaultBatchSize; } + (NSArray *) MR_executeFetchRequest:(NSFetchRequest *)request inContext:(NSManagedObjectContext *)context @@ -43,7 +64,10 @@ + (NSArray *) MR_executeFetchRequest:(NSFetchRequest *)request inContext:(NSMana + (NSArray *) MR_executeFetchRequest:(NSFetchRequest *)request { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [self MR_executeFetchRequest:request inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } + (id) MR_executeFetchRequestAndReturnFirstObject:(NSFetchRequest *)request inContext:(NSManagedObjectContext *)context @@ -55,60 +79,63 @@ + (id) MR_executeFetchRequestAndReturnFirstObject:(NSFetchRequest *)request inCo { return nil; } - return [results objectAtIndex:0]; + return [results firstObject]; } + (id) MR_executeFetchRequestAndReturnFirstObject:(NSFetchRequest *)request { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [self MR_executeFetchRequestAndReturnFirstObject:request inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } #if TARGET_OS_IPHONE -+ (void) MR_performFetch:(NSFetchedResultsController *)controller ++ (BOOL) MR_performFetch:(NSFetchedResultsController *)controller { NSError *error = nil; - if (![controller performFetch:&error]) + BOOL success = [controller performFetch:&error]; + if (!success) { [MagicalRecord handleErrors:error]; } + return success; } #endif -+ (NSString *) MR_entityName ++ (NSEntityDescription *) MR_entityDescription { - return NSStringFromClass(self); +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + return [self MR_entityDescriptionInContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } + (NSEntityDescription *) MR_entityDescriptionInContext:(NSManagedObjectContext *)context { - if ([self respondsToSelector:@selector(entityInManagedObjectContext:)]) - { - NSEntityDescription *entity = [self performSelector:@selector(entityInManagedObjectContext:) withObject:context]; - return entity; - } - else - { - NSString *entityName = [self MR_entityName]; - return [NSEntityDescription entityForName:entityName inManagedObjectContext:context]; - } + NSString *entityName = [self MR_entityName]; + return [NSEntityDescription entityForName:entityName inManagedObjectContext:context]; } -+ (NSEntityDescription *) MR_entityDescription ++ (NSArray *) MR_propertiesNamed:(NSArray *)properties { - return [self MR_entityDescriptionInContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + return [self MR_propertiesNamed:properties inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } -+ (NSArray *) MR_propertiesNamed:(NSArray *)properties ++ (NSArray *) MR_propertiesNamed:(NSArray *)properties inContext:(NSManagedObjectContext *)context { - NSEntityDescription *description = [self MR_entityDescription]; + NSEntityDescription *description = [self MR_entityDescriptionInContext:context]; NSMutableArray *propertiesWanted = [NSMutableArray array]; - + if (properties) { NSDictionary *propDict = [description propertiesByName]; - + for (NSString *propertyName in properties) { NSPropertyDescription *property = [propDict objectForKey:propertyName]; @@ -118,7 +145,7 @@ + (NSArray *) MR_propertiesNamed:(NSArray *)properties } else { - MRLog(@"Property '%@' not found in %lx properties for %@", propertyName, (unsigned long)[propDict count], NSStringFromClass(self)); + MRLogWarn(@"Property '%@' not found in %lx properties for %@", propertyName, (unsigned long)[propDict count], NSStringFromClass(self)); } } } @@ -150,35 +177,59 @@ + (NSArray *) MR_descendingSortDescriptors:(NSArray *)attributesToSortBy #pragma mark - -+ (id) MR_createInContext:(NSManagedObjectContext *)context ++ (id) MR_createEntityInContext:(NSManagedObjectContext *)context { - if ([self respondsToSelector:@selector(insertInManagedObjectContext:)]) + if ([self respondsToSelector:@selector(insertInManagedObjectContext:)] && context != nil) { id entity = [self performSelector:@selector(insertInManagedObjectContext:) withObject:context]; return entity; } else { - return [NSEntityDescription insertNewObjectForEntityForName:[self MR_entityName] inManagedObjectContext:context]; + NSEntityDescription *entity = nil; + if (context == nil) + { + entity = [self MR_entityDescription]; + } + else + { + entity = [self MR_entityDescriptionInContext:context]; + } + + if (entity == nil) + { + return nil; + } + + return [[self alloc] initWithEntity:entity insertIntoManagedObjectContext:context]; } } + (id) MR_createEntity -{ - NSManagedObject *newEntity = [self MR_createInContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +{ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + NSManagedObject *newEntity = [self MR_createEntityInContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop return newEntity; } -- (BOOL) MR_deleteInContext:(NSManagedObjectContext *)context +- (BOOL) MR_deleteEntityInContext:(NSManagedObjectContext *)context { - [context deleteObject:self]; - return YES; + NSError *error = nil; + NSManagedObject *inContext = [context existingObjectWithID:[self objectID] error:&error]; + + [MagicalRecord handleErrors:error]; + + [context deleteObject:inContext]; + + return YES; } - (BOOL) MR_deleteEntity { - [self MR_deleteInContext:[self managedObjectContext]]; + [self MR_deleteEntityInContext:[self managedObjectContext]]; return YES; } @@ -200,28 +251,52 @@ + (BOOL) MR_deleteAllMatchingPredicate:(NSPredicate *)predicate inContext:(NSMan + (BOOL) MR_deleteAllMatchingPredicate:(NSPredicate *)predicate { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [self MR_deleteAllMatchingPredicate:predicate inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } + (BOOL) MR_truncateAllInContext:(NSManagedObjectContext *)context { - NSArray *allEntities = [self MR_findAllInContext:context]; - for (NSManagedObject *obj in allEntities) + NSFetchRequest *request = [self MR_requestAllInContext:context]; + [request setReturnsObjectsAsFaults:YES]; + [request setIncludesPropertyValues:NO]; + + NSArray *objectsToDelete = [self MR_executeFetchRequest:request inContext:context]; + for (NSManagedObject *objectToDelete in objectsToDelete) { - [obj MR_deleteInContext:context]; + [objectToDelete MR_deleteEntityInContext:context]; } return YES; } + (BOOL) MR_truncateAll { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" [self MR_truncateAllInContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop + return YES; } - (id) MR_inContext:(NSManagedObjectContext *)otherContext { NSError *error = nil; + + if ([[self objectID] isTemporaryID]) + { + BOOL success = [[self managedObjectContext] obtainPermanentIDsForObjects:@[self] error:&error]; + if (!success) + { + [MagicalRecord handleErrors:error]; + return nil; + } + } + + error = nil; + NSManagedObject *inContext = [otherContext existingObjectWithID:[self objectID] error:&error]; [MagicalRecord handleErrors:error]; @@ -231,7 +306,25 @@ - (id) MR_inContext:(NSManagedObjectContext *)otherContext - (id) MR_inThreadContext { NSManagedObject *weakSelf = self; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [weakSelf MR_inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop +} + +@end + +#pragma mark - Deprecated Methods — DO NOT USE +@implementation NSManagedObject (MagicalRecordDeprecated) + ++ (instancetype) MR_createInContext:(NSManagedObjectContext *)context +{ + return [self MR_createEntityInContext:context]; +} + +- (BOOL) MR_deleteInContext:(NSManagedObjectContext *)context +{ + return [self MR_deleteEntityInContext:context]; } @end diff --git a/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalRequests.m b/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalRequests.m index 0c6b2a15d..8e4f0d801 100644 --- a/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalRequests.m +++ b/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalRequests.m @@ -23,13 +23,19 @@ + (NSFetchRequest *)MR_createFetchRequestInContext:(NSManagedObjectContext *)con + (NSFetchRequest *) MR_createFetchRequest { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [self MR_createFetchRequestInContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } + (NSFetchRequest *) MR_requestAll { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [self MR_createFetchRequestInContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } + (NSFetchRequest *) MR_requestAllInContext:(NSManagedObjectContext *)context @@ -39,7 +45,10 @@ + (NSFetchRequest *) MR_requestAllInContext:(NSManagedObjectContext *)context + (NSFetchRequest *) MR_requestAllWithPredicate:(NSPredicate *)searchTerm; { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [self MR_requestAllWithPredicate:searchTerm inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } + (NSFetchRequest *) MR_requestAllWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context; @@ -52,7 +61,10 @@ + (NSFetchRequest *) MR_requestAllWithPredicate:(NSPredicate *)searchTerm inCont + (NSFetchRequest *) MR_requestAllWhere:(NSString *)property isEqualTo:(id)value { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [self MR_requestAllWhere:property isEqualTo:value inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } + (NSFetchRequest *) MR_requestAllWhere:(NSString *)property isEqualTo:(id)value inContext:(NSManagedObjectContext *)context @@ -65,7 +77,10 @@ + (NSFetchRequest *) MR_requestAllWhere:(NSString *)property isEqualTo:(id)value + (NSFetchRequest *) MR_requestFirstWithPredicate:(NSPredicate *)searchTerm { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [self MR_requestFirstWithPredicate:searchTerm inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } + (NSFetchRequest *) MR_requestFirstWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context @@ -79,7 +94,10 @@ + (NSFetchRequest *) MR_requestFirstWithPredicate:(NSPredicate *)searchTerm inCo + (NSFetchRequest *) MR_requestFirstByAttribute:(NSString *)attribute withValue:(id)searchValue; { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [self MR_requestFirstByAttribute:attribute withValue:searchValue inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } + (NSFetchRequest *) MR_requestFirstByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context; @@ -100,9 +118,12 @@ + (NSFetchRequest *) MR_requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL) + (NSFetchRequest *) MR_requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return [self MR_requestAllSortedBy:sortTerm ascending:ascending inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop } + (NSFetchRequest *) MR_requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context @@ -116,8 +137,16 @@ + (NSFetchRequest *) MR_requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL) NSMutableArray* sortDescriptors = [[NSMutableArray alloc] init]; NSArray* sortKeys = [sortTerm componentsSeparatedByString:@","]; - for (NSString* sortKey in sortKeys) + for (__strong NSString* sortKey in sortKeys) { + NSArray * sortComponents = [sortKey componentsSeparatedByString:@":"]; + if (sortComponents.count > 1) + { + NSString * customAscending = sortComponents.lastObject; + ascending = customAscending.boolValue; + sortKey = sortComponents[0]; + } + NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:sortKey ascending:ascending]; [sortDescriptors addObject:sortDescriptor]; } @@ -129,10 +158,14 @@ + (NSFetchRequest *) MR_requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL) + (NSFetchRequest *) MR_requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm; { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" NSFetchRequest *request = [self MR_requestAllSortedBy:sortTerm ascending:ascending withPredicate:searchTerm inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; +#pragma clang diagnostic pop + return request; } diff --git a/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalChainSave.h b/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalChainSave.h new file mode 100644 index 000000000..5769bdcd0 --- /dev/null +++ b/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalChainSave.h @@ -0,0 +1,35 @@ +// +// NSManagedObjectContext+MagicalChainSave.h +// Magical Record +// +// Created by Lee on 8/27/14. +// Copyright (c) 2014 Magical Panda Software LLC. All rights reserved. +// + +#import +#import + +@interface NSManagedObjectContext (MagicalRecordChainSave) +/** + Creates a child context for the current context that you can make changes within, before saving up through all parent contexts to the main queue context, and finally to the saving context. This method will return immediately, and execute the save initially on a background thread, and then on the appropriate thread for each context it saves. + + @param block Block that is passed a managed object context. +*/ +- (void)MR_saveWithBlock:(void (^)(NSManagedObjectContext *localContext))block; + +/** + Creates a child context for the current context that you can make changes within, before saving up through all parent contexts to the main queue context, and finally to the saving context. This method will return immediately, and execute the save initially on a background thread, and then on the appropriate thread for each context it saves. + + @param block Block that is passed a managed object context. + @param completion Completion block that is called once all contexts have been saved, or if an error is encountered. + */ +- (void)MR_saveWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(MRSaveCompletionHandler)completion; + +/** + Creates a child context for the current context that you can make changes within, before saving up through all parent contexts to the main queue context, and finally to the saving context. This method will not return until the save has completed, blocking the thread it is called on. + + @param block Block that is passed a managed object context. + */ +- (void)MR_saveWithBlockAndWait:(void (^)(NSManagedObjectContext *localContext))block; + +@end diff --git a/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalChainSave.m b/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalChainSave.m new file mode 100644 index 000000000..a3e1e9e8a --- /dev/null +++ b/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalChainSave.m @@ -0,0 +1,50 @@ +// +// NSManagedObjectContext+MagicalChainSave.m +// Magical Record +// +// Created by Lee on 8/27/14. +// Copyright (c) 2014 Magical Panda Software LLC. All rights reserved. +// + +#import "NSManagedObjectContext+MagicalChainSave.h" +#import "NSManagedObjectContext+MagicalRecord.h" + +@implementation NSManagedObjectContext (MagicalRecord_ChainSave) +- (void)MR_saveWithBlock:(void (^)(NSManagedObjectContext *localContext))block; +{ + [self MR_saveWithBlock:block completion:nil]; +} + +- (void)MR_saveWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(MRSaveCompletionHandler)completion; +{ + NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextWithParent:self]; + + [localContext performBlock:^{ + [localContext MR_setWorkingName:NSStringFromSelector(_cmd)]; + + if (block) { + block(localContext); + } + + [localContext MR_saveWithOptions:MRSaveParentContexts completion:completion]; + }]; +} + +#pragma mark - Synchronous saving + +- (void)MR_saveWithBlockAndWait:(void (^)(NSManagedObjectContext *localContext))block; +{ + NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextWithParent:self]; + + [localContext performBlockAndWait:^{ + [localContext MR_setWorkingName:NSStringFromSelector(_cmd)]; + + if (block) { + block(localContext); + } + + [localContext MR_saveWithOptions:MRSaveParentContexts|MRSaveSynchronously completion:nil]; + }]; +} + +@end diff --git a/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalObserving.h b/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalObserving.h index 8faf3400d..728acab8a 100644 --- a/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalObserving.h +++ b/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalObserving.h @@ -8,13 +8,62 @@ #import +extern NSString * const kMagicalRecordDidMergeChangesFromiCloudNotification; + +/** + Category methods to aid in observing changes in other contexts. + + @since Available in v2.0 and later. + */ @interface NSManagedObjectContext (MagicalObserving) +/** + Merge changes from another context into self. + + @param otherContext Managed object context to observe. + + @since Available in v2.0 and later. + */ - (void) MR_observeContext:(NSManagedObjectContext *)otherContext; + +/** + Stops merging changes from the supplied context into self. + + @param otherContext Managed object context to stop observing. + + @since Available in v2.0 and later. + */ - (void) MR_stopObservingContext:(NSManagedObjectContext *)otherContext; + +/** + Merges changes from another context into self on the main thread. + + @param otherContext Managed object context to observe. + + @since Available in v2.0 and later. + */ - (void) MR_observeContextOnMainThread:(NSManagedObjectContext *)otherContext; +/** + Merges changes from the supplied persistent store coordinator into self in response to changes from iCloud. + + @param coordinator Persistent store coordinator + + @see -MR_stopObservingiCloudChangesInCoordinator: + + @since Available in v2.0 and later. + */ - (void) MR_observeiCloudChangesInCoordinator:(NSPersistentStoreCoordinator *)coordinator; + +/** + Stops observation and merging of changes from the supplied persistent store coordinator in response to changes from iCloud. + + @param coordinator Persistent store coordinator + + @see -MR_observeiCloudChangesInCoordinator: + + @since Available in v2.0 and later. + */ - (void) MR_stopObservingiCloudChangesInCoordinator:(NSPersistentStoreCoordinator *)coordinator; @end diff --git a/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalObserving.m b/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalObserving.m index 81f84e51f..949634ad0 100644 --- a/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalObserving.m +++ b/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalObserving.m @@ -8,12 +8,11 @@ #import "NSManagedObjectContext+MagicalObserving.h" #import "NSManagedObjectContext+MagicalRecord.h" -#import "MagicalRecord.h" #import "MagicalRecord+iCloud.h" +#import "MagicalRecordLogging.h" NSString * const kMagicalRecordDidMergeChangesFromiCloudNotification = @"kMagicalRecordDidMergeChangesFromiCloudNotification"; - @implementation NSManagedObjectContext (MagicalObserving) #pragma mark - Context Observation Helpers @@ -27,15 +26,6 @@ - (void) MR_observeContext:(NSManagedObjectContext *)otherContext object:otherContext]; } -- (void) MR_observeContextOnMainThread:(NSManagedObjectContext *)otherContext -{ - NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; - [notificationCenter addObserver:self - selector:@selector(MR_mergeChangesOnMainThread:) - name:NSManagedObjectContextDidSaveNotification - object:otherContext]; -} - - (void) MR_stopObservingContext:(NSManagedObjectContext *)otherContext { NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; @@ -45,13 +35,22 @@ - (void) MR_stopObservingContext:(NSManagedObjectContext *)otherContext object:otherContext]; } +- (void) MR_observeContextOnMainThread:(NSManagedObjectContext *)otherContext +{ + NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; + [notificationCenter addObserver:self + selector:@selector(MR_mergeChangesOnMainThread:) + name:NSManagedObjectContextDidSaveNotification + object:otherContext]; +} + #pragma mark - Context iCloud Merge Helpers - (void) MR_mergeChangesFromiCloud:(NSNotification *)notification; { [self performBlock:^{ - MRLog(@"Merging changes From iCloud %@context%@", + MRLogVerbose(@"Merging changes From iCloud %@context%@", self == [NSManagedObjectContext MR_defaultContext] ? @"*** DEFAULT *** " : @"", ([NSThread isMainThread] ? @" *** on Main Thread ***" : @"")); @@ -67,7 +66,7 @@ - (void) MR_mergeChangesFromiCloud:(NSNotification *)notification; - (void) MR_mergeChangesFromNotification:(NSNotification *)notification; { - MRLog(@"Merging changes to %@context%@", + MRLogVerbose(@"Merging changes to %@context%@", self == [NSManagedObjectContext MR_defaultContext] ? @"*** DEFAULT *** " : @"", ([NSThread isMainThread] ? @" *** on Main Thread ***" : @"")); diff --git a/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalRecord.h b/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalRecord.h index 2fb684bac..b2accdbbb 100644 --- a/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalRecord.h +++ b/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalRecord.h @@ -5,26 +5,125 @@ // Copyright 2010 Magical Panda Software, LLC All rights reserved. // -#import "MagicalRecord.h" - -extern NSString * const kMagicalRecordDidMergeChangesFromiCloudNotification; +#import +#import @interface NSManagedObjectContext (MagicalRecord) +#pragma mark - Setup + +/** + Initializes MagicalRecord's default contexts using the provided persistent store coordinator. + + @param coordinator Persistent Store Coordinator + */ + (void) MR_initializeDefaultContextWithCoordinator:(NSPersistentStoreCoordinator *)coordinator; -+ (NSManagedObjectContext *) MR_context NS_RETURNS_RETAINED; -+ (NSManagedObjectContext *) MR_contextWithParent:(NSManagedObjectContext *)parentContext NS_RETURNS_RETAINED; -+ (NSManagedObjectContext *) MR_newMainQueueContext NS_RETURNS_RETAINED; -+ (NSManagedObjectContext *) MR_contextWithStoreCoordinator:(NSPersistentStoreCoordinator *)coordinator NS_RETURNS_RETAINED; +#pragma mark - Default Contexts +/** + Root context responsible for sending changes to the main persistent store coordinator that will be saved to disk. -+ (void) MR_resetDefaultContext; + @discussion Use this context for making and saving changes. All saves will be merged into the context returned by `MR_defaultContext` as well. + + @return Private context used for saving changes to disk on a background thread + */ + (NSManagedObjectContext *) MR_rootSavingContext; + +/** + @discussion Please do not use this context for saving changes, as it will block the main thread when doing so. + + @return Main queue context that can be observed for changes + */ + (NSManagedObjectContext *) MR_defaultContext; +#pragma mark - Context Creation + +/** + Creates and returns a new managed object context of type `NSPrivateQueueConcurrencyType`, with it's parent context set to the root saving context. + @return Private context with the parent set to the root saving context + */ ++ (NSManagedObjectContext *) MR_context; + +/** + Creates and returns a new managed object context of type `NSPrivateQueueConcurrencyType`, with it's parent context set to the root saving context. + + @param parentContext Context to set as the parent of the newly initialized context + + @return Private context with the parent set to the provided context + */ ++ (NSManagedObjectContext *) MR_contextWithParent:(NSManagedObjectContext *)parentContext; + +/** + Creates and returns a new managed object context of type `NSPrivateQueueConcurrencyType`, with it's persistent store coordinator set to the provided coordinator. + + @param coordinator A persistent store coordinator + + @return Private context with it's persistent store coordinator set to the provided coordinator + */ ++ (NSManagedObjectContext *) MR_contextWithStoreCoordinator:(NSPersistentStoreCoordinator *)coordinator; + +/** + Initializes a context of type `NSMainQueueConcurrencyType`. + + @return A context initialized using the `NSPrivateQueueConcurrencyType` concurrency type. + */ ++ (NSManagedObjectContext *) MR_newMainQueueContext NS_RETURNS_RETAINED; + +/** + Initializes a context of type `NSPrivateQueueConcurrencyType`. + + @return A context initialized using the `NSPrivateQueueConcurrencyType` concurrency type. + */ ++ (NSManagedObjectContext *) MR_newPrivateQueueContext NS_RETURNS_RETAINED; + +#pragma mark - Debugging + +/** + Sets a working name for the context, which will be used in debug logs. + + @param workingName Name for the context + */ +- (void) MR_setWorkingName:(NSString *)workingName; + +/** + @return Working name for the context + */ +- (NSString *) MR_workingName; + +/** + @return Description of this context + */ - (NSString *) MR_description; + +/** + @return Description of the parent contexts of this context + */ - (NSString *) MR_parentChain; -@property (nonatomic, copy, setter = MR_setWorkingName:) NSString *MR_workingName; + +#pragma mark - Helpers + +/** + Reset the default context. + */ ++ (void) MR_resetDefaultContext; + +/** + Delete the provided objects from the context + + @param objects An object conforming to `NSFastEnumeration`, containing NSManagedObject instances + */ +- (void) MR_deleteObjects:(id )objects; + +@end + +#pragma mark - Deprecated Methods — DO NOT USE +@interface NSManagedObjectContext (MagicalRecordDeprecated) + ++ (NSManagedObjectContext *) MR_contextWithoutParent MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("4.0", "MR_newPrivateQueueContext"); ++ (NSManagedObjectContext *) MR_newContext MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("4.0", "MR_context"); ++ (NSManagedObjectContext *) MR_newContextWithParent:(NSManagedObjectContext *)parentContext MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("4.0", "MR_contextWithParent:"); ++ (NSManagedObjectContext *) MR_newContextWithStoreCoordinator:(NSPersistentStoreCoordinator *)coordinator MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("4.0", "MR_contextWithStoreCoordinator:"); + @end diff --git a/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalRecord.m b/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalRecord.m index cbeeb5a73..c8787e53f 100644 --- a/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalRecord.m +++ b/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalRecord.m @@ -5,217 +5,171 @@ // Copyright 2010 Magical Panda Software, LLC All rights reserved. // -#import "CoreData+MagicalRecord.h" -#import +#import "NSManagedObjectContext+MagicalRecord.h" +#import "NSManagedObjectContext+MagicalObserving.h" +#import "NSManagedObjectContext+MagicalThreading.h" +#import "NSPersistentStoreCoordinator+MagicalRecord.h" +#import "MagicalRecord+ErrorHandling.h" +#import "MagicalRecord+iCloud.h" +#import "MagicalRecordLogging.h" -static NSManagedObjectContext *rootSavingContext = nil; -static NSManagedObjectContext *defaultManagedObjectContext_ = nil; -static id iCloudSetupNotificationObserver = nil; +static NSString * const MagicalRecordContextWorkingName = @"MagicalRecordContextWorkingName"; -static NSString * const kMagicalRecordNSManagedObjectContextWorkingName = @"kNSManagedObjectContextWorkingName"; - -@interface NSManagedObjectContext (MagicalRecordInternal) - -- (void) MR_mergeChangesFromNotification:(NSNotification *)notification; -- (void) MR_mergeChangesOnMainThread:(NSNotification *)notification; -+ (void) MR_setDefaultContext:(NSManagedObjectContext *)moc; -+ (void) MR_setRootSavingContext:(NSManagedObjectContext *)context; - -@end +static NSManagedObjectContext *MagicalRecordRootSavingContext; +static NSManagedObjectContext *MagicalRecordDefaultContext; +static id MagicalRecordUbiquitySetupNotificationObserver; @implementation NSManagedObjectContext (MagicalRecord) -+ (void) MR_cleanUp; -{ - [self MR_setDefaultContext:nil]; - [self MR_setRootSavingContext:nil]; -} +#pragma mark - Setup -- (NSString *) MR_description; ++ (void) MR_initializeDefaultContextWithCoordinator:(NSPersistentStoreCoordinator *)coordinator; { - NSString *contextLabel = [NSString stringWithFormat:@"*** %@ ***", [self MR_workingName]]; - NSString *onMainThread = [NSThread isMainThread] ? @"*** MAIN THREAD ***" : @"*** BACKGROUND THREAD ***"; + NSAssert(coordinator, @"Provided coordinator cannot be nil!"); + if (MagicalRecordDefaultContext == nil) + { + NSManagedObjectContext *rootContext = [self MR_contextWithStoreCoordinator:coordinator]; + [self MR_setRootSavingContext:rootContext]; - return [NSString stringWithFormat:@"<%@ (%p): %@> on %@", NSStringFromClass([self class]), self, contextLabel, onMainThread]; -} + NSManagedObjectContext *defaultContext = [self MR_newMainQueueContext]; + [self MR_setDefaultContext:defaultContext]; -- (NSString *) MR_parentChain; -{ - NSMutableString *familyTree = [@"\n" mutableCopy]; - NSManagedObjectContext *currentContext = self; - do - { - [familyTree appendFormat:@"- %@ (%p) %@\n", [currentContext MR_workingName], currentContext, (currentContext == self ? @"(*)" : @"")]; + [defaultContext setParentContext:rootContext]; } - while ((currentContext = [currentContext parentContext])); - - return [NSString stringWithString:familyTree]; } +#pragma mark - Default Contexts + + (NSManagedObjectContext *) MR_defaultContext { - @synchronized (self) - { - NSAssert(defaultManagedObjectContext_ != nil, @"Default Context is nil! Did you forget to initialize the Core Data Stack?"); - return defaultManagedObjectContext_; - } + @synchronized(self) { + NSAssert(MagicalRecordDefaultContext != nil, @"Default context is nil! Did you forget to initialize the Core Data Stack?"); + return MagicalRecordDefaultContext; + } } -+ (void) MR_setDefaultContext:(NSManagedObjectContext *)moc ++ (NSManagedObjectContext *) MR_rootSavingContext; { - if (defaultManagedObjectContext_) - { - [[NSNotificationCenter defaultCenter] removeObserver:defaultManagedObjectContext_]; - } - - NSPersistentStoreCoordinator *coordinator = [NSPersistentStoreCoordinator MR_defaultStoreCoordinator]; - if (iCloudSetupNotificationObserver) - { - [[NSNotificationCenter defaultCenter] removeObserver:iCloudSetupNotificationObserver]; - iCloudSetupNotificationObserver = nil; - } - - if ([MagicalRecord isICloudEnabled]) - { - [defaultManagedObjectContext_ MR_stopObservingiCloudChangesInCoordinator:coordinator]; - } - - defaultManagedObjectContext_ = moc; - [defaultManagedObjectContext_ MR_setWorkingName:@"DEFAULT"]; - - if ((defaultManagedObjectContext_ != nil) && ([self MR_rootSavingContext] != nil)) { - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(rootContextChanged:) - name:NSManagedObjectContextDidSaveNotification - object:[self MR_rootSavingContext]]; - } - - [moc MR_obtainPermanentIDsBeforeSaving]; - if ([MagicalRecord isICloudEnabled]) - { - [defaultManagedObjectContext_ MR_observeiCloudChangesInCoordinator:coordinator]; - } - else - { - // If icloud is NOT enabled at the time of this method being called, listen for it to be setup later, and THEN set up observing cloud changes - iCloudSetupNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMagicalRecordPSCDidCompleteiCloudSetupNotification - object:nil - queue:[NSOperationQueue mainQueue] - usingBlock:^(NSNotification *note) { - [[NSManagedObjectContext MR_defaultContext] MR_observeiCloudChangesInCoordinator:coordinator]; - }]; - } - MRLog(@"Set Default Context: %@", defaultManagedObjectContext_); + return MagicalRecordRootSavingContext; } -+ (void)rootContextChanged:(NSNotification *)notification { - if ([NSThread isMainThread] == NO) { - dispatch_async(dispatch_get_main_queue(), ^{ - [self rootContextChanged:notification]; - }); - - return; - } - - [[self MR_defaultContext] mergeChangesFromContextDidSaveNotification:notification]; -} +#pragma mark - Context Creation -+ (NSManagedObjectContext *) MR_rootSavingContext; ++ (NSManagedObjectContext *) MR_context { - return rootSavingContext; + return [self MR_contextWithParent:[self MR_rootSavingContext]]; } -+ (void) MR_setRootSavingContext:(NSManagedObjectContext *)context; ++ (NSManagedObjectContext *) MR_contextWithParent:(NSManagedObjectContext *)parentContext { - if (rootSavingContext) - { - [[NSNotificationCenter defaultCenter] removeObserver:rootSavingContext]; - } - - rootSavingContext = context; + NSManagedObjectContext *context = [self MR_newPrivateQueueContext]; + [context setParentContext:parentContext]; [context MR_obtainPermanentIDsBeforeSaving]; - [rootSavingContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy]; - [rootSavingContext MR_setWorkingName:@"BACKGROUND SAVING (ROOT)"]; - MRLog(@"Set Root Saving Context: %@", rootSavingContext); + return context; } -+ (void) MR_initializeDefaultContextWithCoordinator:(NSPersistentStoreCoordinator *)coordinator; ++ (NSManagedObjectContext *) MR_contextWithStoreCoordinator:(NSPersistentStoreCoordinator *)coordinator { - if (defaultManagedObjectContext_ == nil) - { - NSManagedObjectContext *rootContext = [self MR_contextWithStoreCoordinator:coordinator]; - [self MR_setRootSavingContext:rootContext]; - - NSManagedObjectContext *defaultContext = [self MR_newMainQueueContext]; - [self MR_setDefaultContext:defaultContext]; - - [defaultContext setParentContext:rootContext]; + NSManagedObjectContext *context = nil; + if (coordinator != nil) + { + context = [self MR_newPrivateQueueContext]; + [context performBlockAndWait:^{ + [context setPersistentStoreCoordinator:coordinator]; + MRLogVerbose(@"Created new context %@ with store coordinator: %@", [context MR_workingName], coordinator); + }]; } + return context; } -+ (void) MR_resetDefaultContext ++ (NSManagedObjectContext *) MR_newMainQueueContext { - void (^resetBlock)(void) = ^{ - [[NSManagedObjectContext MR_defaultContext] reset]; - }; - - dispatch_async(dispatch_get_main_queue(), resetBlock); + NSManagedObjectContext *context = [[self alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; + MRLogInfo(@"Created new main queue context: %@", context); + return context; } -+ (NSManagedObjectContext *) MR_contextWithoutParent; ++ (NSManagedObjectContext *) MR_newPrivateQueueContext { NSManagedObjectContext *context = [[self alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; + MRLogInfo(@"Created new private queue context: %@", context); return context; } -+ (NSManagedObjectContext *) MR_context; +#pragma mark - Debugging + +- (void) MR_setWorkingName:(NSString *)workingName { - NSManagedObjectContext *context = [[self alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; - [context setParentContext:[self MR_defaultContext]]; - return context; + [[self userInfo] setObject:workingName forKey:MagicalRecordContextWorkingName]; } -+ (NSManagedObjectContext *) MR_contextWithParent:(NSManagedObjectContext *)parentContext; +- (NSString *) MR_workingName { - NSManagedObjectContext *context = [self MR_contextWithoutParent]; - [context setParentContext:parentContext]; - [context MR_obtainPermanentIDsBeforeSaving]; - return context; + NSString *workingName = [[self userInfo] objectForKey:MagicalRecordContextWorkingName]; + + if ([workingName length] == 0) + { + workingName = @"Untitled Context"; + } + + return workingName; } -+ (NSManagedObjectContext *) MR_newMainQueueContext; +- (NSString *) MR_description { - NSManagedObjectContext *context = [[self alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; - MRLog(@"Created Main Queue Context: %@", context); - return context; + NSString *onMainThread = [NSThread isMainThread] ? @"the main thread" : @"a background thread"; + + __block NSString *workingName; + + [self performBlockAndWait:^{ + workingName = [self MR_workingName]; + }]; + + return [NSString stringWithFormat:@"<%@ (%p): %@> on %@", NSStringFromClass([self class]), self, workingName, onMainThread]; } -+ (NSManagedObjectContext *) MR_contextWithStoreCoordinator:(NSPersistentStoreCoordinator *)coordinator; +- (NSString *) MR_parentChain { - NSManagedObjectContext *context = nil; - if (coordinator != nil) - { - context = [self MR_contextWithoutParent]; - [context performBlockAndWait:^{ - [context setPersistentStoreCoordinator:coordinator]; - }]; - - MRLog(@"-> Created Context %@", [context MR_workingName]); + NSMutableString *familyTree = [@"\n" mutableCopy]; + NSManagedObjectContext *currentContext = self; + do + { + [familyTree appendFormat:@"- %@ (%p) %@\n", [currentContext MR_workingName], currentContext, (currentContext == self ? @"(*)" : @"")]; } - return context; + while ((currentContext = [currentContext parentContext])); + + return [NSString stringWithString:familyTree]; } -- (void) MR_obtainPermanentIDsBeforeSaving; +#pragma mark - Helpers + ++ (void) MR_resetDefaultContext { - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(MR_contextWillSave:) - name:NSManagedObjectContextWillSaveNotification - object:self]; - - + NSManagedObjectContext *defaultContext = [NSManagedObjectContext MR_defaultContext]; + NSAssert(NSConfinementConcurrencyType == [defaultContext concurrencyType], @"Do not call this method on a confinement context."); + + if ([NSThread isMainThread] == NO) { + dispatch_async(dispatch_get_main_queue(), ^{ + [self MR_resetDefaultContext]; + }); + + return; + } + + [defaultContext reset]; } +- (void) MR_deleteObjects:(id )objects +{ + for (NSManagedObject *managedObject in objects) + { + [self deleteObject:managedObject]; + } +} + +#pragma mark - Notification Handlers + - (void) MR_contextWillSave:(NSNotification *)notification { NSManagedObjectContext *context = [notification object]; @@ -223,7 +177,7 @@ - (void) MR_contextWillSave:(NSNotification *)notification if ([insertedObjects count]) { - MRLog(@"Context %@ is about to save. Obtaining permanent IDs for new %lu inserted objects", [context MR_workingName], (unsigned long)[insertedObjects count]); + MRLogVerbose(@"Context '%@' is about to save: obtaining permanent IDs for %lu new inserted object(s).", [context MR_workingName], (unsigned long)[insertedObjects count]); NSError *error = nil; BOOL success = [context obtainPermanentIDsForObjects:[insertedObjects allObjects] error:&error]; if (!success) @@ -233,20 +187,138 @@ - (void) MR_contextWillSave:(NSNotification *)notification } } -- (void) MR_setWorkingName:(NSString *)workingName; ++ (void)rootContextDidSave:(NSNotification *)notification +{ + if ([notification object] != [self MR_rootSavingContext]) + { + return; + } + + if ([NSThread isMainThread] == NO) + { + dispatch_async(dispatch_get_main_queue(), ^{ + [self rootContextDidSave:notification]; + }); + + return; + } + + for (NSManagedObject *object in [[notification userInfo] objectForKey:NSUpdatedObjectsKey]) + { + [[[self MR_defaultContext] objectWithID:[object objectID]] willAccessValueForKey:nil]; + } + + [[self MR_defaultContext] mergeChangesFromContextDidSaveNotification:notification]; +} + +#pragma mark - Private Methods + ++ (void) MR_cleanUp +{ + [self MR_setDefaultContext:nil]; + [self MR_setRootSavingContext:nil]; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + [self MR_clearNonMainThreadContextsCache]; +#pragma clang diagnostic pop +} + +- (void) MR_obtainPermanentIDsBeforeSaving { - [[self userInfo] setObject:workingName forKey:kMagicalRecordNSManagedObjectContextWorkingName]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(MR_contextWillSave:) + name:NSManagedObjectContextWillSaveNotification + object:self]; } -- (NSString *) MR_workingName; ++ (void) MR_setDefaultContext:(NSManagedObjectContext *)moc { - NSString *workingName = [[self userInfo] objectForKey:kMagicalRecordNSManagedObjectContextWorkingName]; - if (nil == workingName) + if (MagicalRecordDefaultContext) { - workingName = @"UNNAMED"; + [[NSNotificationCenter defaultCenter] removeObserver:MagicalRecordDefaultContext]; } - return workingName; + + NSPersistentStoreCoordinator *coordinator = [NSPersistentStoreCoordinator MR_defaultStoreCoordinator]; + if (MagicalRecordUbiquitySetupNotificationObserver) + { + [[NSNotificationCenter defaultCenter] removeObserver:MagicalRecordUbiquitySetupNotificationObserver]; + MagicalRecordUbiquitySetupNotificationObserver = nil; + } + + if ([MagicalRecord isICloudEnabled]) + { + [MagicalRecordDefaultContext MR_stopObservingiCloudChangesInCoordinator:coordinator]; + } + + MagicalRecordDefaultContext = moc; + [MagicalRecordDefaultContext MR_setWorkingName:@"MagicalRecord Default Context"]; + + if ((MagicalRecordDefaultContext != nil) && ([self MR_rootSavingContext] != nil)) { + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(rootContextDidSave:) + name:NSManagedObjectContextDidSaveNotification + object:[self MR_rootSavingContext]]; + } + + [moc MR_obtainPermanentIDsBeforeSaving]; + if ([MagicalRecord isICloudEnabled]) + { + [MagicalRecordDefaultContext MR_observeiCloudChangesInCoordinator:coordinator]; + } + else + { + // If icloud is NOT enabled at the time of this method being called, listen for it to be setup later, and THEN set up observing cloud changes + MagicalRecordUbiquitySetupNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMagicalRecordPSCDidCompleteiCloudSetupNotification + object:nil + queue:[NSOperationQueue mainQueue] + usingBlock:^(NSNotification *note) { + [[NSManagedObjectContext MR_defaultContext] MR_observeiCloudChangesInCoordinator:coordinator]; + }]; + } + MRLogInfo(@"Set default context: %@", MagicalRecordDefaultContext); +} + ++ (void)MR_setRootSavingContext:(NSManagedObjectContext *)context +{ + if (MagicalRecordRootSavingContext) + { + [[NSNotificationCenter defaultCenter] removeObserver:MagicalRecordRootSavingContext]; + } + + MagicalRecordRootSavingContext = context; + + [MagicalRecordRootSavingContext performBlock:^{ + [MagicalRecordRootSavingContext MR_obtainPermanentIDsBeforeSaving]; + [MagicalRecordRootSavingContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy]; + [MagicalRecordRootSavingContext MR_setWorkingName:@"MagicalRecord Root Saving Context"]; + }]; + + MRLogInfo(@"Set root saving context: %@", MagicalRecordRootSavingContext); +} + +@end + +#pragma mark - Deprecated Methods — DO NOT USE +@implementation NSManagedObjectContext (MagicalRecordDeprecated) + ++ (NSManagedObjectContext *) MR_contextWithoutParent +{ + return [self MR_newPrivateQueueContext]; } ++ (NSManagedObjectContext *) MR_newContext +{ + return [self MR_context]; +} + ++ (NSManagedObjectContext *) MR_newContextWithParent:(NSManagedObjectContext *)parentContext +{ + return [self MR_contextWithParent:parentContext]; +} + ++ (NSManagedObjectContext *) MR_newContextWithStoreCoordinator:(NSPersistentStoreCoordinator *)coordinator +{ + return [self MR_contextWithStoreCoordinator:coordinator]; +} @end diff --git a/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalSaves.h b/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalSaves.h index 2eb1bc7ad..a0404d26e 100644 --- a/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalSaves.h +++ b/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalSaves.h @@ -7,87 +7,85 @@ // #import +#import -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 NS_OPTIONS(NSUInteger, MRSaveOptions) { + /** No options — used for cleanliness only */ + MRSaveOptionNone = 0, + + /** When saving, continue saving parent contexts until the changes are present in the persistent store */ + MRSaveParentContexts = 1 << 1, + + /** Perform saves synchronously, blocking execution on the current thread until the save is complete */ + MRSaveSynchronously = 1 << 2, + + /** Perform saves synchronously, blocking execution on the current thread until the save is complete; however, saves root context asynchronously */ + MRSaveSynchronouslyExceptRootContext = 1 << 3 }; -typedef void (^MRSaveCompletionHandler)(BOOL success, NSError *error); +typedef void (^MRSaveCompletionHandler)(BOOL contextDidSave, NSError *error); @interface NSManagedObjectContext (MagicalSaves) -/// \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. +/** + Asynchronously save changes in the current context and it's parent. + 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. + + @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. + + @since Available in v2.1.0 and later. +*/ - (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. +/** + Asynchronously save changes in the current context all the way back to the persistent store. + 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. + + @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. + + @since Available in v2.1.0 and later. + */ - (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. +/** + Synchronously save changes in the current context and it's parent. + 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. + + @since Available in v2.1.0 and later. + */ - (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. +/** + Synchronously save changes in the current context all the way back to the persistent store. + 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. + + @since Available in v2.1.0 and later. + */ - (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; +/** + Save the current context with options. + All other save methods are conveniences to this method. + @param saveOptions 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. -/* DEPRECATION NOTICE: - * The following methods are deprecated, but remain in place for backwards compatibility until the next major version (3.x) + @since Available in v2.1.0 and later. */ +- (void) MR_saveWithOptions:(MRSaveOptions)saveOptions completion:(MRSaveCompletionHandler)completion; + +@end -/// \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)); - -/// \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)); - -/// \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)); +#pragma mark - Deprecated Methods — DO NOT USE +@interface NSManagedObjectContext (MagicalSavesDeprecated) + +- (void) MR_save MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("3.0", "MR_saveToPersistentStoreAndWait"); +- (void) MR_saveWithErrorCallback:(void(^)(NSError *error))errorCallback MR_DEPRECATED_WILL_BE_REMOVED_IN("3.0"); +- (void) MR_saveInBackgroundCompletion:(void (^)(void))completion MR_DEPRECATED_WILL_BE_REMOVED_IN("3.0"); +- (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback MR_DEPRECATED_WILL_BE_REMOVED_IN("3.0"); +- (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion MR_DEPRECATED_WILL_BE_REMOVED_IN("3.0"); +- (void) MR_saveNestedContexts MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("3.0", "MR_saveToPersistentStoreWithCompletion:"); +- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("3.0", "MR_saveToPersistentStoreWithCompletion:"); +- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("3.0", "MR_saveToPersistentStoreWithCompletion:"); @end diff --git a/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalSaves.m b/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalSaves.m index 35239e042..c95cdbd5f 100644 --- a/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalSaves.m +++ b/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalSaves.m @@ -7,18 +7,18 @@ // #import "NSManagedObjectContext+MagicalSaves.h" -#import "MagicalRecord+ErrorHandling.h" #import "NSManagedObjectContext+MagicalRecord.h" -#import "MagicalRecord.h" +#import "MagicalRecord+ErrorHandling.h" +#import "MagicalRecordLogging.h" @implementation NSManagedObjectContext (MagicalSaves) -- (void)MR_saveOnlySelfWithCompletion:(MRSaveCompletionHandler)completion; +- (void) MR_saveOnlySelfWithCompletion:(MRSaveCompletionHandler)completion; { - [self MR_saveWithOptions:0 completion:completion]; + [self MR_saveWithOptions:MRSaveOptionNone completion:completion]; } -- (void)MR_saveOnlySelfAndWait; +- (void) MR_saveOnlySelfAndWait; { [self MR_saveWithOptions:MRSaveSynchronously completion:nil]; } @@ -33,13 +33,24 @@ - (void) MR_saveToPersistentStoreAndWait; [self MR_saveWithOptions:MRSaveParentContexts | MRSaveSynchronously completion:nil]; } -- (void)MR_saveWithOptions:(MRSaveContextOptions)mask completion:(MRSaveCompletionHandler)completion; +- (void) MR_saveWithOptions:(MRSaveOptions)saveOptions completion:(MRSaveCompletionHandler)completion; { - BOOL syncSave = ((mask & MRSaveSynchronously) == MRSaveSynchronously); - BOOL saveParentContexts = ((mask & MRSaveParentContexts) == MRSaveParentContexts); + __block BOOL hasChanges = NO; + + if ([self concurrencyType] == NSConfinementConcurrencyType) + { + hasChanges = [self hasChanges]; + } + else + { + [self performBlockAndWait:^{ + hasChanges = [self hasChanges]; + }]; + } - if (![self hasChanges]) { - MRLog(@"NO CHANGES IN ** %@ ** CONTEXT - NOT SAVING", [self MR_workingName]); + if (!hasChanges) + { + MRLogVerbose(@"NO CHANGES IN ** %@ ** CONTEXT - NOT SAVING", [self MR_workingName]); if (completion) { @@ -47,156 +58,162 @@ - (void)MR_saveWithOptions:(MRSaveContextOptions)mask completion:(MRSaveCompleti completion(NO, nil); }); } - + return; } - MRLog(@"→ Saving %@", [self MR_description]); - MRLog(@"→ Save Parents? %@", @(saveParentContexts)); - MRLog(@"→ Save Synchronously? %@", @(syncSave)); + BOOL shouldSaveParentContexts = ((saveOptions & MRSaveParentContexts) == MRSaveParentContexts); + BOOL shouldSaveSynchronously = ((saveOptions & MRSaveSynchronously) == MRSaveSynchronously); + BOOL shouldSaveSynchronouslyExceptRoot = ((saveOptions & MRSaveSynchronouslyExceptRootContext) == MRSaveSynchronouslyExceptRootContext); + + BOOL saveSynchronously = (shouldSaveSynchronously && !shouldSaveSynchronouslyExceptRoot) || + (shouldSaveSynchronouslyExceptRoot && (self != [[self class] MR_rootSavingContext])); id saveBlock = ^{ + MRLogInfo(@"→ Saving %@", [self MR_description]); + MRLogVerbose(@"→ Save Parents? %@", shouldSaveParentContexts ? @"YES" : @"NO"); + MRLogVerbose(@"→ Save Synchronously? %@", saveSynchronously ? @"YES" : @"NO"); + + BOOL saveResult = NO; NSError *error = nil; - BOOL saved = NO; @try { - saved = [self save:&error]; + saveResult = [self save:&error]; } @catch(NSException *exception) { - MRLog(@"Unable to perform save: %@", (id)[exception userInfo] ? : (id)[exception reason]); + MRLogError(@"Unable to perform save: %@", (id)[exception userInfo] ?: (id)[exception reason]); } - @finally { - if (!saved) { - [MagicalRecord handleErrors:error]; + [MagicalRecord handleErrors:error]; - if (completion) { - dispatch_async(dispatch_get_main_queue(), ^{ - completion(saved, error); - }); + if (saveResult && shouldSaveParentContexts && [self parentContext]) + { + // Add/remove the synchronous save option from the mask if necessary + MRSaveOptions modifiedOptions = saveOptions; + + if (saveSynchronously) + { + modifiedOptions |= MRSaveSynchronously; + } + else + { + modifiedOptions &= ~MRSaveSynchronously; } - } else { - // If we're the default context, save to disk too (the user expects it to persist) - BOOL isDefaultContext = (self == [[self class] MR_defaultContext]); - BOOL shouldSaveParentContext = ((YES == saveParentContexts) || isDefaultContext); - - if (shouldSaveParentContext && [self parentContext]) { - [[self parentContext] MR_saveWithOptions:mask completion:completion]; + + // If we're saving parent contexts, do so + [[self parentContext] MR_saveWithOptions:modifiedOptions completion:completion]; + } + else + { + if (saveResult) + { + MRLogVerbose(@"→ Finished saving: %@", [self MR_description]); } - // If we should not save the parent context, or there is not a parent context to save (root context), call the completion block - else { - MRLog(@"→ Finished saving: %@", [self MR_description]); - - if (completion) { - dispatch_async(dispatch_get_main_queue(), ^{ - completion(saved, error); - }); - } + + if (completion) + { + dispatch_async(dispatch_get_main_queue(), ^{ + completion(saveResult, error); + }); } } } }; - if (YES == syncSave) { + if (saveSynchronously) + { [self performBlockAndWait:saveBlock]; - } else { + } + else + { [self performBlock:saveBlock]; } } -#pragma mark - Deprecated methods -// These methods will be removed in MagicalRecord 3.0 +@end -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-implementations" +#pragma mark - Deprecated Methods — DO NOT USE +@implementation NSManagedObjectContext (MagicalSavesDeprecated) -- (void)MR_save; +- (void) MR_save; { [self MR_saveToPersistentStoreAndWait]; } -- (void)MR_saveWithErrorCallback:(void (^)(NSError *error))errorCallback; +- (void) MR_saveWithErrorCallback:(void (^)(NSError *error))errorCallback; { - [self MR_saveWithOptions:MRSaveSynchronously|MRSaveParentContexts completion:^(BOOL success, NSError *error) { - if (!success) { - if (errorCallback) { - errorCallback(error); - } + [self MR_saveWithOptions:MRSaveSynchronously | MRSaveParentContexts completion:^(BOOL contextDidSave, NSError *error) { + if (!contextDidSave && errorCallback) + { + errorCallback(error); } }]; } -- (void)MR_saveInBackgroundCompletion:(void (^)(void))completion; +- (void) MR_saveInBackgroundCompletion:(void (^)(void))completion; { - [self MR_saveOnlySelfWithCompletion:^(BOOL success, NSError *error) { - if (success) { - if (completion) { - completion(); - } + [self MR_saveOnlySelfWithCompletion:^(BOOL contextDidSave, NSError *error) { + if (contextDidSave && completion) + { + completion(); } }]; } -- (void)MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback; +- (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback; { - [self MR_saveOnlySelfWithCompletion:^(BOOL success, NSError *error) { - if (!success) { - if (errorCallback) { - errorCallback(error); - } + [self MR_saveOnlySelfWithCompletion:^(BOOL contextDidSave, NSError *error) { + if (!contextDidSave && errorCallback) + { + errorCallback(error); } }]; } -- (void)MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion; +- (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion; { - [self MR_saveOnlySelfWithCompletion:^(BOOL success, NSError *error) { - if (success) { - if (completion) { - completion(); - } - } else { - if (errorCallback) { - errorCallback(error); - } + [self MR_saveOnlySelfWithCompletion:^(BOOL contextDidSave, NSError *error) { + if (contextDidSave && completion) + { + completion(); + } + else if (errorCallback) + { + errorCallback(error); } }]; } -- (void)MR_saveNestedContexts; +- (void) MR_saveNestedContexts; { [self MR_saveToPersistentStoreWithCompletion:nil]; } -- (void)MR_saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback; +- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback; { - [self MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) { - if (!success) { - if (errorCallback) { - errorCallback(error); - } + [self MR_saveToPersistentStoreWithCompletion:^(BOOL contextDidSave, NSError *error) { + if (!contextDidSave && errorCallback) + { + errorCallback(error); } }]; } -- (void)MR_saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))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); - } + [self MR_saveToPersistentStoreWithCompletion:^(BOOL contextDidSave, NSError *error) { + if (contextDidSave && completion) + { + completion(); + } + else if (errorCallback) + { + errorCallback(error); } }]; } -#pragma clang diagnostic pop // ignored "-Wdeprecated-implementations" - @end diff --git a/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalThreading.h b/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalThreading.h index 6b9ae00cc..babadfcab 100644 --- a/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalThreading.h +++ b/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalThreading.h @@ -10,7 +10,9 @@ @interface NSManagedObjectContext (MagicalThreading) -+ (NSManagedObjectContext *) MR_contextForCurrentThread; -+ (void) MR_resetContextForCurrentThread; ++ (NSManagedObjectContext *) MR_contextForCurrentThread __attribute((deprecated("This method will be removed in MagicalRecord 3.0"))); ++ (void) MR_clearNonMainThreadContextsCache __attribute((deprecated("This method will be removed in MagicalRecord 3.0"))); ++ (void) MR_resetContextForCurrentThread __attribute((deprecated("This method will be removed in MagicalRecord 3.0"))); ++ (void) MR_clearContextForCurrentThread __attribute((deprecated("This method will be removed in MagicalRecord 3.0"))); @end diff --git a/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalThreading.m b/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalThreading.m index 7d345e5d4..a5cb78603 100644 --- a/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalThreading.m +++ b/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalThreading.m @@ -7,10 +7,14 @@ // #import "NSManagedObjectContext+MagicalThreading.h" -#import "NSManagedObject+MagicalRecord.h" #import "NSManagedObjectContext+MagicalRecord.h" +#import "NSManagedObject+MagicalRecord.h" +#include static NSString const * kMagicalRecordManagedObjectContextKey = @"MagicalRecord_NSManagedObjectContextForThreadKey"; +static NSString const * kMagicalRecordManagedObjectContextCacheVersionKey = @"MagicalRecord_CacheVersionOfNSManagedObjectContextForThreadKey"; +static volatile int32_t contextsCacheVersion = 0; + @implementation NSManagedObjectContext (MagicalThreading) @@ -19,6 +23,11 @@ + (void)MR_resetContextForCurrentThread [[NSManagedObjectContext MR_contextForCurrentThread] reset]; } ++ (void) MR_clearNonMainThreadContextsCache +{ + OSAtomicIncrement32(&contextsCacheVersion); +} + + (NSManagedObjectContext *) MR_contextForCurrentThread; { if ([NSThread isMainThread]) @@ -27,15 +36,34 @@ + (NSManagedObjectContext *) MR_contextForCurrentThread; } else { + // contextsCacheVersion can change (atomically) at any time, so grab a copy to ensure that we always + // use the same value throughout the remainder of this method. We are OK with this method returning + // an outdated context if MR_clearNonMainThreadContextsCache is called from another thread while this + // method is being executed. This behavior is unrelated to our choice to use a counter for synchronization. + // We would have the same behavior if we used @synchronized() (or any other lock-based synchronization + // method) since MR_clearNonMainThreadContextsCache would have to wait until this method finished before + // it could acquire the mutex, resulting in us still returning an outdated context in that case as well. + int32_t targetCacheVersionForContext = contextsCacheVersion; + NSMutableDictionary *threadDict = [[NSThread currentThread] threadDictionary]; NSManagedObjectContext *threadContext = [threadDict objectForKey:kMagicalRecordManagedObjectContextKey]; - if (threadContext == nil) + NSNumber *currentCacheVersionForContext = [threadDict objectForKey:kMagicalRecordManagedObjectContextCacheVersionKey]; + NSAssert((threadContext && currentCacheVersionForContext) || (!threadContext && !currentCacheVersionForContext), + @"The Magical Record keys should either both be present or neither be present, otherwise we're in an inconsistent state!"); + if ((threadContext == nil) || (currentCacheVersionForContext == nil) || ((int32_t)[currentCacheVersionForContext integerValue] != targetCacheVersionForContext)) { threadContext = [self MR_contextWithParent:[NSManagedObjectContext MR_defaultContext]]; [threadDict setObject:threadContext forKey:kMagicalRecordManagedObjectContextKey]; + [threadDict setObject:[NSNumber numberWithInteger:targetCacheVersionForContext] + forKey:kMagicalRecordManagedObjectContextCacheVersionKey]; } return threadContext; } } ++ (void) MR_clearContextForCurrentThread { + [[[NSThread currentThread] threadDictionary] removeObjectForKey:kMagicalRecordManagedObjectContextKey]; + [[[NSThread currentThread] threadDictionary] removeObjectForKey:kMagicalRecordManagedObjectContextCacheVersionKey]; +} + @end diff --git a/MagicalRecord/Categories/NSManagedObjectModel+MagicalRecord.h b/MagicalRecord/Categories/NSManagedObjectModel+MagicalRecord.h index 8a543b494..2c0c07555 100644 --- a/MagicalRecord/Categories/NSManagedObjectModel+MagicalRecord.h +++ b/MagicalRecord/Categories/NSManagedObjectModel+MagicalRecord.h @@ -5,9 +5,7 @@ // Copyright 2010 Magical Panda Software, LLC All rights reserved. // -#import -#import "MagicalRecord.h" - +#import @interface NSManagedObjectModel (MagicalRecord) @@ -19,5 +17,6 @@ + (NSManagedObjectModel *) MR_newManagedObjectModelNamed:(NSString *)modelFileName NS_RETURNS_RETAINED; + (NSManagedObjectModel *) MR_managedObjectModelNamed:(NSString *)modelFileName; + (NSManagedObjectModel *) MR_newModelNamed:(NSString *) modelName inBundleNamed:(NSString *) bundleName NS_RETURNS_RETAINED; ++ (NSManagedObjectModel *) MR_newModelNamed:(NSString *) modelName inBundle:(NSBundle*) bundle NS_RETURNS_RETAINED; @end diff --git a/MagicalRecord/Categories/NSManagedObjectModel+MagicalRecord.m b/MagicalRecord/Categories/NSManagedObjectModel+MagicalRecord.m index cc4df40a0..e0fb9f59a 100644 --- a/MagicalRecord/Categories/NSManagedObjectModel+MagicalRecord.m +++ b/MagicalRecord/Categories/NSManagedObjectModel+MagicalRecord.m @@ -5,9 +5,8 @@ // Copyright 2010 Magical Panda Software, LLC All rights reserved. // -//#import "NSManagedObjectModel+MagicalRecord.h" -#import "CoreData+MagicalRecord.h" - +#import "NSManagedObjectModel+MagicalRecord.h" +#import "MagicalRecord+Options.h" static NSManagedObjectModel *defaultManagedObjectModel_ = nil; @@ -44,6 +43,17 @@ + (NSManagedObjectModel *) MR_newModelNamed:(NSString *) modelName inBundleNamed return mom; } ++ (NSManagedObjectModel *) MR_newModelNamed:(NSString *) modelName inBundle:(NSBundle*) bundle +{ + NSString *path = [bundle pathForResource:[modelName stringByDeletingPathExtension] + ofType:[modelName pathExtension]]; + NSURL *modelUrl = [NSURL fileURLWithPath:path]; + + NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelUrl]; + + return mom; +} + + (NSManagedObjectModel *) MR_newManagedObjectModelNamed:(NSString *)modelFileName { NSString *path = [[NSBundle mainBundle] pathForResource:[modelFileName stringByDeletingPathExtension] diff --git a/MagicalRecord/Categories/NSPersistentStore+MagicalRecord.h b/MagicalRecord/Categories/NSPersistentStore+MagicalRecord.h index 948aa2e76..560d3a22c 100644 --- a/MagicalRecord/Categories/NSPersistentStore+MagicalRecord.h +++ b/MagicalRecord/Categories/NSPersistentStore+MagicalRecord.h @@ -5,7 +5,7 @@ // Copyright 2010 Magical Panda Software, LLC All rights reserved. // -#import "MagicalRecord.h" +#import // option to autodelete store if it already exists diff --git a/MagicalRecord/Categories/NSPersistentStore+MagicalRecord.m b/MagicalRecord/Categories/NSPersistentStore+MagicalRecord.m index 44ccf78fb..77507a7ce 100644 --- a/MagicalRecord/Categories/NSPersistentStore+MagicalRecord.m +++ b/MagicalRecord/Categories/NSPersistentStore+MagicalRecord.m @@ -5,8 +5,7 @@ // Copyright 2010 Magical Panda Software, LLC All rights reserved. // -//#import "NSPersistentStore+MagicalRecord.h" -#import "CoreData+MagicalRecord.h" +#import "NSPersistentStore+MagicalRecord.h" NSString * const kMagicalRecordDefaultStoreFileName = @"CoreDataStore.sqlite"; @@ -20,12 +19,12 @@ + (NSPersistentStore *) MR_defaultPersistentStore return defaultPersistentStore_; } -+ (void) MR_setDefaultPersistentStore:(NSPersistentStore *) store ++ (void) MR_setDefaultPersistentStore:(NSPersistentStore *)store { defaultPersistentStore_ = store; } -+ (NSString *) MR_directory:(int) type ++ (NSString *) MR_directory:(NSSearchPathDirectory)type { return [NSSearchPathForDirectoriesInDomains(type, NSUserDomainMask, YES) lastObject]; } @@ -43,20 +42,8 @@ + (NSString *)MR_applicationStorageDirectory + (NSURL *) MR_urlForStoreName:(NSString *)storeFileName { - NSArray *paths = [NSArray arrayWithObjects:[self MR_applicationDocumentsDirectory], [self MR_applicationStorageDirectory], nil]; - NSFileManager *fm = [[NSFileManager alloc] init]; - - for (NSString *path in paths) - { - NSString *filepath = [path stringByAppendingPathComponent:storeFileName]; - if ([fm fileExistsAtPath:filepath]) - { - return [NSURL fileURLWithPath:filepath]; - } - } - - //set default url - return [NSURL fileURLWithPath:[[self MR_applicationStorageDirectory] stringByAppendingPathComponent:storeFileName]]; + NSString *pathForStoreName = [[self MR_applicationStorageDirectory] stringByAppendingPathComponent:storeFileName]; + return [NSURL fileURLWithPath:pathForStoreName]; } + (NSURL *) MR_cloudURLForUbiqutiousContainer:(NSString *)bucketName; diff --git a/MagicalRecord/Categories/NSPersistentStoreCoordinator+MagicalRecord.h b/MagicalRecord/Categories/NSPersistentStoreCoordinator+MagicalRecord.h index b4be8b7c5..08ea2b22c 100644 --- a/MagicalRecord/Categories/NSPersistentStoreCoordinator+MagicalRecord.h +++ b/MagicalRecord/Categories/NSPersistentStoreCoordinator+MagicalRecord.h @@ -5,10 +5,15 @@ // Copyright 2010 Magical Panda Software, LLC All rights reserved. // -#import "MagicalRecord.h" -#import "NSPersistentStore+MagicalRecord.h" +#import extern NSString * const kMagicalRecordPSCDidCompleteiCloudSetupNotification; +extern NSString * const kMagicalRecordPSCMismatchWillDeleteStore; +extern NSString * const kMagicalRecordPSCMismatchDidDeleteStore; +extern NSString * const kMagicalRecordPSCMismatchWillRecreateStore; +extern NSString * const kMagicalRecordPSCMismatchDidRecreateStore; +extern NSString * const kMagicalRecordPSCMismatchCouldNotDeleteStore; +extern NSString * const kMagicalRecordPSCMismatchCouldNotRecreateStore; @interface NSPersistentStoreCoordinator (MagicalRecord) @@ -21,16 +26,25 @@ extern NSString * const kMagicalRecordPSCDidCompleteiCloudSetupNotification; + (NSPersistentStoreCoordinator *) MR_coordinatorWithSqliteStoreNamed:(NSString *)storeFileName; + (NSPersistentStoreCoordinator *) MR_coordinatorWithAutoMigratingSqliteStoreNamed:(NSString *)storeFileName; ++ (NSPersistentStoreCoordinator *) MR_coordinatorWithSqliteStoreAtURL:(NSURL *)storeURL; ++ (NSPersistentStoreCoordinator *) MR_coordinatorWithAutoMigratingSqliteStoreAtURL:(NSURL *)storeURL; + (NSPersistentStoreCoordinator *) MR_coordinatorWithPersistentStore:(NSPersistentStore *)persistentStore; + (NSPersistentStoreCoordinator *) MR_coordinatorWithiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)subPathComponent; ++ (NSPersistentStoreCoordinator *) MR_coordinatorWithiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreAtURL:(NSURL *)storeURL cloudStorePathComponent:(NSString *)subPathComponent; + (NSPersistentStoreCoordinator *) MR_coordinatorWithiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)subPathComponent completion:(void(^)(void))completionHandler; ++ (NSPersistentStoreCoordinator *) MR_coordinatorWithiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreAtURL:(NSURL *)storeURL cloudStorePathComponent:(NSString *)subPathComponent completion:(void (^)(void))completionHandler; - (NSPersistentStore *) MR_addInMemoryStore; - (NSPersistentStore *) MR_addAutoMigratingSqliteStoreNamed:(NSString *) storeFileName; +- (NSPersistentStore *) MR_addAutoMigratingSqliteStoreAtURL:(NSURL *)storeURL; + - (NSPersistentStore *) MR_addSqliteStoreNamed:(id)storeFileName withOptions:(__autoreleasing NSDictionary *)options; +- (NSPersistentStore *) MR_addSqliteStoreNamed:(id)storeFileName configuration:(NSString *)configuration withOptions:(__autoreleasing NSDictionary *)options; - (void) MR_addiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)subPathComponent; +- (void) MR_addiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreAtURL:(NSURL *)storeURL cloudStorePathComponent:(NSString *)subPathComponent; - (void) MR_addiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)subPathComponent completion:(void(^)(void))completionBlock; +- (void) MR_addiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreAtURL:(NSURL *)storeURL cloudStorePathComponent:(NSString *)subPathComponent completion:(void (^)(void))completionBlock; @end diff --git a/MagicalRecord/Categories/NSPersistentStoreCoordinator+MagicalRecord.m b/MagicalRecord/Categories/NSPersistentStoreCoordinator+MagicalRecord.m index 80c8cd316..fe11737b0 100644 --- a/MagicalRecord/Categories/NSPersistentStoreCoordinator+MagicalRecord.m +++ b/MagicalRecord/Categories/NSPersistentStoreCoordinator+MagicalRecord.m @@ -5,10 +5,21 @@ // Copyright 2010 Magical Panda Software, LLC All rights reserved. // -#import "CoreData+MagicalRecord.h" +#import "NSPersistentStoreCoordinator+MagicalRecord.h" +#import "NSPersistentStore+MagicalRecord.h" +#import "NSManagedObjectModel+MagicalRecord.h" +#import "MagicalRecord+ErrorHandling.h" +#import "MagicalRecordLogging.h" + static NSPersistentStoreCoordinator *defaultCoordinator_ = nil; NSString * const kMagicalRecordPSCDidCompleteiCloudSetupNotification = @"kMagicalRecordPSCDidCompleteiCloudSetupNotification"; +NSString * const kMagicalRecordPSCMismatchWillDeleteStore = @"kMagicalRecordPSCMismatchWillDeleteStore"; +NSString * const kMagicalRecordPSCMismatchDidDeleteStore = @"kMagicalRecordPSCMismatchDidDeleteStore"; +NSString * const kMagicalRecordPSCMismatchWillRecreateStore = @"kMagicalRecordPSCMismatchWillRecreateStore"; +NSString * const kMagicalRecordPSCMismatchDidRecreateStore = @"kMagicalRecordPSCMismatchDidRecreateStore"; +NSString * const kMagicalRecordPSCMismatchCouldNotDeleteStore = @"kMagicalRecordPSCMismatchCouldNotDeleteStore"; +NSString * const kMagicalRecordPSCMismatchCouldNotRecreateStore = @"kMagicalRecordPSCMismatchCouldNotRecreateStore"; @interface NSDictionary (MagicalRecordMerging) @@ -43,7 +54,7 @@ + (void) MR_setDefaultStoreCoordinator:(NSPersistentStoreCoordinator *)coordinat if ([persistentStores count] && [NSPersistentStore MR_defaultPersistentStore] == nil) { - [NSPersistentStore MR_setDefaultPersistentStore:[persistentStores objectAtIndex:0]]; + [NSPersistentStore MR_setDefaultPersistentStore:[persistentStores firstObject]]; } } } @@ -63,6 +74,11 @@ - (void) MR_createPathToStoreFileIfNeccessary:(NSURL *)urlForStore } - (NSPersistentStore *) MR_addSqliteStoreNamed:(id)storeFileName withOptions:(__autoreleasing NSDictionary *)options +{ + return [self MR_addSqliteStoreNamed:storeFileName configuration:nil withOptions:options]; +} + +- (NSPersistentStore *) MR_addSqliteStoreNamed:(id)storeFileName configuration:(NSString *)configuration withOptions:(__autoreleasing NSDictionary *)options { NSURL *url = [storeFileName isKindOfClass:[NSURL class]] ? storeFileName : [NSPersistentStore MR_urlForStoreName:storeFileName]; NSError *error = nil; @@ -70,39 +86,128 @@ - (NSPersistentStore *) MR_addSqliteStoreNamed:(id)storeFileName withOptions:(__ [self MR_createPathToStoreFileIfNeccessary:url]; NSPersistentStore *store = [self addPersistentStoreWithType:NSSQLiteStoreType - configuration:nil + configuration:configuration URL:url options:options error:&error]; - if (!store && [MagicalRecord shouldDeleteStoreOnModelMismatch]) + if (!store) { - BOOL isMigrationError = [error code] == NSPersistentStoreIncompatibleVersionHashError || [error code] == NSMigrationMissingSourceModelError; - if ([[error domain] isEqualToString:NSCocoaErrorDomain] && isMigrationError) + if ([MagicalRecord shouldDeleteStoreOnModelMismatch]) { - // Could not open the database, so... kill it! - [[NSFileManager defaultManager] removeItemAtURL:url error:nil]; - - MRLog(@"Removed incompatible model version: %@", [url lastPathComponent]); - - // Try one more time to create the store - store = [self addPersistentStoreWithType:NSSQLiteStoreType - configuration:nil - URL:url - options:options - error:&error]; - if (store) + BOOL isMigrationError = (([error code] == NSPersistentStoreIncompatibleVersionHashError) || ([error code] == NSMigrationMissingSourceModelError) || ([error code] == NSMigrationError)); + if ([[error domain] isEqualToString:NSCocoaErrorDomain] && isMigrationError) { - // If we successfully added a store, remove the error that was initially created - error = nil; + [[NSNotificationCenter defaultCenter] postNotificationName:kMagicalRecordPSCMismatchWillDeleteStore object:nil]; + + NSError * deleteStoreError; + // Could not open the database, so... kill it! (AND WAL bits) + NSString *rawURL = [url absoluteString]; + NSURL *shmSidecar = [NSURL URLWithString:[rawURL stringByAppendingString:@"-shm"]]; + NSURL *walSidecar = [NSURL URLWithString:[rawURL stringByAppendingString:@"-wal"]]; + [[NSFileManager defaultManager] removeItemAtURL:url error:&deleteStoreError]; + [[NSFileManager defaultManager] removeItemAtURL:shmSidecar error:nil]; + [[NSFileManager defaultManager] removeItemAtURL:walSidecar error:nil]; + + MRLogWarn(@"Removed incompatible model version: %@", [url lastPathComponent]); + if(deleteStoreError) { + [[NSNotificationCenter defaultCenter] postNotificationName:kMagicalRecordPSCMismatchCouldNotDeleteStore object:nil userInfo:@{@"Error":deleteStoreError}]; + } + else { + [[NSNotificationCenter defaultCenter] postNotificationName:kMagicalRecordPSCMismatchDidDeleteStore object:nil]; + } + + [[NSNotificationCenter defaultCenter] postNotificationName:kMagicalRecordPSCMismatchWillRecreateStore object:nil]; + // Try one more time to create the store + store = [self addPersistentStoreWithType:NSSQLiteStoreType + configuration:nil + URL:url + options:options + error:&error]; + if (store) + { + [[NSNotificationCenter defaultCenter] postNotificationName:kMagicalRecordPSCMismatchDidRecreateStore object:nil]; + // If we successfully added a store, remove the error that was initially created + error = nil; + } + else { + [[NSNotificationCenter defaultCenter] postNotificationName:kMagicalRecordPSCMismatchCouldNotRecreateStore object:nil userInfo:@{@"Error":error}]; + } } } - [MagicalRecord handleErrors:error]; } return store; } +- (void) MR_addiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey storeIdentifier:(id)storeIdentifier cloudStorePathComponent:(NSString *)subPathComponent completion:(void(^)(void))completionBlock +{ + NSAssert([contentNameKey containsString:@"."] == NO, @"NSPersistentStoreUbiquitousContentNameKey cannot contain a period."); + + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + + NSURL *cloudURL = [NSPersistentStore MR_cloudURLForUbiqutiousContainer:containerID]; + if (subPathComponent) + { + cloudURL = [cloudURL URLByAppendingPathComponent:subPathComponent]; + } + + [MagicalRecord setICloudEnabled:cloudURL != nil]; + + NSDictionary *options = [[self class] MR_autoMigrationOptions]; + if (cloudURL) //iCloud is available + { + NSMutableDictionary *iCloudOptions = [[NSMutableDictionary alloc] init]; + [iCloudOptions setObject:cloudURL forKey:NSPersistentStoreUbiquitousContentURLKey]; + + if ([contentNameKey length] > 0) + { + [iCloudOptions setObject:contentNameKey forKey:NSPersistentStoreUbiquitousContentNameKey]; + } + + options = [options MR_dictionaryByMergingDictionary:iCloudOptions]; + } + else + { + MRLogWarn(@"iCloud is not enabled"); + } + + + if ([self respondsToSelector:@selector(performBlockAndWait:)]) + { + [self performSelector:@selector(performBlockAndWait:) withObject:^{ + [self MR_addSqliteStoreNamed:storeIdentifier withOptions:options]; + }]; + } + else + { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + [self lock]; +#pragma clang diagnostic pop + [self MR_addSqliteStoreNamed:storeIdentifier withOptions:options]; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + [self unlock]; +#pragma clang diagnostic pop + } + + dispatch_async(dispatch_get_main_queue(), ^{ + if ([NSPersistentStore MR_defaultPersistentStore] == nil) + { + [NSPersistentStore MR_setDefaultPersistentStore:[[self persistentStores] firstObject]]; + } + if (completionBlock) + { + completionBlock(); + } + NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; + [notificationCenter postNotificationName:kMagicalRecordPSCDidCompleteiCloudSetupNotification object:nil]; + }); + }); +} + + #pragma mark - Public Instance Methods @@ -141,6 +246,12 @@ - (NSPersistentStore *) MR_addAutoMigratingSqliteStoreNamed:(NSString *) storeFi return [self MR_addSqliteStoreNamed:storeFileName withOptions:options]; } +- (NSPersistentStore *) MR_addAutoMigratingSqliteStoreAtURL:(NSURL *)storeURL +{ + NSDictionary *options = [[self class] MR_autoMigrationOptions]; + return [self MR_addSqliteStoreNamed:storeURL withOptions:options]; +} + #pragma mark - Public Class Methods @@ -161,6 +272,22 @@ + (NSPersistentStoreCoordinator *) MR_coordinatorWithAutoMigratingSqliteStoreNam return coordinator; } ++ (NSPersistentStoreCoordinator *) MR_coordinatorWithAutoMigratingSqliteStoreAtURL:(NSURL *)storeURL +{ + NSManagedObjectModel *model = [NSManagedObjectModel MR_defaultManagedObjectModel]; + NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model]; + + [coordinator MR_addAutoMigratingSqliteStoreAtURL:storeURL]; + + //HACK: lame solution to fix automigration error "Migration failed after first pass" + if ([[coordinator persistentStores] count] == 0) + { + [coordinator performSelector:@selector(MR_addAutoMigratingSqliteStoreAtURL:) withObject:storeURL afterDelay:0.5]; + } + + return coordinator; +} + + (NSPersistentStoreCoordinator *) MR_coordinatorWithInMemoryStore { NSManagedObjectModel *model = [NSManagedObjectModel MR_defaultManagedObjectModel]; @@ -187,48 +314,31 @@ - (void) MR_addiCloudContainerID:(NSString *)containerID contentNameKey:(NSStrin completion:nil]; } -- (void) MR_addiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)subPathComponent completion:(void(^)(void))completionBlock; +- (void) MR_addiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreAtURL:(NSURL *)storeURL cloudStorePathComponent:(NSString *)subPathComponent { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - - NSURL *cloudURL = [NSPersistentStore MR_cloudURLForUbiqutiousContainer:containerID]; - if (subPathComponent) - { - cloudURL = [cloudURL URLByAppendingPathComponent:subPathComponent]; - } + [self MR_addiCloudContainerID:containerID + contentNameKey:contentNameKey + localStoreAtURL:storeURL + cloudStorePathComponent:subPathComponent + completion:nil]; +} - [MagicalRecord setICloudEnabled:cloudURL != nil]; - - NSDictionary *options = [[self class] MR_autoMigrationOptions]; - if (cloudURL) //iCloud is available - { - NSDictionary *iCloudOptions = [NSDictionary dictionaryWithObjectsAndKeys: - contentNameKey, NSPersistentStoreUbiquitousContentNameKey, - cloudURL, NSPersistentStoreUbiquitousContentURLKey, nil]; - options = [options MR_dictionaryByMergingDictionary:iCloudOptions]; - } - else - { - MRLog(@"iCloud is not enabled"); - } - - [self lock]; - [self MR_addSqliteStoreNamed:localStoreName withOptions:options]; - [self unlock]; +- (void) MR_addiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)subPathComponent completion:(void(^)(void))completionBlock; +{ + [self MR_addiCloudContainerID:containerID + contentNameKey:contentNameKey + storeIdentifier:localStoreName + cloudStorePathComponent:subPathComponent + completion:completionBlock]; +} - dispatch_async(dispatch_get_main_queue(), ^{ - if ([NSPersistentStore MR_defaultPersistentStore] == nil) - { - [NSPersistentStore MR_setDefaultPersistentStore:[[self persistentStores] objectAtIndex:0]]; - } - if (completionBlock) - { - completionBlock(); - } - NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; - [notificationCenter postNotificationName:kMagicalRecordPSCDidCompleteiCloudSetupNotification object:nil]; - }); - }); +- (void) MR_addiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreAtURL:(NSURL *)storeURL cloudStorePathComponent:(NSString *)subPathComponent completion:(void(^)(void))completionBlock; +{ + [self MR_addiCloudContainerID:containerID + contentNameKey:contentNameKey + storeIdentifier:storeURL + cloudStorePathComponent:subPathComponent + completion:completionBlock]; } + (NSPersistentStoreCoordinator *) MR_coordinatorWithiCloudContainerID:(NSString *)containerID @@ -243,6 +353,18 @@ + (NSPersistentStoreCoordinator *) MR_coordinatorWithiCloudContainerID:(NSString completion:nil]; } ++ (NSPersistentStoreCoordinator *) MR_coordinatorWithiCloudContainerID:(NSString *)containerID + contentNameKey:(NSString *)contentNameKey + localStoreAtURL:(NSURL *)storeURL + cloudStorePathComponent:(NSString *)subPathComponent +{ + return [self MR_coordinatorWithiCloudContainerID:containerID + contentNameKey:contentNameKey + localStoreAtURL:storeURL + cloudStorePathComponent:subPathComponent + completion:nil]; +} + + (NSPersistentStoreCoordinator *) MR_coordinatorWithiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName @@ -261,6 +383,24 @@ + (NSPersistentStoreCoordinator *) MR_coordinatorWithiCloudContainerID:(NSString return psc; } ++ (NSPersistentStoreCoordinator *) MR_coordinatorWithiCloudContainerID:(NSString *)containerID + contentNameKey:(NSString *)contentNameKey + localStoreAtURL:(NSURL *)storeURL + cloudStorePathComponent:(NSString *)subPathComponent + completion:(void (^)(void))completionHandler +{ + NSManagedObjectModel *model = [NSManagedObjectModel MR_defaultManagedObjectModel]; + NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model]; + + [psc MR_addiCloudContainerID:containerID + contentNameKey:contentNameKey + localStoreAtURL:storeURL + cloudStorePathComponent:subPathComponent + completion:completionHandler]; + + return psc; +} + + (NSPersistentStoreCoordinator *) MR_coordinatorWithPersistentStore:(NSPersistentStore *)persistentStore; { NSManagedObjectModel *model = [NSManagedObjectModel MR_defaultManagedObjectModel]; @@ -280,11 +420,25 @@ + (NSPersistentStoreCoordinator *) MR_coordinatorWithSqliteStoreNamed:(NSString return psc; } ++ (NSPersistentStoreCoordinator *) MR_coordinatorWithSqliteStoreAtURL:(NSURL *)storeURL withOptions:(NSDictionary *)options +{ + NSManagedObjectModel *model = [NSManagedObjectModel MR_defaultManagedObjectModel]; + NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model]; + + [psc MR_addSqliteStoreNamed:storeURL withOptions:options]; + return psc; +} + + (NSPersistentStoreCoordinator *) MR_coordinatorWithSqliteStoreNamed:(NSString *)storeFileName { return [self MR_coordinatorWithSqliteStoreNamed:storeFileName withOptions:nil]; } ++ (NSPersistentStoreCoordinator *) MR_coordinatorWithSqliteStoreAtURL:(NSURL *)storeURL +{ + return [self MR_coordinatorWithSqliteStoreAtURL:storeURL withOptions:nil]; +} + @end diff --git a/MagicalRecord/Core/MagicalRecord+Actions.h b/MagicalRecord/Core/MagicalRecord+Actions.h index c11759daf..fa999d710 100644 --- a/MagicalRecord/Core/MagicalRecord+Actions.h +++ b/MagicalRecord/Core/MagicalRecord+Actions.h @@ -6,8 +6,9 @@ // #import -#import "NSManagedObjectContext+MagicalRecord.h" -#import "NSManagedObjectContext+MagicalSaves.h" +#import +#import +#import @interface MagicalRecord (Actions) @@ -20,25 +21,14 @@ */ + (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) - */ +@end -/* For all background saving operations. These calls will be sent to a different thread/queue. - */ -+ (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block __attribute__((deprecated)); -+ (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block completion:(void(^)(void))completion __attribute__((deprecated)); +@interface MagicalRecord (ActionsDeprecated) -/* - If you want to reuse the context on the current thread, use this method. - */ -+ (void) saveInBackgroundUsingCurrentContextWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(void (^)(void))completion errorHandler:(void (^)(NSError *error))errorHandler __attribute__((deprecated)); ++ (void) saveUsingCurrentThreadContextWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(MRSaveCompletionHandler)completion MR_DEPRECATED_WILL_BE_REMOVED_IN("3.0"); ++ (void) saveUsingCurrentThreadContextWithBlockAndWait:(void (^)(NSManagedObjectContext *localContext))block MR_DEPRECATED_WILL_BE_REMOVED_IN("3.0"); ++ (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block MR_DEPRECATED_WILL_BE_REMOVED_IN("3.0"); ++ (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block completion:(void(^)(void))completion MR_DEPRECATED_WILL_BE_REMOVED_IN("3.0"); ++ (void) saveInBackgroundUsingCurrentContextWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(void (^)(void))completion errorHandler:(void (^)(NSError *error))errorHandler MR_DEPRECATED_WILL_BE_REMOVED_IN("3.0"); @end diff --git a/MagicalRecord/Core/MagicalRecord+Actions.m b/MagicalRecord/Core/MagicalRecord+Actions.m index 0d3eeabc5..812521c3d 100644 --- a/MagicalRecord/Core/MagicalRecord+Actions.m +++ b/MagicalRecord/Core/MagicalRecord+Actions.m @@ -5,9 +5,9 @@ // Copyright 2011 Magical Panda Software. All rights reserved. // -#import "CoreData+MagicalRecord.h" +#import "MagicalRecord+Actions.h" #import "NSManagedObjectContext+MagicalRecord.h" - +#import "NSManagedObjectContext+MagicalThreading.h" @implementation MagicalRecord (Actions) @@ -20,10 +20,12 @@ + (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block; + (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block completion:(MRSaveCompletionHandler)completion; { - NSManagedObjectContext *mainContext = [NSManagedObjectContext MR_rootSavingContext]; - NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextWithParent:mainContext]; + NSManagedObjectContext *savingContext = [NSManagedObjectContext MR_rootSavingContext]; + NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextWithParent:savingContext]; [localContext performBlock:^{ + [localContext MR_setWorkingName:NSStringFromSelector(_cmd)]; + if (block) { block(localContext); } @@ -32,33 +34,41 @@ + (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block comp }]; } -+ (void) saveUsingCurrentThreadContextWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(MRSaveCompletionHandler)completion; +#pragma mark - Synchronous saving + ++ (void) saveWithBlockAndWait:(void(^)(NSManagedObjectContext *localContext))block; { - NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread]; + NSManagedObjectContext *savingContext = [NSManagedObjectContext MR_rootSavingContext]; + NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextWithParent:savingContext]; + + [localContext performBlockAndWait:^{ + [localContext MR_setWorkingName:NSStringFromSelector(_cmd)]; - [localContext performBlock:^{ if (block) { block(localContext); } - [localContext MR_saveWithOptions:MRSaveParentContexts completion:completion]; + [localContext MR_saveWithOptions:MRSaveParentContexts|MRSaveSynchronously completion:nil]; }]; } +@end -#pragma mark - Synchronous saving +#pragma mark - Deprecated Methods — DO NOT USE +@implementation MagicalRecord (ActionsDeprecated) -+ (void) saveWithBlockAndWait:(void(^)(NSManagedObjectContext *localContext))block; ++ (void) saveUsingCurrentThreadContextWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(MRSaveCompletionHandler)completion; { - NSManagedObjectContext *mainContext = [NSManagedObjectContext MR_rootSavingContext]; - NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextWithParent:mainContext]; + NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread]; + + [localContext performBlock:^{ + [localContext MR_setWorkingName:NSStringFromSelector(_cmd)]; - [localContext performBlockAndWait:^{ if (block) { block(localContext); } - [localContext MR_saveWithOptions:MRSaveParentContexts|MRSaveSynchronously completion:nil]; + [localContext MR_saveWithOptions:MRSaveParentContexts completion:completion]; }]; } @@ -67,6 +77,8 @@ + (void) saveUsingCurrentThreadContextWithBlockAndWait:(void (^)(NSManagedObject NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread]; [localContext performBlockAndWait:^{ + [localContext MR_setWorkingName:NSStringFromSelector(_cmd)]; + if (block) { block(localContext); } @@ -75,12 +87,6 @@ + (void) saveUsingCurrentThreadContextWithBlockAndWait:(void (^)(NSManagedObject }]; } - -#pragma mark - Deprecated methods - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-implementations" - + (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block { [[self class] saveWithBlock:block completion:nil]; @@ -88,10 +94,12 @@ + (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext + (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block completion:(void(^)(void))completion { - NSManagedObjectContext *mainContext = [NSManagedObjectContext MR_defaultContext]; - NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextWithParent:mainContext]; + NSManagedObjectContext *savingContext = [NSManagedObjectContext MR_rootSavingContext]; + NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextWithParent:savingContext]; [localContext performBlock:^{ + [localContext MR_setWorkingName:NSStringFromSelector(_cmd)]; + if (block) { block(localContext); @@ -111,12 +119,14 @@ + (void) saveInBackgroundUsingCurrentContextWithBlock:(void (^)(NSManagedObjectC NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread]; [localContext performBlock:^{ + [localContext MR_setWorkingName:NSStringFromSelector(_cmd)]; + if (block) { block(localContext); } - [localContext MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) { - if (success) { + [localContext MR_saveToPersistentStoreWithCompletion:^(BOOL contextDidSave, NSError *error) { + if (contextDidSave) { if (completion) { completion(); } @@ -130,6 +140,4 @@ + (void) saveInBackgroundUsingCurrentContextWithBlock:(void (^)(NSManagedObjectC }]; } -#pragma clang diagnostic pop // ignored "-Wdeprecated-implementations" - @end diff --git a/MagicalRecord/Core/MagicalRecord+ErrorHandling.h b/MagicalRecord/Core/MagicalRecord+ErrorHandling.h index f247b7c96..e7fd15dd6 100644 --- a/MagicalRecord/Core/MagicalRecord+ErrorHandling.h +++ b/MagicalRecord/Core/MagicalRecord+ErrorHandling.h @@ -6,7 +6,7 @@ // Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. // -#import "MagicalRecord.h" +#import @interface MagicalRecord (ErrorHandling) diff --git a/MagicalRecord/Core/MagicalRecord+ErrorHandling.m b/MagicalRecord/Core/MagicalRecord+ErrorHandling.m index eaf1c05e8..3f1f12636 100644 --- a/MagicalRecord/Core/MagicalRecord+ErrorHandling.m +++ b/MagicalRecord/Core/MagicalRecord+ErrorHandling.m @@ -7,9 +7,10 @@ // #import "MagicalRecord+ErrorHandling.h" +#import "MagicalRecordLogging.h" -static id errorHandlerTarget = nil; +__weak static id errorHandlerTarget = nil; static SEL errorHandlerAction = nil; @@ -32,22 +33,22 @@ + (void) defaultErrorHandler:(NSError *)error { if ([e respondsToSelector:@selector(userInfo)]) { - MRLog(@"Error Details: %@", [e userInfo]); + MRLogError(@"Error Details: %@", [e userInfo]); } else { - MRLog(@"Error Details: %@", e); + MRLogError(@"Error Details: %@", e); } } } else { - MRLog(@"Error: %@", detailedError); + MRLogError(@"Error: %@", detailedError); } } - MRLog(@"Error Message: %@", [error localizedDescription]); - MRLog(@"Error Domain: %@", [error domain]); - MRLog(@"Recovery Suggestion: %@", [error localizedRecoverySuggestion]); + MRLogError(@"Error Message: %@", [error localizedDescription]); + MRLogError(@"Error Domain: %@", [error domain]); + MRLogError(@"Recovery Suggestion: %@", [error localizedRecoverySuggestion]); } + (void) handleErrors:(NSError *)error diff --git a/MagicalRecord/Core/MagicalRecord+Options.h b/MagicalRecord/Core/MagicalRecord+Options.h index 72012c7c9..75f47e394 100644 --- a/MagicalRecord/Core/MagicalRecord+Options.h +++ b/MagicalRecord/Core/MagicalRecord+Options.h @@ -6,28 +6,143 @@ // Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. // -#import "MagicalRecord.h" +#import + +/** + Defines "levels" of logging that will be used as values in a bitmask that filters log messages. + + @since Available in v2.3 and later. + */ +typedef NS_ENUM (NSUInteger, MagicalRecordLoggingMask) +{ + /** Log all errors */ + MagicalRecordLoggingMaskError = 1 << 0, + + /** Log warnings, and all errors */ + MagicalRecordLoggingMaskWarn = 1 << 1, + + /** Log informative messagess, warnings and all errors */ + MagicalRecordLoggingMaskInfo = 1 << 2, + + /** Log debugging messages, informative messages, warnings and all errors */ + MagicalRecordLoggingMaskDebug = 1 << 3, + + /** Log verbose diagnostic information, debugging messages, informative messages, messages, warnings and all errors */ + MagicalRecordLoggingMaskVerbose = 1 << 4, +}; + +/** + Defines a mask for logging that will be used by to filter log messages. + + @since Available in v2.3 and later. + */ +typedef NS_ENUM (NSUInteger, MagicalRecordLoggingLevel) +{ + /** Don't log anything */ + MagicalRecordLoggingLevelOff = 0, + + /** Log all errors and fatal messages */ + MagicalRecordLoggingLevelError = (MagicalRecordLoggingMaskError), + + /** Log warnings, errors and fatal messages */ + MagicalRecordLoggingLevelWarn = (MagicalRecordLoggingLevelError | MagicalRecordLoggingMaskWarn), + + /** Log informative, warning and error messages */ + MagicalRecordLoggingLevelInfo = (MagicalRecordLoggingLevelWarn | MagicalRecordLoggingMaskInfo), + + /** Log all debugging, informative, warning and error messages */ + MagicalRecordLoggingLevelDebug = (MagicalRecordLoggingLevelInfo | MagicalRecordLoggingMaskDebug), + + /** Log verbose diagnostic, debugging, informative, warning and error messages */ + MagicalRecordLoggingLevelVerbose = (MagicalRecordLoggingLevelDebug | MagicalRecordLoggingMaskVerbose), + + /** Log everything */ + MagicalRecordLoggingLevelAll = NSUIntegerMax +}; + @interface MagicalRecord (Options) -//global options -// enable/disable logging -// add logging provider -// autocreate new PSC per Store -// autoassign new instances to default store +/** + @name Configuration Options + */ +/** + If this is true, the default managed object model will be automatically created if it doesn't exist when calling `[NSManagedObjectModel MR_defaultManagedObjectModel]`. + + @return current value of shouldAutoCreateManagedObjectModel. + + @since Available in v2.0.4 and later. + */ + (BOOL) shouldAutoCreateManagedObjectModel; -+ (void) setShouldAutoCreateManagedObjectModel:(BOOL)shouldAutoCreate; + +/** + Setting this to true will make MagicalRecord create the default managed object model automatically if it doesn't exist when calling `[NSManagedObjectModel MR_defaultManagedObjectModel]`. + + @param autoCreate BOOL value that flags whether the default persistent store should be automatically created. + + @since Available in v2.0.4 and later. + */ ++ (void) setShouldAutoCreateManagedObjectModel:(BOOL)autoCreate; + +/** + If this is true, the default persistent store will be automatically created if it doesn't exist when calling `[NSPersistentStoreCoordinator MR_defaultStoreCoordinator]`. + + @return current value of shouldAutoCreateDefaultPersistentStoreCoordinator. + + @since Available in v2.0.4 and later. + */ + (BOOL) shouldAutoCreateDefaultPersistentStoreCoordinator; -+ (void) setShouldAutoCreateDefaultPersistentStoreCoordinator:(BOOL)shouldAutoCreate; -+ (void) setShouldDeleteStoreOnModelMismatch:(BOOL)shouldDeleteStoreOnModelMismatch; -/*! - @method shouldDeleteStoreOnModelMistmatch - @abstract If true, when configuring the persistant store coordinator, and Magical Record encounters a store that does not match the model, it will attempt to remove it and re-create a new store. - This is extremely useful during development where every model change could potentially require a delete/reinstall of the app. +/** + Setting this to true will make MagicalRecord create the default persistent store automatically if it doesn't exist when calling `[NSPersistentStoreCoordinator MR_defaultStoreCoordinator]`. + + @param autoCreate BOOL value that flags whether the default persistent store should be automatically created. + + @since Available in v2.0.4 and later. + */ ++ (void) setShouldAutoCreateDefaultPersistentStoreCoordinator:(BOOL)autoCreate; + +/** + If this is true and MagicalRecord encounters a store with a version that does not match that of the model, the store will be removed from the disk. + This is extremely useful during development where frequent model changes can potentially require a delete and reinstall of the app. + + @return current value of shouldDeleteStoreOnModelMismatch + + @since Available in v2.0.4 and later. */ + (BOOL) shouldDeleteStoreOnModelMismatch; +/** + Setting this to true will make MagicalRecord delete any stores that it encounters which do not match the version of their model. + This is extremely useful during development where frequent model changes can potentially require a delete and reinstall of the app. + + @param shouldDelete BOOL value that flags whether mismatched stores should be deleted + + @since Available in v2.0.4 and later. + */ ++ (void) setShouldDeleteStoreOnModelMismatch:(BOOL)shouldDelete; + +/** + @name Logging Levels + */ + +/** + Returns the logging mask set for MagicalRecord in the current application. + + @return Current MagicalRecordLoggingLevel + + @since Available in v2.3 and later. + */ ++ (MagicalRecordLoggingLevel) loggingLevel; + +/** + Sets the logging mask set for MagicalRecord in the current application. + + @param level Any value from MagicalRecordLogLevel + + @since Available in v2.3 and later. + */ ++ (void) setLoggingLevel:(MagicalRecordLoggingLevel)level; @end diff --git a/MagicalRecord/Core/MagicalRecord+Options.m b/MagicalRecord/Core/MagicalRecord+Options.m index a07655833..b9ba7857e 100644 --- a/MagicalRecord/Core/MagicalRecord+Options.m +++ b/MagicalRecord/Core/MagicalRecord+Options.m @@ -8,42 +8,57 @@ #import "MagicalRecord+Options.h" -static BOOL shouldAutoCreateManagedObjectModel_; -static BOOL shouldAutoCreateDefaultPersistentStoreCoordinator_; -static BOOL shouldDeleteStoreOnModelMismatch_; +#ifdef DEBUG +static MagicalRecordLoggingLevel kMagicalRecordLoggingLevel = MagicalRecordLoggingLevelDebug; +#else +static MagicalRecordLoggingLevel kMagicalRecordLoggingLevel = MagicalRecordLoggingLevelError; +#endif +static BOOL kMagicalRecordShouldAutoCreateManagedObjectModel = NO; +static BOOL kMagicalRecordShouldAutoCreateDefaultPersistentStoreCoordinator = NO; +static BOOL kMagicalRecordShouldDeleteStoreOnModelMismatch = NO; @implementation MagicalRecord (Options) -#pragma mark - Options +#pragma mark - Configuration Options + (BOOL) shouldAutoCreateManagedObjectModel; { - return shouldAutoCreateManagedObjectModel_; + return kMagicalRecordShouldAutoCreateManagedObjectModel; } -+ (void) setShouldAutoCreateManagedObjectModel:(BOOL)shouldAutoCreate; ++ (void) setShouldAutoCreateManagedObjectModel:(BOOL)autoCreate; { - shouldAutoCreateManagedObjectModel_ = shouldAutoCreate; + kMagicalRecordShouldAutoCreateManagedObjectModel = autoCreate; } + (BOOL) shouldAutoCreateDefaultPersistentStoreCoordinator; { - return shouldAutoCreateDefaultPersistentStoreCoordinator_; + return kMagicalRecordShouldAutoCreateDefaultPersistentStoreCoordinator; } -+ (void) setShouldAutoCreateDefaultPersistentStoreCoordinator:(BOOL)shouldAutoCreate; ++ (void) setShouldAutoCreateDefaultPersistentStoreCoordinator:(BOOL)autoCreate; { - shouldAutoCreateDefaultPersistentStoreCoordinator_ = shouldAutoCreate; + kMagicalRecordShouldAutoCreateDefaultPersistentStoreCoordinator = autoCreate; } + (BOOL) shouldDeleteStoreOnModelMismatch; { - return shouldDeleteStoreOnModelMismatch_; + return kMagicalRecordShouldDeleteStoreOnModelMismatch; } -+ (void) setShouldDeleteStoreOnModelMismatch:(BOOL)shouldDeleteStoreOnModelMismatch ++ (void) setShouldDeleteStoreOnModelMismatch:(BOOL)shouldDelete; { - shouldDeleteStoreOnModelMismatch_ = shouldDeleteStoreOnModelMismatch; + kMagicalRecordShouldDeleteStoreOnModelMismatch = shouldDelete; +} + ++ (MagicalRecordLoggingLevel) loggingLevel; +{ + return kMagicalRecordLoggingLevel; +} + ++ (void) setLoggingLevel:(MagicalRecordLoggingLevel)level; +{ + kMagicalRecordLoggingLevel = level; } @end diff --git a/MagicalRecord/Core/MagicalRecord+Setup.h b/MagicalRecord/Core/MagicalRecord+Setup.h index a92fa9290..666db69d7 100644 --- a/MagicalRecord/Core/MagicalRecord+Setup.h +++ b/MagicalRecord/Core/MagicalRecord+Setup.h @@ -6,7 +6,7 @@ // Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. // -#import "MagicalRecord.h" +#import @interface MagicalRecord (Setup) @@ -17,5 +17,8 @@ + (void) setupCoreDataStackWithStoreNamed:(NSString *)storeName; + (void) setupCoreDataStackWithAutoMigratingSqliteStoreNamed:(NSString *)storeName; ++ (void) setupCoreDataStackWithStoreAtURL:(NSURL *)storeURL; ++ (void) setupCoreDataStackWithAutoMigratingSqliteStoreAtURL:(NSURL *)storeURL; + @end diff --git a/MagicalRecord/Core/MagicalRecord+Setup.m b/MagicalRecord/Core/MagicalRecord+Setup.m index 1d5c1fdeb..d0829fd82 100644 --- a/MagicalRecord/Core/MagicalRecord+Setup.m +++ b/MagicalRecord/Core/MagicalRecord+Setup.m @@ -43,6 +43,26 @@ + (void) setupCoreDataStackWithAutoMigratingSqliteStoreNamed:(NSString *)storeNa [NSManagedObjectContext MR_initializeDefaultContextWithCoordinator:coordinator]; } ++ (void) setupCoreDataStackWithStoreAtURL:(NSURL *)storeURL +{ + if ([NSPersistentStoreCoordinator MR_defaultStoreCoordinator] != nil) return; + + NSPersistentStoreCoordinator *coordinator = [NSPersistentStoreCoordinator MR_coordinatorWithSqliteStoreAtURL:storeURL]; + [NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:coordinator]; + + [NSManagedObjectContext MR_initializeDefaultContextWithCoordinator:coordinator]; +} + ++ (void) setupCoreDataStackWithAutoMigratingSqliteStoreAtURL:(NSURL *)storeURL +{ + if ([NSPersistentStoreCoordinator MR_defaultStoreCoordinator] != nil) return; + + NSPersistentStoreCoordinator *coordinator = [NSPersistentStoreCoordinator MR_coordinatorWithAutoMigratingSqliteStoreAtURL:storeURL]; + [NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:coordinator]; + + [NSManagedObjectContext MR_initializeDefaultContextWithCoordinator:coordinator]; +} + + (void) setupCoreDataStackWithInMemoryStore; { if ([NSPersistentStoreCoordinator MR_defaultStoreCoordinator] != nil) return; diff --git a/MagicalRecord/Core/MagicalRecord+ShorthandMethods.h b/MagicalRecord/Core/MagicalRecord+ShorthandMethods.h new file mode 100644 index 000000000..bf38be2c6 --- /dev/null +++ b/MagicalRecord/Core/MagicalRecord+ShorthandMethods.h @@ -0,0 +1,10 @@ +// +// Copyright (c) 2015 Magical Panda Software LLC. All rights reserved. + +#import + +@interface MagicalRecord (ShorthandMethods) + ++ (void)enableShorthandMethods; + +@end diff --git a/MagicalRecord/Core/MagicalRecord+ShorthandMethods.m b/MagicalRecord/Core/MagicalRecord+ShorthandMethods.m new file mode 100644 index 000000000..80e741040 --- /dev/null +++ b/MagicalRecord/Core/MagicalRecord+ShorthandMethods.m @@ -0,0 +1,135 @@ +// +// Copyright (c) 2015 Magical Panda Software LLC. All rights reserved. + +#import "MagicalRecord+ShorthandMethods.h" +#import + +static NSString *const kMagicalRecordCategoryPrefix = @"MR_"; +static BOOL kMagicalRecordShorthandMethodsSwizzled = NO; + +@implementation MagicalRecord (ShorthandMethods) + ++ (void)enableShorthandMethods +{ + if (kMagicalRecordShorthandMethodsSwizzled == NO) + { + NSArray *classes = [self classesToSwizzle]; + + [classes enumerateObjectsUsingBlock:^(id object, NSUInteger idx, BOOL *stop) { + Class objectClass = (Class)object; + + [self updateResolveMethodsForClass:objectClass]; + }]; + + kMagicalRecordShorthandMethodsSwizzled = YES; + } +} + ++ (NSArray *)classesToSwizzle +{ + return @[ [NSManagedObject class], + [NSManagedObjectContext class], + [NSManagedObjectModel class], + [NSPersistentStore class], + [NSPersistentStoreCoordinator class] ]; +} + ++ (NSArray *)methodNameBlacklist +{ + return @[ NSStringFromSelector(@selector(entityName)) ]; +} + ++ (BOOL)MR_resolveClassMethod:(SEL)originalSelector +{ + BOOL resolvedClassMethod = [self MR_resolveClassMethod:originalSelector]; + if (!resolvedClassMethod) + { + resolvedClassMethod = MRAddShortHandMethodForPrefixedClassMethod(self, originalSelector, kMagicalRecordCategoryPrefix); + } + return resolvedClassMethod; +} + ++ (BOOL)MR_resolveInstanceMethod:(SEL)originalSelector +{ + BOOL resolvedClassMethod = [self MR_resolveInstanceMethod:originalSelector]; + if (!resolvedClassMethod) + { + resolvedClassMethod = MRAddShorthandMethodForPrefixedInstanceMethod(self, originalSelector, kMagicalRecordCategoryPrefix); + } + return resolvedClassMethod; +} + +// In order to add support for non-prefixed AND prefixed methods, we need to swap the existing resolveClassMethod: and resolveInstanceMethod: implementations with the one in this class. ++ (void)updateResolveMethodsForClass:(Class)objectClass +{ + MRReplaceSelectorForTargetWithSourceImplementation(self, @selector(MR_resolveClassMethod:), objectClass, @selector(resolveClassMethod:)); + MRReplaceSelectorForTargetWithSourceImplementation(self, @selector(MR_resolveInstanceMethod:), objectClass, @selector(resolveInstanceMethod:)); +} + +static void MRReplaceSelectorForTargetWithSourceImplementation(Class sourceClass, SEL sourceSelector, Class targetClass, SEL targetSelector) +{ + Method sourceClassMethod = class_getClassMethod(sourceClass, sourceSelector); + Method targetClassMethod = class_getClassMethod(targetClass, targetSelector); + + Class targetMetaClass = objc_getMetaClass([NSStringFromClass(targetClass) cStringUsingEncoding:NSUTF8StringEncoding]); + + BOOL methodWasAdded = class_addMethod(targetMetaClass, sourceSelector, + method_getImplementation(targetClassMethod), + method_getTypeEncoding(targetClassMethod)); + + if (methodWasAdded) + { + class_replaceMethod(targetMetaClass, targetSelector, + method_getImplementation(sourceClassMethod), + method_getTypeEncoding(sourceClassMethod)); + } +} + +static BOOL MRAddShorthandMethodForPrefixedInstanceMethod(Class objectClass, SEL originalSelector, NSString *prefix) +{ + NSString *originalSelectorString = NSStringFromSelector(originalSelector); + + if ([originalSelectorString hasPrefix:prefix] == NO && + ([originalSelectorString hasPrefix:@"_"] || [originalSelectorString hasPrefix:@"init"])) + { + NSString *prefixedSelector = [prefix stringByAppendingString:originalSelectorString]; + Method existingMethod = class_getInstanceMethod(objectClass, NSSelectorFromString(prefixedSelector)); + + if (existingMethod) + { + BOOL methodWasAdded = class_addMethod(objectClass, + originalSelector, + method_getImplementation(existingMethod), + method_getTypeEncoding(existingMethod)); + + return methodWasAdded; + } + } + return NO; +} + +static BOOL MRAddShortHandMethodForPrefixedClassMethod(Class objectClass, SEL originalSelector, NSString *prefix) +{ + NSString *originalSelectorString = NSStringFromSelector(originalSelector); + + if ([originalSelectorString hasPrefix:prefix] == NO && + [originalSelectorString hasSuffix:@"entityName"] == NO) + { + NSString *prefixedSelector = [prefix stringByAppendingString:originalSelectorString]; + Method existingMethod = class_getClassMethod(objectClass, NSSelectorFromString(prefixedSelector)); + + if (existingMethod) + { + Class metaClass = objc_getMetaClass([NSStringFromClass(objectClass) cStringUsingEncoding:NSUTF8StringEncoding]); + BOOL methodWasAdded = class_addMethod(metaClass, + originalSelector, + method_getImplementation(existingMethod), + method_getTypeEncoding(existingMethod)); + + return methodWasAdded; + } + } + return NO; +} + +@end diff --git a/MagicalRecord/Core/MagicalRecord+ShorthandSupport.h b/MagicalRecord/Core/MagicalRecord+ShorthandSupport.h deleted file mode 100644 index f283599ad..000000000 --- a/MagicalRecord/Core/MagicalRecord+ShorthandSupport.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// MagicalRecord+ShorthandSupport.h -// Magical Record -// -// Created by Saul Mora on 3/6/12. -// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. -// - -#import "MagicalRecord.h" - -@interface MagicalRecord (ShorthandSupport) - -#ifdef MR_SHORTHAND -+ (void) swizzleShorthandMethods; -#endif - -@end diff --git a/MagicalRecord/Core/MagicalRecord+ShorthandSupport.m b/MagicalRecord/Core/MagicalRecord+ShorthandSupport.m deleted file mode 100644 index e36ffc69e..000000000 --- a/MagicalRecord/Core/MagicalRecord+ShorthandSupport.m +++ /dev/null @@ -1,147 +0,0 @@ -// -// MagicalRecord+ShorthandSupport.m -// Magical Record -// -// Created by Saul Mora on 3/6/12. -// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. -// - -#import "MagicalRecord+ShorthandSupport.h" -#import - - -static NSString * const kMagicalRecordCategoryPrefix = @"MR_"; -#ifdef MR_SHORTHAND -static BOOL methodsHaveBeenSwizzled = NO; -#endif - - -//Dynamic shorthand method helpers -BOOL addMagicalRecordShortHandMethodToPrefixedClassMethod(Class class, SEL selector); -BOOL addMagicalRecordShorthandMethodToPrefixedInstanceMethod(Class klass, SEL originalSelector); - -void swizzleInstanceMethods(Class originalClass, SEL originalSelector, Class targetClass, SEL newSelector); -void replaceSelectorForTargetWithSourceImpAndSwizzle(Class originalClass, SEL originalSelector, Class newClass, SEL newSelector); - - -@implementation MagicalRecord (ShorthandSupport) - -#pragma mark - Support methods for shorthand methods - -#ifdef MR_SHORTHAND -+ (BOOL) MR_resolveClassMethod:(SEL)originalSelector -{ - BOOL resolvedClassMethod = [self MR_resolveClassMethod:originalSelector]; - if (!resolvedClassMethod) - { - resolvedClassMethod = addMagicalRecordShortHandMethodToPrefixedClassMethod(self, originalSelector); - } - return resolvedClassMethod; -} - -+ (BOOL) MR_resolveInstanceMethod:(SEL)originalSelector -{ - BOOL resolvedClassMethod = [self MR_resolveInstanceMethod:originalSelector]; - if (!resolvedClassMethod) - { - resolvedClassMethod = addMagicalRecordShorthandMethodToPrefixedInstanceMethod(self, originalSelector); - } - return resolvedClassMethod; -} - -//In order to add support for non-prefixed AND prefixed methods, we need to swap the existing resolveClassMethod: and resolveInstanceMethod: implementations with the one in this class. -+ (void) updateResolveMethodsForClass:(Class)klass -{ - replaceSelectorForTargetWithSourceImpAndSwizzle(self, @selector(MR_resolveClassMethod:), klass, @selector(resolveClassMethod:)); - replaceSelectorForTargetWithSourceImpAndSwizzle(self, @selector(MR_resolveInstanceMethod:), klass, @selector(resolveInstanceMethod:)); -} - -+ (void) swizzleShorthandMethods; -{ - if (methodsHaveBeenSwizzled) return; - - NSArray *classes = [NSArray arrayWithObjects: - [NSManagedObject class], - [NSManagedObjectContext class], - [NSManagedObjectModel class], - [NSPersistentStore class], - [NSPersistentStoreCoordinator class], nil]; - - [classes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { - Class klass = (Class)obj; - - [self updateResolveMethodsForClass:klass]; - }]; - methodsHaveBeenSwizzled = YES; -} -#endif - -@end - -#pragma mark - Support functions for runtime shorthand Method calling - -void replaceSelectorForTargetWithSourceImpAndSwizzle(Class sourceClass, SEL sourceSelector, Class targetClass, SEL targetSelector) -{ - Method sourceClassMethod = class_getClassMethod(sourceClass, sourceSelector); - Method targetClassMethod = class_getClassMethod(targetClass, targetSelector); - - Class targetMetaClass = objc_getMetaClass([NSStringFromClass(targetClass) cStringUsingEncoding:NSUTF8StringEncoding]); - - BOOL methodWasAdded = class_addMethod(targetMetaClass, sourceSelector, - method_getImplementation(targetClassMethod), - method_getTypeEncoding(targetClassMethod)); - - if (methodWasAdded) - { - class_replaceMethod(targetMetaClass, targetSelector, - method_getImplementation(sourceClassMethod), - method_getTypeEncoding(sourceClassMethod)); - } -} - -BOOL addMagicalRecordShorthandMethodToPrefixedInstanceMethod(Class klass, SEL originalSelector) -{ - NSString *originalSelectorString = NSStringFromSelector(originalSelector); - if ([originalSelectorString hasPrefix:@"_"] || [originalSelectorString hasPrefix:@"init"]) return NO; - - if (![originalSelectorString hasPrefix:kMagicalRecordCategoryPrefix]) - { - NSString *prefixedSelector = [kMagicalRecordCategoryPrefix stringByAppendingString:originalSelectorString]; - Method existingMethod = class_getInstanceMethod(klass, NSSelectorFromString(prefixedSelector)); - - if (existingMethod) - { - BOOL methodWasAdded = class_addMethod(klass, - originalSelector, - method_getImplementation(existingMethod), - method_getTypeEncoding(existingMethod)); - - return methodWasAdded; - } - } - return NO; -} - - -BOOL addMagicalRecordShortHandMethodToPrefixedClassMethod(Class klass, SEL originalSelector) -{ - NSString *originalSelectorString = NSStringFromSelector(originalSelector); - if (![originalSelectorString hasPrefix:kMagicalRecordCategoryPrefix]) - { - NSString *prefixedSelector = [kMagicalRecordCategoryPrefix stringByAppendingString:originalSelectorString]; - Method existingMethod = class_getClassMethod(klass, NSSelectorFromString(prefixedSelector)); - - if (existingMethod) - { - Class metaClass = objc_getMetaClass([NSStringFromClass(klass) cStringUsingEncoding:NSUTF8StringEncoding]); - BOOL methodWasAdded = class_addMethod(metaClass, - originalSelector, - method_getImplementation(existingMethod), - method_getTypeEncoding(existingMethod)); - - return methodWasAdded; - } - } - return NO; -} - diff --git a/MagicalRecord/Core/MagicalRecord+iCloud.h b/MagicalRecord/Core/MagicalRecord+iCloud.h index b7818b226..d6e82d2e1 100644 --- a/MagicalRecord/Core/MagicalRecord+iCloud.h +++ b/MagicalRecord/Core/MagicalRecord+iCloud.h @@ -6,14 +6,38 @@ // Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. // -#import "MagicalRecord.h" +#import @interface MagicalRecord (iCloud) -+ (BOOL) isICloudEnabled; ++ (BOOL)isICloudEnabled; -+ (void) setupCoreDataStackWithiCloudContainer:(NSString *)icloudBucket localStoreNamed:(NSString *)localStore; -+ (void) setupCoreDataStackWithiCloudContainer:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)pathSubcomponent; -+ (void) setupCoreDataStackWithiCloudContainer:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)pathSubcomponent completion:(void(^)(void))completion; ++ (void)setupCoreDataStackWithiCloudContainer:(NSString *)containerID + localStoreNamed:(NSString *)localStore; + ++ (void)setupCoreDataStackWithiCloudContainer:(NSString *)containerID + contentNameKey:(NSString *)contentNameKey + localStoreNamed:(NSString *)localStoreName + cloudStorePathComponent:(NSString *)pathSubcomponent; + ++ (void)setupCoreDataStackWithiCloudContainer:(NSString *)containerID + contentNameKey:(NSString *)contentNameKey + localStoreNamed:(NSString *)localStoreName + cloudStorePathComponent:(NSString *)pathSubcomponent + completion:(void (^)(void))completion; + ++ (void)setupCoreDataStackWithiCloudContainer:(NSString *)containerID + localStoreAtURL:(NSURL *)storeURL; + ++ (void)setupCoreDataStackWithiCloudContainer:(NSString *)containerID + contentNameKey:(NSString *)contentNameKey + localStoreAtURL:(NSURL *)storeURL + cloudStorePathComponent:(NSString *)pathSubcomponent; + ++ (void)setupCoreDataStackWithiCloudContainer:(NSString *)containerID + contentNameKey:(NSString *)contentNameKey + localStoreAtURL:(NSURL *)storeURL + cloudStorePathComponent:(NSString *)pathSubcomponent + completion:(void (^)(void))completion; @end diff --git a/MagicalRecord/Core/MagicalRecord+iCloud.m b/MagicalRecord/Core/MagicalRecord+iCloud.m index bcaf0dc4d..90c6b454f 100644 --- a/MagicalRecord/Core/MagicalRecord+iCloud.m +++ b/MagicalRecord/Core/MagicalRecord+iCloud.m @@ -29,11 +29,10 @@ + (void) setICloudEnabled:(BOOL)enabled; } } -+ (void) setupCoreDataStackWithiCloudContainer:(NSString *)icloudBucket localStoreNamed:(NSString *)localStore; ++ (void) setupCoreDataStackWithiCloudContainer:(NSString *)containerID localStoreNamed:(NSString *)localStore; { - NSString *contentNameKey = [[[NSBundle mainBundle] infoDictionary] objectForKey:(id)kCFBundleIdentifierKey]; - [self setupCoreDataStackWithiCloudContainer:icloudBucket - contentNameKey:contentNameKey + [self setupCoreDataStackWithiCloudContainer:containerID + contentNameKey:nil localStoreNamed:localStore cloudStorePathComponent:nil]; } @@ -58,4 +57,30 @@ + (void) setupCoreDataStackWithiCloudContainer:(NSString *)containerID contentNa [NSManagedObjectContext MR_initializeDefaultContextWithCoordinator:coordinator]; } ++ (void) setupCoreDataStackWithiCloudContainer:(NSString *)containerID localStoreAtURL:(NSURL *)storeURL +{ + NSString *contentNameKey = [[[NSBundle mainBundle] infoDictionary] objectForKey:(id)kCFBundleIdentifierKey]; + [self setupCoreDataStackWithiCloudContainer:containerID + contentNameKey:contentNameKey + localStoreAtURL:storeURL + cloudStorePathComponent:nil]; +} + ++ (void) setupCoreDataStackWithiCloudContainer:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreAtURL:(NSURL *)storeURL cloudStorePathComponent:(NSString *)pathSubcomponent +{ + [self setupCoreDataStackWithiCloudContainer:containerID + contentNameKey:contentNameKey + localStoreAtURL:storeURL + cloudStorePathComponent:pathSubcomponent + completion:nil]; +} + ++ (void) setupCoreDataStackWithiCloudContainer:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreAtURL:(NSURL *)storeURL cloudStorePathComponent:(NSString *)pathSubcomponent completion:(void (^)(void))completion +{ + NSPersistentStoreCoordinator *coordinator = [NSPersistentStoreCoordinator MR_coordinatorWithiCloudContainerID:containerID contentNameKey:contentNameKey localStoreAtURL:storeURL cloudStorePathComponent:pathSubcomponent completion:completion]; + + [NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:coordinator]; + [NSManagedObjectContext MR_initializeDefaultContextWithCoordinator:coordinator]; +} + @end diff --git a/MagicalRecord/Core/MagicalRecord.h b/MagicalRecord/Core/MagicalRecord.h deleted file mode 100644 index dbc893716..000000000 --- a/MagicalRecord/Core/MagicalRecord.h +++ /dev/null @@ -1,52 +0,0 @@ -// -// MagicalRecord.h -// -// Created by Saul Mora on 3/11/10. -// Copyright 2010 Magical Panda Software, LLC All rights reserved. -// - -#if TARGET_OS_IPHONE == 0 -#define MAC_PLATFORM_ONLY YES -#endif - -// enable to use caches for the fetchedResultsControllers (iOS only) -// #define STORE_USE_CACHE - -#ifndef MR_ENABLE_ACTIVE_RECORD_LOGGING - #ifdef DEBUG - #define MR_ENABLE_ACTIVE_RECORD_LOGGING 1 - #else - #define MR_ENABLE_ACTIVE_RECORD_LOGGING 0 - #endif -#endif - -#if MR_ENABLE_ACTIVE_RECORD_LOGGING != 0 - // First, check if we can use Cocoalumberjack for logging - #ifdef LOG_VERBOSE - extern int ddLogLevel; - #define MRLog(...) DDLogVerbose(__VA_ARGS__) - #else - #define MRLog(...) NSLog(@"%s(%p) %@", __PRETTY_FUNCTION__, self, [NSString stringWithFormat:__VA_ARGS__]) - #endif -#else - #define MRLog(...) ((void)0) -#endif - -#ifdef NS_BLOCKS_AVAILABLE - -@class NSManagedObjectContext; -typedef void (^CoreDataBlock)(NSManagedObjectContext *context); - -#endif - -@interface MagicalRecord : NSObject - -+ (NSString *) currentStack; - -+ (void) cleanUp; - -+ (void) setDefaultModelFromClass:(Class)klass; -+ (void) setDefaultModelNamed:(NSString *)modelName; -+ (NSString *) defaultStoreName; - -@end diff --git a/MagicalRecord/Core/MagicalRecordDeprecationMacros.h b/MagicalRecord/Core/MagicalRecordDeprecationMacros.h new file mode 100644 index 000000000..22d80f12f --- /dev/null +++ b/MagicalRecord/Core/MagicalRecordDeprecationMacros.h @@ -0,0 +1,7 @@ +// +// Created by Tony Arnold on 10/04/2014. +// Copyright (c) 2014 Magical Panda Software LLC. All rights reserved. +// + +#define MR_DEPRECATED_WILL_BE_REMOVED_IN(VERSION) __attribute__((deprecated("This method has been deprecated and will be removed in MagicalRecord " VERSION "."))) +#define MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE(VERSION, METHOD) __attribute__((deprecated("This method has been deprecated and will be removed in MagicalRecord " VERSION ". Please use `" METHOD "` instead."))) diff --git a/MagicalRecord/Core/MagicalRecordInternal.h b/MagicalRecord/Core/MagicalRecordInternal.h new file mode 100644 index 000000000..526d98d52 --- /dev/null +++ b/MagicalRecord/Core/MagicalRecordInternal.h @@ -0,0 +1,98 @@ +// +// MagicalRecord.h +// +// Created by Saul Mora on 3/11/10. +// Copyright 2010 Magical Panda Software, LLC All rights reserved. +// + +#import + +/** + Defines current and historical version numbers for MagicalRecord. + + @since Available in v2.3 and later. + */ +typedef NS_ENUM(NSUInteger, MagicalRecordVersionTag) +{ + /** Version 2.2.0 */ + MagicalRecordVersionTag2_2 = 220, + + /** Version 2.3.0 */ + MagicalRecordVersionTag2_3 = 230, + + /** Version 3.0.0 */ + MagicalRecordVersionTag3_0 = 300 +}; + +// enable to use caches for the fetchedResultsControllers (iOS only) +// #define STORE_USE_CACHE + +#ifdef NS_BLOCKS_AVAILABLE + +extern NSString * const kMagicalRecordCleanedUpNotification; + +@class NSManagedObjectContext; +typedef void (^CoreDataBlock)(NSManagedObjectContext *context); + +#endif + +/** + Provides class methods to help setup, save, handle errors and provide information about the currently loaded version of MagicalRecord. + + @since Available in v1.0 and later. + */ +@interface MagicalRecord : NSObject + +/** + Returns the current version of MagicalRecord. See the MagicalRecordVersionTag enumeration for valid current and historical values. + + @return The current version as a double. + + @since Available in v2.3 and later. + */ ++ (MagicalRecordVersionTag) version; + +/** + Provides information about the current stack, including the model, coordinator, persistent store, the default context and any parent contexts of the default context. + + @return Description of the current state of the stack. + + @since Available in v2.3 and later. + */ ++ (NSString *) currentStack; + +/** + Cleans up the entire MagicalRecord stack. Sets the default model, store and context to nil before posting a kMagicalRecordCleanedUpNotification notification. + + @since Available in v1.0 and later. + */ ++ (void) cleanUp; + +/** + Calls NSBundle's -bundleForClass: to determine the bundle to search for the default model within. + + @param modelClass Class to set the model from + + @since Available in v2.0 and later. + */ ++ (void) setDefaultModelFromClass:(Class)modelClass; + +/** + Looks for a momd file with the specified name, and if found sets it as the default model. + + @param modelName Model name as a string, including file extension + + @since Available in v1.0 and later. + */ ++ (void) setDefaultModelNamed:(NSString *)modelName; + +/** + Determines the store file name your app should use. This method is used by the MagicalRecord SQLite stacks when a store file is not specified. The file name returned is in the form ".sqlite". `` is taken from the application's info dictionary, which is retrieved from the method [[NSBundle mainBundle] infoDictionary]. If no bundle name is available, "CoreDataStore.sqlite" will be used. + + @return String of the form .sqlite + + @since Available in v2.0 and later. + */ ++ (NSString *) defaultStoreName; + +@end diff --git a/MagicalRecord/Core/MagicalRecord.m b/MagicalRecord/Core/MagicalRecordInternal.m similarity index 81% rename from MagicalRecord/Core/MagicalRecord.m rename to MagicalRecord/Core/MagicalRecordInternal.m index 42d577a9e..230f04bce 100644 --- a/MagicalRecord/Core/MagicalRecord.m +++ b/MagicalRecord/Core/MagicalRecordInternal.m @@ -5,7 +5,9 @@ // Copyright 2010 Magical Panda Software, LLC All rights reserved. // -#import "CoreData+MagicalRecord.h" +#import "MagicalRecord.h" + +NSString * const kMagicalRecordCleanedUpNotification = @"kMagicalRecordCleanedUpNotification"; @interface MagicalRecord (Internal) @@ -23,10 +25,19 @@ + (void) MR_cleanUp; @implementation MagicalRecord ++ (MagicalRecordVersionTag) version +{ + return MagicalRecordVersionTag2_3; +} + + (void) cleanUp { [self cleanUpErrorHanding]; [self cleanUpStack]; + NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; + [notificationCenter postNotificationName:kMagicalRecordCleanedUpNotification + object:nil + userInfo:nil]; } + (void) cleanUpStack; @@ -56,9 +67,9 @@ + (void) setDefaultModelNamed:(NSString *)modelName; [NSManagedObjectModel MR_setDefaultManagedObjectModel:model]; } -+ (void) setDefaultModelFromClass:(Class)klass; ++ (void) setDefaultModelFromClass:(Class)modelClass; { - NSBundle *bundle = [NSBundle bundleForClass:klass]; + NSBundle *bundle = [NSBundle bundleForClass:modelClass]; NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:[NSArray arrayWithObject:bundle]]; [NSManagedObjectModel MR_setDefaultManagedObjectModel:model]; } @@ -85,9 +96,6 @@ + (void) initialize; { if (self == [MagicalRecord class]) { -#ifdef MR_SHORTHAND - [self swizzleShorthandMethods]; -#endif [self setShouldAutoCreateManagedObjectModel:YES]; [self setShouldAutoCreateDefaultPersistentStoreCoordinator:NO]; #ifdef DEBUG diff --git a/MagicalRecord/Core/MagicalRecordLogging.h b/MagicalRecord/Core/MagicalRecordLogging.h new file mode 100644 index 000000000..8cc262554 --- /dev/null +++ b/MagicalRecord/Core/MagicalRecordLogging.h @@ -0,0 +1,49 @@ +// +// MagicalRecordLogging.h +// MagicalRecord +// +// Created by Saul Mora on 10/4/13. +// Copyright (c) 2013 Magical Panda Software LLC. All rights reserved. +// + +#import + +#if MR_LOGGING_DISABLED + +#define MRLogError(frmt, ...) ((void)0) +#define MRLogWarn(frmt, ...) ((void)0) +#define MRLogInfo(frmt, ...) ((void)0) +#define MRLogDebug(frmt, ...) ((void)0) +#define MRLogVerbose(frmt, ...) ((void)0) + +#else + +#ifndef MR_LOGGING_CONTEXT +#define MR_LOGGING_CONTEXT 0 +#endif + +#if __has_include("CocoaLumberjack.h") + #define MR_LOG_LEVEL_DEF (DDLogLevel)[MagicalRecord loggingLevel] + #define CAST (DDLogFlag) + #import +#else + #define MR_LOG_LEVEL_DEF [MagicalRecord loggingLevel] + #define LOG_ASYNC_ENABLED YES + #define CAST + #define LOG_MAYBE(async, lvl, flg, ctx, tag, fnct, frmt, ...) \ + do \ + { \ + if ((lvl & flg) == flg) \ + { \ + NSLog(frmt, ##__VA_ARGS__); \ + } \ + } while (0) +#endif + +#define MRLogError(frmt, ...) LOG_MAYBE(NO, MR_LOG_LEVEL_DEF, CAST MagicalRecordLoggingMaskError, MR_LOGGING_CONTEXT, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__) +#define MRLogWarn(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, MR_LOG_LEVEL_DEF, CAST MagicalRecordLoggingMaskWarn, MR_LOGGING_CONTEXT, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__) +#define MRLogInfo(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, MR_LOG_LEVEL_DEF, CAST MagicalRecordLoggingMaskInfo, MR_LOGGING_CONTEXT, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__) +#define MRLogDebug(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, MR_LOG_LEVEL_DEF, CAST MagicalRecordLoggingMaskDebug, MR_LOGGING_CONTEXT, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__) +#define MRLogVerbose(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, MR_LOG_LEVEL_DEF, CAST MagicalRecordLoggingMaskVerbose, MR_LOGGING_CONTEXT, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__) + +#endif diff --git a/MagicalRecord/Core/MagicalRecordShorthand.h b/MagicalRecord/Core/MagicalRecordShorthandMethodAliases.h similarity index 54% rename from MagicalRecord/Core/MagicalRecordShorthand.h rename to MagicalRecord/Core/MagicalRecordShorthandMethodAliases.h index ccac6fe25..934287300 100644 --- a/MagicalRecord/Core/MagicalRecordShorthand.h +++ b/MagicalRecord/Core/MagicalRecordShorthandMethodAliases.h @@ -1,12 +1,9 @@ -#ifdef MR_SHORTHAND - - - - - +#import +#import @interface NSManagedObject (MagicalAggregationShortHand) + + (NSNumber *) numberOfEntities; + (NSNumber *) numberOfEntitiesWithContext:(NSManagedObjectContext *)context; + (NSNumber *) numberOfEntitiesWithPredicate:(NSPredicate *)searchTerm; @@ -17,19 +14,20 @@ + (NSUInteger) countOfEntitiesWithPredicate:(NSPredicate *)searchFilter inContext:(NSManagedObjectContext *)context; + (BOOL) hasAtLeastOneEntity; + (BOOL) hasAtLeastOneEntityInContext:(NSManagedObjectContext *)context; -+ (NSNumber *)aggregateOperation:(NSString *)function onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate inContext:(NSManagedObjectContext *)context; -+ (NSNumber *)aggregateOperation:(NSString *)function onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate; -- (id) objectWithMinValueFor:(NSString *)property; -- (id) objectWithMinValueFor:(NSString *)property inContext:(NSManagedObjectContext *)context; -@end -@interface NSManagedObject (MagicalRecord_DataImportShortHand) -- (BOOL) importValuesForKeysWithObject:(id)objectData; -+ (id) importFromObject:(id)data; -+ (id) importFromObject:(id)data inContext:(NSManagedObjectContext *)context; -+ (NSArray *) importFromArray:(NSArray *)listOfObjectData; -+ (NSArray *) importFromArray:(NSArray *)listOfObjectData inContext:(NSManagedObjectContext *)context; +- (id) minValueFor:(NSString *)property; +- (id) maxValueFor:(NSString *)property; ++ (id) aggregateOperation:(NSString *)function onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate inContext:(NSManagedObjectContext *)context; ++ (id) aggregateOperation:(NSString *)function onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate; ++ (NSArray *) aggregateOperation:(NSString *)collectionOperator onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate groupBy:(NSString*)groupingKeyPath inContext:(NSManagedObjectContext *)context; ++ (NSArray *) aggregateOperation:(NSString *)collectionOperator onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate groupBy:(NSString*)groupingKeyPath; +- (instancetype) objectWithMinValueFor:(NSString *)property; +- (instancetype) objectWithMinValueFor:(NSString *)property inContext:(NSManagedObjectContext *)context; + @end + + @interface NSManagedObject (MagicalFindersShortHand) + + (NSArray *) findAll; + (NSArray *) findAllInContext:(NSManagedObjectContext *)context; + (NSArray *) findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending; @@ -38,62 +36,86 @@ + (NSArray *) findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context; + (NSArray *) findAllWithPredicate:(NSPredicate *)searchTerm; + (NSArray *) findAllWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context; -+ (id) findFirst; -+ (id) findFirstInContext:(NSManagedObjectContext *)context; -+ (id) findFirstWithPredicate:(NSPredicate *)searchTerm; -+ (id) findFirstWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context; -+ (id) findFirstWithPredicate:(NSPredicate *)searchterm sortedBy:(NSString *)property ascending:(BOOL)ascending; -+ (id) findFirstWithPredicate:(NSPredicate *)searchterm sortedBy:(NSString *)property ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context; -+ (id) findFirstWithPredicate:(NSPredicate *)searchTerm andRetrieveAttributes:(NSArray *)attributes; -+ (id) findFirstWithPredicate:(NSPredicate *)searchTerm andRetrieveAttributes:(NSArray *)attributes inContext:(NSManagedObjectContext *)context; -+ (id) findFirstWithPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortBy ascending:(BOOL)ascending andRetrieveAttributes:(id)attributes, ...; -+ (id) findFirstWithPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortBy ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context andRetrieveAttributes:(id)attributes, ...; -+ (id) findFirstByAttribute:(NSString *)attribute withValue:(id)searchValue; -+ (id) findFirstByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context; -+ (id) findFirstOrderedByAttribute:(NSString *)attribute ascending:(BOOL)ascending; -+ (id) findFirstOrderedByAttribute:(NSString *)attribute ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context; ++ (instancetype) findFirst; ++ (instancetype) findFirstInContext:(NSManagedObjectContext *)context; ++ (instancetype) findFirstWithPredicate:(NSPredicate *)searchTerm; ++ (instancetype) findFirstWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context; ++ (instancetype) findFirstWithPredicate:(NSPredicate *)searchterm sortedBy:(NSString *)property ascending:(BOOL)ascending; ++ (instancetype) findFirstWithPredicate:(NSPredicate *)searchterm sortedBy:(NSString *)property ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context; ++ (instancetype) findFirstWithPredicate:(NSPredicate *)searchTerm andRetrieveAttributes:(NSArray *)attributes; ++ (instancetype) findFirstWithPredicate:(NSPredicate *)searchTerm andRetrieveAttributes:(NSArray *)attributes inContext:(NSManagedObjectContext *)context; ++ (instancetype) findFirstWithPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortBy ascending:(BOOL)ascending andRetrieveAttributes:(id)attributes, ...; ++ (instancetype) findFirstWithPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortBy ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context andRetrieveAttributes:(id)attributes, ...; ++ (instancetype) findFirstByAttribute:(NSString *)attribute withValue:(id)searchValue; ++ (instancetype) findFirstByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context; ++ (instancetype) findFirstOrderedByAttribute:(NSString *)attribute ascending:(BOOL)ascending; ++ (instancetype) findFirstOrderedByAttribute:(NSString *)attribute ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context; ++ (instancetype) findFirstOrCreateByAttribute:(NSString *)attribute withValue:(id)searchValue; ++ (instancetype) findFirstOrCreateByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context; + (NSArray *) findByAttribute:(NSString *)attribute withValue:(id)searchValue; + (NSArray *) findByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context; + (NSArray *) findByAttribute:(NSString *)attribute withValue:(id)searchValue andOrderBy:(NSString *)sortTerm ascending:(BOOL)ascending; + (NSArray *) findByAttribute:(NSString *)attribute withValue:(id)searchValue andOrderBy:(NSString *)sortTerm ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context; + #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR + ++ (NSFetchedResultsController *) fetchController:(NSFetchRequest *)request delegate:(id)delegate useFileCache:(BOOL)useFileCache groupedBy:(NSString *)groupKeyPath inContext:(NSManagedObjectContext *)context; + +#endif /* TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR */ + +#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR + + (NSFetchedResultsController *) fetchAllWithDelegate:(id)delegate; + +#endif /* TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR */ + +#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR + + (NSFetchedResultsController *) fetchAllWithDelegate:(id)delegate inContext:(NSManagedObjectContext *)context; + +#endif /* TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR */ + +#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR + + (NSFetchedResultsController *) fetchAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm groupBy:(NSString *)groupingKeyPath delegate:(id)delegate; + +#endif /* TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR */ + +#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR + + (NSFetchedResultsController *) fetchAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm groupBy:(NSString *)groupingKeyPath delegate:(id)delegate inContext:(NSManagedObjectContext *)context; + +#endif /* TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR */ + +#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR + + (NSFetchedResultsController *) fetchAllGroupedBy:(NSString *)group withPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortTerm ascending:(BOOL)ascending; + +#endif /* TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR */ + +#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR + + (NSFetchedResultsController *) fetchAllGroupedBy:(NSString *)group withPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortTerm ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context; + +#endif /* TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR */ + +#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR + + (NSFetchedResultsController *) fetchAllGroupedBy:(NSString *)group withPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortTerm ascending:(BOOL)ascending delegate:(id)delegate; -+ (NSFetchedResultsController *) fetchAllGroupedBy:(NSString *)group withPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortTerm ascending:(BOOL)ascending delegate:(id)delegate inContext:(NSManagedObjectContext *)context; -#endif -@end -@interface NSManagedObject (MagicalRecordShortHand) -+ (NSUInteger) defaultBatchSize; -+ (void) setDefaultBatchSize:(NSUInteger)newBatchSize; -+ (NSArray *) executeFetchRequest:(NSFetchRequest *)request; -+ (NSArray *) executeFetchRequest:(NSFetchRequest *)request inContext:(NSManagedObjectContext *)context; -+ (id) executeFetchRequestAndReturnFirstObject:(NSFetchRequest *)request; -+ (id) executeFetchRequestAndReturnFirstObject:(NSFetchRequest *)request inContext:(NSManagedObjectContext *)context; + +#endif /* TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR */ + #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR -+ (void) performFetch:(NSFetchedResultsController *)controller; -#endif -+ (NSEntityDescription *) entityDescription; -+ (NSEntityDescription *) entityDescriptionInContext:(NSManagedObjectContext *)context; -+ (NSArray *) propertiesNamed:(NSArray *)properties; -+ (id) createEntity; -+ (id) createInContext:(NSManagedObjectContext *)context; -- (BOOL) deleteEntity; -- (BOOL) deleteInContext:(NSManagedObjectContext *)context; -+ (BOOL) deleteAllMatchingPredicate:(NSPredicate *)predicate; -+ (BOOL) deleteAllMatchingPredicate:(NSPredicate *)predicate inContext:(NSManagedObjectContext *)context; -+ (BOOL) truncateAll; -+ (BOOL) truncateAllInContext:(NSManagedObjectContext *)context; -+ (NSArray *) ascendingSortDescriptors:(NSArray *)attributesToSortBy; -+ (NSArray *) descendingSortDescriptors:(NSArray *)attributesToSortBy; -- (id) inContext:(NSManagedObjectContext *)otherContext; -- (id) inThreadContext; + ++ (NSFetchedResultsController *) fetchAllGroupedBy:(NSString *)group withPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortTerm ascending:(BOOL)ascending delegate:(id)delegate inContext:(NSManagedObjectContext *)context; + +#endif /* TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR */ + @end + + @interface NSManagedObject (MagicalRequestsShortHand) + + (NSFetchRequest *) createFetchRequest; + (NSFetchRequest *) createFetchRequestInContext:(NSManagedObjectContext *)context; + (NSFetchRequest *) requestAll; @@ -110,85 +132,142 @@ + (NSFetchRequest *) requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context; + (NSFetchRequest *) requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm; + (NSFetchRequest *) requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context; + @end + + +@interface NSManagedObjectContext (MagicalRecordChainSaveShortHand) + +- (void)saveWithBlock:(void (^)(NSManagedObjectContext *localContext))block; +- (void)saveWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(MRSaveCompletionHandler)completion; +- (void)saveWithBlockAndWait:(void (^)(NSManagedObjectContext *localContext))block; + +@end + + @interface NSManagedObjectContext (MagicalObservingShortHand) + - (void) observeContext:(NSManagedObjectContext *)otherContext; - (void) stopObservingContext:(NSManagedObjectContext *)otherContext; - (void) observeContextOnMainThread:(NSManagedObjectContext *)otherContext; - (void) observeiCloudChangesInCoordinator:(NSPersistentStoreCoordinator *)coordinator; - (void) stopObservingiCloudChangesInCoordinator:(NSPersistentStoreCoordinator *)coordinator; + @end + + @interface NSManagedObjectContext (MagicalRecordShortHand) + + (void) initializeDefaultContextWithCoordinator:(NSPersistentStoreCoordinator *)coordinator; -+ (NSManagedObjectContext *) context NS_RETURNS_RETAINED; -+ (NSManagedObjectContext *) contextWithParent:(NSManagedObjectContext *)parentContext NS_RETURNS_RETAINED; -+ (NSManagedObjectContext *) newMainQueueContext NS_RETURNS_RETAINED; -+ (NSManagedObjectContext *) contextThatPushesChangesToDefaultContext NS_RETURNS_RETAINED; -+ (NSManagedObjectContext *) contextWithStoreCoordinator:(NSPersistentStoreCoordinator *)coordinator NS_RETURNS_RETAINED; -+ (void) resetDefaultContext; + (NSManagedObjectContext *) rootSavingContext; + (NSManagedObjectContext *) defaultContext; -+ (void) cleanUp; ++ (NSManagedObjectContext *) context; ++ (NSManagedObjectContext *) contextWithParent:(NSManagedObjectContext *)parentContext; ++ (NSManagedObjectContext *) contextWithStoreCoordinator:(NSPersistentStoreCoordinator *)coordinator; ++ (NSManagedObjectContext *) newMainQueueContext NS_RETURNS_RETAINED; ++ (NSManagedObjectContext *) newPrivateQueueContext NS_RETURNS_RETAINED; +- (void) setWorkingName:(NSString *)workingName; +- (NSString *) workingName; - (NSString *) description; +- (NSString *) parentChain; ++ (void) resetDefaultContext; +- (void) deleteObjects:(id )objects; + +@end + + +@interface NSManagedObjectContext (MagicalRecordDeprecatedShortHand) + ++ (NSManagedObjectContext *) contextWithoutParent MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("4.0", "MR_newPrivateQueueContext"); ++ (NSManagedObjectContext *) newContext MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("4.0", "MR_context"); ++ (NSManagedObjectContext *) newContextWithParent:(NSManagedObjectContext *)parentContext MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("4.0", "MR_contextWithParent:"); ++ (NSManagedObjectContext *) newContextWithStoreCoordinator:(NSPersistentStoreCoordinator *)coordinator MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("4.0", "MR_contextWithStoreCoordinator:"); + @end -#import "NSManagedObjectContext+MagicalSaves.h" + + @interface NSManagedObjectContext (MagicalSavesShortHand) + - (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)); +- (void) saveWithOptions:(MRSaveOptions)saveOptions completion:(MRSaveCompletionHandler)completion; + @end + + +@interface NSManagedObjectContext (MagicalSavesDeprecatedShortHand) + +- (void) save MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("3.0", "MR_saveToPersistentStoreAndWait"); +- (void) saveWithErrorCallback:(void(^)(NSError *error))errorCallback MR_DEPRECATED_WILL_BE_REMOVED_IN("3.0"); +- (void) saveInBackgroundCompletion:(void (^)(void))completion MR_DEPRECATED_WILL_BE_REMOVED_IN("3.0"); +- (void) saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback MR_DEPRECATED_WILL_BE_REMOVED_IN("3.0"); +- (void) saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion MR_DEPRECATED_WILL_BE_REMOVED_IN("3.0"); +- (void) saveNestedContexts MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("3.0", "MR_saveToPersistentStoreWithCompletion:"); +- (void) saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("3.0", "MR_saveToPersistentStoreWithCompletion:"); +- (void) saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("3.0", "MR_saveToPersistentStoreWithCompletion:"); + +@end + + @interface NSManagedObjectContext (MagicalThreadingShortHand) -+ (NSManagedObjectContext *) contextForCurrentThread; -+ (NSManagedObjectContext *) contextThatNotifiesDefaultContextOnMainThread; -+ (NSManagedObjectContext *) contextThatNotifiesDefaultContextOnMainThreadWithCoordinator:(NSPersistentStoreCoordinator *)coordinator; -+ (void) resetContextForCurrentThread; + ++ (NSManagedObjectContext *) contextForCurrentThread __attribute((deprecated("This method will be removed in MagicalRecord 3.0"))); ++ (void) clearNonMainThreadContextsCache __attribute((deprecated("This method will be removed in MagicalRecord 3.0"))); ++ (void) resetContextForCurrentThread __attribute((deprecated("This method will be removed in MagicalRecord 3.0"))); ++ (void) clearContextForCurrentThread __attribute((deprecated("This method will be removed in MagicalRecord 3.0"))); + @end + + @interface NSManagedObjectModel (MagicalRecordShortHand) + + (NSManagedObjectModel *) defaultManagedObjectModel; + (void) setDefaultManagedObjectModel:(NSManagedObjectModel *)newDefaultModel; + (NSManagedObjectModel *) mergedObjectModelFromMainBundle; + (NSManagedObjectModel *) newManagedObjectModelNamed:(NSString *)modelFileName NS_RETURNS_RETAINED; + (NSManagedObjectModel *) managedObjectModelNamed:(NSString *)modelFileName; + (NSManagedObjectModel *) newModelNamed:(NSString *) modelName inBundleNamed:(NSString *) bundleName NS_RETURNS_RETAINED; ++ (NSManagedObjectModel *) newModelNamed:(NSString *) modelName inBundle:(NSBundle*) bundle NS_RETURNS_RETAINED; + @end + + @interface NSPersistentStore (MagicalRecordShortHand) + + (NSURL *) defaultLocalStoreUrl; + (NSPersistentStore *) defaultPersistentStore; + (void) setDefaultPersistentStore:(NSPersistentStore *) store; + (NSURL *) urlForStoreName:(NSString *)storeFileName; + (NSURL *) cloudURLForUbiqutiousContainer:(NSString *)bucketName; + @end + + @interface NSPersistentStoreCoordinator (MagicalRecordShortHand) + + (NSPersistentStoreCoordinator *) defaultStoreCoordinator; + (void) setDefaultStoreCoordinator:(NSPersistentStoreCoordinator *)coordinator; + (NSPersistentStoreCoordinator *) coordinatorWithInMemoryStore; + (NSPersistentStoreCoordinator *) newPersistentStoreCoordinator NS_RETURNS_RETAINED; + (NSPersistentStoreCoordinator *) coordinatorWithSqliteStoreNamed:(NSString *)storeFileName; + (NSPersistentStoreCoordinator *) coordinatorWithAutoMigratingSqliteStoreNamed:(NSString *)storeFileName; ++ (NSPersistentStoreCoordinator *) coordinatorWithSqliteStoreAtURL:(NSURL *)storeURL; ++ (NSPersistentStoreCoordinator *) coordinatorWithAutoMigratingSqliteStoreAtURL:(NSURL *)storeURL; + (NSPersistentStoreCoordinator *) coordinatorWithPersistentStore:(NSPersistentStore *)persistentStore; + (NSPersistentStoreCoordinator *) coordinatorWithiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)subPathComponent; ++ (NSPersistentStoreCoordinator *) coordinatorWithiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreAtURL:(NSURL *)storeURL cloudStorePathComponent:(NSString *)subPathComponent; + (NSPersistentStoreCoordinator *) coordinatorWithiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)subPathComponent completion:(void(^)(void))completionHandler; ++ (NSPersistentStoreCoordinator *) coordinatorWithiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreAtURL:(NSURL *)storeURL cloudStorePathComponent:(NSString *)subPathComponent completion:(void (^)(void))completionHandler; - (NSPersistentStore *) addInMemoryStore; - (NSPersistentStore *) addAutoMigratingSqliteStoreNamed:(NSString *) storeFileName; +- (NSPersistentStore *) addAutoMigratingSqliteStoreAtURL:(NSURL *)storeURL; - (NSPersistentStore *) addSqliteStoreNamed:(id)storeFileName withOptions:(__autoreleasing NSDictionary *)options; +- (NSPersistentStore *) addSqliteStoreNamed:(id)storeFileName configuration:(NSString *)configuration withOptions:(__autoreleasing NSDictionary *)options; - (void) addiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)subPathComponent; +- (void) addiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreAtURL:(NSURL *)storeURL cloudStorePathComponent:(NSString *)subPathComponent; - (void) addiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)subPathComponent completion:(void(^)(void))completionBlock; -@end - - - - - - -#endif +- (void) addiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreAtURL:(NSURL *)storeURL cloudStorePathComponent:(NSString *)subPathComponent completion:(void (^)(void))completionBlock; +@end diff --git a/MagicalRecord/CoreData+MagicalRecord.h b/MagicalRecord/CoreData+MagicalRecord.h deleted file mode 100644 index 17dd22e6e..000000000 --- a/MagicalRecord/CoreData+MagicalRecord.h +++ /dev/null @@ -1,62 +0,0 @@ - -#ifndef NS_BLOCKS_AVAILABLE - #warning MagicalRecord requires blocks -#endif - -#ifdef __OBJC__ -// #if !( __has_feature(objc_arc) && __has_feature(objc_arc_weak) ) -// #error MagicalRecord now requires ARC to be enabled -// #endif - - #import - #import - - #ifdef MR_SHORTHAND - #import "MagicalRecordShorthand.h" - #endif - - #import "MagicalRecord.h" - #import "MagicalRecord+Actions.h" - #import "MagicalRecord+ErrorHandling.h" - #import "MagicalRecord+Options.h" - #import "MagicalRecord+ShorthandSupport.h" - #import "MagicalRecord+Setup.h" - #import "MagicalRecord+iCloud.h" - - #import "NSManagedObject+MagicalRecord.h" - #import "NSManagedObject+MagicalRequests.h" - #import "NSManagedObject+MagicalFinders.h" - #import "NSManagedObject+MagicalAggregation.h" - #import "NSManagedObjectContext+MagicalRecord.h" - #import "NSManagedObjectContext+MagicalObserving.h" - #import "NSManagedObjectContext+MagicalSaves.h" - #import "NSManagedObjectContext+MagicalThreading.h" - #import "NSPersistentStoreCoordinator+MagicalRecord.h" - #import "NSManagedObjectModel+MagicalRecord.h" - #import "NSPersistentStore+MagicalRecord.h" - - #import "MagicalImportFunctions.h" - #import "NSManagedObject+MagicalDataImport.h" - #import "NSNumber+MagicalDataImport.h" - #import "NSObject+MagicalDataImport.h" - #import "NSString+MagicalDataImport.h" - #import "NSAttributeDescription+MagicalDataImport.h" - #import "NSRelationshipDescription+MagicalDataImport.h" - #import "NSEntityDescription+MagicalDataImport.h" - -#endif - -// @see https://github.com/ccgus/fmdb/commit/aef763eeb64e6fa654e7d121f1df4c16a98d9f4f -#define MRDispatchQueueRelease(q) (dispatch_release(q)) - -#if TARGET_OS_IPHONE - #if __IPHONE_OS_VERSION_MIN_REQUIRED >= 60000 - #undef MRDispatchQueueRelease - #define MRDispatchQueueRelease(q) - #endif -#else - #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 - #undef MRDispatchQueueRelease - #define MRDispatchQueueRelease(q) - #endif -#endif diff --git a/MagicalRecord/MagicalRecord.h b/MagicalRecord/MagicalRecord.h new file mode 100644 index 000000000..0b5fd97d2 --- /dev/null +++ b/MagicalRecord/MagicalRecord.h @@ -0,0 +1,46 @@ +// +// MagicalRecord.h +// +// Created by Saul Mora on 28/07/10. +// Copyright 2010 Magical Panda Software, LLC All rights reserved. +// + +#import +#import + +//! Project version number for MagicalRecord. +FOUNDATION_EXPORT double MagicalRecordVersionNumber; + +//! Project version string for MagicalRecord. +FOUNDATION_EXPORT const unsigned char MagicalRecordVersionString[]; + +#import +#import + +#import +#import +#import +#import +#import + +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import + +#import +#import +#import +#import +#import +#import +#import +#import diff --git a/Project Files/Default-568h@2x.png b/Project Files/Default-568h@2x.png deleted file mode 100644 index 0891b7aab..000000000 Binary files a/Project Files/Default-568h@2x.png and /dev/null differ diff --git a/Project Files/Library/Support/MagicalRecord-OSX-Prefix.pch b/Project Files/Library/Support/MagicalRecord-OSX-Prefix.pch deleted file mode 100644 index f65cc9f99..000000000 --- a/Project Files/Library/Support/MagicalRecord-OSX-Prefix.pch +++ /dev/null @@ -1,7 +0,0 @@ -// -// Prefix header for all source files of the 'MagicalRecordTests' target in the 'MagicalRecordTests' project -// - -#ifdef __OBJC__ - #import -#endif diff --git a/Project Files/Library/Support/MagicalRecord-iOS-Prefix.pch b/Project Files/Library/Support/MagicalRecord-iOS-Prefix.pch deleted file mode 100644 index 275a9cb81..000000000 --- a/Project Files/Library/Support/MagicalRecord-iOS-Prefix.pch +++ /dev/null @@ -1,9 +0,0 @@ -// -// Prefix header for all source files of the 'MagicalRecordTests' target in the 'MagicalRecordTests' project -// - -#ifdef __OBJC__ - #import - #import - #import -#endif diff --git a/Project Files/MagicalRecord.xcodeproj/project.pbxproj b/Project Files/MagicalRecord.xcodeproj/project.pbxproj deleted file mode 100644 index 6dbfbbb7b..000000000 --- a/Project Files/MagicalRecord.xcodeproj/project.pbxproj +++ /dev/null @@ -1,1432 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - C7CF97AC17498414008D9D13 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C721C7E313D0C3A00097AB6F /* Foundation.framework */; }; - C7CF97BC1749843F008D9D13 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 90DD2020167AA4350033BA25 /* Cocoa.framework */; }; - C7CF97C617498493008D9D13 /* MagicalImportFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD729D150F832A00216827 /* MagicalImportFunctions.m */; }; - C7CF97C717498493008D9D13 /* NSEntityDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A1150F832A00216827 /* NSEntityDescription+MagicalDataImport.m */; }; - C7CF97C817498493008D9D13 /* NSAttributeDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD729F150F832A00216827 /* NSAttributeDescription+MagicalDataImport.m */; }; - C7CF97C917498493008D9D13 /* NSRelationshipDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A7150F832A00216827 /* NSRelationshipDescription+MagicalDataImport.m */; }; - C7CF97CA17498493008D9D13 /* NSNumber+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A3150F832A00216827 /* NSNumber+MagicalDataImport.m */; }; - C7CF97CB17498493008D9D13 /* NSObject+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A5150F832A00216827 /* NSObject+MagicalDataImport.m */; }; - C7CF97CC17498493008D9D13 /* NSString+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A9150F832A00216827 /* NSString+MagicalDataImport.m */; }; - C7CF97CD17498493008D9D13 /* NSManagedObject+MagicalAggregation.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72AC150F832A00216827 /* NSManagedObject+MagicalAggregation.m */; }; - C7CF97CE17498493008D9D13 /* NSManagedObject+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72AE150F832A00216827 /* NSManagedObject+MagicalDataImport.m */; }; - C7CF97CF17498493008D9D13 /* NSManagedObject+MagicalFinders.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B0150F832A00216827 /* NSManagedObject+MagicalFinders.m */; }; - C7CF97D017498493008D9D13 /* NSManagedObject+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B2150F832A00216827 /* NSManagedObject+MagicalRecord.m */; }; - C7CF97D117498493008D9D13 /* NSManagedObject+MagicalRequests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B4150F832A00216827 /* NSManagedObject+MagicalRequests.m */; }; - C7CF97D217498493008D9D13 /* NSManagedObjectContext+MagicalObserving.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B7150F832A00216827 /* NSManagedObjectContext+MagicalObserving.m */; }; - C7CF97D317498493008D9D13 /* NSManagedObjectContext+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B9150F832A00216827 /* NSManagedObjectContext+MagicalRecord.m */; }; - C7CF97D417498493008D9D13 /* NSManagedObjectContext+MagicalSaves.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72BB150F832A00216827 /* NSManagedObjectContext+MagicalSaves.m */; }; - C7CF97D517498493008D9D13 /* NSManagedObjectContext+MagicalThreading.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72BD150F832A00216827 /* NSManagedObjectContext+MagicalThreading.m */; }; - C7CF97D617498493008D9D13 /* NSManagedObjectModel+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72BF150F832A00216827 /* NSManagedObjectModel+MagicalRecord.m */; }; - C7CF97D717498493008D9D13 /* NSPersistentStore+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C1150F832A00216827 /* NSPersistentStore+MagicalRecord.m */; }; - C7CF97D817498493008D9D13 /* NSPersistentStoreCoordinator+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C3150F832A00216827 /* NSPersistentStoreCoordinator+MagicalRecord.m */; }; - C7CF97D917498493008D9D13 /* MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72D2150F832A00216827 /* MagicalRecord.m */; }; - C7CF97DA17498493008D9D13 /* MagicalRecord+Actions.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C6150F832A00216827 /* MagicalRecord+Actions.m */; }; - C7CF97DB17498493008D9D13 /* MagicalRecord+ErrorHandling.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C8150F832A00216827 /* MagicalRecord+ErrorHandling.m */; }; - C7CF97DC17498493008D9D13 /* MagicalRecord+iCloud.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72CA150F832A00216827 /* MagicalRecord+iCloud.m */; }; - C7CF97DD17498493008D9D13 /* MagicalRecord+Options.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72CC150F832A00216827 /* MagicalRecord+Options.m */; }; - C7CF97DE17498493008D9D13 /* MagicalRecord+Setup.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72CE150F832A00216827 /* MagicalRecord+Setup.m */; }; - C7CF97DF17498493008D9D13 /* MagicalRecord+ShorthandSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72D0150F832A00216827 /* MagicalRecord+ShorthandSupport.m */; }; - C7CF97E0174984A5008D9D13 /* MagicalImportFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD729D150F832A00216827 /* MagicalImportFunctions.m */; }; - C7CF97E1174984A5008D9D13 /* NSEntityDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A1150F832A00216827 /* NSEntityDescription+MagicalDataImport.m */; }; - C7CF97E2174984A5008D9D13 /* NSAttributeDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD729F150F832A00216827 /* NSAttributeDescription+MagicalDataImport.m */; }; - C7CF97E3174984A5008D9D13 /* NSRelationshipDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A7150F832A00216827 /* NSRelationshipDescription+MagicalDataImport.m */; }; - C7CF97E4174984A5008D9D13 /* NSNumber+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A3150F832A00216827 /* NSNumber+MagicalDataImport.m */; }; - C7CF97E5174984A5008D9D13 /* NSObject+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A5150F832A00216827 /* NSObject+MagicalDataImport.m */; }; - C7CF97E6174984A5008D9D13 /* NSString+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A9150F832A00216827 /* NSString+MagicalDataImport.m */; }; - C7CF97E7174984A5008D9D13 /* NSManagedObject+MagicalAggregation.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72AC150F832A00216827 /* NSManagedObject+MagicalAggregation.m */; }; - C7CF97E8174984A5008D9D13 /* NSManagedObject+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72AE150F832A00216827 /* NSManagedObject+MagicalDataImport.m */; }; - C7CF97E9174984A5008D9D13 /* NSManagedObject+MagicalFinders.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B0150F832A00216827 /* NSManagedObject+MagicalFinders.m */; }; - C7CF97EA174984A5008D9D13 /* NSManagedObject+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B2150F832A00216827 /* NSManagedObject+MagicalRecord.m */; }; - C7CF97EB174984A5008D9D13 /* NSManagedObject+MagicalRequests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B4150F832A00216827 /* NSManagedObject+MagicalRequests.m */; }; - C7CF97EC174984A5008D9D13 /* NSManagedObjectContext+MagicalObserving.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B7150F832A00216827 /* NSManagedObjectContext+MagicalObserving.m */; }; - C7CF97ED174984A5008D9D13 /* NSManagedObjectContext+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B9150F832A00216827 /* NSManagedObjectContext+MagicalRecord.m */; }; - C7CF97EE174984A5008D9D13 /* NSManagedObjectContext+MagicalSaves.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72BB150F832A00216827 /* NSManagedObjectContext+MagicalSaves.m */; }; - C7CF97EF174984A5008D9D13 /* NSManagedObjectContext+MagicalThreading.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72BD150F832A00216827 /* NSManagedObjectContext+MagicalThreading.m */; }; - C7CF97F0174984A5008D9D13 /* NSManagedObjectModel+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72BF150F832A00216827 /* NSManagedObjectModel+MagicalRecord.m */; }; - C7CF97F1174984A5008D9D13 /* NSPersistentStore+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C1150F832A00216827 /* NSPersistentStore+MagicalRecord.m */; }; - C7CF97F2174984A5008D9D13 /* NSPersistentStoreCoordinator+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C3150F832A00216827 /* NSPersistentStoreCoordinator+MagicalRecord.m */; }; - C7CF97F3174984A5008D9D13 /* MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72D2150F832A00216827 /* MagicalRecord.m */; }; - C7CF97F4174984A5008D9D13 /* MagicalRecord+Actions.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C6150F832A00216827 /* MagicalRecord+Actions.m */; }; - C7CF97F5174984A5008D9D13 /* MagicalRecord+ErrorHandling.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C8150F832A00216827 /* MagicalRecord+ErrorHandling.m */; }; - C7CF97F6174984A5008D9D13 /* MagicalRecord+iCloud.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72CA150F832A00216827 /* MagicalRecord+iCloud.m */; }; - C7CF97F7174984A5008D9D13 /* MagicalRecord+Options.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72CC150F832A00216827 /* MagicalRecord+Options.m */; }; - C7CF97F8174984A5008D9D13 /* MagicalRecord+Setup.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72CE150F832A00216827 /* MagicalRecord+Setup.m */; }; - C7CF97F9174984A5008D9D13 /* MagicalRecord+ShorthandSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72D0150F832A00216827 /* MagicalRecord+ShorthandSupport.m */; }; - C7CF9800174984CA008D9D13 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 90DD201E167AA4350033BA25 /* SenTestingKit.framework */; }; - C7CF9802174984CA008D9D13 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C7CF9801174984CA008D9D13 /* UIKit.framework */; }; - C7CF9803174984CA008D9D13 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C721C7E313D0C3A00097AB6F /* Foundation.framework */; }; - C7CF9817174984E4008D9D13 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 90DD201E167AA4350033BA25 /* SenTestingKit.framework */; }; - C7CF9818174984E4008D9D13 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 90DD2020167AA4350033BA25 /* Cocoa.framework */; }; - C7CF9975174985FF008D9D13 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9827174985FC008D9D13 /* InfoPlist.strings */; }; - C7CF9976174985FF008D9D13 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9827174985FC008D9D13 /* InfoPlist.strings */; }; - C7CF9AE6174986B5008D9D13 /* MagicalRecord-OSX-Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = C7CF9AE4174986B5008D9D13 /* MagicalRecord-OSX-Prefix.pch */; }; - C7CF9AE917498739008D9D13 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C7CF9AE817498739008D9D13 /* CoreData.framework */; }; - C7CF9AF717498811008D9D13 /* libKiwi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C7CF9AF217498803008D9D13 /* libKiwi.a */; }; - C7CF9AF817498819008D9D13 /* libKiwi-OSX.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C7CF9AF417498803008D9D13 /* libKiwi-OSX.a */; }; - C7CF9B09174988EA008D9D13 /* libExpecta-iOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C7CF9B03174988D0008D9D13 /* libExpecta-iOS.a */; }; - C7CF9B0A1749894D008D9D13 /* MagicalImportFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD729D150F832A00216827 /* MagicalImportFunctions.m */; }; - C7CF9B0B1749894D008D9D13 /* NSEntityDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A1150F832A00216827 /* NSEntityDescription+MagicalDataImport.m */; }; - C7CF9B0C1749894D008D9D13 /* NSAttributeDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD729F150F832A00216827 /* NSAttributeDescription+MagicalDataImport.m */; }; - C7CF9B0D1749894D008D9D13 /* NSRelationshipDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A7150F832A00216827 /* NSRelationshipDescription+MagicalDataImport.m */; }; - C7CF9B0E1749894D008D9D13 /* NSNumber+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A3150F832A00216827 /* NSNumber+MagicalDataImport.m */; }; - C7CF9B0F1749894D008D9D13 /* NSObject+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A5150F832A00216827 /* NSObject+MagicalDataImport.m */; }; - C7CF9B101749894D008D9D13 /* NSString+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72A9150F832A00216827 /* NSString+MagicalDataImport.m */; }; - C7CF9B111749894D008D9D13 /* NSManagedObject+MagicalAggregation.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72AC150F832A00216827 /* NSManagedObject+MagicalAggregation.m */; }; - C7CF9B121749894D008D9D13 /* NSManagedObject+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72AE150F832A00216827 /* NSManagedObject+MagicalDataImport.m */; }; - C7CF9B131749894D008D9D13 /* NSManagedObject+MagicalFinders.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B0150F832A00216827 /* NSManagedObject+MagicalFinders.m */; }; - C7CF9B141749894D008D9D13 /* NSManagedObject+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B2150F832A00216827 /* NSManagedObject+MagicalRecord.m */; }; - C7CF9B151749894D008D9D13 /* NSManagedObject+MagicalRequests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B4150F832A00216827 /* NSManagedObject+MagicalRequests.m */; }; - C7CF9B161749894D008D9D13 /* NSManagedObjectContext+MagicalObserving.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B7150F832A00216827 /* NSManagedObjectContext+MagicalObserving.m */; }; - C7CF9B171749894D008D9D13 /* NSManagedObjectContext+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72B9150F832A00216827 /* NSManagedObjectContext+MagicalRecord.m */; }; - C7CF9B181749894D008D9D13 /* NSManagedObjectContext+MagicalSaves.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72BB150F832A00216827 /* NSManagedObjectContext+MagicalSaves.m */; }; - C7CF9B191749894D008D9D13 /* NSManagedObjectContext+MagicalThreading.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72BD150F832A00216827 /* NSManagedObjectContext+MagicalThreading.m */; }; - C7CF9B1A1749894D008D9D13 /* NSManagedObjectModel+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72BF150F832A00216827 /* NSManagedObjectModel+MagicalRecord.m */; }; - C7CF9B1B1749894D008D9D13 /* NSPersistentStore+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C1150F832A00216827 /* NSPersistentStore+MagicalRecord.m */; }; - C7CF9B1C1749894D008D9D13 /* NSPersistentStoreCoordinator+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C3150F832A00216827 /* NSPersistentStoreCoordinator+MagicalRecord.m */; }; - C7CF9B1D1749894D008D9D13 /* MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72D2150F832A00216827 /* MagicalRecord.m */; }; - C7CF9B1E1749894D008D9D13 /* MagicalRecord+Actions.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C6150F832A00216827 /* MagicalRecord+Actions.m */; }; - C7CF9B1F1749894D008D9D13 /* MagicalRecord+ErrorHandling.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72C8150F832A00216827 /* MagicalRecord+ErrorHandling.m */; }; - C7CF9B201749894D008D9D13 /* MagicalRecord+iCloud.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72CA150F832A00216827 /* MagicalRecord+iCloud.m */; }; - C7CF9B211749894D008D9D13 /* MagicalRecord+Options.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72CC150F832A00216827 /* MagicalRecord+Options.m */; }; - C7CF9B221749894D008D9D13 /* MagicalRecord+Setup.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72CE150F832A00216827 /* MagicalRecord+Setup.m */; }; - C7CF9B231749894D008D9D13 /* MagicalRecord+ShorthandSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7DD72D0150F832A00216827 /* MagicalRecord+ShorthandSupport.m */; }; - C7CF9B2417498962008D9D13 /* MagicalRecordTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF976817498275008D9D13 /* MagicalRecordTests.m */; }; - C7CF9B2517498962008D9D13 /* NSManagedObjectContextHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF976A17498275008D9D13 /* NSManagedObjectContextHelperTests.m */; }; - C7CF9B2617498962008D9D13 /* NSManagedObjectHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF976C17498275008D9D13 /* NSManagedObjectHelperTests.m */; }; - C7CF9B2717498962008D9D13 /* NSManagedObjectModelHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF976E17498275008D9D13 /* NSManagedObjectModelHelperTests.m */; }; - C7CF9B2817498962008D9D13 /* NSPersisentStoreHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF977017498275008D9D13 /* NSPersisentStoreHelperTests.m */; }; - C7CF9B2917498962008D9D13 /* NSPersistentStoreCoordinatorHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF977217498275008D9D13 /* NSPersistentStoreCoordinatorHelperTests.m */; }; - C7CF9B2A17498962008D9D13 /* ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9786174982AD008D9D13 /* ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m */; }; - C7CF9B2B17498962008D9D13 /* ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9787174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m */; }; - C7CF9B2C17498962008D9D13 /* ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9788174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m */; }; - C7CF9B2D17498962008D9D13 /* ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9789174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m */; }; - C7CF9B2E17498962008D9D13 /* ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF978A174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m */; }; - C7CF9B2F17498962008D9D13 /* ImportSingleEntityWithNoRelationshipsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF978B174982AD008D9D13 /* ImportSingleEntityWithNoRelationshipsTests.m */; }; - C7CF9B3017498962008D9D13 /* ImportSingleRelatedEntityTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF978C174982AD008D9D13 /* ImportSingleRelatedEntityTests.m */; }; - C7CF9B3117498962008D9D13 /* MagicalDataImportTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF978E174982AD008D9D13 /* MagicalDataImportTestCase.m */; }; - C7CF9B5317498985008D9D13 /* SampleJSONDataForImport.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4917498985008D9D13 /* SampleJSONDataForImport.json */; }; - C7CF9B5417498985008D9D13 /* SampleJSONDataForImport.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4917498985008D9D13 /* SampleJSONDataForImport.json */; }; - C7CF9B5517498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4A17498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json */; }; - C7CF9B5617498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4A17498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json */; }; - C7CF9B5717498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4B17498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json */; }; - C7CF9B5817498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4B17498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json */; }; - C7CF9B5917498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingDefaults.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4C17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingDefaults.json */; }; - C7CF9B5A17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingDefaults.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4C17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingDefaults.json */; }; - C7CF9B5B17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4D17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json */; }; - C7CF9B5C17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4D17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json */; }; - C7CF9B5D17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4E17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json */; }; - C7CF9B5E17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4E17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json */; }; - C7CF9B5F17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4F17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.json */; }; - C7CF9B6017498985008D9D13 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B4F17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.json */; }; - C7CF9B6117498985008D9D13 /* SingleEntityWithNoRelationships.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B5017498985008D9D13 /* SingleEntityWithNoRelationships.json */; }; - C7CF9B6217498985008D9D13 /* SingleEntityWithNoRelationships.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B5017498985008D9D13 /* SingleEntityWithNoRelationships.json */; }; - C7CF9B6317498986008D9D13 /* SingleEntityWithNoRelationships.plist in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B5117498985008D9D13 /* SingleEntityWithNoRelationships.plist */; }; - C7CF9B6417498986008D9D13 /* SingleEntityWithNoRelationships.plist in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B5117498985008D9D13 /* SingleEntityWithNoRelationships.plist */; }; - C7CF9B6517498986008D9D13 /* SingleRelatedEntity.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B5217498985008D9D13 /* SingleRelatedEntity.json */; }; - C7CF9B6617498986008D9D13 /* SingleRelatedEntity.json in Resources */ = {isa = PBXBuildFile; fileRef = C7CF9B5217498985008D9D13 /* SingleRelatedEntity.json */; }; - C7CF9B6D17498B5C008D9D13 /* FixtureHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9B6C17498B5C008D9D13 /* FixtureHelpers.m */; }; - C7CF9B6E17498B5C008D9D13 /* FixtureHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9B6C17498B5C008D9D13 /* FixtureHelpers.m */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - C7CF9AF117498803008D9D13 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = C7CF9AEA17498803008D9D13 /* Kiwi.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = F5015B9F11583A77002E9A98; - remoteInfo = Kiwi; - }; - C7CF9AF317498803008D9D13 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = C7CF9AEA17498803008D9D13 /* Kiwi.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 832C83C7157263B300F160D5; - remoteInfo = "Kiwi-OSX"; - }; - C7CF9AF517498803008D9D13 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = C7CF9AEA17498803008D9D13 /* Kiwi.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = F5015C9E11584017002E9A98; - remoteInfo = KiwiTests; - }; - C7CF9B00174988D0008D9D13 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = C7CF9AF9174988CF008D9D13 /* Expecta.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = E9ACDF0C13B2DD520010F4D7; - remoteInfo = Expecta; - }; - C7CF9B02174988D0008D9D13 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = C7CF9AF9174988CF008D9D13 /* Expecta.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = E93067CE13B2E6D100EA26FF; - remoteInfo = "Expecta-iOS"; - }; - C7CF9B04174988D0008D9D13 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = C7CF9AF9174988CF008D9D13 /* Expecta.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = E9ACDF1D13B2DD520010F4D7; - remoteInfo = ExpectaTests; - }; - C7CF9B06174988D0008D9D13 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = C7CF9AF9174988CF008D9D13 /* Expecta.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = E93067DA13B2E6D100EA26FF; - remoteInfo = "Expecta-iOSTests"; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - C7CF97A917498414008D9D13 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "include/${PRODUCT_NAME}"; - dstSubfolderSpec = 16; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 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; }; - C721C7E213D0C3A00097AB6F /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; - C721C7E313D0C3A00097AB6F /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - C75C7D69147220D300D0C2FE /* generateShorthandFile.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = generateShorthandFile.rb; sourceTree = ""; }; - C7CF963C174963D0008D9D13 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; - C7CF976717498275008D9D13 /* MagicalRecordTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MagicalRecordTests.h; sourceTree = ""; }; - C7CF976817498275008D9D13 /* MagicalRecordTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MagicalRecordTests.m; sourceTree = ""; }; - C7CF976917498275008D9D13 /* NSManagedObjectContextHelperTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSManagedObjectContextHelperTests.h; sourceTree = ""; }; - C7CF976A17498275008D9D13 /* NSManagedObjectContextHelperTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSManagedObjectContextHelperTests.m; sourceTree = ""; }; - C7CF976B17498275008D9D13 /* NSManagedObjectHelperTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSManagedObjectHelperTests.h; sourceTree = ""; }; - C7CF976C17498275008D9D13 /* NSManagedObjectHelperTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSManagedObjectHelperTests.m; sourceTree = ""; }; - C7CF976D17498275008D9D13 /* NSManagedObjectModelHelperTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSManagedObjectModelHelperTests.h; sourceTree = ""; }; - C7CF976E17498275008D9D13 /* NSManagedObjectModelHelperTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSManagedObjectModelHelperTests.m; sourceTree = ""; }; - C7CF976F17498275008D9D13 /* NSPersisentStoreHelperTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSPersisentStoreHelperTests.h; sourceTree = ""; }; - C7CF977017498275008D9D13 /* NSPersisentStoreHelperTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSPersisentStoreHelperTests.m; sourceTree = ""; }; - C7CF977117498275008D9D13 /* NSPersistentStoreCoordinatorHelperTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSPersistentStoreCoordinatorHelperTests.h; sourceTree = ""; }; - C7CF977217498275008D9D13 /* NSPersistentStoreCoordinatorHelperTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSPersistentStoreCoordinatorHelperTests.m; sourceTree = ""; }; - C7CF9786174982AD008D9D13 /* ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m; sourceTree = ""; }; - C7CF9787174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m; sourceTree = ""; }; - C7CF9788174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m; sourceTree = ""; }; - C7CF9789174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m; sourceTree = ""; }; - C7CF978A174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m; sourceTree = ""; }; - C7CF978B174982AD008D9D13 /* ImportSingleEntityWithNoRelationshipsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImportSingleEntityWithNoRelationshipsTests.m; sourceTree = ""; }; - C7CF978C174982AD008D9D13 /* ImportSingleRelatedEntityTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImportSingleRelatedEntityTests.m; sourceTree = ""; }; - C7CF978D174982AD008D9D13 /* MagicalDataImportTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MagicalDataImportTestCase.h; sourceTree = ""; }; - C7CF978E174982AD008D9D13 /* MagicalDataImportTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MagicalDataImportTestCase.m; sourceTree = ""; }; - C7CF97AB17498414008D9D13 /* libMagicalRecord-iOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libMagicalRecord-iOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - C7CF97BB1749843F008D9D13 /* libMagicalRecord-OSX.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = "libMagicalRecord-OSX.dylib"; sourceTree = BUILT_PRODUCTS_DIR; }; - C7CF97FF174984CA008D9D13 /* MagicalRecordTests-iOS.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "MagicalRecordTests-iOS.octest"; sourceTree = BUILT_PRODUCTS_DIR; }; - C7CF9801174984CA008D9D13 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; - C7CF9816174984E4008D9D13 /* MagicalRecordTests-OSX.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "MagicalRecordTests-OSX.octest"; sourceTree = BUILT_PRODUCTS_DIR; }; - C7CF9828174985FC008D9D13 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; - C7CF9ADF17498650008D9D13 /* MagicalRecordTests-iOS-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecordTests-iOS-Prefix.pch"; sourceTree = ""; }; - C7CF9AE017498650008D9D13 /* MagicalRecordTests-OSX-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecordTests-OSX-Prefix.pch"; sourceTree = ""; }; - C7CF9AE3174986B5008D9D13 /* MagicalRecord-iOS-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord-iOS-Prefix.pch"; sourceTree = ""; }; - C7CF9AE4174986B5008D9D13 /* MagicalRecord-OSX-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord-OSX-Prefix.pch"; sourceTree = ""; }; - C7CF9AE817498739008D9D13 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk/System/Library/Frameworks/CoreData.framework; sourceTree = DEVELOPER_DIR; }; - C7CF9AEA17498803008D9D13 /* Kiwi.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Kiwi.xcodeproj; path = Kiwi/Kiwi.xcodeproj; sourceTree = ""; }; - C7CF9AF9174988CF008D9D13 /* Expecta.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Expecta.xcodeproj; path = Expecta/Expecta.xcodeproj; sourceTree = ""; }; - C7CF9B4917498985008D9D13 /* SampleJSONDataForImport.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = SampleJSONDataForImport.json; path = Fixtures/SampleJSONDataForImport.json; sourceTree = ""; }; - C7CF9B4A17498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json; path = Fixtures/SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json; sourceTree = ""; }; - C7CF9B4B17498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json; path = Fixtures/SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json; sourceTree = ""; }; - C7CF9B4C17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingDefaults.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = SingleEntityRelatedToMappedEntityUsingDefaults.json; path = Fixtures/SingleEntityRelatedToMappedEntityUsingDefaults.json; sourceTree = ""; }; - C7CF9B4D17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json; path = Fixtures/SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json; sourceTree = ""; }; - C7CF9B4E17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json; path = Fixtures/SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json; sourceTree = ""; }; - C7CF9B4F17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = SingleEntityRelatedToMappedEntityWithSecondaryMappings.json; path = Fixtures/SingleEntityRelatedToMappedEntityWithSecondaryMappings.json; sourceTree = ""; }; - C7CF9B5017498985008D9D13 /* SingleEntityWithNoRelationships.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = SingleEntityWithNoRelationships.json; path = Fixtures/SingleEntityWithNoRelationships.json; sourceTree = ""; }; - C7CF9B5117498985008D9D13 /* SingleEntityWithNoRelationships.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = SingleEntityWithNoRelationships.plist; path = Fixtures/SingleEntityWithNoRelationships.plist; sourceTree = ""; }; - C7CF9B5217498985008D9D13 /* SingleRelatedEntity.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = SingleRelatedEntity.json; path = Fixtures/SingleRelatedEntity.json; sourceTree = ""; }; - C7CF9B6B17498B5C008D9D13 /* FixtureHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FixtureHelpers.h; path = Fixtures/FixtureHelpers.h; sourceTree = ""; }; - C7CF9B6C17498B5C008D9D13 /* FixtureHelpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FixtureHelpers.m; path = Fixtures/FixtureHelpers.m; sourceTree = ""; }; - C7CF9B6F17498B83008D9D13 /* MagicalRecordTests-iOS-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "MagicalRecordTests-iOS-Info.plist"; sourceTree = ""; }; - C7CF9B7017498B83008D9D13 /* MagicalRecordTests-OSX-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "MagicalRecordTests-OSX-Info.plist"; sourceTree = ""; }; - C7DD729C150F832A00216827 /* MagicalImportFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MagicalImportFunctions.h; sourceTree = ""; }; - C7DD729D150F832A00216827 /* MagicalImportFunctions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MagicalImportFunctions.m; sourceTree = ""; }; - C7DD729E150F832A00216827 /* NSAttributeDescription+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSAttributeDescription+MagicalDataImport.h"; sourceTree = ""; }; - C7DD729F150F832A00216827 /* NSAttributeDescription+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSAttributeDescription+MagicalDataImport.m"; sourceTree = ""; }; - C7DD72A0150F832A00216827 /* NSEntityDescription+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSEntityDescription+MagicalDataImport.h"; sourceTree = ""; }; - C7DD72A1150F832A00216827 /* NSEntityDescription+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSEntityDescription+MagicalDataImport.m"; sourceTree = ""; }; - C7DD72A2150F832A00216827 /* NSNumber+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSNumber+MagicalDataImport.h"; sourceTree = ""; }; - C7DD72A3150F832A00216827 /* NSNumber+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSNumber+MagicalDataImport.m"; sourceTree = ""; }; - C7DD72A4150F832A00216827 /* NSObject+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+MagicalDataImport.h"; sourceTree = ""; }; - C7DD72A5150F832A00216827 /* NSObject+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+MagicalDataImport.m"; sourceTree = ""; }; - C7DD72A6150F832A00216827 /* NSRelationshipDescription+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSRelationshipDescription+MagicalDataImport.h"; sourceTree = ""; }; - C7DD72A7150F832A00216827 /* NSRelationshipDescription+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSRelationshipDescription+MagicalDataImport.m"; sourceTree = ""; }; - C7DD72A8150F832A00216827 /* NSString+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+MagicalDataImport.h"; sourceTree = ""; }; - C7DD72A9150F832A00216827 /* NSString+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+MagicalDataImport.m"; sourceTree = ""; }; - C7DD72AB150F832A00216827 /* NSManagedObject+MagicalAggregation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+MagicalAggregation.h"; sourceTree = ""; }; - C7DD72AC150F832A00216827 /* NSManagedObject+MagicalAggregation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+MagicalAggregation.m"; sourceTree = ""; }; - C7DD72AD150F832A00216827 /* NSManagedObject+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+MagicalDataImport.h"; sourceTree = ""; }; - C7DD72AE150F832A00216827 /* NSManagedObject+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+MagicalDataImport.m"; sourceTree = ""; }; - C7DD72AF150F832A00216827 /* NSManagedObject+MagicalFinders.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+MagicalFinders.h"; sourceTree = ""; }; - C7DD72B0150F832A00216827 /* NSManagedObject+MagicalFinders.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+MagicalFinders.m"; sourceTree = ""; }; - C7DD72B1150F832A00216827 /* NSManagedObject+MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+MagicalRecord.h"; sourceTree = ""; }; - C7DD72B2150F832A00216827 /* NSManagedObject+MagicalRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+MagicalRecord.m"; sourceTree = ""; }; - C7DD72B3150F832A00216827 /* NSManagedObject+MagicalRequests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+MagicalRequests.h"; sourceTree = ""; }; - C7DD72B4150F832A00216827 /* NSManagedObject+MagicalRequests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+MagicalRequests.m"; sourceTree = ""; }; - C7DD72B6150F832A00216827 /* NSManagedObjectContext+MagicalObserving.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObjectContext+MagicalObserving.h"; sourceTree = ""; }; - C7DD72B7150F832A00216827 /* NSManagedObjectContext+MagicalObserving.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectContext+MagicalObserving.m"; sourceTree = ""; }; - C7DD72B8150F832A00216827 /* NSManagedObjectContext+MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObjectContext+MagicalRecord.h"; sourceTree = ""; }; - C7DD72B9150F832A00216827 /* NSManagedObjectContext+MagicalRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectContext+MagicalRecord.m"; sourceTree = ""; }; - C7DD72BA150F832A00216827 /* NSManagedObjectContext+MagicalSaves.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObjectContext+MagicalSaves.h"; sourceTree = ""; }; - C7DD72BB150F832A00216827 /* NSManagedObjectContext+MagicalSaves.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectContext+MagicalSaves.m"; sourceTree = ""; }; - C7DD72BC150F832A00216827 /* NSManagedObjectContext+MagicalThreading.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObjectContext+MagicalThreading.h"; sourceTree = ""; }; - C7DD72BD150F832A00216827 /* NSManagedObjectContext+MagicalThreading.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectContext+MagicalThreading.m"; sourceTree = ""; }; - C7DD72BE150F832A00216827 /* NSManagedObjectModel+MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObjectModel+MagicalRecord.h"; sourceTree = ""; }; - C7DD72BF150F832A00216827 /* NSManagedObjectModel+MagicalRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectModel+MagicalRecord.m"; sourceTree = ""; }; - C7DD72C0150F832A00216827 /* NSPersistentStore+MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSPersistentStore+MagicalRecord.h"; sourceTree = ""; }; - C7DD72C1150F832A00216827 /* NSPersistentStore+MagicalRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSPersistentStore+MagicalRecord.m"; sourceTree = ""; }; - C7DD72C2150F832A00216827 /* NSPersistentStoreCoordinator+MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSPersistentStoreCoordinator+MagicalRecord.h"; sourceTree = ""; }; - C7DD72C3150F832A00216827 /* NSPersistentStoreCoordinator+MagicalRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSPersistentStoreCoordinator+MagicalRecord.m"; sourceTree = ""; }; - C7DD72C5150F832A00216827 /* MagicalRecord+Actions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord+Actions.h"; sourceTree = ""; }; - C7DD72C6150F832A00216827 /* MagicalRecord+Actions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+Actions.m"; sourceTree = ""; }; - C7DD72C7150F832A00216827 /* MagicalRecord+ErrorHandling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord+ErrorHandling.h"; sourceTree = ""; }; - C7DD72C8150F832A00216827 /* MagicalRecord+ErrorHandling.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+ErrorHandling.m"; sourceTree = ""; }; - C7DD72C9150F832A00216827 /* MagicalRecord+iCloud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord+iCloud.h"; sourceTree = ""; }; - C7DD72CA150F832A00216827 /* MagicalRecord+iCloud.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+iCloud.m"; sourceTree = ""; }; - C7DD72CB150F832A00216827 /* MagicalRecord+Options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord+Options.h"; sourceTree = ""; }; - C7DD72CC150F832A00216827 /* MagicalRecord+Options.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+Options.m"; sourceTree = ""; }; - C7DD72CD150F832A00216827 /* MagicalRecord+Setup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord+Setup.h"; sourceTree = ""; }; - C7DD72CE150F832A00216827 /* MagicalRecord+Setup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+Setup.m"; sourceTree = ""; }; - C7DD72CF150F832A00216827 /* MagicalRecord+ShorthandSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord+ShorthandSupport.h"; sourceTree = ""; }; - C7DD72D0150F832A00216827 /* MagicalRecord+ShorthandSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+ShorthandSupport.m"; sourceTree = ""; }; - C7DD72D1150F832A00216827 /* MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MagicalRecord.h; sourceTree = ""; }; - C7DD72D2150F832A00216827 /* MagicalRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MagicalRecord.m; sourceTree = ""; }; - C7DD72D3150F832A00216827 /* MagicalRecordShorthand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MagicalRecordShorthand.h; sourceTree = ""; }; - C7DD72D4150F832A00216827 /* CoreData+MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CoreData+MagicalRecord.h"; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - C7CF97A817498414008D9D13 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - C7CF9AE917498739008D9D13 /* CoreData.framework in Frameworks */, - C7CF97AC17498414008D9D13 /* Foundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - C7CF97B81749843F008D9D13 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - C7CF97BC1749843F008D9D13 /* Cocoa.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - C7CF97FB174984CA008D9D13 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - C7CF9800174984CA008D9D13 /* SenTestingKit.framework in Frameworks */, - C7CF9802174984CA008D9D13 /* UIKit.framework in Frameworks */, - C7CF9AF717498811008D9D13 /* libKiwi.a in Frameworks */, - C7CF9B09174988EA008D9D13 /* libExpecta-iOS.a in Frameworks */, - C7CF9803174984CA008D9D13 /* Foundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - C7CF9812174984E4008D9D13 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - C7CF9817174984E4008D9D13 /* SenTestingKit.framework in Frameworks */, - C7CF9818174984E4008D9D13 /* Cocoa.framework in Frameworks */, - C7CF9AF817498819008D9D13 /* libKiwi-OSX.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 90DD2022167AA4350033BA25 /* Other Frameworks */ = { - isa = PBXGroup; - children = ( - 90DD2023167AA4350033BA25 /* AppKit.framework */, - 90DD2024167AA4350033BA25 /* CoreData.framework */, - 90DD2025167AA4350033BA25 /* Foundation.framework */, - ); - name = "Other Frameworks"; - sourceTree = ""; - }; - C721C7A013D0A3750097AB6F = { - isa = PBXGroup; - children = ( - C7CF963C174963D0008D9D13 /* Default-568h@2x.png */, - C75C7D69147220D300D0C2FE /* generateShorthandFile.rb */, - C7CF9AE11749867D008D9D13 /* Library */, - C7DD7299150F832A00216827 /* MagicalRecord */, - C77E5FA513D0CBA600298F87 /* Tests */, - C721C7B313D0A3AF0097AB6F /* Frameworks */, - C721C7B113D0A3AF0097AB6F /* Products */, - ); - sourceTree = ""; - }; - C721C7B113D0A3AF0097AB6F /* Products */ = { - isa = PBXGroup; - children = ( - C7CF97AB17498414008D9D13 /* libMagicalRecord-iOS.a */, - C7CF97BB1749843F008D9D13 /* libMagicalRecord-OSX.dylib */, - C7CF97FF174984CA008D9D13 /* MagicalRecordTests-iOS.octest */, - C7CF9816174984E4008D9D13 /* MagicalRecordTests-OSX.octest */, - ); - name = Products; - sourceTree = ""; - }; - C721C7B313D0A3AF0097AB6F /* Frameworks */ = { - isa = PBXGroup; - children = ( - C721C7E313D0C3A00097AB6F /* Foundation.framework */, - C721C7E213D0C3A00097AB6F /* CoreData.framework */, - 90DD201E167AA4350033BA25 /* SenTestingKit.framework */, - 90DD2020167AA4350033BA25 /* Cocoa.framework */, - C7CF9801174984CA008D9D13 /* UIKit.framework */, - 90DD2022167AA4350033BA25 /* Other Frameworks */, - ); - name = Frameworks; - sourceTree = ""; - }; - C77E5FA513D0CBA600298F87 /* Tests */ = { - isa = PBXGroup; - children = ( - C7CF9826174985FC008D9D13 /* Support */, - C7CF976617498275008D9D13 /* Core */, - C7CF9785174982AD008D9D13 /* DataImport */, - C77E5FA913D0CBE300298F87 /* Fixtures */, - ); - path = Tests; - sourceTree = ""; - }; - C77E5FA913D0CBE300298F87 /* Fixtures */ = { - isa = PBXGroup; - children = ( - C7CF9B6B17498B5C008D9D13 /* FixtureHelpers.h */, - C7CF9B6C17498B5C008D9D13 /* FixtureHelpers.m */, - C77E5FB113D0D18D00298F87 /* Sample Data Files */, - C77E5FB013D0D18000298F87 /* Sample Models */, - ); - name = Fixtures; - sourceTree = ""; - }; - C77E5FB013D0D18000298F87 /* Sample Models */ = { - isa = PBXGroup; - children = ( - C7BD887713DBFA6200274567 /* TestEntities */, - ); - name = "Sample Models"; - sourceTree = ""; - }; - C77E5FB113D0D18D00298F87 /* Sample Data Files */ = { - isa = PBXGroup; - children = ( - C7CF9B4917498985008D9D13 /* SampleJSONDataForImport.json */, - C7CF9B4A17498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json */, - C7CF9B4B17498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json */, - C7CF9B4C17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingDefaults.json */, - C7CF9B4D17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json */, - C7CF9B4E17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json */, - C7CF9B4F17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.json */, - C7CF9B5017498985008D9D13 /* SingleEntityWithNoRelationships.json */, - C7CF9B5117498985008D9D13 /* SingleEntityWithNoRelationships.plist */, - C7CF9B5217498985008D9D13 /* SingleRelatedEntity.json */, - ); - name = "Sample Data Files"; - sourceTree = ""; - }; - C7BD887713DBFA6200274567 /* TestEntities */ = { - isa = PBXGroup; - children = ( - ); - name = TestEntities; - path = "Unit Tests/Fixtures/iOS/TestEntities"; - sourceTree = ""; - }; - C7CF976617498275008D9D13 /* Core */ = { - isa = PBXGroup; - children = ( - C7CF976717498275008D9D13 /* MagicalRecordTests.h */, - C7CF976817498275008D9D13 /* MagicalRecordTests.m */, - C7CF976917498275008D9D13 /* NSManagedObjectContextHelperTests.h */, - C7CF976A17498275008D9D13 /* NSManagedObjectContextHelperTests.m */, - C7CF976B17498275008D9D13 /* NSManagedObjectHelperTests.h */, - C7CF976C17498275008D9D13 /* NSManagedObjectHelperTests.m */, - C7CF976D17498275008D9D13 /* NSManagedObjectModelHelperTests.h */, - C7CF976E17498275008D9D13 /* NSManagedObjectModelHelperTests.m */, - C7CF976F17498275008D9D13 /* NSPersisentStoreHelperTests.h */, - C7CF977017498275008D9D13 /* NSPersisentStoreHelperTests.m */, - C7CF977117498275008D9D13 /* NSPersistentStoreCoordinatorHelperTests.h */, - C7CF977217498275008D9D13 /* NSPersistentStoreCoordinatorHelperTests.m */, - ); - path = Core; - sourceTree = ""; - }; - C7CF9785174982AD008D9D13 /* DataImport */ = { - isa = PBXGroup; - children = ( - C7CF9786174982AD008D9D13 /* ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m */, - C7CF9787174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m */, - C7CF9788174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m */, - C7CF9789174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m */, - C7CF978A174982AD008D9D13 /* ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m */, - C7CF978B174982AD008D9D13 /* ImportSingleEntityWithNoRelationshipsTests.m */, - C7CF978C174982AD008D9D13 /* ImportSingleRelatedEntityTests.m */, - C7CF978D174982AD008D9D13 /* MagicalDataImportTestCase.h */, - C7CF978E174982AD008D9D13 /* MagicalDataImportTestCase.m */, - ); - path = DataImport; - sourceTree = ""; - }; - C7CF9826174985FC008D9D13 /* Support */ = { - isa = PBXGroup; - children = ( - C7CF9B6F17498B83008D9D13 /* MagicalRecordTests-iOS-Info.plist */, - C7CF9B7017498B83008D9D13 /* MagicalRecordTests-OSX-Info.plist */, - C7CF9ADF17498650008D9D13 /* MagicalRecordTests-iOS-Prefix.pch */, - C7CF9AE017498650008D9D13 /* MagicalRecordTests-OSX-Prefix.pch */, - C7CF9827174985FC008D9D13 /* InfoPlist.strings */, - C7CF982B174985FC008D9D13 /* Vendor */, - ); - path = Support; - sourceTree = ""; - }; - C7CF982B174985FC008D9D13 /* Vendor */ = { - isa = PBXGroup; - children = ( - C7CF9AF9174988CF008D9D13 /* Expecta.xcodeproj */, - C7CF9AEA17498803008D9D13 /* Kiwi.xcodeproj */, - ); - path = Vendor; - sourceTree = ""; - }; - C7CF9AE11749867D008D9D13 /* Library */ = { - isa = PBXGroup; - children = ( - C7CF9AE21749867D008D9D13 /* Support */, - ); - path = Library; - sourceTree = ""; - }; - C7CF9AE21749867D008D9D13 /* Support */ = { - isa = PBXGroup; - children = ( - C7CF9AE817498739008D9D13 /* CoreData.framework */, - C7CF9AE3174986B5008D9D13 /* MagicalRecord-iOS-Prefix.pch */, - C7CF9AE4174986B5008D9D13 /* MagicalRecord-OSX-Prefix.pch */, - ); - path = Support; - sourceTree = ""; - }; - C7CF9AEB17498803008D9D13 /* Products */ = { - isa = PBXGroup; - children = ( - C7CF9AF217498803008D9D13 /* libKiwi.a */, - C7CF9AF417498803008D9D13 /* libKiwi-OSX.a */, - C7CF9AF617498803008D9D13 /* KiwiTests.octest */, - ); - name = Products; - sourceTree = ""; - }; - C7CF9AFA174988CF008D9D13 /* Products */ = { - isa = PBXGroup; - children = ( - C7CF9B01174988D0008D9D13 /* libExpecta.a */, - C7CF9B03174988D0008D9D13 /* libExpecta-iOS.a */, - C7CF9B05174988D0008D9D13 /* ExpectaTests.octest */, - C7CF9B07174988D0008D9D13 /* Expecta-iOSTests.octest */, - ); - name = Products; - sourceTree = ""; - }; - C7DD7299150F832A00216827 /* MagicalRecord */ = { - isa = PBXGroup; - children = ( - C7DD729A150F832A00216827 /* Categories */, - C7DD72C4150F832A00216827 /* Core */, - C7DD72D4150F832A00216827 /* CoreData+MagicalRecord.h */, - ); - name = MagicalRecord; - path = ../MagicalRecord; - sourceTree = ""; - }; - C7DD729A150F832A00216827 /* Categories */ = { - isa = PBXGroup; - children = ( - C7DD729B150F832A00216827 /* DataImport */, - C7DD72AA150F832A00216827 /* NSManagedObject */, - C7DD72B5150F832A00216827 /* NSManagedObjectContext */, - C7DD72BE150F832A00216827 /* NSManagedObjectModel+MagicalRecord.h */, - C7DD72BF150F832A00216827 /* NSManagedObjectModel+MagicalRecord.m */, - C7DD72C0150F832A00216827 /* NSPersistentStore+MagicalRecord.h */, - C7DD72C1150F832A00216827 /* NSPersistentStore+MagicalRecord.m */, - C7DD72C2150F832A00216827 /* NSPersistentStoreCoordinator+MagicalRecord.h */, - C7DD72C3150F832A00216827 /* NSPersistentStoreCoordinator+MagicalRecord.m */, - ); - path = Categories; - sourceTree = ""; - }; - C7DD729B150F832A00216827 /* DataImport */ = { - isa = PBXGroup; - children = ( - C7DD729C150F832A00216827 /* MagicalImportFunctions.h */, - C7DD729D150F832A00216827 /* MagicalImportFunctions.m */, - C7DD72A0150F832A00216827 /* NSEntityDescription+MagicalDataImport.h */, - C7DD72A1150F832A00216827 /* NSEntityDescription+MagicalDataImport.m */, - C7DD729E150F832A00216827 /* NSAttributeDescription+MagicalDataImport.h */, - C7DD729F150F832A00216827 /* NSAttributeDescription+MagicalDataImport.m */, - C7DD72A6150F832A00216827 /* NSRelationshipDescription+MagicalDataImport.h */, - C7DD72A7150F832A00216827 /* NSRelationshipDescription+MagicalDataImport.m */, - C7DD72A2150F832A00216827 /* NSNumber+MagicalDataImport.h */, - C7DD72A3150F832A00216827 /* NSNumber+MagicalDataImport.m */, - C7DD72A4150F832A00216827 /* NSObject+MagicalDataImport.h */, - C7DD72A5150F832A00216827 /* NSObject+MagicalDataImport.m */, - C7DD72A8150F832A00216827 /* NSString+MagicalDataImport.h */, - C7DD72A9150F832A00216827 /* NSString+MagicalDataImport.m */, - ); - path = DataImport; - sourceTree = ""; - }; - C7DD72AA150F832A00216827 /* NSManagedObject */ = { - isa = PBXGroup; - children = ( - C7DD72AB150F832A00216827 /* NSManagedObject+MagicalAggregation.h */, - C7DD72AC150F832A00216827 /* NSManagedObject+MagicalAggregation.m */, - C7DD72AD150F832A00216827 /* NSManagedObject+MagicalDataImport.h */, - C7DD72AE150F832A00216827 /* NSManagedObject+MagicalDataImport.m */, - C7DD72AF150F832A00216827 /* NSManagedObject+MagicalFinders.h */, - C7DD72B0150F832A00216827 /* NSManagedObject+MagicalFinders.m */, - C7DD72B1150F832A00216827 /* NSManagedObject+MagicalRecord.h */, - C7DD72B2150F832A00216827 /* NSManagedObject+MagicalRecord.m */, - C7DD72B3150F832A00216827 /* NSManagedObject+MagicalRequests.h */, - C7DD72B4150F832A00216827 /* NSManagedObject+MagicalRequests.m */, - ); - path = NSManagedObject; - sourceTree = ""; - }; - C7DD72B5150F832A00216827 /* NSManagedObjectContext */ = { - isa = PBXGroup; - children = ( - C7DD72B6150F832A00216827 /* NSManagedObjectContext+MagicalObserving.h */, - C7DD72B7150F832A00216827 /* NSManagedObjectContext+MagicalObserving.m */, - C7DD72B8150F832A00216827 /* NSManagedObjectContext+MagicalRecord.h */, - C7DD72B9150F832A00216827 /* NSManagedObjectContext+MagicalRecord.m */, - C7DD72BA150F832A00216827 /* NSManagedObjectContext+MagicalSaves.h */, - C7DD72BB150F832A00216827 /* NSManagedObjectContext+MagicalSaves.m */, - C7DD72BC150F832A00216827 /* NSManagedObjectContext+MagicalThreading.h */, - C7DD72BD150F832A00216827 /* NSManagedObjectContext+MagicalThreading.m */, - ); - path = NSManagedObjectContext; - sourceTree = ""; - }; - C7DD72C4150F832A00216827 /* Core */ = { - isa = PBXGroup; - children = ( - C7DD72D1150F832A00216827 /* MagicalRecord.h */, - C7DD72D2150F832A00216827 /* MagicalRecord.m */, - C7DD72C5150F832A00216827 /* MagicalRecord+Actions.h */, - C7DD72C6150F832A00216827 /* MagicalRecord+Actions.m */, - C7DD72C7150F832A00216827 /* MagicalRecord+ErrorHandling.h */, - C7DD72C8150F832A00216827 /* MagicalRecord+ErrorHandling.m */, - C7DD72C9150F832A00216827 /* MagicalRecord+iCloud.h */, - C7DD72CA150F832A00216827 /* MagicalRecord+iCloud.m */, - C7DD72CB150F832A00216827 /* MagicalRecord+Options.h */, - C7DD72CC150F832A00216827 /* MagicalRecord+Options.m */, - C7DD72CD150F832A00216827 /* MagicalRecord+Setup.h */, - C7DD72CE150F832A00216827 /* MagicalRecord+Setup.m */, - C7DD72CF150F832A00216827 /* MagicalRecord+ShorthandSupport.h */, - C7DD72D0150F832A00216827 /* MagicalRecord+ShorthandSupport.m */, - C7DD72D3150F832A00216827 /* MagicalRecordShorthand.h */, - ); - path = Core; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - C7CF97B91749843F008D9D13 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - C7CF9AE6174986B5008D9D13 /* MagicalRecord-OSX-Prefix.pch in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - C7CF97AA17498414008D9D13 /* libMagicalRecord-iOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = C7CF97B417498414008D9D13 /* Build configuration list for PBXNativeTarget "libMagicalRecord-iOS" */; - buildPhases = ( - C7CF97A717498414008D9D13 /* Sources */, - C7CF97A817498414008D9D13 /* Frameworks */, - C7CF97A917498414008D9D13 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "libMagicalRecord-iOS"; - productName = libMagicalRecord; - productReference = C7CF97AB17498414008D9D13 /* libMagicalRecord-iOS.a */; - productType = "com.apple.product-type.library.static"; - }; - C7CF97BA1749843F008D9D13 /* libMagicalRecord-OSX */ = { - isa = PBXNativeTarget; - buildConfigurationList = C7CF97C31749843F008D9D13 /* Build configuration list for PBXNativeTarget "libMagicalRecord-OSX" */; - buildPhases = ( - C7CF97B71749843F008D9D13 /* Sources */, - C7CF97B81749843F008D9D13 /* Frameworks */, - C7CF97B91749843F008D9D13 /* Headers */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "libMagicalRecord-OSX"; - productName = libMagicalRecord; - productReference = C7CF97BB1749843F008D9D13 /* libMagicalRecord-OSX.dylib */; - productType = "com.apple.product-type.library.dynamic"; - }; - C7CF97FE174984CA008D9D13 /* MagicalRecordTests-iOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = C7CF980E174984CA008D9D13 /* Build configuration list for PBXNativeTarget "MagicalRecordTests-iOS" */; - buildPhases = ( - C7CF9B671749899D008D9D13 /* Regenerate Core Data Entity Classes */, - C7CF97FA174984CA008D9D13 /* Sources */, - C7CF97FB174984CA008D9D13 /* Frameworks */, - C7CF97FC174984CA008D9D13 /* Resources */, - C7CF97FD174984CA008D9D13 /* ShellScript */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "MagicalRecordTests-iOS"; - productName = MagicalRecordTests; - productReference = C7CF97FF174984CA008D9D13 /* MagicalRecordTests-iOS.octest */; - productType = "com.apple.product-type.bundle"; - }; - C7CF9815174984E4008D9D13 /* MagicalRecordTests-OSX */ = { - isa = PBXNativeTarget; - buildConfigurationList = C7CF9823174984E4008D9D13 /* Build configuration list for PBXNativeTarget "MagicalRecordTests-OSX" */; - buildPhases = ( - C7CF9B68174989CC008D9D13 /* Regenerate Core Data Entity Classes */, - C7CF9811174984E4008D9D13 /* Sources */, - C7CF9812174984E4008D9D13 /* Frameworks */, - C7CF9813174984E4008D9D13 /* Resources */, - C7CF9814174984E4008D9D13 /* ShellScript */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "MagicalRecordTests-OSX"; - productName = "MagicalRecordTests-OSX"; - productReference = C7CF9816174984E4008D9D13 /* MagicalRecordTests-OSX.octest */; - productType = "com.apple.product-type.bundle"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - C721C7A213D0A3750097AB6F /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0460; - ORGANIZATIONNAME = "Magical Panda Software LLC"; - }; - buildConfigurationList = C721C7A513D0A3750097AB6F /* Build configuration list for PBXProject "MagicalRecord" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = C721C7A013D0A3750097AB6F; - productRefGroup = C721C7B113D0A3AF0097AB6F /* Products */; - projectDirPath = ""; - projectReferences = ( - { - ProductGroup = C7CF9AFA174988CF008D9D13 /* Products */; - ProjectRef = C7CF9AF9174988CF008D9D13 /* Expecta.xcodeproj */; - }, - { - ProductGroup = C7CF9AEB17498803008D9D13 /* Products */; - ProjectRef = C7CF9AEA17498803008D9D13 /* Kiwi.xcodeproj */; - }, - ); - projectRoot = ""; - targets = ( - C7CF97AA17498414008D9D13 /* libMagicalRecord-iOS */, - C7CF97BA1749843F008D9D13 /* libMagicalRecord-OSX */, - C7CF97FE174984CA008D9D13 /* MagicalRecordTests-iOS */, - C7CF9815174984E4008D9D13 /* MagicalRecordTests-OSX */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXReferenceProxy section */ - C7CF9AF217498803008D9D13 /* libKiwi.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libKiwi.a; - remoteRef = C7CF9AF117498803008D9D13 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - C7CF9AF417498803008D9D13 /* libKiwi-OSX.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libKiwi-OSX.a"; - remoteRef = C7CF9AF317498803008D9D13 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - C7CF9AF617498803008D9D13 /* KiwiTests.octest */ = { - isa = PBXReferenceProxy; - fileType = wrapper.cfbundle; - path = KiwiTests.octest; - remoteRef = C7CF9AF517498803008D9D13 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - C7CF9B01174988D0008D9D13 /* libExpecta.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libExpecta.a; - remoteRef = C7CF9B00174988D0008D9D13 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - C7CF9B03174988D0008D9D13 /* libExpecta-iOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libExpecta-iOS.a"; - remoteRef = C7CF9B02174988D0008D9D13 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - C7CF9B05174988D0008D9D13 /* ExpectaTests.octest */ = { - isa = PBXReferenceProxy; - fileType = wrapper.cfbundle; - path = ExpectaTests.octest; - remoteRef = C7CF9B04174988D0008D9D13 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - C7CF9B07174988D0008D9D13 /* Expecta-iOSTests.octest */ = { - isa = PBXReferenceProxy; - fileType = wrapper.cfbundle; - path = "Expecta-iOSTests.octest"; - remoteRef = C7CF9B06174988D0008D9D13 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; -/* End PBXReferenceProxy section */ - -/* Begin PBXResourcesBuildPhase section */ - C7CF97FC174984CA008D9D13 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - C7CF9975174985FF008D9D13 /* InfoPlist.strings in Resources */, - C7CF9B5317498985008D9D13 /* SampleJSONDataForImport.json in Resources */, - C7CF9B5517498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json in Resources */, - C7CF9B5717498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json in Resources */, - C7CF9B5917498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingDefaults.json in Resources */, - C7CF9B5B17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json in Resources */, - C7CF9B5D17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json in Resources */, - C7CF9B5F17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.json in Resources */, - C7CF9B6117498985008D9D13 /* SingleEntityWithNoRelationships.json in Resources */, - C7CF9B6317498986008D9D13 /* SingleEntityWithNoRelationships.plist in Resources */, - C7CF9B6517498986008D9D13 /* SingleRelatedEntity.json in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - C7CF9813174984E4008D9D13 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - C7CF9976174985FF008D9D13 /* InfoPlist.strings in Resources */, - C7CF9B5417498985008D9D13 /* SampleJSONDataForImport.json in Resources */, - C7CF9B5617498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json in Resources */, - C7CF9B5817498985008D9D13 /* SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json in Resources */, - C7CF9B5A17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingDefaults.json in Resources */, - C7CF9B5C17498985008D9D13 /* SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json in Resources */, - C7CF9B5E17498985008D9D13 /* SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json in Resources */, - C7CF9B6017498985008D9D13 /* SingleEntityRelatedToMappedEntityWithSecondaryMappings.json in Resources */, - C7CF9B6217498985008D9D13 /* SingleEntityWithNoRelationships.json in Resources */, - C7CF9B6417498986008D9D13 /* SingleEntityWithNoRelationships.plist in Resources */, - C7CF9B6617498986008D9D13 /* SingleRelatedEntity.json in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - C7CF97FD174984CA008D9D13 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n"; - }; - C7CF9814174984E4008D9D13 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n"; - }; - C7CF9B671749899D008D9D13 /* Regenerate Core Data Entity Classes */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Regenerate Core Data Entity Classes"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "mogen=`which mogenerator`\nPlistBuddy=/usr/libexec/PlistBuddy\nHUMAN_FILES_OUTPUT_FOLDER=$PROJECT_DIR/TestsFixtures/iOS/entities\nMACHINE_FILES_OUTPUT_FOLDER=$PROJECT_DIR/Tests/Fixtures/iOS/generated\nMODEL_DATA_FOLDER=$PROJECT_DIR/Tests/Fixtures/iOS/TestModel.xcdatamodeld\n\n#figure out current model version\nCURRENT_MODEL_VERSION=`\"$PlistBuddy\" -c 'Print _XCCurrentVersionName' \"$MODEL_DATA_FOLDER/.xccurrentversion\"`\n\n\nif [[ -x $mogen ]]; then\necho \"Updating data objects from $MODEL_DATA_FOLDER/$CURRENT_MODEL_VERSION using $mogen\"\n\"$mogen\" -m \"$MODEL_DATA_FOLDER/$CURRENT_MODEL_VERSION\" -M \"$MACHINE_FILES_OUTPUT_FOLDER\" -H \"$HUMAN_FILES_OUTPUT_FOLDER\" --template-var arc=true\nfi"; - }; - C7CF9B68174989CC008D9D13 /* Regenerate Core Data Entity Classes */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Regenerate Core Data Entity Classes"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "mogen=`which mogenerator`\nPlistBuddy=/usr/libexec/PlistBuddy\nHUMAN_FILES_OUTPUT_FOLDER=$PROJECT_DIR/Application/Models/entities\nMACHINE_FILES_OUTPUT_FOLDER=$PROJECT_DIR/Application/Models/generated\nMODEL_DATA_FOLDER=$PROJECT_DIR/Application/Models/TestModel.xcdatamodeld\n\n#figure out current model version\nCURRENT_MODEL_VERSION=`\"$PlistBuddy\" -c 'Print _XCCurrentVersionName' \"$MODEL_DATA_FOLDER/.xccurrentversion\"`\n\n\nif [[ -x $mogen ]]; then\necho \"Updating data objects from $MODEL_DATA_FOLDER/$CURRENT_MODEL_VERSION using $mogen\"\n\"$mogen\" -m \"$MODEL_DATA_FOLDER/$CURRENT_MODEL_VERSION\" -M \"$MACHINE_FILES_OUTPUT_FOLDER\" -H \"$HUMAN_FILES_OUTPUT_FOLDER\" --template-var arc=true\nfi"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - C7CF97A717498414008D9D13 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - C7CF97C617498493008D9D13 /* MagicalImportFunctions.m in Sources */, - C7CF97C717498493008D9D13 /* NSEntityDescription+MagicalDataImport.m in Sources */, - C7CF97C817498493008D9D13 /* NSAttributeDescription+MagicalDataImport.m in Sources */, - C7CF97C917498493008D9D13 /* NSRelationshipDescription+MagicalDataImport.m in Sources */, - C7CF97CA17498493008D9D13 /* NSNumber+MagicalDataImport.m in Sources */, - C7CF97CB17498493008D9D13 /* NSObject+MagicalDataImport.m in Sources */, - C7CF97CC17498493008D9D13 /* NSString+MagicalDataImport.m in Sources */, - C7CF97CD17498493008D9D13 /* NSManagedObject+MagicalAggregation.m in Sources */, - C7CF97CE17498493008D9D13 /* NSManagedObject+MagicalDataImport.m in Sources */, - C7CF97CF17498493008D9D13 /* NSManagedObject+MagicalFinders.m in Sources */, - C7CF97D017498493008D9D13 /* NSManagedObject+MagicalRecord.m in Sources */, - C7CF97D117498493008D9D13 /* NSManagedObject+MagicalRequests.m in Sources */, - C7CF97D217498493008D9D13 /* NSManagedObjectContext+MagicalObserving.m in Sources */, - C7CF97D317498493008D9D13 /* NSManagedObjectContext+MagicalRecord.m in Sources */, - C7CF97D417498493008D9D13 /* NSManagedObjectContext+MagicalSaves.m in Sources */, - C7CF97D517498493008D9D13 /* NSManagedObjectContext+MagicalThreading.m in Sources */, - C7CF97D617498493008D9D13 /* NSManagedObjectModel+MagicalRecord.m in Sources */, - C7CF97D717498493008D9D13 /* NSPersistentStore+MagicalRecord.m in Sources */, - C7CF97D817498493008D9D13 /* NSPersistentStoreCoordinator+MagicalRecord.m in Sources */, - C7CF97D917498493008D9D13 /* MagicalRecord.m in Sources */, - C7CF97DA17498493008D9D13 /* MagicalRecord+Actions.m in Sources */, - C7CF97DB17498493008D9D13 /* MagicalRecord+ErrorHandling.m in Sources */, - C7CF97DC17498493008D9D13 /* MagicalRecord+iCloud.m in Sources */, - C7CF97DD17498493008D9D13 /* MagicalRecord+Options.m in Sources */, - C7CF97DE17498493008D9D13 /* MagicalRecord+Setup.m in Sources */, - C7CF97DF17498493008D9D13 /* MagicalRecord+ShorthandSupport.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - C7CF97B71749843F008D9D13 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - C7CF97E0174984A5008D9D13 /* MagicalImportFunctions.m in Sources */, - C7CF97E1174984A5008D9D13 /* NSEntityDescription+MagicalDataImport.m in Sources */, - C7CF97E2174984A5008D9D13 /* NSAttributeDescription+MagicalDataImport.m in Sources */, - C7CF97E3174984A5008D9D13 /* NSRelationshipDescription+MagicalDataImport.m in Sources */, - C7CF97E4174984A5008D9D13 /* NSNumber+MagicalDataImport.m in Sources */, - C7CF97E5174984A5008D9D13 /* NSObject+MagicalDataImport.m in Sources */, - C7CF97E6174984A5008D9D13 /* NSString+MagicalDataImport.m in Sources */, - C7CF97E7174984A5008D9D13 /* NSManagedObject+MagicalAggregation.m in Sources */, - C7CF97E8174984A5008D9D13 /* NSManagedObject+MagicalDataImport.m in Sources */, - C7CF97E9174984A5008D9D13 /* NSManagedObject+MagicalFinders.m in Sources */, - C7CF97EA174984A5008D9D13 /* NSManagedObject+MagicalRecord.m in Sources */, - C7CF97EB174984A5008D9D13 /* NSManagedObject+MagicalRequests.m in Sources */, - C7CF97EC174984A5008D9D13 /* NSManagedObjectContext+MagicalObserving.m in Sources */, - C7CF97ED174984A5008D9D13 /* NSManagedObjectContext+MagicalRecord.m in Sources */, - C7CF97EE174984A5008D9D13 /* NSManagedObjectContext+MagicalSaves.m in Sources */, - C7CF97EF174984A5008D9D13 /* NSManagedObjectContext+MagicalThreading.m in Sources */, - C7CF97F0174984A5008D9D13 /* NSManagedObjectModel+MagicalRecord.m in Sources */, - C7CF97F1174984A5008D9D13 /* NSPersistentStore+MagicalRecord.m in Sources */, - C7CF97F2174984A5008D9D13 /* NSPersistentStoreCoordinator+MagicalRecord.m in Sources */, - C7CF97F3174984A5008D9D13 /* MagicalRecord.m in Sources */, - C7CF97F4174984A5008D9D13 /* MagicalRecord+Actions.m in Sources */, - C7CF97F5174984A5008D9D13 /* MagicalRecord+ErrorHandling.m in Sources */, - C7CF97F6174984A5008D9D13 /* MagicalRecord+iCloud.m in Sources */, - C7CF97F7174984A5008D9D13 /* MagicalRecord+Options.m in Sources */, - C7CF97F8174984A5008D9D13 /* MagicalRecord+Setup.m in Sources */, - C7CF97F9174984A5008D9D13 /* MagicalRecord+ShorthandSupport.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - C7CF97FA174984CA008D9D13 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - C7CF9B2417498962008D9D13 /* MagicalRecordTests.m in Sources */, - C7CF9B2517498962008D9D13 /* NSManagedObjectContextHelperTests.m in Sources */, - C7CF9B2617498962008D9D13 /* NSManagedObjectHelperTests.m in Sources */, - C7CF9B2717498962008D9D13 /* NSManagedObjectModelHelperTests.m in Sources */, - C7CF9B2817498962008D9D13 /* NSPersisentStoreHelperTests.m in Sources */, - C7CF9B2917498962008D9D13 /* NSPersistentStoreCoordinatorHelperTests.m in Sources */, - C7CF9B2A17498962008D9D13 /* ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m in Sources */, - C7CF9B2B17498962008D9D13 /* ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m in Sources */, - C7CF9B2C17498962008D9D13 /* ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m in Sources */, - C7CF9B2D17498962008D9D13 /* ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m in Sources */, - C7CF9B2E17498962008D9D13 /* ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m in Sources */, - C7CF9B2F17498962008D9D13 /* ImportSingleEntityWithNoRelationshipsTests.m in Sources */, - C7CF9B3017498962008D9D13 /* ImportSingleRelatedEntityTests.m in Sources */, - C7CF9B3117498962008D9D13 /* MagicalDataImportTestCase.m in Sources */, - C7CF9B0A1749894D008D9D13 /* MagicalImportFunctions.m in Sources */, - C7CF9B0B1749894D008D9D13 /* NSEntityDescription+MagicalDataImport.m in Sources */, - C7CF9B0C1749894D008D9D13 /* NSAttributeDescription+MagicalDataImport.m in Sources */, - C7CF9B0D1749894D008D9D13 /* NSRelationshipDescription+MagicalDataImport.m in Sources */, - C7CF9B0E1749894D008D9D13 /* NSNumber+MagicalDataImport.m in Sources */, - C7CF9B0F1749894D008D9D13 /* NSObject+MagicalDataImport.m in Sources */, - C7CF9B101749894D008D9D13 /* NSString+MagicalDataImport.m in Sources */, - C7CF9B111749894D008D9D13 /* NSManagedObject+MagicalAggregation.m in Sources */, - C7CF9B121749894D008D9D13 /* NSManagedObject+MagicalDataImport.m in Sources */, - C7CF9B131749894D008D9D13 /* NSManagedObject+MagicalFinders.m in Sources */, - C7CF9B141749894D008D9D13 /* NSManagedObject+MagicalRecord.m in Sources */, - C7CF9B151749894D008D9D13 /* NSManagedObject+MagicalRequests.m in Sources */, - C7CF9B161749894D008D9D13 /* NSManagedObjectContext+MagicalObserving.m in Sources */, - C7CF9B171749894D008D9D13 /* NSManagedObjectContext+MagicalRecord.m in Sources */, - C7CF9B181749894D008D9D13 /* NSManagedObjectContext+MagicalSaves.m in Sources */, - C7CF9B191749894D008D9D13 /* NSManagedObjectContext+MagicalThreading.m in Sources */, - C7CF9B1A1749894D008D9D13 /* NSManagedObjectModel+MagicalRecord.m in Sources */, - C7CF9B1B1749894D008D9D13 /* NSPersistentStore+MagicalRecord.m in Sources */, - C7CF9B1C1749894D008D9D13 /* NSPersistentStoreCoordinator+MagicalRecord.m in Sources */, - C7CF9B1D1749894D008D9D13 /* MagicalRecord.m in Sources */, - C7CF9B1E1749894D008D9D13 /* MagicalRecord+Actions.m in Sources */, - C7CF9B1F1749894D008D9D13 /* MagicalRecord+ErrorHandling.m in Sources */, - C7CF9B201749894D008D9D13 /* MagicalRecord+iCloud.m in Sources */, - C7CF9B211749894D008D9D13 /* MagicalRecord+Options.m in Sources */, - C7CF9B221749894D008D9D13 /* MagicalRecord+Setup.m in Sources */, - C7CF9B231749894D008D9D13 /* MagicalRecord+ShorthandSupport.m in Sources */, - C7CF9B6D17498B5C008D9D13 /* FixtureHelpers.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - C7CF9811174984E4008D9D13 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - C7CF9B6E17498B5C008D9D13 /* FixtureHelpers.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - C7CF9827174985FC008D9D13 /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - C7CF9828174985FC008D9D13 /* en */, - ); - name = InfoPlist.strings; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - C721C7A713D0A3750097AB6F /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - GCC_TREAT_WARNINGS_AS_ERRORS = NO; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; - GCC_WARN_ABOUT_MISSING_NEWLINE = YES; - GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; - GCC_WARN_SHADOW = YES; - GCC_WARN_SIGN_COMPARE = YES; - GCC_WARN_STRICT_SELECTOR_MATCH = YES; - GCC_WARN_UNDECLARED_SELECTOR = NO; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_LABEL = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 4.3; - MACOSX_DEPLOYMENT_TARGET = 10.7; - SDKROOT = ""; - WARNING_CFLAGS = "-Wdocumentation"; - }; - name = Debug; - }; - C721C7A813D0A3750097AB6F /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - GCC_TREAT_WARNINGS_AS_ERRORS = NO; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; - GCC_WARN_ABOUT_MISSING_NEWLINE = YES; - GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; - GCC_WARN_SHADOW = YES; - GCC_WARN_SIGN_COMPARE = YES; - GCC_WARN_STRICT_SELECTOR_MATCH = YES; - GCC_WARN_UNDECLARED_SELECTOR = NO; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_LABEL = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 4.3; - MACOSX_DEPLOYMENT_TARGET = 10.7; - SDKROOT = ""; - WARNING_CFLAGS = "-Wdocumentation"; - }; - name = Release; - }; - C7CF97B517498414008D9D13 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - COPY_PHASE_STRIP = NO; - DSTROOT = /tmp/libMagicalRecord.dst; - EXECUTABLE_PREFIX = ""; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "Library/Support/MagicalRecord-iOS-Prefix.pch"; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - IPHONEOS_DEPLOYMENT_TARGET = 6.1; - ONLY_ACTIVE_ARCH = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - }; - name = Debug; - }; - C7CF97B617498414008D9D13 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - COPY_PHASE_STRIP = YES; - DSTROOT = /tmp/libMagicalRecord.dst; - EXECUTABLE_PREFIX = ""; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "Library/Support/MagicalRecord-iOS-Prefix.pch"; - IPHONEOS_DEPLOYMENT_TARGET = 6.1; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - C7CF97C41749843F008D9D13 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - COPY_PHASE_STRIP = NO; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Library/Frameworks\"", - ); - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "Library/Support/MagicalRecord-OSX-Prefix.pch"; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - MACOSX_DEPLOYMENT_TARGET = 10.8; - ONLY_ACTIVE_ARCH = YES; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; - }; - name = Debug; - }; - C7CF97C51749843F008D9D13 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Library/Frameworks\"", - ); - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "Library/Support/MagicalRecord-OSX-Prefix.pch"; - MACOSX_DEPLOYMENT_TARGET = 10.8; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; - }; - name = Release; - }; - C7CF980F174984CA008D9D13 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - COPY_PHASE_STRIP = NO; - FRAMEWORK_SEARCH_PATHS = ( - "\"$(SDKROOT)/Developer/Library/Frameworks\"", - "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", - ); - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "Tests/Support/MagicalRecordTests-iOS-Prefix.pch"; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - INFOPLIST_FILE = "Tests/Support/MagicalRecordTests-iOS-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 6.1; - ONLY_ACTIVE_ARCH = YES; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = iphoneos; - WRAPPER_EXTENSION = octest; - }; - name = Debug; - }; - C7CF9810174984CA008D9D13 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - COPY_PHASE_STRIP = YES; - FRAMEWORK_SEARCH_PATHS = ( - "\"$(SDKROOT)/Developer/Library/Frameworks\"", - "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", - ); - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "Tests/Support/MagicalRecordTests-iOS-Prefix.pch"; - INFOPLIST_FILE = "Tests/Support/MagicalRecordTests-iOS-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 6.1; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = iphoneos; - VALIDATE_PRODUCT = YES; - WRAPPER_EXTENSION = octest; - }; - name = Release; - }; - C7CF9824174984E4008D9D13 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - COMBINE_HIDPI_IMAGES = YES; - COPY_PHASE_STRIP = NO; - FRAMEWORK_SEARCH_PATHS = "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\""; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "Tests/Support/MagicalRecordTests-OSX-Prefix.pch"; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - INFOPLIST_FILE = "Tests/Support/MagicalRecordTests-OSX-Info.plist"; - MACOSX_DEPLOYMENT_TARGET = 10.8; - ONLY_ACTIVE_ARCH = YES; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; - WRAPPER_EXTENSION = octest; - }; - name = Debug; - }; - C7CF9825174984E4008D9D13 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - COMBINE_HIDPI_IMAGES = YES; - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - FRAMEWORK_SEARCH_PATHS = "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\""; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "Tests/Support/MagicalRecordTests-OSX-Prefix.pch"; - INFOPLIST_FILE = "Tests/Support/MagicalRecordTests-OSX-Info.plist"; - MACOSX_DEPLOYMENT_TARGET = 10.8; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; - WRAPPER_EXTENSION = octest; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - C721C7A513D0A3750097AB6F /* Build configuration list for PBXProject "MagicalRecord" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C721C7A713D0A3750097AB6F /* Debug */, - C721C7A813D0A3750097AB6F /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - C7CF97B417498414008D9D13 /* Build configuration list for PBXNativeTarget "libMagicalRecord-iOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C7CF97B517498414008D9D13 /* Debug */, - C7CF97B617498414008D9D13 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - C7CF97C31749843F008D9D13 /* Build configuration list for PBXNativeTarget "libMagicalRecord-OSX" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C7CF97C41749843F008D9D13 /* Debug */, - C7CF97C51749843F008D9D13 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - C7CF980E174984CA008D9D13 /* Build configuration list for PBXNativeTarget "MagicalRecordTests-iOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C7CF980F174984CA008D9D13 /* Debug */, - C7CF9810174984CA008D9D13 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - C7CF9823174984E4008D9D13 /* Build configuration list for PBXNativeTarget "MagicalRecordTests-OSX" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C7CF9824174984E4008D9D13 /* Debug */, - C7CF9825174984E4008D9D13 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = C721C7A213D0A3750097AB6F /* Project object */; -} diff --git a/Project Files/Rakefile b/Project Files/Rakefile deleted file mode 100644 index 330febd6c..000000000 --- a/Project Files/Rakefile +++ /dev/null @@ -1,60 +0,0 @@ -@ios_fixtures = "Unit Tests/Fixtures/iOS" - - -@target = "" -@project = "" -@fixtures = "" - -namespace :setup do - task :ios do - - end - - task :osx do - @target = "Mac App Unit Tests" - @project = "Magical Record.xcodeproj" - @fixtures = "Unit Tests/Fixtures/Mac" - end -end - -namespace :clean do - task :osx => ["setup:osx"] do - rm_rf "#{@fixtures}/TestEntities" - end -end - -namespace :build do - - task :run do - results = system("xcodebuild -project '#{@project}' -target '#{@target}'") - puts results - end - - namespace :db do - task :create do - Dir.chdir(@fixtures) do - puts `/usr/local/bin/mogenerator -m TestModel.xcdatamodeld/TestModel.xcdatamodel -O TestEntities` - end - end - end - - task :osx => ["setup:osx", "clean:osx", "build:db:create", "build:run"] - - task :ios => [] do - - end -end - -namespace :test do - task :osx => ["build:osx"] do - puts "testing osx" - end - - task :ios do - puts "testing ios" - end -end - -task :test => ["test:osx", "test:ios"] - -task :default => :test diff --git a/Project Files/Tests/Core/MagicalRecordTests.h b/Project Files/Tests/Core/MagicalRecordTests.h deleted file mode 100644 index 508265e26..000000000 --- a/Project Files/Tests/Core/MagicalRecordTests.h +++ /dev/null @@ -1,14 +0,0 @@ -// -// MagicalRecordHelperTests.h -// Magical Record -// -// Created by Saul Mora on 7/15/11. -// Copyright 2011 Magical Panda Software LLC. All rights reserved. -// - -@interface MagicalRecordTests : GHTestCase -{ - BOOL errorHandlerWasCalled_; -} - -@end diff --git a/Project Files/Tests/Core/MagicalRecordTests.m b/Project Files/Tests/Core/MagicalRecordTests.m deleted file mode 100644 index bc1db7629..000000000 --- a/Project Files/Tests/Core/MagicalRecordTests.m +++ /dev/null @@ -1,123 +0,0 @@ -// -// MagicalRecordHelperTests.m -// Magical Record -// -// Created by Saul Mora on 7/15/11. -// Copyright 2011 Magical Panda Software LLC. All rights reserved. -// - -#import "MagicalRecordTests.h" - - -@protocol MagicalRecordErrorHandlerProtocol - -- (void) testHandlingError:(NSError *)error; - -@end - -@implementation MagicalRecordTests - -- (void) setUp -{ - [MagicalRecord setDefaultModelNamed:@"TestModel.momd"]; -} - -- (void) tearDown -{ - [MagicalRecord cleanUp]; -} - -- (void) assertDefaultStack -{ - assertThat([NSManagedObjectContext MR_defaultContext], is(notNilValue())); - assertThat([NSManagedObjectModel MR_defaultManagedObjectModel], is(notNilValue())); - assertThat([NSPersistentStoreCoordinator MR_defaultStoreCoordinator], is(notNilValue())); - assertThat([NSPersistentStore MR_defaultPersistentStore], is(notNilValue())); -} - -- (void) testCreateDefaultCoreDataStack -{ - NSURL *testStoreURL = [NSPersistentStore urlForStoreName:kMagicalRecordDefaultStoreFileName]; - [[NSFileManager defaultManager] removeItemAtPath:[testStoreURL path] error:nil]; - - [MagicalRecord setupCoreDataStack]; - - [self assertDefaultStack]; - - NSPersistentStore *defaultStore = [NSPersistentStore MR_defaultPersistentStore]; - assertThat([[defaultStore URL] absoluteString], endsWith(@".sqlite")); - assertThat([defaultStore type], is(equalTo(NSSQLiteStoreType))); -} - -- (void) testCreateInMemoryCoreDataStack -{ - [MagicalRecord setupCoreDataStackWithInMemoryStore]; - - [self assertDefaultStack]; - - NSPersistentStore *defaultStore = [NSPersistentStore MR_defaultPersistentStore]; - assertThat([defaultStore type], is(equalTo(NSInMemoryStoreType))); -} - -- (void) testCreateSqliteStackWithCustomName -{ - NSString *testStoreName = @"MyTestDataStore.sqlite"; - - NSURL *testStoreURL = [NSPersistentStore MR_urlForStoreName:testStoreName]; - [[NSFileManager defaultManager] removeItemAtPath:[testStoreURL path] error:nil]; - - [MagicalRecord setupCoreDataStackWithStoreNamed:testStoreName]; - - [self assertDefaultStack]; - - NSPersistentStore *defaultStore = [NSPersistentStore MR_defaultPersistentStore]; - assertThat([defaultStore type], is(equalTo(NSSQLiteStoreType))); - assertThat([[defaultStore URL] absoluteString], endsWith(testStoreName)); -} - -- (void) customErrorHandler:(id)error; -{ -} - -- (void) testCanSetAUserSpecifiedErrorHandler -{ - [MagicalRecord setErrorHandlerTarget:self action:@selector(customErrorHandler:)]; - - assertThat([MagicalRecord errorHandlerTarget], is(equalTo(self))); - assertThat(NSStringFromSelector([MagicalRecord errorHandlerAction]), is(equalTo(NSStringFromSelector(@selector(customErrorHandler:))))); -} - -- (void) magicalRecordErrorHandlerTest:(NSError *)error -{ - assertThat(error, is(notNilValue())); - assertThat([error domain], is(equalTo(@"MRTests"))); - assertThatInteger([error code], is(equalToInteger(1000))); - errorHandlerWasCalled_ = YES; -} - -- (void) testUserSpecifiedErrorHandlersAreTriggeredOnError -{ - errorHandlerWasCalled_ = NO; - [MagicalRecord setErrorHandlerTarget:self action:@selector(magicalRecordErrorHandlerTest:)]; - - NSError *testError = [NSError errorWithDomain:@"MRTests" code:1000 userInfo:nil]; - [MagicalRecord handleErrors:testError]; - - assertThatBool(errorHandlerWasCalled_, is(equalToBool(YES))); -} - -- (void) testLogsErrorsToLogger -{ - NSError *testError = [NSError errorWithDomain:@"Cocoa" code:1000 userInfo:nil]; - id mockErrorHandler = [OCMockObject mockForProtocol:@protocol(MagicalRecordErrorHandlerProtocol)]; - [[mockErrorHandler expect] testHandlingError:testError]; - - // [[mockErrorHandler expect] performSelector:@selector(testErrorHandler:) withObject:[OCMArg any]]; - - [MagicalRecord setErrorHandlerTarget:mockErrorHandler action:@selector(testHandlingError:)]; - [MagicalRecord handleErrors:testError]; - - [mockErrorHandler verify]; -} - -@end diff --git a/Project Files/Tests/Core/NSManagedObjectContextHelperTests.h b/Project Files/Tests/Core/NSManagedObjectContextHelperTests.h deleted file mode 100644 index f17f93f6b..000000000 --- a/Project Files/Tests/Core/NSManagedObjectContextHelperTests.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// NSManagedObjectContextHelperTests.h -// Magical Record -// -// Created by Saul Mora on 7/15/11. -// Copyright 2011 Magical Panda Software LLC. All rights reserved. -// - - - -@interface NSManagedObjectContextHelperTests : GHTestCase - -@end diff --git a/Project Files/Tests/Core/NSManagedObjectHelperTests.h b/Project Files/Tests/Core/NSManagedObjectHelperTests.h deleted file mode 100644 index 68f261975..000000000 --- a/Project Files/Tests/Core/NSManagedObjectHelperTests.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// NSManagedObjectHelperTests.h -// Magical Record -// -// Created by Saul Mora on 7/15/11. -// Copyright 2011 Magical Panda Software LLC. All rights reserved. -// - - - -@interface NSManagedObjectHelperTests : GHTestCase - -@end diff --git a/Project Files/Tests/Core/NSManagedObjectHelperTests.m b/Project Files/Tests/Core/NSManagedObjectHelperTests.m deleted file mode 100644 index adfd6057d..000000000 --- a/Project Files/Tests/Core/NSManagedObjectHelperTests.m +++ /dev/null @@ -1,124 +0,0 @@ -// -// NSManagedObjectHelperTests.m -// Magical Record -// -// Created by Saul Mora on 7/15/11. -// Copyright 2011 Magical Panda Software LLC. All rights reserved. -// - -#import "NSManagedObjectHelperTests.h" -#import "SingleRelatedEntity.h" - -@implementation NSManagedObjectHelperTests - -- (void) setUpClass -{ - [NSManagedObjectModel MR_setDefaultManagedObjectModel:[NSManagedObjectModel MR_managedObjectModelNamed:@"TestModel.momd"]]; -} - -- (void) setUp -{ - [MagicalRecord setupCoreDataStackWithInMemoryStore]; -} - -- (void) tearDown -{ - [MagicalRecord cleanUp]; -} - --(BOOL)shouldRunOnMainThread -{ - return YES; -} -//Test Request Creation - -- (void) testCreateFetchRequestForEntity -{ - NSFetchRequest *testRequest = [SingleRelatedEntity requestAll]; - - assertThat([[testRequest entity] name], is(equalTo(NSStringFromClass([SingleRelatedEntity class])))); -} - -- (void) testCanRequestFirstEntityWithPredicate -{ - NSPredicate *testPredicate = [NSPredicate predicateWithFormat:@"mappedStringAttribute = 'Test Predicate'"]; - NSFetchRequest *testRequest = [SingleRelatedEntity requestFirstWithPredicate:testPredicate]; - - assertThatInteger([testRequest fetchLimit], is(equalToInteger(1))); - assertThat([testRequest predicate], is(equalTo([NSPredicate predicateWithFormat:@"mappedStringAttribute = 'Test Predicate'"]))); -} - -// Test return result set, all, first - -- (void) testCreateRequestForFirstEntity -{ - NSFetchRequest *testRequest = [SingleRelatedEntity requestFirstByAttribute:@"mappedStringAttribute" withValue:nil]; - - assertThat([[testRequest entity] name], is(equalTo(NSStringFromClass([SingleRelatedEntity class])))); - assertThatInteger([testRequest fetchLimit], is(equalToInteger(1))); - assertThatInteger([testRequest fetchOffset], is(equalToInteger(0))); - assertThat([testRequest predicate], is(equalTo([NSPredicate predicateWithFormat:@"mappedStringAttribute = nil"]))); -} - -- (void) testCanGetEntityDescriptionFromEntityClass -{ - NSEntityDescription *testDescription = [SingleRelatedEntity entityDescription]; - assertThat(testDescription, is(notNilValue())); -} - -// Test Entity creation - -- (void) testCanCreateEntityInstance -{ - id testEntity = [SingleRelatedEntity createEntity]; - - assertThat(testEntity, is(notNilValue())); -} - -// Test Entity Deletion - -- (void) testCanDeleteEntityInstance -{ - id testEntity = [SingleRelatedEntity createEntity]; - [[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait]; - - assertThatBool([testEntity isDeleted], is(equalToBool(NO))); - - [testEntity MR_deleteEntity]; - - assertThat(testEntity, is(notNilValue())); - assertThatBool([testEntity isDeleted], is(equalToBool(YES))); -} - -// Test Number of Entities - -- (void) createSampleData:(NSInteger)numberOfTestEntitiesToCreate -{ - for (int i = 0; i < numberOfTestEntitiesToCreate; i++) - { - SingleRelatedEntity *testEntity = [SingleRelatedEntity createEntity]; - testEntity.mappedStringAttribute = [NSString stringWithFormat:@"%d", i / 5]; - } - - [[NSManagedObjectContext MR_defaultContext] MR_saveOnlySelfAndWait]; -} - -- (void) testCanSearchForNumberOfAllEntities -{ - NSInteger numberOfTestEntitiesToCreate = 20; - [self createSampleData:numberOfTestEntitiesToCreate]; - - assertThat([SingleRelatedEntity numberOfEntities], is(equalToInteger(numberOfTestEntitiesToCreate))); -} - -- (void) testCanSearchForNumberOfEntitiesWithPredicate -{ - NSInteger numberOfTestEntitiesToCreate = 20; - [self createSampleData:numberOfTestEntitiesToCreate]; - - NSPredicate *searchFilter = [NSPredicate predicateWithFormat:@"mappedStringAttribute = '1'"]; - assertThat([SingleRelatedEntity numberOfEntitiesWithPredicate:searchFilter], is(equalToInteger(5))); - -} - -@end diff --git a/Project Files/Tests/Core/NSManagedObjectModelHelperTests.h b/Project Files/Tests/Core/NSManagedObjectModelHelperTests.h deleted file mode 100644 index 7a443b5a8..000000000 --- a/Project Files/Tests/Core/NSManagedObjectModelHelperTests.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// NSManagedObjectModelHelperTests.h -// Magical Record -// -// Created by Saul Mora on 7/15/11. -// Copyright 2011 Magical Panda Software LLC. All rights reserved. -// - - - -@interface NSManagedObjectModelHelperTests : GHTestCase - -@end diff --git a/Project Files/Tests/Core/NSManagedObjectModelHelperTests.m b/Project Files/Tests/Core/NSManagedObjectModelHelperTests.m deleted file mode 100644 index 1db894a1a..000000000 --- a/Project Files/Tests/Core/NSManagedObjectModelHelperTests.m +++ /dev/null @@ -1,14 +0,0 @@ -// -// NSManagedObjectModelHelperTests.m -// Magical Record -// -// Created by Saul Mora on 7/15/11. -// Copyright 2011 Magical Panda Software LLC. All rights reserved. -// - -#import "NSManagedObjectModelHelperTests.h" - -@implementation NSManagedObjectModelHelperTests - - -@end diff --git a/Project Files/Tests/Core/NSPersisentStoreHelperTests.h b/Project Files/Tests/Core/NSPersisentStoreHelperTests.h deleted file mode 100644 index cb9a8ed2c..000000000 --- a/Project Files/Tests/Core/NSPersisentStoreHelperTests.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// NSPersisentStoreHelperTests.h -// Magical Record -// -// Created by Saul Mora on 7/15/11. -// Copyright 2011 Magical Panda Software LLC. All rights reserved. -// - - - -@interface NSPersisentStoreHelperTests : GHTestCase - -@end diff --git a/Project Files/Tests/Core/NSPersisentStoreHelperTests.m b/Project Files/Tests/Core/NSPersisentStoreHelperTests.m deleted file mode 100644 index b8b675caa..000000000 --- a/Project Files/Tests/Core/NSPersisentStoreHelperTests.m +++ /dev/null @@ -1,109 +0,0 @@ -// -// NSPersisentStoreHelperTests.m -// Magical Record -// -// Created by Saul Mora on 7/15/11. -// Copyright 2011 Magical Panda Software LLC. All rights reserved. -// - -#import "NSPersisentStoreHelperTests.h" - -@implementation NSPersisentStoreHelperTests - -- (NSString *) applicationStorageDirectory -{ - NSString *appSupportDirectory = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) lastObject]; - appSupportDirectory = [appSupportDirectory stringByAppendingPathComponent:@"iOS App Unit Tests"]; - return appSupportDirectory; -} - -#if TARGET_OS_IPHONE - -- (void) testDefaultStoreFolderForiOSDevicesIsTheApplicationSupportFolder -{ - NSString *applicationLibraryDirectory = [self applicationStorageDirectory]; - NSString *defaultStoreName = kMagicalRecordDefaultStoreFileName; - - NSURL *expectedStoreUrl = [NSURL fileURLWithPath:[applicationLibraryDirectory stringByAppendingPathComponent:defaultStoreName]]; - - NSURL *defaultStoreUrl = [NSPersistentStore defaultLocalStoreUrl]; - - assertThat(defaultStoreUrl, is(equalTo(expectedStoreUrl))); -} - - -- (void) testCanFindAURLInTheLibraryForiOSForASpecifiedStoreName -{ - NSString *storeFileName = @"NotTheDefaultStoreName.storefile"; - NSString *applicationLibraryDirectory = [self applicationStorageDirectory]; - NSString *testStorePath = [applicationLibraryDirectory stringByAppendingPathComponent:storeFileName]; - - BOOL fileWasCreated = [[NSFileManager defaultManager] createFileAtPath:testStorePath contents:[storeFileName dataUsingEncoding:NSUTF8StringEncoding] attributes:nil]; - - assertThatBool(fileWasCreated, is(equalToBool(YES))); - - NSURL *expectedFoundStoreUrl = [NSURL fileURLWithPath:testStorePath]; - NSURL *foundStoreUrl = [NSPersistentStore urlForStoreName:storeFileName]; - - assertThat(foundStoreUrl, is(equalTo(expectedFoundStoreUrl))); - - [[NSFileManager defaultManager] removeItemAtPath:testStorePath error:nil]; -} - -- (void) testCanFindAURLInDocumentsFolderForiOSForASpecifiedStoreName -{ - NSString *storeFileName = @"NotTheDefaultStoreName.storefile"; - NSString *documentDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; - NSString *testStorePath = [documentDirectory stringByAppendingPathComponent:storeFileName]; - - BOOL fileWasCreated = [[NSFileManager defaultManager] createFileAtPath:testStorePath contents:[storeFileName dataUsingEncoding:NSUTF8StringEncoding] attributes:nil]; - - assertThatBool(fileWasCreated, is(equalToBool(YES))); - - NSURL *expectedFoundStoreUrl = [NSURL fileURLWithPath:testStorePath]; - NSURL *foundStoreUrl = [NSPersistentStore urlForStoreName:storeFileName]; - - assertThat(foundStoreUrl, is(equalTo(expectedFoundStoreUrl))); - - [[NSFileManager defaultManager] removeItemAtPath:testStorePath error:nil]; -} - -#else - -- (void) testDefaultStoreFolderForMacIsTheApplicationSupportSlashApplicationFolder -{ - NSString *applictionSupportDirectory = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) lastObject]; - NSString *applicationName = [[[NSBundle mainBundle] infoDictionary] valueForKey:(NSString *)kCFBundleNameKey]; - NSString *defaultStoreName = kMagicalRecordDefaultStoreFileName; - - NSURL *expectedStoreUrl = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/%@/%@", applictionSupportDirectory, applicationName, defaultStoreName]]; - - NSURL *defaultStoreUrl = [NSPersistentStore defaultLocalStoreUrl]; - assertThat(defaultStoreUrl, is(equalTo(expectedStoreUrl))); -} - - -- (void) testCanFindAURLInTheApplicationSupportLibraryForMacForASpecifiedStoreName -{ - NSString *storeFileName = @"NotTheDefaultStoreName.storefile"; - NSString *applicationSupportDirectory = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) lastObject]; - NSString *applicationName = [[[NSBundle mainBundle] infoDictionary] valueForKey:(NSString *)kCFBundleNameKey]; - NSString *testStorePath = [applicationSupportDirectory stringByAppendingPathComponent:storeFileName]; - - BOOL fileWasCreated = [[NSFileManager defaultManager] createFileAtPath:testStorePath contents:[storeFileName dataUsingEncoding:NSUTF8StringEncoding] attributes:nil]; - - assertThatBool(fileWasCreated, is(equalToBool(YES))); - - NSURL *expectedStoreUrl = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/%@/%@", applicationSupportDirectory, applicationName, storeFileName]]; - - NSURL *foundStoreUrl = [NSPersistentStore urlForStoreName:storeFileName]; - - assertThat(foundStoreUrl, is(equalTo(expectedStoreUrl))); - - [[NSFileManager defaultManager] removeItemAtPath:testStorePath error:nil]; -} - -#endif - - -@end diff --git a/Project Files/Tests/Core/NSPersistentStoreCoordinatorHelperTests.h b/Project Files/Tests/Core/NSPersistentStoreCoordinatorHelperTests.h deleted file mode 100644 index f25f80864..000000000 --- a/Project Files/Tests/Core/NSPersistentStoreCoordinatorHelperTests.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// NSPersistentStoreCoordinatorHelperTests.h -// Magical Record -// -// Created by Saul Mora on 7/15/11. -// Copyright 2011 Magical Panda Software LLC. All rights reserved. -// - - - -@interface NSPersistentStoreCoordinatorHelperTests : GHTestCase - -@end diff --git a/Project Files/Tests/Core/NSPersistentStoreCoordinatorHelperTests.m b/Project Files/Tests/Core/NSPersistentStoreCoordinatorHelperTests.m deleted file mode 100644 index 31e0f2521..000000000 --- a/Project Files/Tests/Core/NSPersistentStoreCoordinatorHelperTests.m +++ /dev/null @@ -1,56 +0,0 @@ -// -// NSPersistentStoreCoordinatorHelperTests.m -// Magical Record -// -// Created by Saul Mora on 7/15/11. -// Copyright 2011 Magical Panda Software LLC. All rights reserved. -// - -#import "NSPersistentStoreCoordinatorHelperTests.h" - -@implementation NSPersistentStoreCoordinatorHelperTests - -- (void) setUp -{ - NSURL *testStoreURL = [NSPersistentStore MR_urlForStoreName:@"TestStore.sqlite"]; - [[NSFileManager defaultManager] removeItemAtPath:[testStoreURL path] error:nil]; -} - -- (void) testCreateCoodinatorWithSqlitePersistentStore -{ - NSPersistentStoreCoordinator *testCoordinator = [NSPersistentStoreCoordinator MR_coordinatorWithSqliteStoreNamed:@"TestStore.sqlite"]; - - assertThatUnsignedInteger([[testCoordinator persistentStores] count], is(equalToUnsignedInteger(1))); - - NSPersistentStore *store = [[testCoordinator persistentStores] objectAtIndex:0]; - assertThat([store type], is(equalTo(NSSQLiteStoreType))); -} - -- (void) testCreateCoordinatorWithInMemoryStore -{ - NSPersistentStoreCoordinator *testCoordinator = [NSPersistentStoreCoordinator MR_coordinatorWithInMemoryStore]; - - assertThatUnsignedInteger([[testCoordinator persistentStores] count], is(equalToUnsignedInteger(1))); - - NSPersistentStore *store = [[testCoordinator persistentStores] objectAtIndex:0]; - assertThat([store type], is(equalTo(NSInMemoryStoreType))); -} - -- (void) testCanAddAnInMemoryStoreToAnExistingCoordinator -{ - NSPersistentStoreCoordinator *testCoordinator = [NSPersistentStoreCoordinator MR_coordinatorWithSqliteStoreNamed:@"TestStore.sqlite"]; - - assertThatUnsignedInteger([[testCoordinator persistentStores] count], is(equalToUnsignedInteger(1))); - - NSPersistentStore *firstStore = [[testCoordinator persistentStores] objectAtIndex:0]; - assertThat([firstStore type], is(equalTo(NSSQLiteStoreType))); - - [testCoordinator MR_addInMemoryStore]; - - assertThatUnsignedInteger([[testCoordinator persistentStores] count], is(equalToUnsignedInteger(2))); - - NSPersistentStore *secondStore = [[testCoordinator persistentStores] objectAtIndex:1]; - assertThat([secondStore type], is(equalTo(NSInMemoryStoreType))); -} - -@end diff --git a/Project Files/Tests/DataImport/ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m b/Project Files/Tests/DataImport/ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m deleted file mode 100644 index 11e5a01c9..000000000 --- a/Project Files/Tests/DataImport/ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m +++ /dev/null @@ -1,109 +0,0 @@ -// -// ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m -// Magical Record -// -// Created by Saul Mora on 8/11/11. -// Copyright (c) 2011 Magical Panda Software LLC. All rights reserved. -// - -#import "MappedEntity.h" -#import "SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.h" -#import "MagicalDataImportTestCase.h" - -@interface ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests : MagicalDataImportTestCase - -@end - -@implementation ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests - -- (void) setupTestData -{ - NSManagedObjectContext *context = [NSManagedObjectContext MR_defaultContext]; - - MappedEntity *testMappedEntity = [MappedEntity createInContext:context]; - testMappedEntity.testMappedEntityIDValue = 42; - testMappedEntity.sampleAttribute = @"This attribute created as part of the test case setup"; - - [context MR_saveToPersistentStoreAndWait]; -} - -- (Class) testEntityClass -{ - return [SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey class]; -} - -- (void) testImportMappedEntityRelatedViaToOneRelationship -{ - SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey *entity = [[self testEntityClass] MR_importFromObject:self.testEntityData]; - [[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait]; - - id testRelatedEntity = entity.mappedEntity; - - //verify mapping in relationship description userinfo - NSEntityDescription *mappedEntity = [entity entity]; - NSRelationshipDescription *testRelationship = [[mappedEntity propertiesByName] valueForKey:@"mappedEntity"]; - assertThat([[testRelationship userInfo] valueForKey:kMagicalRecordImportRelationshipMapKey], is(equalTo(@"someRandomAttributeName"))); - - assertThat([SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey numberOfEntities], is(equalToInteger(1))); - assertThat([MappedEntity numberOfEntities], is(equalToInteger(1))); - assertThat(testRelatedEntity, is(notNilValue())); - assertThat([testRelatedEntity sampleAttribute], is(containsString(@"sample json file"))); -} - -//- (void) testUpdateMappedEntityRelatedViaToOneRelationship -//{ -// SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey *entity = [SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey createEntity]; -// [entity MR_updateValuesForKeysWithObject:self.testEntityData]; -// [[NSManagedObjectContext MR_defaultContext] MR_save]; -// -// id testRelatedEntity = entity.mappedEntity; -// -// //verify mapping in relationship description userinfo -// NSEntityDescription *mappedEntity = [entity entity]; -// NSRelationshipDescription *testRelationship = [[mappedEntity propertiesByName] valueForKey:@"mappedEntity"]; -// assertThat([[testRelationship userInfo] valueForKey:kMagicalRecordImportRelationshipMapKey], is(equalTo(@"someRandomAttributeName"))); -// -// assertThat([SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey numberOfEntities], is(equalToInteger(1))); -// assertThat([MappedEntity numberOfEntities], is(equalToInteger(1))); -// assertThat(testRelatedEntity, is(notNilValue())); -// assertThat([testRelatedEntity sampleAttribute], is(containsString(@"sample json file"))); -//} - -- (void) testImportMappedEntityUsingPrimaryRelationshipKey -{ - SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey *entity = [[self testEntityClass] MR_importFromObject:self.testEntityData]; - [[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait]; - - id testRelatedEntity = entity.mappedEntity; - - //verify mapping in relationship description userinfo - NSEntityDescription *mappedEntity = [entity entity]; - NSRelationshipDescription *testRelationship = [[mappedEntity propertiesByName] valueForKey:@"mappedEntity"]; - assertThat([[testRelationship userInfo] valueForKey:kMagicalRecordImportRelationshipLinkedByKey], is(equalTo(@"testMappedEntityID"))); - - assertThat([SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey numberOfEntities], is(equalToInteger(1))); - assertThat([MappedEntity numberOfEntities], is(equalToInteger(1))); - assertThat([testRelatedEntity testMappedEntityID], is(equalToInteger(42))); - assertThat([testRelatedEntity sampleAttribute], containsString(@"sample json file")); -} - -//- (void) testUpdateMappedEntityUsingPrimaryRelationshipKey -//{ -// SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey *entity = [SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey createEntity]; -// [entity MR_updateValuesForKeysWithObject:self.testEntityData]; -// [[NSManagedObjectContext MR_defaultContext] MR_save]; -// -// id testRelatedEntity = entity.mappedEntity; -// -// //verify mapping in relationship description userinfo -// NSEntityDescription *mappedEntity = [entity entity]; -// NSRelationshipDescription *testRelationship = [[mappedEntity propertiesByName] valueForKey:@"mappedEntity"]; -// assertThat([[testRelationship userInfo] valueForKey:kMagicalRecordImportRelationshipLinkedByKey], is(equalTo(@"testMappedEntityID"))); -// -// assertThat([MappedEntity numberOfEntities], is(equalToInteger(1))); -// assertThat([testRelatedEntity testMappedEntityID], is(equalToInteger(42))); -// assertThat([testRelatedEntity sampleAttribute], containsString(@"sample json file")); -//} - - -@end diff --git a/Project Files/Tests/DataImport/ImportSingleEntityWithNoRelationshipsTests.m b/Project Files/Tests/DataImport/ImportSingleEntityWithNoRelationshipsTests.m deleted file mode 100644 index b4f379962..000000000 --- a/Project Files/Tests/DataImport/ImportSingleEntityWithNoRelationshipsTests.m +++ /dev/null @@ -1,193 +0,0 @@ -// -// DataImportTests.m -// Magical Record -// -// Created by Saul Mora on 7/15/11. -// Copyright 2011 Magical Panda Software LLC. All rights reserved. -// - -#import "SingleEntityWithNoRelationships.h" - -@interface ImportSingleEntityWithNoRelationshipsTests : GHTestCase - -@property (nonatomic, retain) SingleEntityWithNoRelationships *testEntity; - -@end - -@implementation ImportSingleEntityWithNoRelationshipsTests - -@synthesize testEntity; - -- (void) setUpClass -{ - [NSManagedObjectModel MR_setDefaultManagedObjectModel:[NSManagedObjectModel MR_managedObjectModelNamed:@"TestModel.momd"]]; - [MagicalRecord setupCoreDataStackWithInMemoryStore]; - - id singleEntity = [self dataFromJSONFixture]; - - testEntity = [SingleEntityWithNoRelationships MR_importFromObject:singleEntity]; -} - -- (void) tearDownClass -{ - [MagicalRecord cleanUp]; -} - -- (void) testImportASingleEntity -{ - assertThat(testEntity, is(notNilValue())); -} - -- (void) testImportStringAttributeToEntity -{ - assertThat(testEntity.stringTestAttribute, is(equalTo(@"This is a test value"))); -} - -- (void) testImportInt16AttributeToEntity -{ - assertThat(testEntity.int16TestAttribute, is(equalToInteger(256))); -} - -- (void) testImportInt32AttributeToEntity -{ - assertThat(testEntity.int32TestAttribute, is(equalToInt(32))); -} - -- (void) testImportInt64AttributeToEntity -{ - assertThat(testEntity.int64TestAttribute, is(equalToInteger(42))); -} - -- (void) testImportDecimalAttributeToEntity -{ - assertThat(testEntity.decimalTestAttribute, is(equalToDouble(1.2))); -} - -- (void) testImportDoubleAttributeToEntity -{ - assertThat(testEntity.doubleTestAttribute, is(equalToDouble(124.3))); -} - -- (void) testImportFloatAttributeToEntity -{ - assertThat(testEntity.floatTestAttribute, is(equalToFloat(10000000000))); -} - -- (void) testImportBooleanAttributeToEntity -{ - assertThat(testEntity.booleanTestAttribute, is(equalToBool(NO))); -} - -- (void) testImportMappedStringAttributeToEntity -{ - assertThat(testEntity.mappedStringAttribute, is(equalTo(@"Mapped value"))); -} - -- (void) testImportStringAttributeWithNullValue -{ - assertThat(testEntity.nullTestAttribute, is(nilValue())); -} - -- (void) testImportAttributeNotInJsonData -{ - assertThat(testEntity.notInJsonAttribute, containsString(@"Core Data Model")); -} - -#if TARGET_OS_IPHONE - -#if defined(__IPHONE_5_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_5_0 - -- (void) testImportUIColorAttributeToEntity -{ - UIColor *actualColor = testEntity.colorTestAttribute; - - if ([actualColor respondsToSelector:@selector(getRed:green:blue:alpha:)]) - { - CGFloat red, blue, green, alpha; - [actualColor getRed:&red green:&green blue:&blue alpha:&alpha]; - - assertThatFloat(alpha, is(equalToFloat(1.))); - assertThatFloat(red, is(equalToFloat(64.0f/255.0f))); - assertThatFloat(green, is(equalToFloat(128.0f/255.0f))); - assertThatFloat(blue, is(equalToFloat(225.0f/255.0f))); - } -} -#endif - -- (NSDate *) dateFromString:(NSString *)date -{ - NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; - formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss ZZZ"; - formatter.timeZone = [NSTimeZone timeZoneWithName:@"GMT"]; - formatter.locale = [NSLocale currentLocale]; - - NSDate *expectedDate = [formatter dateFromString:date]; - - return expectedDate; -} - -#else - -- (void) testImportNSColorAttributeToEntity -{ -#warning Proper fix is to extract out color tests to seperate mac and iOS specific model files with proper configurations - NSColor *actualColor = (NSColor *)[testEntity colorTestAttribute]; - - assertThatDouble([actualColor alphaComponent], is(equalToDouble(255.0/255.0))); - assertThatDouble([actualColor redComponent], is(equalToFloat(64.0f/255.0f))); - assertThatDouble([actualColor greenComponent], is(equalToFloat(128.0f/255.0f))); - assertThatDouble([actualColor blueComponent], is(equalToFloat(225.0f/255.0f))); -} - -- (NSDate *) dateFromString:(NSString *)date -{ - NSDate *expectedDate = [NSDate dateWithString:date]; - return expectedDate; -} - -#endif - -- (void) testImportDateAttributeToEntity -{ - NSDate *expectedDate = [self dateFromString:@"2011-07-23 22:30:40 +0000"]; - assertThat(testEntity.dateTestAttribute, is(equalTo(expectedDate))); -} - -- (void) testImportDateAttributeWithCustomFormat -{ - NSDate *expectedDate = [self dateFromString:@"2011-08-05 00:56:04 +0000"]; - assertThat(testEntity.dateWithCustomFormat, is(equalTo(expectedDate))); - -} - -- (void) testImportInt16AsStringAttributeToEntity -{ - assertThat(testEntity.int16AsStringTestAttribute, is(equalToInteger(256))); -} - -- (void) testImportInt32AsStringAttributeToEntity -{ - assertThat(testEntity.int32AsStringTestAttribute, is(equalToInt(32))); -} - -- (void) testImportInt64AsStringAttributeToEntity -{ - assertThat(testEntity.int64AsStringTestAttribute, is(equalToInteger(42))); -} - -- (void) testImportDecimalAsStringAttributeToEntity -{ - assertThat(testEntity.decimalAsStringTestAttribute, is(equalToDouble(1.2))); -} - -- (void) testImportDoubleAsStringAttributeToEntity -{ - assertThat(testEntity.doubleAsStringTestAttribute, is(equalToDouble(124.3))); -} - -- (void) testImportFloatAsStringAttributeToEntity -{ - assertThat(testEntity.floatAsStringTestAttribute, is(equalToFloat(10000000000))); -} - -@end diff --git a/Project Files/Tests/DataImport/ImportSingleRelatedEntityTests.m b/Project Files/Tests/DataImport/ImportSingleRelatedEntityTests.m deleted file mode 100644 index 76a8d0789..000000000 --- a/Project Files/Tests/DataImport/ImportSingleRelatedEntityTests.m +++ /dev/null @@ -1,96 +0,0 @@ -// -// ImportSingleEntityWithRelatedEntitiesTests.m -// Magical Record -// -// Created by Saul Mora on 7/23/11. -// Copyright 2011 Magical Panda Software LLC. All rights reserved. -// - -#import "SingleRelatedEntity.h" -#import "AbstractRelatedEntity.h" -#import "ConcreteRelatedEntity.h" -#import "MappedEntity.h" -#import "MagicalDataImportTestCase.h" - -@interface ImportSingleRelatedEntityTests : MagicalDataImportTestCase - -@property (nonatomic, retain) SingleRelatedEntity *singleTestEntity; - -@end - -@implementation ImportSingleRelatedEntityTests - -@synthesize singleTestEntity = _singleTestEntity;; - -- (void) setupTestData -{ - NSManagedObjectContext *context = [NSManagedObjectContext MR_defaultContext]; - - MappedEntity *testMappedEntity = [MappedEntity createInContext:context]; - testMappedEntity.testMappedEntityIDValue = 42; - testMappedEntity.sampleAttribute = @"This attribute created as part of the test case setup"; - - [context MR_saveToPersistentStoreAndWait]; -} - -- (void) setUp -{ - [super setUp]; - self.singleTestEntity = [SingleRelatedEntity MR_importFromObject:self.testEntityData]; - [[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait]; -} - -- (void) testImportAnEntityRelatedToAbstractEntityViaToOneRelationshop -{ - assertThat(self.singleTestEntity, is(notNilValue())); - - id testRelatedEntity = self.singleTestEntity.testAbstractToOneRelationship; - - assertThat(testRelatedEntity, is(notNilValue())); - assertThat([testRelatedEntity sampleBaseAttribute], containsString(@"BASE")); - assertThatBool([testRelatedEntity respondsToSelector:@selector(sampleConcreteAttribute)], is(equalToBool(NO))); -} - -- (void) testImportAnEntityRelatedToAbstractEntityViaToManyRelationship -{ - assertThat(self.singleTestEntity, is(notNilValue())); - assertThatInteger([self.singleTestEntity.testAbstractToManyRelationship count], is(equalToInteger(2))); - - id testRelatedEntity = [self.singleTestEntity.testAbstractToManyRelationship anyObject]; - - assertThat(testRelatedEntity, is(notNilValue())); - assertThat([testRelatedEntity sampleBaseAttribute], containsString(@"BASE")); - assertThatBool([testRelatedEntity respondsToSelector:@selector(sampleConcreteAttribute)], is(equalToBool(NO))); -} - - -#pragma mark - Subentity tests - - -- (void) testImportAnEntityRelatedToAConcreteSubEntityViaToOneRelationship -{ - id testRelatedEntity = self.singleTestEntity.testConcreteToOneRelationship; - assertThat(testRelatedEntity, is(notNilValue())); - - assertThat([testRelatedEntity sampleBaseAttribute], containsString(@"BASE")); - assertThat([testRelatedEntity sampleConcreteAttribute], containsString(@"DECENDANT")); -} - -- (void) testImportAnEntityRelatedToASubEntityViaToManyRelationship -{ - assertThatInteger([self.singleTestEntity.testConcreteToManyRelationship count], is(equalToInteger(3))); - - id testRelatedEntity = [self.singleTestEntity.testConcreteToManyRelationship anyObject]; - assertThat(testRelatedEntity, is(notNilValue())); - - assertThat([testRelatedEntity sampleBaseAttribute], containsString(@"BASE")); - assertThat([testRelatedEntity sampleConcreteAttribute], containsString(@"DECENDANT")); -} - - -//Test ordered to many - - - - -@end diff --git a/Project Files/Tests/DataImport/MagicalDataImportTestCase.h b/Project Files/Tests/DataImport/MagicalDataImportTestCase.h deleted file mode 100644 index 32b90f0c2..000000000 --- a/Project Files/Tests/DataImport/MagicalDataImportTestCase.h +++ /dev/null @@ -1,21 +0,0 @@ -// -// MagicalDataImportTestCase.h -// Magical Record -// -// Created by Saul Mora on 8/16/11. -// Copyright (c) 2011 Magical Panda Software LLC. All rights reserved. -// - -#ifdef MAC_PLATFORM_ONLY -#import -#else -#import -#endif -@interface MagicalDataImportTestCase : GHTestCase - -@property (nonatomic, retain) id testEntityData; -@property (nonatomic, retain) id testEntity; - -- (Class) testEntityClass; - -@end diff --git a/Project Files/Tests/DataImport/MagicalDataImportTestCase.m b/Project Files/Tests/DataImport/MagicalDataImportTestCase.m deleted file mode 100644 index 7cf42b673..000000000 --- a/Project Files/Tests/DataImport/MagicalDataImportTestCase.m +++ /dev/null @@ -1,45 +0,0 @@ -// -// MagicalDataImportTestCase.m -// Magical Record -// -// Created by Saul Mora on 8/16/11. -// Copyright (c) 2011 Magical Panda Software LLC. All rights reserved. -// - -#import "MagicalDataImportTestCase.h" - -@implementation MagicalDataImportTestCase - -@synthesize testEntityData = testEntityData__; -@synthesize testEntity = testEntity__; - -- (void) setUp -{ - [MagicalRecord setDefaultModelNamed:@"TestModel.momd"]; - [MagicalRecord setupCoreDataStackWithInMemoryStore]; - //[MagicalRecord setupCoreDataStack]; - - if ([self respondsToSelector:@selector(setupTestData)]) - { - [self performSelector:@selector(setupTestData)]; - } - - self.testEntityData = [self dataFromJSONFixture]; -} - -- (void) tearDown -{ - [MagicalRecord cleanUp]; -} - -- (Class) testEntityClass; -{ - return [NSManagedObject class]; -} - --(BOOL)shouldRunOnMainThread -{ - return YES; -} - -@end diff --git a/Project Files/Tests/Fixtures/Mac/TestModel.xcdatamodeld/.xccurrentversion b/Project Files/Tests/Fixtures/Mac/TestModel.xcdatamodeld/.xccurrentversion deleted file mode 100644 index 0c67376eb..000000000 --- a/Project Files/Tests/Fixtures/Mac/TestModel.xcdatamodeld/.xccurrentversion +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/Project Files/Tests/MagicalDataImportTestCase.h.orig b/Project Files/Tests/MagicalDataImportTestCase.h.orig deleted file mode 100644 index b86b98dcb..000000000 --- a/Project Files/Tests/MagicalDataImportTestCase.h.orig +++ /dev/null @@ -1,24 +0,0 @@ -// -// MagicalDataImportTestCase.h -// Magical Record -// -// Created by Saul Mora on 8/16/11. -// Copyright (c) 2011 Magical Panda Software LLC. All rights reserved. -// - -<<<<<<< HEAD:Project Files/Unit Tests/MagicalDataImportTestCase.h -======= -#ifdef MAC_PLATFORM_ONLY -#import -#else -#import -#endif ->>>>>>> master:Unit Tests/MagicalDataImportTestCase.h -@interface MagicalDataImportTestCase : GHTestCase - -@property (nonatomic, retain) id testEntityData; -@property (nonatomic, retain) id testEntity; - -- (Class) testEntityClass; - -@end diff --git a/Project Files/Tests/MagicalRecord+ActionsSpec.m b/Project Files/Tests/MagicalRecord+ActionsSpec.m deleted file mode 100644 index a4fe9e5e3..000000000 --- a/Project Files/Tests/MagicalRecord+ActionsSpec.m +++ /dev/null @@ -1,390 +0,0 @@ -#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]; - }); - - it(@"should make inserted entities available to the default context", ^{ - __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_defaultContext] objectWithID:objectId]; - - [[fetchedObject should] beNonNil]; - [[@([fetchedObject hasChanges]) should] beFalse]; - }); - - it(@"should make updates to entities available to the default context", ^{ - __block NSManagedObjectID *objectId; - __block NSManagedObject *fetchedObject; - - NSString * const kTestAttributeKey = @"booleanTestAttribute"; - - [MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) { - NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:localContext]; - - [inserted setValue:@YES forKey:kTestAttributeKey]; - - [[@([inserted hasChanges]) should] beTrue]; - - [localContext obtainPermanentIDsForObjects:@[inserted] error:nil]; - objectId = [inserted objectID]; - }]; - - fetchedObject = [[NSManagedObjectContext MR_defaultContext] objectWithID:objectId]; - [[[fetchedObject valueForKey:kTestAttributeKey] should] beTrue]; - - [MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) { - NSManagedObject *changed = [localContext objectWithID:objectId]; - - [changed setValue:@NO forKey:kTestAttributeKey]; - }]; - - fetchedObject = [[NSManagedObjectContext MR_defaultContext] objectWithID:objectId]; - - // Async since the merge to the main thread context after persistence - [[expectFutureValue([fetchedObject valueForKey:kTestAttributeKey]) shouldEventually] 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]; - }); - - it(@"should make inserted entities available to the default context", ^{ - __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_defaultContext] objectWithID:objectId]; - }]; - - [[expectFutureValue(@(saveSuccessState)) shouldEventually] beTrue]; - [[expectFutureValue(fetchedObject) shouldEventually] beNonNil]; - [[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beFalse]; - }); - - it(@"should make updates to entities available to the default context", ^{ - __block NSManagedObjectID *objectId; - __block NSManagedObject *fetchedObject; - - NSString * const kTestAttributeKey = @"booleanTestAttribute"; - - [MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) { - NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:localContext]; - - [inserted setValue:@YES forKey:kTestAttributeKey]; - - [[@([inserted hasChanges]) should] beTrue]; - - [localContext obtainPermanentIDsForObjects:@[inserted] error:nil]; - objectId = [inserted objectID]; - }]; - - fetchedObject = [[NSManagedObjectContext MR_defaultContext] objectWithID:objectId]; - [[[fetchedObject valueForKey:kTestAttributeKey] should] beTrue]; - - [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) { - NSManagedObject *changed = [localContext objectWithID:objectId]; - - [changed setValue:@NO forKey:kTestAttributeKey]; - } completion:^(BOOL success, NSError *error) { - fetchedObject = [[NSManagedObjectContext MR_defaultContext] objectWithID:objectId]; - }]; - - - [[expectFutureValue([fetchedObject valueForKey:kTestAttributeKey]) 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 diff --git a/Project Files/Tests/NSManagedObjectContext+MagicalSavesSpec.m b/Project Files/Tests/NSManagedObjectContext+MagicalSavesSpec.m deleted file mode 100644 index f0ecca5e2..000000000 --- a/Project Files/Tests/NSManagedObjectContext+MagicalSavesSpec.m +++ /dev/null @@ -1,528 +0,0 @@ -#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 diff --git a/Project Files/Tests/SaveTests.m b/Project Files/Tests/SaveTests.m deleted file mode 100644 index 94456edd1..000000000 --- a/Project Files/Tests/SaveTests.m +++ /dev/null @@ -1,188 +0,0 @@ -// -// SaveTests.m -// Magical Record -// -// Created by Stephen J Vanterpool on 9/6/12. -// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. -// - -#define EXP_SHORTHAND -#import "Expecta.h" -#import "SaveTests.h" -#import "SingleEntityWithNoRelationships.h" - -@implementation SaveTests - -- (void) setUpClass -{ - [NSManagedObjectModel MR_setDefaultManagedObjectModel:[NSManagedObjectModel MR_managedObjectModelNamed:@"TestModel.momd"]]; -} - -- (void) setUp -{ - NSLog(@"Creating stack"); - [MagicalRecord setupCoreDataStackWithInMemoryStore]; -} - -- (void) tearDown -{ - [MagicalRecord cleanUp]; -} - -- (void)testAsynchronousSaveCallsCompletionHandler -{ - __block BOOL completionHandlerCalled = NO; - - dispatch_group_t group = dispatch_group_create(); - - dispatch_group_enter(group); - - [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) { - expect(localContext).toNot.beNil(); - [SingleEntityWithNoRelationships MR_createInContext:localContext]; - } completion:^(BOOL success, NSError *error) { - // Ignore the success state — we only care that this block is executed - completionHandlerCalled = YES; - dispatch_group_leave(group); - }]; - - dispatch_group_wait(group, DISPATCH_TIME_FOREVER); - expect(completionHandlerCalled).will.beTruthy(); -} - -- (void)testAsynchronousSavesActuallySave -{ - __block BOOL saveSuccessState = NO; - __block NSManagedObjectID *objectId; - __block NSManagedObject *fetchedObject; - - dispatch_group_t group = dispatch_group_create(); - - dispatch_group_enter(group); - - [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) { - NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:localContext]; - expect([inserted hasChanges]).to.beTruthy(); - [localContext obtainPermanentIDsForObjects:@[inserted] error:nil]; - objectId = inserted.objectID; - } completion:^(BOOL success, NSError *error) { - saveSuccessState = success; - fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectWithID:objectId]; - dispatch_group_leave(group); - }]; - - dispatch_group_wait(group, DISPATCH_TIME_FOREVER); - expect(saveSuccessState).to.beTruthy(); - expect(fetchedObject).toNot.beNil(); - expect([fetchedObject hasChanges]).to.beFalsy(); -} - -- (void)testAsynchronousSavesAreAvailableInDefaultContext -{ - __block BOOL saveSuccessState = NO; - __block NSManagedObjectID *objectId; - __block NSManagedObject *fetchedObject; - - dispatch_group_t group = dispatch_group_create(); - - dispatch_group_enter(group); - - [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) { - NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:localContext]; - expect([inserted hasChanges]).to.beTruthy(); - [localContext obtainPermanentIDsForObjects:@[inserted] error:nil]; - objectId = inserted.objectID; - } completion:^(BOOL success, NSError *error) { - saveSuccessState = success; - fetchedObject = [[NSManagedObjectContext MR_defaultContext] objectWithID:objectId]; - dispatch_group_leave(group); - }]; - - dispatch_group_wait(group, DISPATCH_TIME_FOREVER); - expect(saveSuccessState).to.beTruthy(); - expect(fetchedObject).toNot.beNil(); - expect([fetchedObject hasChanges]).to.beFalsy(); -} - -- (void)testSynchronousSavesActuallySave -{ - __block NSManagedObjectID *objectId; - __block NSManagedObject *fetchedObject; - - [MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) { - NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:localContext]; - expect([inserted hasChanges]).to.beTruthy(); - [localContext obtainPermanentIDsForObjects:@[inserted] error:nil]; - objectId = inserted.objectID; - }]; - - fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectWithID:objectId]; - - expect(fetchedObject).toNot.beNil(); - expect([fetchedObject hasChanges]).to.beFalsy(); -} - -#pragma mark - Test deprecated methods still work as expected - -- (void)testDeprecatedSimpleSynchronousSaveActuallySaves -{ - NSManagedObjectContext *managedObjectContext = [NSManagedObjectContext MR_defaultContext]; - NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:managedObjectContext]; - - expect([inserted hasChanges]).to.beTruthy(); - [managedObjectContext obtainPermanentIDsForObjects:@[inserted] error:nil]; - NSManagedObjectID *objectId = inserted.objectID; - - [managedObjectContext MR_save]; - - NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectWithID:objectId]; - expect(fetchedObject).toNot.beNil(); - expect([fetchedObject hasChanges]).to.beFalsy(); -} - -- (void)testDeprecatedBackgroundSaveCallsCompletionHandler -{ - __block BOOL didSave = NO; - - dispatch_group_t group = dispatch_group_create(); - - dispatch_group_enter(group); - - [MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *localContext) { - expect(localContext).toNot.beNil(); - [SingleEntityWithNoRelationships MR_createInContext:localContext]; - } completion:^{ - didSave = YES; - dispatch_group_leave(group); - }]; - - dispatch_group_wait(group, DISPATCH_TIME_FOREVER); - expect(didSave).will.beTruthy(); -} - -- (void)testDeprecatedBackgroundSavesActuallySave -{ - __block NSManagedObjectID *objectId; - __block NSManagedObject *fetchedObject; - - dispatch_group_t group = dispatch_group_create(); - - dispatch_group_enter(group); - - [MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *localContext) { - NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:localContext]; - expect([inserted hasChanges]).to.beTruthy(); - - [localContext obtainPermanentIDsForObjects:@[inserted] error:nil]; - objectId = inserted.objectID; - } completion:^{ - fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectWithID:objectId]; - dispatch_group_leave(group); - }]; - - dispatch_group_wait(group, DISPATCH_TIME_FOREVER); - expect(fetchedObject).toNot.beNil(); - expect([fetchedObject hasChanges]).to.beFalsy(); -} - -@end diff --git a/Project Files/Tests/Support/Vendor/Expecta b/Project Files/Tests/Support/Vendor/Expecta deleted file mode 160000 index abc3d8328..000000000 --- a/Project Files/Tests/Support/Vendor/Expecta +++ /dev/null @@ -1 +0,0 @@ -Subproject commit abc3d83283fdc3942413e2f3603be6dbb2fe44b8 diff --git a/Project Files/Tests/Support/Vendor/Kiwi b/Project Files/Tests/Support/Vendor/Kiwi deleted file mode 160000 index 25bfee40a..000000000 --- a/Project Files/Tests/Support/Vendor/Kiwi +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 25bfee40a092a5cbeba57d896dd46da57e66b604 diff --git a/Project Files/Tests/Support/en.lproj/InfoPlist.strings b/Project Files/Tests/Support/en.lproj/InfoPlist.strings deleted file mode 100644 index 477b28ff8..000000000 --- a/Project Files/Tests/Support/en.lproj/InfoPlist.strings +++ /dev/null @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/Project Files/generateShorthandFile.rb b/Project Files/generateShorthandFile.rb deleted file mode 100755 index 0733d4d11..000000000 --- a/Project Files/generateShorthandFile.rb +++ /dev/null @@ -1,133 +0,0 @@ -#!/usr/bin/env ruby -# -# ProcessHeader.rb -# Magical Record -# -# Created by Saul Mora on 11/14/11. -# Copyright 2011 Magical Panda Software LLC. All rights reserved. -# - - -def processHeader(headerFile) - unless headerFile.end_with? ".h" - puts "#{headerFile} not a header" - return - end - - puts "Reading #{headerFile}" - - method_match_expression = /^(?[\+|\-]\s*\([a-zA-Z\s\*]*\)\s*)(?\w+)(?\:?.*)/ - category_match_expression = /^\s*(?@[[:alnum:]]+)\s*(?[[:alnum:]]+)\s*(\((?\w+)\))?/ - - lines = File.readlines(headerFile) - non_prefixed_methods = [] - processed_methods_count = 0 - objects_to_process = ["NSManagedObject", "NSManagedObjectContext", "NSManagedObjectModel", "NSPersistentStoreCoordinator", "NSPersistentStore"] - - lines.each { |line| - - processed_line = nil - if line.start_with?("@interface") - matches = category_match_expression.match(line) - if objects_to_process.include?(matches[:ObjectName]) - processed_line = "#{matches[:Interface]} #{matches[:ObjectName]} (#{matches[:Category]}ShortHand)" - else - puts "Skipping #{headerFile}" - non_prefixed_methods = nil - return - end - end - - if processed_line == nil - matches = method_match_expression.match(line) - - if matches - if matches[:MethodName].start_with?("MR_") - ++processed_methods_count - methodName = matches[:MethodName].sub("MR_", "") - processed_line = "#{matches[:Start]}#{methodName}#{matches[:End]}" - - else - puts "Skipping #{headerFile}" - non_prefixed_methods = nil - return - end - end - end - - if processed_line == nil - if line.start_with?("@end") - processed_line = "@end" - end - end - - unless processed_line == nil - # puts "#{line} -----> #{processed_line}" - non_prefixed_methods << processed_line - end - } - - non_prefixed_methods -end - -def processDirectory(path) - - headers = File.join(path, "**", "*+*.h") - processedHeaders = [] - - Dir.glob(headers).each { |file| - puts "Processing #{file}" - - processDirectory(file) if File.directory?(file) - if file.end_with?(".h") - processedHeaders << processHeader(file) - end - } - - processedHeaders -end - -def generateHeaders(startingPoint) - - processedHeaders = [] - if startingPoint - path = File.expand_path(startingPoint) - - if path.end_with?(".h") - processedHeaders << processHeader(path) - else - puts "Processing Headers in #{path}" - processedHeaders << processDirectory(path) - end - - else - processedHeaders << processDirectory(startingPoint || Dir.getwd()) - end - - processedHeaders -end - - -puts "Input dir: #{File.expand_path(ARGV[0])}" - -output_file = ARGV[1] -puts "Output file: #{File.expand_path(output_file)}" - -unless output_file - puts "Need an output file specified" - return -else - puts "Genrating shorthand headers" -end - -headers = generateHeaders(ARGV[0]) - -File.open(output_file, "w") { |file| - file.write("#ifdef MR_SHORTHAND\n\n") - file.write(headers.join("\n")) - file.write("#endif\n\n") -} - - - - diff --git a/README.md b/README.md index ddc90f932..1f5e89bd2 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # ![Awesome](https://github.com/magicalpanda/magicalpanda.github.com/blob/master/images/awesome_logo_small.png?raw=true) MagicalRecord +[![Circle CI](https://circleci.com/gh/magicalpanda/MagicalRecord/tree/develop.svg?style=svg)](https://circleci.com/gh/magicalpanda/MagicalRecord/tree/develop) + In software engineering, the active record pattern is a design pattern found in software that stores its data in relational databases. It was named by Martin Fowler in his book Patterns of Enterprise Application Architecture. The interface to such an object would include functions such as Insert, Update, and Delete, plus properties that correspond more-or-less directly to the columns in the underlying database table. > Active record is an approach to accessing data in a database. A database table or view is wrapped into a class; thus an object instance is tied to a single row in the table. After creation of an object, a new row is added to the table upon save. Any object loaded gets its information from the database; when an object is updated, the corresponding row in the table is also updated. The wrapper class implements accessor methods or properties for each column in the table or view. @@ -12,4 +14,28 @@ MagicalRecord was inspired by the ease of Ruby on Rails' Active Record fetching. * Allow for clear, simple, one-line fetches * Still allow the modification of the NSFetchRequest when request optimizations are needed +## Documentation + +- [Installation](Docs/Installing-MagicalRecord.md) +- [Getting Started](Docs/Getting-Started.md) +- [Working with Managed Object Contexts](Docs/Working-with-Managed-Object-Contexts.md) +- [Creating Entities](Docs/Creating-Entities.md) +- [Deleting Entities](Docs/Deleting-Entities.md) +- [Fetching Entities](Docs/Fetching-Entities.md) +- [Saving Entities](Docs/Saving-Entities.md) +- [Importing Data](Docs/Importing-Data.md) +- [Logging](Docs/Logging.md) +* [Other Resources](Docs/Other-Resources.md) + +## Support + +MagicalRecord is provided as-is, free of charge. For support, you have a few choices: + +- Ask your support question on [Stackoverflow.com](http://stackoverflow.com), and tag your question with **MagicalRecord**. The core team will be notified of your question only if you mark your question with this tag. The general Stack Overflow community is provided the opportunity to answer the question to help you faster, and to reap the reputation points. If the community is unable to answer, we'll try to step in and answer your question. +- If you believe you have found a bug in MagicalRecord, please submit a support ticket on the [Github Issues page for MagicalRecord](http://github.com/magicalpanda/magicalrecord/issues). We'll get to them as soon as we can. Please do **NOT** ask general questions on the issue tracker. Support questions will be closed unanswered. +- For more personal or immediate support, [MagicalPanda](http://magicalpanda.com/) is available for hire to consult on your project. + + +## Twitter +Follow [@MagicalRecord](http://twitter.com/magicalrecord) on twitter to stay up to date with the latest updates relating to MagicalRecord. diff --git a/Samples/Mac/Mac Sample App.xcodeproj/project.pbxproj b/Samples/Mac/Mac Sample App.xcodeproj/project.pbxproj deleted file mode 100644 index a928b1fca..000000000 --- a/Samples/Mac/Mac Sample App.xcodeproj/project.pbxproj +++ /dev/null @@ -1,67 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXGroup section */ - C7CF965417496776008D9D13 = { - isa = PBXGroup; - children = ( - ); - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXProject section */ - C7CF965517496776008D9D13 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0460; - }; - buildConfigurationList = C7CF965817496776008D9D13 /* Build configuration list for PBXProject "Mac Sample App" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = C7CF965417496776008D9D13; - projectDirPath = ""; - projectRoot = ""; - targets = ( - ); - }; -/* End PBXProject section */ - -/* Begin XCBuildConfiguration section */ - C7CF965917496776008D9D13 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - }; - name = Debug; - }; - C7CF965A17496776008D9D13 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - C7CF965817496776008D9D13 /* Build configuration list for PBXProject "Mac Sample App" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C7CF965917496776008D9D13 /* Debug */, - C7CF965A17496776008D9D13 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = C7CF965517496776008D9D13 /* Project object */; -} diff --git a/Samples/iOS/Application/Controllers/ImperialPickerController.m b/Samples/iOS/Application/Controllers/ImperialPickerController.m index 1285f9267..53fe17b0a 100644 --- a/Samples/iOS/Application/Controllers/ImperialPickerController.m +++ b/Samples/iOS/Application/Controllers/ImperialPickerController.m @@ -123,7 +123,7 @@ - (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forC } // The text shown in the component is just the number of the component. - NSString *text = [NSString stringWithFormat:@"%d", row]; + NSString *text = [NSString stringWithFormat:@"%zd", row]; // Where to set the text in depends on what sort of view it is. UILabel *theLabel = nil; @@ -168,7 +168,7 @@ - (void)updateLabel { if (grams > 1000.0) { NSInteger kg = grams / 1000; grams -= kg *1000; - self.label.text = [NSString stringWithFormat:@"%d kg %1.0f g", kg, grams]; + self.label.text = [NSString stringWithFormat:@"%zd kg %1.0f g", kg, grams]; } else { self.label.text = [NSString stringWithFormat:@"%1.0f g", grams]; diff --git a/Samples/iOS/Application/Controllers/IngredientDetailViewController.m b/Samples/iOS/Application/Controllers/IngredientDetailViewController.m index 0163e21ca..b4d72dc18 100644 --- a/Samples/iOS/Application/Controllers/IngredientDetailViewController.m +++ b/Samples/iOS/Application/Controllers/IngredientDetailViewController.m @@ -133,9 +133,9 @@ - (void)save:(id)sender { If there isn't an ingredient object, create and configure one. */ if (!_ingredient) { - self.ingredient = [Ingredient MR_createInContext:context]; + self.ingredient = [Ingredient MR_createEntityInContext:context]; [_recipe addIngredientsObject:_ingredient]; - _ingredient.displayOrder = [NSNumber numberWithInteger:[_recipe.ingredients count]]; + _ingredient.displayOrder = @([_recipe.ingredients count]); } /* diff --git a/Samples/iOS/Application/Controllers/InstructionsViewController.m b/Samples/iOS/Application/Controllers/InstructionsViewController.m index 62147b3ba..7826265d3 100644 --- a/Samples/iOS/Application/Controllers/InstructionsViewController.m +++ b/Samples/iOS/Application/Controllers/InstructionsViewController.m @@ -53,6 +53,8 @@ @implementation InstructionsViewController - (void)viewDidLoad { + [super viewDidLoad]; + UINavigationItem *navigationItem = self.navigationItem; navigationItem.title = @"Instructions"; self.navigationItem.rightBarButtonItem = self.editButtonItem; @@ -62,11 +64,14 @@ - (void)viewDidLoad { - (void)viewDidUnload { self.instructionsText = nil; self.nameLabel = nil; + [super viewDidUnload]; } -- (void)viewWillAppear:(BOOL)animated { +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + // Update the views appropriately self.nameLabel.text = self.recipe.name; self.instructionsText.text = self.recipe.instructions; diff --git a/Samples/iOS/Application/Controllers/MetricPickerController.m b/Samples/iOS/Application/Controllers/MetricPickerController.m index d5318c8c6..6cc5ca031 100644 --- a/Samples/iOS/Application/Controllers/MetricPickerController.m +++ b/Samples/iOS/Application/Controllers/MetricPickerController.m @@ -145,7 +145,7 @@ - (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forC } // The text shown in the component is just the number of the component. - NSString *text = [NSString stringWithFormat:@"%d", row]; + NSString *text = [NSString stringWithFormat:@"%zd", row]; // Where to set the text in depends on what sort of view it is. UILabel *theLabel = nil; @@ -215,7 +215,7 @@ - (void)updateLabel { } ouncesDecimal = [[NSDecimalNumber alloc] initWithFloat:ounces]; roundedOunces = [ouncesDecimal decimalNumberByRoundingAccordingToBehavior:roundingBehavior]; - self.label.text = [NSString stringWithFormat:@"%d lbs %@ oz", lbs, roundedOunces]; + self.label.text = [NSString stringWithFormat:@"%zd lbs %@ oz", lbs, roundedOunces]; } else { ouncesDecimal = [[NSDecimalNumber alloc] initWithFloat:ounces]; diff --git a/Samples/iOS/Application/Controllers/RecipeAddViewController.m b/Samples/iOS/Application/Controllers/RecipeAddViewController.m index 054c04fca..a79c396a5 100644 --- a/Samples/iOS/Application/Controllers/RecipeAddViewController.m +++ b/Samples/iOS/Application/Controllers/RecipeAddViewController.m @@ -53,7 +53,8 @@ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF @implementation RecipeAddViewController - (void)viewDidLoad { - + [super viewDidLoad]; + // Configure the navigation bar self.navigationItem.title = @"Add Recipe"; @@ -69,6 +70,7 @@ - (void)viewDidLoad { - (void)viewDidUnload { self.nameTextField = nil; + [super viewDidUnload]; } diff --git a/Samples/iOS/Application/Controllers/RecipeDetailViewController.m b/Samples/iOS/Application/Controllers/RecipeDetailViewController.m index 0e6d78c1d..ecb14da53 100644 --- a/Samples/iOS/Application/Controllers/RecipeDetailViewController.m +++ b/Samples/iOS/Application/Controllers/RecipeDetailViewController.m @@ -86,13 +86,13 @@ - (void)reloadRecipe:(NSNotification*)note { NSManagedObjectID* photoID = [self.recipe.image objectID]; if (recipeID) { - BOOL shouldReload = ([ui objectForKey:NSInvalidatedAllObjectsKey] != nil); - BOOL wasInvalidated = ([ui objectForKey:NSInvalidatedAllObjectsKey] != nil); + BOOL shouldReload = (ui[NSInvalidatedAllObjectsKey] != nil); + BOOL wasInvalidated = (ui[NSInvalidatedAllObjectsKey] != nil); - NSArray *interestingKeys = [NSArray arrayWithObjects:NSUpdatedObjectsKey, NSRefreshedObjectsKey, NSInvalidatedObjectsKey, nil]; + NSArray *interestingKeys = @[NSUpdatedObjectsKey, NSRefreshedObjectsKey, NSInvalidatedObjectsKey]; for (NSString* key in interestingKeys) { - NSSet* collection = [ui objectForKey:key]; + NSSet* collection = ui[key]; for (NSManagedObjectID* moid in collection) { if ([moid isEqual:recipeID] || [moid isEqual:photoID]) { if ([key isEqual:NSInvalidatedObjectsKey]) { @@ -124,6 +124,8 @@ - (void)reloadRecipe:(NSNotification*)note { - (void)viewDidLoad { + [super viewDidLoad]; + self.navigationItem.rightBarButtonItem = self.editButtonItem; // Create and set the table header view. @@ -200,7 +202,7 @@ - (void)setEditing:(BOOL)editing animated:(BOOL)animated { NSUInteger ingredientsCount = [self.recipe.ingredients count]; - NSArray *ingredientsInsertIndexPath = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:ingredientsCount inSection:INGREDIENTS_SECTION]]; + NSArray *ingredientsInsertIndexPath = @[[NSIndexPath indexPathForRow:ingredientsCount inSection:INGREDIENTS_SECTION]]; if (editing) { [self.tableView insertRowsAtIndexPaths:ingredientsInsertIndexPath withRowAnimation:UITableViewRowAnimationTop]; @@ -314,7 +316,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N cell.accessoryType = UITableViewCellAccessoryNone; } - Ingredient *ingredient = [self.ingredients objectAtIndex:row]; + Ingredient *ingredient = (self.ingredients)[row]; cell.textLabel.text = ingredient.name; cell.detailTextLabel.text = ingredient.amount; } else { @@ -406,7 +408,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath ((IngredientDetailViewController *)nextViewController).recipe = self.recipe; if (indexPath.row < [self.recipe.ingredients count]) { - Ingredient *ingredient = [self.ingredients objectAtIndex:indexPath.row]; + Ingredient *ingredient = (self.ingredients)[indexPath.row]; ((IngredientDetailViewController *)nextViewController).ingredient = ingredient; } break; @@ -445,13 +447,13 @@ - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEd // Only allow deletion, and only in the ingredients section if ((editingStyle == UITableViewCellEditingStyleDelete) && (indexPath.section == INGREDIENTS_SECTION)) { // Remove the corresponding ingredient object from the recipe's ingredient list and delete the appropriate table view cell. - Ingredient *ingredient = [self.ingredients objectAtIndex:indexPath.row]; + Ingredient *ingredient = (self.ingredients)[indexPath.row]; [self.recipe removeIngredientsObject:ingredient]; [self.ingredients removeObject:ingredient]; [ingredient MR_deleteEntity]; - [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop]; + [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop]; } } @@ -500,7 +502,7 @@ - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fro Update the ingredients array in response to the move. Update the display order indexes within the range of the move. */ - Ingredient *ingredient = [self.ingredients objectAtIndex:fromIndexPath.row]; + Ingredient *ingredient = (self.ingredients)[fromIndexPath.row]; [self.ingredients removeObjectAtIndex:fromIndexPath.row]; [self.ingredients insertObject:ingredient atIndex:toIndexPath.row]; @@ -513,8 +515,8 @@ - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fro end = fromIndexPath.row; } for (NSInteger i = start; i <= end; i++) { - ingredient = [self.ingredients objectAtIndex:i]; - ingredient.displayOrder = [NSNumber numberWithInteger:i]; + ingredient = (self.ingredients)[i]; + ingredient.displayOrder = @(i); } } diff --git a/Samples/iOS/Application/Controllers/RecipeListTableViewController.m b/Samples/iOS/Application/Controllers/RecipeListTableViewController.m index 44a9c3fe4..0a0ea42e6 100644 --- a/Samples/iOS/Application/Controllers/RecipeListTableViewController.m +++ b/Samples/iOS/Application/Controllers/RecipeListTableViewController.m @@ -79,6 +79,8 @@ - (void)reloadFetchedResults:(NSNotification*)note { } - (void)viewDidLoad { + [super viewDidLoad]; + // Configure the navigation bar self.title = @"Recipes"; @@ -99,6 +101,8 @@ - (void)viewDidLoad { // clean up our new observers - (void)viewDidUnload { [[NSNotificationCenter defaultCenter] removeObserver:self]; + + [super viewDidUnload]; } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { @@ -115,7 +119,7 @@ - (void)add:(id)sender { RecipeAddViewController *addController = [[RecipeAddViewController alloc] initWithNibName:@"RecipeAddView" bundle:nil]; addController.delegate = self; - Recipe *newRecipe = [Recipe MR_createInContext:self.managedObjectContext]; + Recipe *newRecipe = [Recipe MR_createEntityInContext:self.managedObjectContext]; addController.recipe = newRecipe; UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:addController]; @@ -161,7 +165,7 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger NSInteger numberOfRows = 0; if ([[self.fetchedResultsController sections] count] > 0) { - id sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section]; + id sectionInfo = [self.fetchedResultsController sections][section]; numberOfRows = [sectionInfo numberOfObjects]; } @@ -239,11 +243,11 @@ - (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id) switch(type) { case NSFetchedResultsChangeInsert: - [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; + [tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; break; case NSFetchedResultsChangeDelete: - [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; + [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; break; case NSFetchedResultsChangeUpdate: @@ -251,8 +255,8 @@ - (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id) break; case NSFetchedResultsChangeMove: - [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; - [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; + [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; + [tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; break; } } @@ -267,6 +271,9 @@ - (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id case NSFetchedResultsChangeDelete: [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade]; break; + + default: + break; } } diff --git a/Samples/iOS/Application/Controllers/RecipePhotoViewController.m b/Samples/iOS/Application/Controllers/RecipePhotoViewController.m index 2ea0ccc9b..0e0acd8ab 100644 --- a/Samples/iOS/Application/Controllers/RecipePhotoViewController.m +++ b/Samples/iOS/Application/Controllers/RecipePhotoViewController.m @@ -55,6 +55,8 @@ @implementation RecipePhotoViewController - (void)loadView { + [super loadView]; + self.title = @"Photo"; _imageView = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame]; @@ -67,6 +69,8 @@ - (void)loadView { - (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + _imageView.image = [_recipe.image valueForKey:@"image"]; } diff --git a/Samples/iOS/Application/Controllers/TemperatureCell.h b/Samples/iOS/Application/Controllers/TemperatureCell.h new file mode 100644 index 000000000..a4bcac9f8 --- /dev/null +++ b/Samples/iOS/Application/Controllers/TemperatureCell.h @@ -0,0 +1,62 @@ +/* + File: TemperatureCell.h + Abstract: A table view cell that displays temperature in Centigrade, Fahrenheit, and Gas Mark. + + Version: 1.4 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +@interface TemperatureCell : UITableViewCell { + + UILabel *cLabel; + UILabel *fLabel; + UILabel *gLabel; +} + +@property (nonatomic, retain) IBOutlet UILabel *cLabel; +@property (nonatomic, retain) IBOutlet UILabel *fLabel; +@property (nonatomic, retain) IBOutlet UILabel *gLabel; + +- (void)setTemperatureDataFromDictionary:(NSDictionary *)temperatureDictionary; + +@end diff --git a/Samples/iOS/Application/Controllers/TemperatureCell.m b/Samples/iOS/Application/Controllers/TemperatureCell.m new file mode 100644 index 000000000..2b1df2e2f --- /dev/null +++ b/Samples/iOS/Application/Controllers/TemperatureCell.m @@ -0,0 +1,67 @@ +/* + File: TemperatureCell.m + Abstract: A table view cell that displays temperature in Centigrade, Fahrenheit, and Gas Mark. + + Version: 1.4 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Inc. ("Apple") in consideration of your agreement to the following + terms, and your use, installation, modification or redistribution of + this Apple software constitutes acceptance of these terms. If you do + not agree with these terms, please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. may + be used to endorse or promote products derived from the Apple Software + without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or + implied, are granted by Apple herein, including but not limited to any + patent rights that may be infringed by your derivative works or by other + works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2010 Apple Inc. All Rights Reserved. + + */ + +#import "TemperatureCell.h" + + +@implementation TemperatureCell + +@synthesize cLabel, fLabel, gLabel; + + +- (void)setTemperatureDataFromDictionary:(NSDictionary *)temperatureDictionary { + // Update text in labels from the dictionary + cLabel.text = temperatureDictionary[@"c"]; + fLabel.text = temperatureDictionary[@"f"]; + gLabel.text = temperatureDictionary[@"g"]; +} + + + + +@end diff --git a/Samples/iOS/Application/Controllers/TemperatureConverterViewController.m b/Samples/iOS/Application/Controllers/TemperatureConverterViewController.m index f9bbd12cd..dedd18b36 100644 --- a/Samples/iOS/Application/Controllers/TemperatureConverterViewController.m +++ b/Samples/iOS/Application/Controllers/TemperatureConverterViewController.m @@ -59,7 +59,9 @@ @implementation TemperatureConverterViewController #pragma mark - #pragma mark View lifecycle -- (void)viewDidLoad { +- (void)viewDidLoad { + [super viewDidLoad]; + self.title = @"Temperature"; self.tableView.allowsSelection = NO; } @@ -67,6 +69,7 @@ - (void)viewDidLoad { - (void)viewDidUnload { self.tableView = nil; + [super viewDidUnload]; } @@ -97,7 +100,7 @@ - (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:( } // Configure the temperature cell with the relevant data - NSDictionary *temperatureDictionary = [self.temperatureData objectAtIndex:indexPath.row]; + NSDictionary *temperatureDictionary = (self.temperatureData)[indexPath.row]; [cell setTemperatureDataFromDictionary:temperatureDictionary]; return cell; } diff --git a/Samples/iOS/Application/Controllers/TypeSelectionViewController.m b/Samples/iOS/Application/Controllers/TypeSelectionViewController.m index fae0a4d72..a84c65226 100644 --- a/Samples/iOS/Application/Controllers/TypeSelectionViewController.m +++ b/Samples/iOS/Application/Controllers/TypeSelectionViewController.m @@ -103,7 +103,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } // Configure the cell - NSManagedObject *recipeType = [self.recipeTypes objectAtIndex:indexPath.row]; + NSManagedObject *recipeType = (self.recipeTypes)[indexPath.row]; cell.textLabel.text = [recipeType valueForKey:@"name"]; if (recipeType == self.recipe.type) { @@ -130,7 +130,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath [[tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryCheckmark]; // Update the type of the recipe instance - self.recipe.type = [self.recipeTypes objectAtIndex:indexPath.row]; + self.recipe.type = (self.recipeTypes)[indexPath.row]; // Deselect the row. [tableView deselectRowAtIndexPath:indexPath animated:YES]; diff --git a/Samples/iOS/Application/Delegate/MGPRecipesAppDelegate.h b/Samples/iOS/Application/Delegate/MGPRecipesAppDelegate.h index 78f29a701..0b2940f67 100644 --- a/Samples/iOS/Application/Delegate/MGPRecipesAppDelegate.h +++ b/Samples/iOS/Application/Delegate/MGPRecipesAppDelegate.h @@ -1,6 +1,6 @@ // // MGPAppDelegate.h -// Recipies +// Recipes // // Created by Saul Mora on 5/19/13. // diff --git a/Samples/iOS/Application/Delegate/MGPRecipesAppDelegate.m b/Samples/iOS/Application/Delegate/MGPRecipesAppDelegate.m index 868be3f9d..8ea0da1d3 100644 --- a/Samples/iOS/Application/Delegate/MGPRecipesAppDelegate.m +++ b/Samples/iOS/Application/Delegate/MGPRecipesAppDelegate.m @@ -1,6 +1,6 @@ // // MGPAppDelegate.m -// Recipies +// Recipes // // Created by Saul Mora on 5/19/13. // @@ -15,6 +15,7 @@ @implementation MGPRecipesAppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [self copyDefaultStoreIfNecessary]; + [MagicalRecord setLoggingLevel:MagicalRecordLoggingLevelVerbose]; [MagicalRecord setupCoreDataStackWithStoreNamed:kRecipesStoreName]; // Override point for customization after application launch. diff --git a/Samples/iOS/Application/Models/generated/_Ingredient.m b/Samples/iOS/Application/Models/generated/_Ingredient.m index a7fb3b4a2..a764aec78 100644 --- a/Samples/iOS/Application/Models/generated/_Ingredient.m +++ b/Samples/iOS/Application/Models/generated/_Ingredient.m @@ -71,7 +71,7 @@ - (int16_t)displayOrderValue { } - (void)setDisplayOrderValue:(int16_t)value_ { - [self setDisplayOrder:[NSNumber numberWithShort:value_]]; + [self setDisplayOrder:@(value_)]; } - (int16_t)primitiveDisplayOrderValue { @@ -80,7 +80,7 @@ - (int16_t)primitiveDisplayOrderValue { } - (void)setPrimitiveDisplayOrderValue:(int16_t)value_ { - [self setPrimitiveDisplayOrder:[NSNumber numberWithShort:value_]]; + [self setPrimitiveDisplayOrder:@(value_)]; } diff --git a/Samples/iOS/Application/Support/Recipies-Info.plist b/Samples/iOS/Application/Support/Recipes-Info.plist similarity index 98% rename from Samples/iOS/Application/Support/Recipies-Info.plist rename to Samples/iOS/Application/Support/Recipes-Info.plist index 31ad1a4a9..d5b9f62f3 100644 --- a/Samples/iOS/Application/Support/Recipies-Info.plist +++ b/Samples/iOS/Application/Support/Recipes-Info.plist @@ -21,7 +21,7 @@ CFBundleSignature ???? CFBundleVersion - 1.0 + 1 LSRequiresIPhoneOS NSMainNibFile diff --git a/Samples/iOS/Application/Support/Recipies-Prefix.pch b/Samples/iOS/Application/Support/Recipes-Prefix.pch similarity index 75% rename from Samples/iOS/Application/Support/Recipies-Prefix.pch rename to Samples/iOS/Application/Support/Recipes-Prefix.pch index 1c3432e97..35ccf0516 100644 --- a/Samples/iOS/Application/Support/Recipies-Prefix.pch +++ b/Samples/iOS/Application/Support/Recipes-Prefix.pch @@ -1,5 +1,5 @@ // -// Prefix header for all source files of the 'Recipies' target in the 'Recipies' project +// Prefix header for all source files of the 'Recipes' target in the 'Recipes' project // #import diff --git a/Samples/iOS/Application/Support/main.m b/Samples/iOS/Application/Support/main.m index bac9b1aa3..7a2b033ff 100644 --- a/Samples/iOS/Application/Support/main.m +++ b/Samples/iOS/Application/Support/main.m @@ -1,6 +1,6 @@ // // main.m -// Recipies +// Recipes // // Created by Saul Mora on 5/19/13. // diff --git a/Samples/iOS/Application/Views/MainWindow.xib b/Samples/iOS/Application/Views/MainWindow.xib index 6824ce01e..1cf73d45b 100644 --- a/Samples/iOS/Application/Views/MainWindow.xib +++ b/Samples/iOS/Application/Views/MainWindow.xib @@ -1,17 +1,16 @@ - + 512 - 12D78 - 3084 - 1187.37 - 626.00 + 13C64 + 5053 + 1265.19 + 697.40 com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 2083 + 3733 - - YES + IBProxyObject IBUIBarButtonItem IBUICustomObject @@ -23,17 +22,15 @@ IBUITabBarItem IBUIViewController IBUIWindow - - - YES + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin - + PluginDependencyRecalculationVersion - - YES + IBFilesOwner IBCocoaTouchFramework @@ -51,6 +48,7 @@ {320, 480} + 1 MSAxIDEAA @@ -58,6 +56,7 @@ NO NO IBCocoaTouchFramework + YES @@ -94,8 +93,7 @@ YES IBCocoaTouchFramework - - YES + Navigation Item @@ -109,10 +107,9 @@ IBCocoaTouchFramework NO - + - - YES + @@ -140,8 +137,7 @@ YES IBCocoaTouchFramework - - YES + Unit Conversion @@ -160,33 +156,36 @@ IBCocoaTouchFramework NO - + - + 266 {{0, 431}, {320, 49}} + 3 MCAwAA NO IBCocoaTouchFramework + + - + - - YES + NO + delegate - 4 + 4 @@ -194,7 +193,7 @@ - 5 + 5 @@ -202,7 +201,7 @@ - 30 + 30 @@ -210,240 +209,228 @@ - 31 + 31 - + - - YES + - 0 - - YES - + 0 + - 2 + 2 - - YES - - + + - -1 + -1 - + File's Owner - 3 + 3 - + - -2 + -2 - + - 14 + 14 - - YES + - - + + - 15 + 15 - 20 + 20 - - YES + - + - 21 + 21 - - YES + - + - 22 + 22 - 23 + 23 - 24 + 24 - 25 + 25 - - YES + - + - 26 + 26 - - YES + - + - 27 + 27 - 28 + 28 - - YES + - + - 29 + 29 - 32 + 32 - + - - YES - - YES - -1.CustomClassName - -1.IBPluginDependency - -2.CustomClassName - -2.IBPluginDependency - 14.IBPluginDependency - 15.IBPluginDependency - 2.IBAttributePlaceholdersKey - 2.IBPluginDependency - 20.IBPluginDependency - 21.CustomClassName - 21.IBPluginDependency - 22.IBPluginDependency - 23.IBPluginDependency - 24.IBPluginDependency - 25.IBPluginDependency - 26.CustomClassName - 26.IBPluginDependency - 27.IBPluginDependency - 28.IBPluginDependency - 29.IBPluginDependency - 3.CustomClassName - 3.IBPluginDependency - 32.IBPluginDependency + + UIApplication + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + RecipeListTableViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UnitConverterTableViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + MGPRecipesAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + + + + + + MGPRecipesAppDelegate + UIResponder + + RecipeListTableViewController + UITabBarController + UIWindow + + + + recipeListController + RecipeListTableViewController + + + tabBarController + UITabBarController + + + window + UIWindow + + + + IBProjectSource + ./Classes/MGPRecipesAppDelegate.h + - - YES - UIApplication - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - YES - - + + RecipeListTableViewController + UITableViewController + + IBProjectSource + ./Classes/RecipeListTableViewController.h - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - RecipeListTableViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UnitConverterTableViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - MGPRecipesAppDelegate - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - YES - - - - - - YES - - - - - 32 + + UnitConverterTableViewController + UITableViewController + + IBProjectSource + ./Classes/UnitConverterTableViewController.h + + + - 0 IBCocoaTouchFramework + YES com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 - + YES 3 - - YES - - YES - convert.png - fork.png - - - YES - {32, 32} - {32, 32} - - - 2083 + + {32, 32} + {32, 32} + + 3733 diff --git a/Samples/iOS/Application/Views/RecipeAddView.xib b/Samples/iOS/Application/Views/RecipeAddView.xib index 2dab044a3..12b7a39c4 100644 --- a/Samples/iOS/Application/Views/RecipeAddView.xib +++ b/Samples/iOS/Application/Views/RecipeAddView.xib @@ -1,56 +1,58 @@ - + 768 - 10A380 - 731 - 1025.2 - 427.00 + 13C64 + 5053 + 1265.19 + 697.40 com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 58 + 3733 - - YES - - - - YES + + IBProxyObject + IBUITextField + IBUIView + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin - + - YES - - YES - - - YES - + PluginDependencyRecalculationVersion + - - YES + IBFilesOwner + IBCocoaTouchFramework IBFirstResponder + IBCocoaTouchFramework 274 - - YES + - 292 - {{20, 49}, {280, 31}} + 300 + {{20, 64}, {280, 31}} - + + + 3 MCAwAA NO NO + -20 + 20 + 0.0 + 0.0 + IBCocoaTouchFramework YES 0 @@ -63,64 +65,50 @@ 2 - - Helvetica - 17 - 16 - YES 17 2 9 + IBCocoaTouchFramework + + + Helvetica + Helvetica + 0 + 17 + + + Helvetica + 17 + 16 - - {320, 460} + + {320, 436} + + - 10 - - 549453824 - {84, 1} - - YES - - YES - - - - TU0AKgAAAVjFzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ -y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ -xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ -xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ -xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ -xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P8ADQEAAAMAAAABAFQAAAEB -AAMAAAABAAEAAAECAAMAAAAEAAAB+gEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAERAAQAAAABAAAACAES -AAMAAAABAAEAAAEVAAMAAAABAAQAAAEWAAMAAAABAAEAAAEXAAQAAAABAAABUAEcAAMAAAABAAEAAAFS -AAMAAAABAAEAAAFTAAMAAAAEAAACAgAAAAAACAAIAAgACAABAAEAAQABA - - - - - - + 1 + MCAwIDAgMAA groupTableViewBackgroundColor NO 2 + IBCocoaTouchFramework - + - - YES + NO + view - 13 + 13 @@ -128,7 +116,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAACAgAAAAAACAAIAAgACAABAAEAAQABA - 17 + 17 @@ -136,317 +124,96 @@ AAMAAAABAAEAAAFTAAMAAAAEAAACAgAAAAAACAAIAAgACAABAAEAAQABA - 19 + 19 - + - - YES + - 0 - + 0 + - -1 + -1 File's Owner - -2 + -2 - 10 + 10 - - YES + - + - 11 + 11 - - - - YES - - YES - -1.CustomClassName - -2.CustomClassName - 10.IBEditorWindowLastContentRect - 10.IBPluginDependency - 11.IBPluginDependency - - - YES - RecipeAddViewController - UIResponder - {{361, 396}, {320, 460}} - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - YES - - - YES - + + + RecipeAddViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + - - YES - - - YES - - + - 19 - - YES + RecipeAddViewController UIViewController - YES - - YES - delegate - nameTextField - - - YES - id - UITextField + nameTextField + UITextField + + + nameTextField + + nameTextField + UITextField IBProjectSource - Classes/RecipeAddViewController.h - - - - - YES - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSError.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFileManager.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueObserving.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyedArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSNetServices.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObject.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSPort.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSRunLoop.h + ./Classes/RecipeAddViewController.h - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSStream.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSThread.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURL.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLConnection.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSXMLParser.h - - - - NSObject - - IBFrameworkSource - UIKit.framework/Headers/UIAccessibility.h - - - - NSObject - - IBFrameworkSource - UIKit.framework/Headers/UINibLoading.h - - - - NSObject - - IBFrameworkSource - UIKit.framework/Headers/UIResponder.h - - - - UIControl - UIView - - IBFrameworkSource - UIKit.framework/Headers/UIControl.h - - - - UIResponder - NSObject - - - - UISearchBar - UIView - - IBFrameworkSource - UIKit.framework/Headers/UISearchBar.h - - - - UISearchDisplayController - NSObject - - IBFrameworkSource - UIKit.framework/Headers/UISearchDisplayController.h - - - - UITextField - UIControl - - IBFrameworkSource - UIKit.framework/Headers/UITextField.h - - - - UIView - - - - UIView - UIResponder - - IBFrameworkSource - UIKit.framework/Headers/UIView.h - - - - UIViewController - - IBFrameworkSource - UIKit.framework/Headers/UINavigationController.h - - - - UIViewController - - IBFrameworkSource - UIKit.framework/Headers/UITabBarController.h - - - - UIViewController - UIResponder - - IBFrameworkSource - UIKit.framework/Headers/UIViewController.h - - - + 0 + IBCocoaTouchFramework + YES com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS - + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 - + YES - ../Recipes.xcodeproj 3 - 3.0 + 3733 diff --git a/Samples/iOS/MagicalRecordRecipes.xcodeproj/project.pbxproj b/Samples/iOS/MagicalRecordRecipes.xcodeproj/project.pbxproj index 630eb2d1a..7e4675381 100644 --- a/Samples/iOS/MagicalRecordRecipes.xcodeproj/project.pbxproj +++ b/Samples/iOS/MagicalRecordRecipes.xcodeproj/project.pbxproj @@ -7,13 +7,35 @@ objects = { /* Begin PBXBuildFile section */ - C7CF966317496EDC008D9D13 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C7CF966217496EDC008D9D13 /* UIKit.framework */; }; - C7CF966517496EDC008D9D13 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C7CF966417496EDC008D9D13 /* Foundation.framework */; }; - C7CF966717496EDC008D9D13 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C7CF966617496EDC008D9D13 /* CoreGraphics.framework */; }; + 90610E1F18F4022D00E2C328 /* MagicalImportFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = 90610DE718F4022D00E2C328 /* MagicalImportFunctions.m */; }; + 90610E2018F4022D00E2C328 /* NSAttributeDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = 90610DE918F4022D00E2C328 /* NSAttributeDescription+MagicalDataImport.m */; }; + 90610E2118F4022D00E2C328 /* NSEntityDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = 90610DEB18F4022D00E2C328 /* NSEntityDescription+MagicalDataImport.m */; }; + 90610E2218F4022D00E2C328 /* NSNumber+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = 90610DED18F4022D00E2C328 /* NSNumber+MagicalDataImport.m */; }; + 90610E2318F4022D00E2C328 /* NSObject+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = 90610DEF18F4022D00E2C328 /* NSObject+MagicalDataImport.m */; }; + 90610E2418F4022D00E2C328 /* NSRelationshipDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = 90610DF118F4022D00E2C328 /* NSRelationshipDescription+MagicalDataImport.m */; }; + 90610E2518F4022D00E2C328 /* NSString+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = 90610DF318F4022D00E2C328 /* NSString+MagicalDataImport.m */; }; + 90610E2618F4022D00E2C328 /* NSManagedObject+MagicalAggregation.m in Sources */ = {isa = PBXBuildFile; fileRef = 90610DF618F4022D00E2C328 /* NSManagedObject+MagicalAggregation.m */; }; + 90610E2718F4022D00E2C328 /* NSManagedObject+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = 90610DF818F4022D00E2C328 /* NSManagedObject+MagicalDataImport.m */; }; + 90610E2818F4022D00E2C328 /* NSManagedObject+MagicalFinders.m in Sources */ = {isa = PBXBuildFile; fileRef = 90610DFA18F4022D00E2C328 /* NSManagedObject+MagicalFinders.m */; }; + 90610E2918F4022D00E2C328 /* NSManagedObject+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 90610DFC18F4022D00E2C328 /* NSManagedObject+MagicalRecord.m */; }; + 90610E2A18F4022D00E2C328 /* NSManagedObject+MagicalRequests.m in Sources */ = {isa = PBXBuildFile; fileRef = 90610DFE18F4022D00E2C328 /* NSManagedObject+MagicalRequests.m */; }; + 90610E2B18F4022D00E2C328 /* NSManagedObjectContext+MagicalObserving.m in Sources */ = {isa = PBXBuildFile; fileRef = 90610E0118F4022D00E2C328 /* NSManagedObjectContext+MagicalObserving.m */; }; + 90610E2C18F4022D00E2C328 /* NSManagedObjectContext+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 90610E0318F4022D00E2C328 /* NSManagedObjectContext+MagicalRecord.m */; }; + 90610E2D18F4022D00E2C328 /* NSManagedObjectContext+MagicalSaves.m in Sources */ = {isa = PBXBuildFile; fileRef = 90610E0518F4022D00E2C328 /* NSManagedObjectContext+MagicalSaves.m */; }; + 90610E2E18F4022D00E2C328 /* NSManagedObjectContext+MagicalThreading.m in Sources */ = {isa = PBXBuildFile; fileRef = 90610E0718F4022D00E2C328 /* NSManagedObjectContext+MagicalThreading.m */; }; + 90610E2F18F4022D00E2C328 /* NSManagedObjectModel+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 90610E0918F4022D00E2C328 /* NSManagedObjectModel+MagicalRecord.m */; }; + 90610E3018F4022D00E2C328 /* NSPersistentStore+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 90610E0B18F4022D00E2C328 /* NSPersistentStore+MagicalRecord.m */; }; + 90610E3118F4022D00E2C328 /* NSPersistentStoreCoordinator+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 90610E0D18F4022D00E2C328 /* NSPersistentStoreCoordinator+MagicalRecord.m */; }; + 90610E3218F4022D00E2C328 /* MagicalRecord+Actions.m in Sources */ = {isa = PBXBuildFile; fileRef = 90610E1018F4022D00E2C328 /* MagicalRecord+Actions.m */; }; + 90610E3318F4022D00E2C328 /* MagicalRecord+ErrorHandling.m in Sources */ = {isa = PBXBuildFile; fileRef = 90610E1218F4022D00E2C328 /* MagicalRecord+ErrorHandling.m */; }; + 90610E3418F4022D00E2C328 /* MagicalRecord+iCloud.m in Sources */ = {isa = PBXBuildFile; fileRef = 90610E1418F4022D00E2C328 /* MagicalRecord+iCloud.m */; }; + 90610E3518F4022D00E2C328 /* MagicalRecord+Options.m in Sources */ = {isa = PBXBuildFile; fileRef = 90610E1618F4022D00E2C328 /* MagicalRecord+Options.m */; }; + 90610E3618F4022D00E2C328 /* MagicalRecord+Setup.m in Sources */ = {isa = PBXBuildFile; fileRef = 90610E1818F4022D00E2C328 /* MagicalRecord+Setup.m */; }; + 90610E3718F4022D00E2C328 /* MagicalRecord+ShorthandSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 90610E1A18F4022D00E2C328 /* MagicalRecord+ShorthandSupport.m */; }; + 90610E3818F4022D00E2C328 /* MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 90610E1C18F4022D00E2C328 /* MagicalRecord.m */; }; C7CF968C17496F83008D9D13 /* MGPRecipesAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF968217496F83008D9D13 /* MGPRecipesAppDelegate.m */; }; C7CF968E17496F83008D9D13 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = C7CF968617496F83008D9D13 /* InfoPlist.strings */; }; C7CF968F17496F83008D9D13 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF968817496F83008D9D13 /* main.m */; }; - C7CF969217496F95008D9D13 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C7CF969117496F95008D9D13 /* CoreData.framework */; }; C7CF96A517497005008D9D13 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = C7CF969417497005008D9D13 /* Default-568h@2x.png */; }; C7CF96A617497005008D9D13 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = C7CF969517497005008D9D13 /* Default.png */; }; C7CF96A717497005008D9D13 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = C7CF969617497005008D9D13 /* Default@2x.png */; }; @@ -57,37 +79,65 @@ C7CF97021749725B008D9D13 /* _Recipe.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF96FE1749725B008D9D13 /* _Recipe.m */; }; C7CF970517497348008D9D13 /* TemperatureCell.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF970417497348008D9D13 /* TemperatureCell.m */; }; C7CF97071749752D008D9D13 /* WeightConverterViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF97061749752C008D9D13 /* WeightConverterViewController.m */; }; - C7CF9745174976AF008D9D13 /* MagicalImportFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF970D174976AF008D9D13 /* MagicalImportFunctions.m */; }; - C7CF9746174976AF008D9D13 /* NSAttributeDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF970F174976AF008D9D13 /* NSAttributeDescription+MagicalDataImport.m */; }; - C7CF9747174976AF008D9D13 /* NSEntityDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9711174976AF008D9D13 /* NSEntityDescription+MagicalDataImport.m */; }; - C7CF9748174976AF008D9D13 /* NSNumber+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9713174976AF008D9D13 /* NSNumber+MagicalDataImport.m */; }; - C7CF9749174976AF008D9D13 /* NSObject+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9715174976AF008D9D13 /* NSObject+MagicalDataImport.m */; }; - C7CF974A174976AF008D9D13 /* NSRelationshipDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9717174976AF008D9D13 /* NSRelationshipDescription+MagicalDataImport.m */; }; - C7CF974B174976AF008D9D13 /* NSString+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9719174976AF008D9D13 /* NSString+MagicalDataImport.m */; }; - C7CF974C174976AF008D9D13 /* NSManagedObject+MagicalAggregation.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF971C174976AF008D9D13 /* NSManagedObject+MagicalAggregation.m */; }; - C7CF974D174976AF008D9D13 /* NSManagedObject+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF971E174976AF008D9D13 /* NSManagedObject+MagicalDataImport.m */; }; - C7CF974E174976AF008D9D13 /* NSManagedObject+MagicalFinders.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9720174976AF008D9D13 /* NSManagedObject+MagicalFinders.m */; }; - C7CF974F174976AF008D9D13 /* NSManagedObject+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9722174976AF008D9D13 /* NSManagedObject+MagicalRecord.m */; }; - C7CF9750174976AF008D9D13 /* NSManagedObject+MagicalRequests.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9724174976AF008D9D13 /* NSManagedObject+MagicalRequests.m */; }; - C7CF9751174976AF008D9D13 /* NSManagedObjectContext+MagicalObserving.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9727174976AF008D9D13 /* NSManagedObjectContext+MagicalObserving.m */; }; - C7CF9752174976AF008D9D13 /* NSManagedObjectContext+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9729174976AF008D9D13 /* NSManagedObjectContext+MagicalRecord.m */; }; - C7CF9753174976AF008D9D13 /* NSManagedObjectContext+MagicalSaves.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF972B174976AF008D9D13 /* NSManagedObjectContext+MagicalSaves.m */; }; - C7CF9754174976AF008D9D13 /* NSManagedObjectContext+MagicalThreading.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF972D174976AF008D9D13 /* NSManagedObjectContext+MagicalThreading.m */; }; - C7CF9755174976AF008D9D13 /* NSManagedObjectModel+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF972F174976AF008D9D13 /* NSManagedObjectModel+MagicalRecord.m */; }; - C7CF9756174976AF008D9D13 /* NSPersistentStore+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9731174976AF008D9D13 /* NSPersistentStore+MagicalRecord.m */; }; - C7CF9757174976AF008D9D13 /* NSPersistentStoreCoordinator+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9733174976AF008D9D13 /* NSPersistentStoreCoordinator+MagicalRecord.m */; }; - C7CF9758174976AF008D9D13 /* MagicalRecord+Actions.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9736174976AF008D9D13 /* MagicalRecord+Actions.m */; }; - C7CF9759174976AF008D9D13 /* MagicalRecord+ErrorHandling.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9738174976AF008D9D13 /* MagicalRecord+ErrorHandling.m */; }; - C7CF975A174976AF008D9D13 /* MagicalRecord+iCloud.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF973A174976AF008D9D13 /* MagicalRecord+iCloud.m */; }; - C7CF975B174976AF008D9D13 /* MagicalRecord+Options.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF973C174976AF008D9D13 /* MagicalRecord+Options.m */; }; - C7CF975C174976AF008D9D13 /* MagicalRecord+Setup.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF973E174976AF008D9D13 /* MagicalRecord+Setup.m */; }; - C7CF975D174976AF008D9D13 /* MagicalRecord+ShorthandSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9740174976AF008D9D13 /* MagicalRecord+ShorthandSupport.m */; }; - C7CF975E174976B0008D9D13 /* MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF9742174976AF008D9D13 /* MagicalRecord.m */; }; C7CF976117497858008D9D13 /* ImageToDataTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = C7CF976017497858008D9D13 /* ImageToDataTransformer.m */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ - C7CF965F17496EDC008D9D13 /* Recipies.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Recipies.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 90610DE618F4022D00E2C328 /* MagicalImportFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MagicalImportFunctions.h; sourceTree = ""; }; + 90610DE718F4022D00E2C328 /* MagicalImportFunctions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MagicalImportFunctions.m; sourceTree = ""; }; + 90610DE818F4022D00E2C328 /* NSAttributeDescription+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSAttributeDescription+MagicalDataImport.h"; sourceTree = ""; }; + 90610DE918F4022D00E2C328 /* NSAttributeDescription+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSAttributeDescription+MagicalDataImport.m"; sourceTree = ""; }; + 90610DEA18F4022D00E2C328 /* NSEntityDescription+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSEntityDescription+MagicalDataImport.h"; sourceTree = ""; }; + 90610DEB18F4022D00E2C328 /* NSEntityDescription+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSEntityDescription+MagicalDataImport.m"; sourceTree = ""; }; + 90610DEC18F4022D00E2C328 /* NSNumber+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSNumber+MagicalDataImport.h"; sourceTree = ""; }; + 90610DED18F4022D00E2C328 /* NSNumber+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSNumber+MagicalDataImport.m"; sourceTree = ""; }; + 90610DEE18F4022D00E2C328 /* NSObject+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+MagicalDataImport.h"; sourceTree = ""; }; + 90610DEF18F4022D00E2C328 /* NSObject+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+MagicalDataImport.m"; sourceTree = ""; }; + 90610DF018F4022D00E2C328 /* NSRelationshipDescription+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSRelationshipDescription+MagicalDataImport.h"; sourceTree = ""; }; + 90610DF118F4022D00E2C328 /* NSRelationshipDescription+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSRelationshipDescription+MagicalDataImport.m"; sourceTree = ""; }; + 90610DF218F4022D00E2C328 /* NSString+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+MagicalDataImport.h"; sourceTree = ""; }; + 90610DF318F4022D00E2C328 /* NSString+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+MagicalDataImport.m"; sourceTree = ""; }; + 90610DF518F4022D00E2C328 /* NSManagedObject+MagicalAggregation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+MagicalAggregation.h"; sourceTree = ""; }; + 90610DF618F4022D00E2C328 /* NSManagedObject+MagicalAggregation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+MagicalAggregation.m"; sourceTree = ""; }; + 90610DF718F4022D00E2C328 /* NSManagedObject+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+MagicalDataImport.h"; sourceTree = ""; }; + 90610DF818F4022D00E2C328 /* NSManagedObject+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+MagicalDataImport.m"; sourceTree = ""; }; + 90610DF918F4022D00E2C328 /* NSManagedObject+MagicalFinders.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+MagicalFinders.h"; sourceTree = ""; }; + 90610DFA18F4022D00E2C328 /* NSManagedObject+MagicalFinders.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+MagicalFinders.m"; sourceTree = ""; }; + 90610DFB18F4022D00E2C328 /* NSManagedObject+MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+MagicalRecord.h"; sourceTree = ""; }; + 90610DFC18F4022D00E2C328 /* NSManagedObject+MagicalRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+MagicalRecord.m"; sourceTree = ""; }; + 90610DFD18F4022D00E2C328 /* NSManagedObject+MagicalRequests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+MagicalRequests.h"; sourceTree = ""; }; + 90610DFE18F4022D00E2C328 /* NSManagedObject+MagicalRequests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+MagicalRequests.m"; sourceTree = ""; }; + 90610E0018F4022D00E2C328 /* NSManagedObjectContext+MagicalObserving.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObjectContext+MagicalObserving.h"; sourceTree = ""; }; + 90610E0118F4022D00E2C328 /* NSManagedObjectContext+MagicalObserving.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectContext+MagicalObserving.m"; sourceTree = ""; }; + 90610E0218F4022D00E2C328 /* NSManagedObjectContext+MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObjectContext+MagicalRecord.h"; sourceTree = ""; }; + 90610E0318F4022D00E2C328 /* NSManagedObjectContext+MagicalRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectContext+MagicalRecord.m"; sourceTree = ""; }; + 90610E0418F4022D00E2C328 /* NSManagedObjectContext+MagicalSaves.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObjectContext+MagicalSaves.h"; sourceTree = ""; }; + 90610E0518F4022D00E2C328 /* NSManagedObjectContext+MagicalSaves.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectContext+MagicalSaves.m"; sourceTree = ""; }; + 90610E0618F4022D00E2C328 /* NSManagedObjectContext+MagicalThreading.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObjectContext+MagicalThreading.h"; sourceTree = ""; }; + 90610E0718F4022D00E2C328 /* NSManagedObjectContext+MagicalThreading.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectContext+MagicalThreading.m"; sourceTree = ""; }; + 90610E0818F4022D00E2C328 /* NSManagedObjectModel+MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObjectModel+MagicalRecord.h"; sourceTree = ""; }; + 90610E0918F4022D00E2C328 /* NSManagedObjectModel+MagicalRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectModel+MagicalRecord.m"; sourceTree = ""; }; + 90610E0A18F4022D00E2C328 /* NSPersistentStore+MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSPersistentStore+MagicalRecord.h"; sourceTree = ""; }; + 90610E0B18F4022D00E2C328 /* NSPersistentStore+MagicalRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSPersistentStore+MagicalRecord.m"; sourceTree = ""; }; + 90610E0C18F4022D00E2C328 /* NSPersistentStoreCoordinator+MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSPersistentStoreCoordinator+MagicalRecord.h"; sourceTree = ""; }; + 90610E0D18F4022D00E2C328 /* NSPersistentStoreCoordinator+MagicalRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSPersistentStoreCoordinator+MagicalRecord.m"; sourceTree = ""; }; + 90610E0F18F4022D00E2C328 /* MagicalRecord+Actions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord+Actions.h"; sourceTree = ""; }; + 90610E1018F4022D00E2C328 /* MagicalRecord+Actions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+Actions.m"; sourceTree = ""; }; + 90610E1118F4022D00E2C328 /* MagicalRecord+ErrorHandling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord+ErrorHandling.h"; sourceTree = ""; }; + 90610E1218F4022D00E2C328 /* MagicalRecord+ErrorHandling.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+ErrorHandling.m"; sourceTree = ""; }; + 90610E1318F4022D00E2C328 /* MagicalRecord+iCloud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord+iCloud.h"; sourceTree = ""; }; + 90610E1418F4022D00E2C328 /* MagicalRecord+iCloud.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+iCloud.m"; sourceTree = ""; }; + 90610E1518F4022D00E2C328 /* MagicalRecord+Options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord+Options.h"; sourceTree = ""; }; + 90610E1618F4022D00E2C328 /* MagicalRecord+Options.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+Options.m"; sourceTree = ""; }; + 90610E1718F4022D00E2C328 /* MagicalRecord+Setup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord+Setup.h"; sourceTree = ""; }; + 90610E1818F4022D00E2C328 /* MagicalRecord+Setup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+Setup.m"; sourceTree = ""; }; + 90610E1918F4022D00E2C328 /* MagicalRecord+ShorthandSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord+ShorthandSupport.h"; sourceTree = ""; }; + 90610E1A18F4022D00E2C328 /* MagicalRecord+ShorthandSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+ShorthandSupport.m"; sourceTree = ""; }; + 90610E1B18F4022D00E2C328 /* MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MagicalRecord.h; sourceTree = ""; }; + 90610E1C18F4022D00E2C328 /* MagicalRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MagicalRecord.m; sourceTree = ""; }; + 90610E1D18F4022D00E2C328 /* MagicalRecordShorthand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MagicalRecordShorthand.h; sourceTree = ""; }; + 90610E1E18F4022D00E2C328 /* CoreData+MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CoreData+MagicalRecord.h"; sourceTree = ""; }; + C7CF965F17496EDC008D9D13 /* Recipes.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Recipes.app; sourceTree = BUILT_PRODUCTS_DIR; }; C7CF966217496EDC008D9D13 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; C7CF966417496EDC008D9D13 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; C7CF966617496EDC008D9D13 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = Library/Frameworks/CoreGraphics.framework; sourceTree = DEVELOPER_DIR; }; @@ -95,8 +145,8 @@ C7CF968217496F83008D9D13 /* MGPRecipesAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGPRecipesAppDelegate.m; sourceTree = ""; }; C7CF968717496F83008D9D13 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; C7CF968817496F83008D9D13 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - C7CF968917496F83008D9D13 /* Recipies-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Recipies-Info.plist"; sourceTree = ""; }; - C7CF968A17496F83008D9D13 /* Recipies-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Recipies-Prefix.pch"; sourceTree = ""; }; + C7CF968917496F83008D9D13 /* Recipes-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Recipes-Info.plist"; sourceTree = ""; }; + C7CF968A17496F83008D9D13 /* Recipes-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Recipes-Prefix.pch"; sourceTree = ""; }; C7CF969117496F95008D9D13 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk/System/Library/Frameworks/CoreData.framework; sourceTree = DEVELOPER_DIR; }; C7CF969417497005008D9D13 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; C7CF969517497005008D9D13 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; @@ -159,88 +209,130 @@ C7CF96FC1749725B008D9D13 /* _Ingredient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = _Ingredient.m; sourceTree = ""; }; C7CF96FD1749725B008D9D13 /* _Recipe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _Recipe.h; sourceTree = ""; }; C7CF96FE1749725B008D9D13 /* _Recipe.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = _Recipe.m; sourceTree = ""; }; - C7CF970317497347008D9D13 /* TemperatureCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TemperatureCell.h; path = ../../../../../../../Downloads/iPhoneCoreDataRecipes/Classes/TemperatureCell.h; sourceTree = ""; }; - C7CF970417497348008D9D13 /* TemperatureCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TemperatureCell.m; path = ../../../../../../../Downloads/iPhoneCoreDataRecipes/Classes/TemperatureCell.m; sourceTree = ""; }; + C7CF970317497347008D9D13 /* TemperatureCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemperatureCell.h; sourceTree = ""; }; + C7CF970417497348008D9D13 /* TemperatureCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TemperatureCell.m; sourceTree = ""; }; C7CF97061749752C008D9D13 /* WeightConverterViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WeightConverterViewController.m; sourceTree = ""; }; - C7CF970C174976AF008D9D13 /* MagicalImportFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MagicalImportFunctions.h; sourceTree = ""; }; - C7CF970D174976AF008D9D13 /* MagicalImportFunctions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MagicalImportFunctions.m; sourceTree = ""; }; - C7CF970E174976AF008D9D13 /* NSAttributeDescription+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSAttributeDescription+MagicalDataImport.h"; sourceTree = ""; }; - C7CF970F174976AF008D9D13 /* NSAttributeDescription+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSAttributeDescription+MagicalDataImport.m"; sourceTree = ""; }; - C7CF9710174976AF008D9D13 /* NSEntityDescription+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSEntityDescription+MagicalDataImport.h"; sourceTree = ""; }; - C7CF9711174976AF008D9D13 /* NSEntityDescription+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSEntityDescription+MagicalDataImport.m"; sourceTree = ""; }; - C7CF9712174976AF008D9D13 /* NSNumber+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSNumber+MagicalDataImport.h"; sourceTree = ""; }; - C7CF9713174976AF008D9D13 /* NSNumber+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSNumber+MagicalDataImport.m"; sourceTree = ""; }; - C7CF9714174976AF008D9D13 /* NSObject+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+MagicalDataImport.h"; sourceTree = ""; }; - C7CF9715174976AF008D9D13 /* NSObject+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+MagicalDataImport.m"; sourceTree = ""; }; - C7CF9716174976AF008D9D13 /* NSRelationshipDescription+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSRelationshipDescription+MagicalDataImport.h"; sourceTree = ""; }; - C7CF9717174976AF008D9D13 /* NSRelationshipDescription+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSRelationshipDescription+MagicalDataImport.m"; sourceTree = ""; }; - C7CF9718174976AF008D9D13 /* NSString+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+MagicalDataImport.h"; sourceTree = ""; }; - C7CF9719174976AF008D9D13 /* NSString+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+MagicalDataImport.m"; sourceTree = ""; }; - C7CF971B174976AF008D9D13 /* NSManagedObject+MagicalAggregation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+MagicalAggregation.h"; sourceTree = ""; }; - C7CF971C174976AF008D9D13 /* NSManagedObject+MagicalAggregation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+MagicalAggregation.m"; sourceTree = ""; }; - C7CF971D174976AF008D9D13 /* NSManagedObject+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+MagicalDataImport.h"; sourceTree = ""; }; - C7CF971E174976AF008D9D13 /* NSManagedObject+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+MagicalDataImport.m"; sourceTree = ""; }; - C7CF971F174976AF008D9D13 /* NSManagedObject+MagicalFinders.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+MagicalFinders.h"; sourceTree = ""; }; - C7CF9720174976AF008D9D13 /* NSManagedObject+MagicalFinders.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+MagicalFinders.m"; sourceTree = ""; }; - C7CF9721174976AF008D9D13 /* NSManagedObject+MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+MagicalRecord.h"; sourceTree = ""; }; - C7CF9722174976AF008D9D13 /* NSManagedObject+MagicalRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+MagicalRecord.m"; sourceTree = ""; }; - C7CF9723174976AF008D9D13 /* NSManagedObject+MagicalRequests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+MagicalRequests.h"; sourceTree = ""; }; - C7CF9724174976AF008D9D13 /* NSManagedObject+MagicalRequests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+MagicalRequests.m"; sourceTree = ""; }; - C7CF9726174976AF008D9D13 /* NSManagedObjectContext+MagicalObserving.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObjectContext+MagicalObserving.h"; sourceTree = ""; }; - C7CF9727174976AF008D9D13 /* NSManagedObjectContext+MagicalObserving.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectContext+MagicalObserving.m"; sourceTree = ""; }; - C7CF9728174976AF008D9D13 /* NSManagedObjectContext+MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObjectContext+MagicalRecord.h"; sourceTree = ""; }; - C7CF9729174976AF008D9D13 /* NSManagedObjectContext+MagicalRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectContext+MagicalRecord.m"; sourceTree = ""; }; - C7CF972A174976AF008D9D13 /* NSManagedObjectContext+MagicalSaves.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObjectContext+MagicalSaves.h"; sourceTree = ""; }; - C7CF972B174976AF008D9D13 /* NSManagedObjectContext+MagicalSaves.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectContext+MagicalSaves.m"; sourceTree = ""; }; - C7CF972C174976AF008D9D13 /* NSManagedObjectContext+MagicalThreading.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObjectContext+MagicalThreading.h"; sourceTree = ""; }; - C7CF972D174976AF008D9D13 /* NSManagedObjectContext+MagicalThreading.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectContext+MagicalThreading.m"; sourceTree = ""; }; - C7CF972E174976AF008D9D13 /* NSManagedObjectModel+MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObjectModel+MagicalRecord.h"; sourceTree = ""; }; - C7CF972F174976AF008D9D13 /* NSManagedObjectModel+MagicalRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectModel+MagicalRecord.m"; sourceTree = ""; }; - C7CF9730174976AF008D9D13 /* NSPersistentStore+MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSPersistentStore+MagicalRecord.h"; sourceTree = ""; }; - C7CF9731174976AF008D9D13 /* NSPersistentStore+MagicalRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSPersistentStore+MagicalRecord.m"; sourceTree = ""; }; - C7CF9732174976AF008D9D13 /* NSPersistentStoreCoordinator+MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSPersistentStoreCoordinator+MagicalRecord.h"; sourceTree = ""; }; - C7CF9733174976AF008D9D13 /* NSPersistentStoreCoordinator+MagicalRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSPersistentStoreCoordinator+MagicalRecord.m"; sourceTree = ""; }; - C7CF9735174976AF008D9D13 /* MagicalRecord+Actions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord+Actions.h"; sourceTree = ""; }; - C7CF9736174976AF008D9D13 /* MagicalRecord+Actions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+Actions.m"; sourceTree = ""; }; - C7CF9737174976AF008D9D13 /* MagicalRecord+ErrorHandling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord+ErrorHandling.h"; sourceTree = ""; }; - C7CF9738174976AF008D9D13 /* MagicalRecord+ErrorHandling.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+ErrorHandling.m"; sourceTree = ""; }; - C7CF9739174976AF008D9D13 /* MagicalRecord+iCloud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord+iCloud.h"; sourceTree = ""; }; - C7CF973A174976AF008D9D13 /* MagicalRecord+iCloud.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+iCloud.m"; sourceTree = ""; }; - C7CF973B174976AF008D9D13 /* MagicalRecord+Options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord+Options.h"; sourceTree = ""; }; - C7CF973C174976AF008D9D13 /* MagicalRecord+Options.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+Options.m"; sourceTree = ""; }; - C7CF973D174976AF008D9D13 /* MagicalRecord+Setup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord+Setup.h"; sourceTree = ""; }; - C7CF973E174976AF008D9D13 /* MagicalRecord+Setup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+Setup.m"; sourceTree = ""; }; - C7CF973F174976AF008D9D13 /* MagicalRecord+ShorthandSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord+ShorthandSupport.h"; sourceTree = ""; }; - C7CF9740174976AF008D9D13 /* MagicalRecord+ShorthandSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+ShorthandSupport.m"; sourceTree = ""; }; - C7CF9741174976AF008D9D13 /* MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MagicalRecord.h; sourceTree = ""; }; - C7CF9742174976AF008D9D13 /* MagicalRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MagicalRecord.m; sourceTree = ""; }; - C7CF9743174976AF008D9D13 /* MagicalRecordShorthand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MagicalRecordShorthand.h; sourceTree = ""; }; - C7CF9744174976AF008D9D13 /* CoreData+MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CoreData+MagicalRecord.h"; sourceTree = ""; }; C7CF975F17497858008D9D13 /* ImageToDataTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageToDataTransformer.h; sourceTree = ""; }; C7CF976017497858008D9D13 /* ImageToDataTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImageToDataTransformer.m; sourceTree = ""; }; /* End PBXFileReference section */ -/* Begin PBXFrameworksBuildPhase section */ - C7CF965C17496EDC008D9D13 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - C7CF969217496F95008D9D13 /* CoreData.framework in Frameworks */, - C7CF966317496EDC008D9D13 /* UIKit.framework in Frameworks */, - C7CF966517496EDC008D9D13 /* Foundation.framework in Frameworks */, - C7CF966717496EDC008D9D13 /* CoreGraphics.framework in Frameworks */, +/* Begin PBXGroup section */ + 90610DDE18F3FAF200E2C328 /* Vendor */ = { + isa = PBXGroup; + children = ( + 90610DE318F4022D00E2C328 /* MagicalRecord */, ); - runOnlyForDeploymentPostprocessing = 0; + name = Vendor; + sourceTree = ""; + }; + 90610DE318F4022D00E2C328 /* MagicalRecord */ = { + isa = PBXGroup; + children = ( + 90610DE418F4022D00E2C328 /* Categories */, + 90610E0E18F4022D00E2C328 /* Core */, + 90610E1E18F4022D00E2C328 /* CoreData+MagicalRecord.h */, + ); + name = MagicalRecord; + path = ../../MagicalRecord; + sourceTree = ""; + }; + 90610DE418F4022D00E2C328 /* Categories */ = { + isa = PBXGroup; + children = ( + 90610DE518F4022D00E2C328 /* DataImport */, + 90610DF418F4022D00E2C328 /* NSManagedObject */, + 90610DFF18F4022D00E2C328 /* NSManagedObjectContext */, + 90610E0818F4022D00E2C328 /* NSManagedObjectModel+MagicalRecord.h */, + 90610E0918F4022D00E2C328 /* NSManagedObjectModel+MagicalRecord.m */, + 90610E0A18F4022D00E2C328 /* NSPersistentStore+MagicalRecord.h */, + 90610E0B18F4022D00E2C328 /* NSPersistentStore+MagicalRecord.m */, + 90610E0C18F4022D00E2C328 /* NSPersistentStoreCoordinator+MagicalRecord.h */, + 90610E0D18F4022D00E2C328 /* NSPersistentStoreCoordinator+MagicalRecord.m */, + ); + path = Categories; + sourceTree = ""; + }; + 90610DE518F4022D00E2C328 /* DataImport */ = { + isa = PBXGroup; + children = ( + 90610DE618F4022D00E2C328 /* MagicalImportFunctions.h */, + 90610DE718F4022D00E2C328 /* MagicalImportFunctions.m */, + 90610DE818F4022D00E2C328 /* NSAttributeDescription+MagicalDataImport.h */, + 90610DE918F4022D00E2C328 /* NSAttributeDescription+MagicalDataImport.m */, + 90610DEA18F4022D00E2C328 /* NSEntityDescription+MagicalDataImport.h */, + 90610DEB18F4022D00E2C328 /* NSEntityDescription+MagicalDataImport.m */, + 90610DEC18F4022D00E2C328 /* NSNumber+MagicalDataImport.h */, + 90610DED18F4022D00E2C328 /* NSNumber+MagicalDataImport.m */, + 90610DEE18F4022D00E2C328 /* NSObject+MagicalDataImport.h */, + 90610DEF18F4022D00E2C328 /* NSObject+MagicalDataImport.m */, + 90610DF018F4022D00E2C328 /* NSRelationshipDescription+MagicalDataImport.h */, + 90610DF118F4022D00E2C328 /* NSRelationshipDescription+MagicalDataImport.m */, + 90610DF218F4022D00E2C328 /* NSString+MagicalDataImport.h */, + 90610DF318F4022D00E2C328 /* NSString+MagicalDataImport.m */, + ); + path = DataImport; + sourceTree = ""; + }; + 90610DF418F4022D00E2C328 /* NSManagedObject */ = { + isa = PBXGroup; + children = ( + 90610DF518F4022D00E2C328 /* NSManagedObject+MagicalAggregation.h */, + 90610DF618F4022D00E2C328 /* NSManagedObject+MagicalAggregation.m */, + 90610DF718F4022D00E2C328 /* NSManagedObject+MagicalDataImport.h */, + 90610DF818F4022D00E2C328 /* NSManagedObject+MagicalDataImport.m */, + 90610DF918F4022D00E2C328 /* NSManagedObject+MagicalFinders.h */, + 90610DFA18F4022D00E2C328 /* NSManagedObject+MagicalFinders.m */, + 90610DFB18F4022D00E2C328 /* NSManagedObject+MagicalRecord.h */, + 90610DFC18F4022D00E2C328 /* NSManagedObject+MagicalRecord.m */, + 90610DFD18F4022D00E2C328 /* NSManagedObject+MagicalRequests.h */, + 90610DFE18F4022D00E2C328 /* NSManagedObject+MagicalRequests.m */, + ); + path = NSManagedObject; + sourceTree = ""; + }; + 90610DFF18F4022D00E2C328 /* NSManagedObjectContext */ = { + isa = PBXGroup; + children = ( + 90610E0018F4022D00E2C328 /* NSManagedObjectContext+MagicalObserving.h */, + 90610E0118F4022D00E2C328 /* NSManagedObjectContext+MagicalObserving.m */, + 90610E0218F4022D00E2C328 /* NSManagedObjectContext+MagicalRecord.h */, + 90610E0318F4022D00E2C328 /* NSManagedObjectContext+MagicalRecord.m */, + 90610E0418F4022D00E2C328 /* NSManagedObjectContext+MagicalSaves.h */, + 90610E0518F4022D00E2C328 /* NSManagedObjectContext+MagicalSaves.m */, + 90610E0618F4022D00E2C328 /* NSManagedObjectContext+MagicalThreading.h */, + 90610E0718F4022D00E2C328 /* NSManagedObjectContext+MagicalThreading.m */, + ); + path = NSManagedObjectContext; + sourceTree = ""; + }; + 90610E0E18F4022D00E2C328 /* Core */ = { + isa = PBXGroup; + children = ( + 90610E0F18F4022D00E2C328 /* MagicalRecord+Actions.h */, + 90610E1018F4022D00E2C328 /* MagicalRecord+Actions.m */, + 90610E1118F4022D00E2C328 /* MagicalRecord+ErrorHandling.h */, + 90610E1218F4022D00E2C328 /* MagicalRecord+ErrorHandling.m */, + 90610E1318F4022D00E2C328 /* MagicalRecord+iCloud.h */, + 90610E1418F4022D00E2C328 /* MagicalRecord+iCloud.m */, + 90610E1518F4022D00E2C328 /* MagicalRecord+Options.h */, + 90610E1618F4022D00E2C328 /* MagicalRecord+Options.m */, + 90610E1718F4022D00E2C328 /* MagicalRecord+Setup.h */, + 90610E1818F4022D00E2C328 /* MagicalRecord+Setup.m */, + 90610E1918F4022D00E2C328 /* MagicalRecord+ShorthandSupport.h */, + 90610E1A18F4022D00E2C328 /* MagicalRecord+ShorthandSupport.m */, + 90610E1B18F4022D00E2C328 /* MagicalRecord.h */, + 90610E1C18F4022D00E2C328 /* MagicalRecord.m */, + 90610E1D18F4022D00E2C328 /* MagicalRecordShorthand.h */, + ); + path = Core; + sourceTree = ""; }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ C7CF964D174966C4008D9D13 = { isa = PBXGroup; children = ( C7CF967D17496F83008D9D13 /* Application */, C7CF969317497005008D9D13 /* Resources */, - C7CF97081749769E008D9D13 /* Vendor */, + 90610DDE18F3FAF200E2C328 /* Vendor */, C7CF966017496EDC008D9D13 /* Products */, ); sourceTree = ""; @@ -248,7 +340,7 @@ C7CF966017496EDC008D9D13 /* Products */ = { isa = PBXGroup; children = ( - C7CF965F17496EDC008D9D13 /* Recipies.app */, + C7CF965F17496EDC008D9D13 /* Recipes.app */, ); name = Products; sourceTree = ""; @@ -350,8 +442,8 @@ C7CF966117496EDC008D9D13 /* Frameworks */, C7CF968617496F83008D9D13 /* InfoPlist.strings */, C7CF968817496F83008D9D13 /* main.m */, - C7CF968917496F83008D9D13 /* Recipies-Info.plist */, - C7CF968A17496F83008D9D13 /* Recipies-Prefix.pch */, + C7CF968917496F83008D9D13 /* Recipes-Info.plist */, + C7CF968A17496F83008D9D13 /* Recipes-Prefix.pch */, ); path = Support; sourceTree = ""; @@ -431,135 +523,24 @@ path = generated; sourceTree = ""; }; - C7CF97081749769E008D9D13 /* Vendor */ = { - isa = PBXGroup; - children = ( - C7CF9709174976AF008D9D13 /* MagicalRecord */, - ); - path = Vendor; - sourceTree = ""; - }; - C7CF9709174976AF008D9D13 /* MagicalRecord */ = { - isa = PBXGroup; - children = ( - C7CF970A174976AF008D9D13 /* Categories */, - C7CF9734174976AF008D9D13 /* Core */, - C7CF9744174976AF008D9D13 /* CoreData+MagicalRecord.h */, - ); - name = MagicalRecord; - path = ../../../MagicalRecord; - sourceTree = ""; - }; - C7CF970A174976AF008D9D13 /* Categories */ = { - isa = PBXGroup; - children = ( - C7CF970B174976AF008D9D13 /* DataImport */, - C7CF971A174976AF008D9D13 /* NSManagedObject */, - C7CF9725174976AF008D9D13 /* NSManagedObjectContext */, - C7CF972E174976AF008D9D13 /* NSManagedObjectModel+MagicalRecord.h */, - C7CF972F174976AF008D9D13 /* NSManagedObjectModel+MagicalRecord.m */, - C7CF9730174976AF008D9D13 /* NSPersistentStore+MagicalRecord.h */, - C7CF9731174976AF008D9D13 /* NSPersistentStore+MagicalRecord.m */, - C7CF9732174976AF008D9D13 /* NSPersistentStoreCoordinator+MagicalRecord.h */, - C7CF9733174976AF008D9D13 /* NSPersistentStoreCoordinator+MagicalRecord.m */, - ); - path = Categories; - sourceTree = ""; - }; - C7CF970B174976AF008D9D13 /* DataImport */ = { - isa = PBXGroup; - children = ( - C7CF970C174976AF008D9D13 /* MagicalImportFunctions.h */, - C7CF970D174976AF008D9D13 /* MagicalImportFunctions.m */, - C7CF970E174976AF008D9D13 /* NSAttributeDescription+MagicalDataImport.h */, - C7CF970F174976AF008D9D13 /* NSAttributeDescription+MagicalDataImport.m */, - C7CF9710174976AF008D9D13 /* NSEntityDescription+MagicalDataImport.h */, - C7CF9711174976AF008D9D13 /* NSEntityDescription+MagicalDataImport.m */, - C7CF9712174976AF008D9D13 /* NSNumber+MagicalDataImport.h */, - C7CF9713174976AF008D9D13 /* NSNumber+MagicalDataImport.m */, - C7CF9714174976AF008D9D13 /* NSObject+MagicalDataImport.h */, - C7CF9715174976AF008D9D13 /* NSObject+MagicalDataImport.m */, - C7CF9716174976AF008D9D13 /* NSRelationshipDescription+MagicalDataImport.h */, - C7CF9717174976AF008D9D13 /* NSRelationshipDescription+MagicalDataImport.m */, - C7CF9718174976AF008D9D13 /* NSString+MagicalDataImport.h */, - C7CF9719174976AF008D9D13 /* NSString+MagicalDataImport.m */, - ); - path = DataImport; - sourceTree = ""; - }; - C7CF971A174976AF008D9D13 /* NSManagedObject */ = { - isa = PBXGroup; - children = ( - C7CF971B174976AF008D9D13 /* NSManagedObject+MagicalAggregation.h */, - C7CF971C174976AF008D9D13 /* NSManagedObject+MagicalAggregation.m */, - C7CF971D174976AF008D9D13 /* NSManagedObject+MagicalDataImport.h */, - C7CF971E174976AF008D9D13 /* NSManagedObject+MagicalDataImport.m */, - C7CF971F174976AF008D9D13 /* NSManagedObject+MagicalFinders.h */, - C7CF9720174976AF008D9D13 /* NSManagedObject+MagicalFinders.m */, - C7CF9721174976AF008D9D13 /* NSManagedObject+MagicalRecord.h */, - C7CF9722174976AF008D9D13 /* NSManagedObject+MagicalRecord.m */, - C7CF9723174976AF008D9D13 /* NSManagedObject+MagicalRequests.h */, - C7CF9724174976AF008D9D13 /* NSManagedObject+MagicalRequests.m */, - ); - path = NSManagedObject; - sourceTree = ""; - }; - C7CF9725174976AF008D9D13 /* NSManagedObjectContext */ = { - isa = PBXGroup; - children = ( - C7CF9726174976AF008D9D13 /* NSManagedObjectContext+MagicalObserving.h */, - C7CF9727174976AF008D9D13 /* NSManagedObjectContext+MagicalObserving.m */, - C7CF9728174976AF008D9D13 /* NSManagedObjectContext+MagicalRecord.h */, - C7CF9729174976AF008D9D13 /* NSManagedObjectContext+MagicalRecord.m */, - C7CF972A174976AF008D9D13 /* NSManagedObjectContext+MagicalSaves.h */, - C7CF972B174976AF008D9D13 /* NSManagedObjectContext+MagicalSaves.m */, - C7CF972C174976AF008D9D13 /* NSManagedObjectContext+MagicalThreading.h */, - C7CF972D174976AF008D9D13 /* NSManagedObjectContext+MagicalThreading.m */, - ); - path = NSManagedObjectContext; - sourceTree = ""; - }; - C7CF9734174976AF008D9D13 /* Core */ = { - isa = PBXGroup; - children = ( - C7CF9735174976AF008D9D13 /* MagicalRecord+Actions.h */, - C7CF9736174976AF008D9D13 /* MagicalRecord+Actions.m */, - C7CF9737174976AF008D9D13 /* MagicalRecord+ErrorHandling.h */, - C7CF9738174976AF008D9D13 /* MagicalRecord+ErrorHandling.m */, - C7CF9739174976AF008D9D13 /* MagicalRecord+iCloud.h */, - C7CF973A174976AF008D9D13 /* MagicalRecord+iCloud.m */, - C7CF973B174976AF008D9D13 /* MagicalRecord+Options.h */, - C7CF973C174976AF008D9D13 /* MagicalRecord+Options.m */, - C7CF973D174976AF008D9D13 /* MagicalRecord+Setup.h */, - C7CF973E174976AF008D9D13 /* MagicalRecord+Setup.m */, - C7CF973F174976AF008D9D13 /* MagicalRecord+ShorthandSupport.h */, - C7CF9740174976AF008D9D13 /* MagicalRecord+ShorthandSupport.m */, - C7CF9741174976AF008D9D13 /* MagicalRecord.h */, - C7CF9742174976AF008D9D13 /* MagicalRecord.m */, - C7CF9743174976AF008D9D13 /* MagicalRecordShorthand.h */, - ); - path = Core; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - C7CF965E17496EDC008D9D13 /* Recipies */ = { + C7CF965E17496EDC008D9D13 /* Recipes */ = { isa = PBXNativeTarget; - buildConfigurationList = C7CF967C17496EDC008D9D13 /* Build configuration list for PBXNativeTarget "Recipies" */; + buildConfigurationList = C7CF967C17496EDC008D9D13 /* Build configuration list for PBXNativeTarget "Recipes" */; buildPhases = ( C7CF96F017497178008D9D13 /* Regenerate Core Data Entities */, C7CF965B17496EDC008D9D13 /* Sources */, - C7CF965C17496EDC008D9D13 /* Frameworks */, C7CF965D17496EDC008D9D13 /* Resources */, ); buildRules = ( ); dependencies = ( ); - name = Recipies; + name = Recipes; productName = Recipies; - productReference = C7CF965F17496EDC008D9D13 /* Recipies.app */; + productReference = C7CF965F17496EDC008D9D13 /* Recipes.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ @@ -568,7 +549,7 @@ C7CF964E174966C4008D9D13 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0460; + LastUpgradeCheck = 0510; }; buildConfigurationList = C7CF9651174966C4008D9D13 /* Build configuration list for PBXProject "MagicalRecordRecipes" */; compatibilityVersion = "Xcode 3.2"; @@ -582,7 +563,7 @@ projectDirPath = ""; projectRoot = ""; targets = ( - C7CF965E17496EDC008D9D13 /* Recipies */, + C7CF965E17496EDC008D9D13 /* Recipes */, ); }; /* End PBXProject section */ @@ -644,53 +625,53 @@ buildActionMask = 2147483647; files = ( C7CF968C17496F83008D9D13 /* MGPRecipesAppDelegate.m in Sources */, + 90610E3418F4022D00E2C328 /* MagicalRecord+iCloud.m in Sources */, + 90610E2318F4022D00E2C328 /* NSObject+MagicalDataImport.m in Sources */, C7CF968F17496F83008D9D13 /* main.m in Sources */, C7CF96E217497086008D9D13 /* EditingTableViewCell.m in Sources */, C7CF96E317497086008D9D13 /* ImperialPickerController.m in Sources */, + 90610E2F18F4022D00E2C328 /* NSManagedObjectModel+MagicalRecord.m in Sources */, + 90610E2518F4022D00E2C328 /* NSString+MagicalDataImport.m in Sources */, + 90610E2418F4022D00E2C328 /* NSRelationshipDescription+MagicalDataImport.m in Sources */, + 90610E2818F4022D00E2C328 /* NSManagedObject+MagicalFinders.m in Sources */, C7CF96E417497086008D9D13 /* IngredientDetailViewController.m in Sources */, + 90610E1F18F4022D00E2C328 /* MagicalImportFunctions.m in Sources */, C7CF96E517497086008D9D13 /* InstructionsViewController.m in Sources */, + 90610E2E18F4022D00E2C328 /* NSManagedObjectContext+MagicalThreading.m in Sources */, C7CF96E617497086008D9D13 /* MetricPickerController.m in Sources */, C7CF96E717497086008D9D13 /* RecipeAddViewController.m in Sources */, + 90610E3318F4022D00E2C328 /* MagicalRecord+ErrorHandling.m in Sources */, + 90610E2D18F4022D00E2C328 /* NSManagedObjectContext+MagicalSaves.m in Sources */, + 90610E3118F4022D00E2C328 /* NSPersistentStoreCoordinator+MagicalRecord.m in Sources */, C7CF96E817497086008D9D13 /* RecipeDetailViewController.m in Sources */, + 90610E2B18F4022D00E2C328 /* NSManagedObjectContext+MagicalObserving.m in Sources */, + 90610E2618F4022D00E2C328 /* NSManagedObject+MagicalAggregation.m in Sources */, C7CF96E917497086008D9D13 /* RecipeListTableViewController.m in Sources */, + 90610E2218F4022D00E2C328 /* NSNumber+MagicalDataImport.m in Sources */, C7CF96EA17497086008D9D13 /* RecipePhotoViewController.m in Sources */, + 90610E2C18F4022D00E2C328 /* NSManagedObjectContext+MagicalRecord.m in Sources */, + 90610E3218F4022D00E2C328 /* MagicalRecord+Actions.m in Sources */, + 90610E2018F4022D00E2C328 /* NSAttributeDescription+MagicalDataImport.m in Sources */, + 90610E3518F4022D00E2C328 /* MagicalRecord+Options.m in Sources */, C7CF96EC17497086008D9D13 /* RecipeTableViewCell.m in Sources */, C7CF96ED17497086008D9D13 /* TemperatureConverterViewController.m in Sources */, + 90610E2A18F4022D00E2C328 /* NSManagedObject+MagicalRequests.m in Sources */, C7CF96EE17497086008D9D13 /* TypeSelectionViewController.m in Sources */, C7CF96EF17497086008D9D13 /* UnitConverterTableViewController.m in Sources */, + 90610E3018F4022D00E2C328 /* NSPersistentStore+MagicalRecord.m in Sources */, C7CF96F4174971C4008D9D13 /* Recipes.xcdatamodeld in Sources */, C7CF96FF1749725B008D9D13 /* Ingredient.m in Sources */, C7CF97001749725B008D9D13 /* Recipe.m in Sources */, + 90610E3718F4022D00E2C328 /* MagicalRecord+ShorthandSupport.m in Sources */, + 90610E2718F4022D00E2C328 /* NSManagedObject+MagicalDataImport.m in Sources */, C7CF97011749725B008D9D13 /* _Ingredient.m in Sources */, C7CF97021749725B008D9D13 /* _Recipe.m in Sources */, + 90610E3618F4022D00E2C328 /* MagicalRecord+Setup.m in Sources */, + 90610E2918F4022D00E2C328 /* NSManagedObject+MagicalRecord.m in Sources */, + 90610E2118F4022D00E2C328 /* NSEntityDescription+MagicalDataImport.m in Sources */, C7CF970517497348008D9D13 /* TemperatureCell.m in Sources */, + 90610E3818F4022D00E2C328 /* MagicalRecord.m in Sources */, C7CF97071749752D008D9D13 /* WeightConverterViewController.m in Sources */, - C7CF9745174976AF008D9D13 /* MagicalImportFunctions.m in Sources */, - C7CF9746174976AF008D9D13 /* NSAttributeDescription+MagicalDataImport.m in Sources */, - C7CF9747174976AF008D9D13 /* NSEntityDescription+MagicalDataImport.m in Sources */, - C7CF9748174976AF008D9D13 /* NSNumber+MagicalDataImport.m in Sources */, - C7CF9749174976AF008D9D13 /* NSObject+MagicalDataImport.m in Sources */, - C7CF974A174976AF008D9D13 /* NSRelationshipDescription+MagicalDataImport.m in Sources */, - C7CF974B174976AF008D9D13 /* NSString+MagicalDataImport.m in Sources */, - C7CF974C174976AF008D9D13 /* NSManagedObject+MagicalAggregation.m in Sources */, - C7CF974D174976AF008D9D13 /* NSManagedObject+MagicalDataImport.m in Sources */, - C7CF974E174976AF008D9D13 /* NSManagedObject+MagicalFinders.m in Sources */, - C7CF974F174976AF008D9D13 /* NSManagedObject+MagicalRecord.m in Sources */, - C7CF9750174976AF008D9D13 /* NSManagedObject+MagicalRequests.m in Sources */, - C7CF9751174976AF008D9D13 /* NSManagedObjectContext+MagicalObserving.m in Sources */, - C7CF9752174976AF008D9D13 /* NSManagedObjectContext+MagicalRecord.m in Sources */, - C7CF9753174976AF008D9D13 /* NSManagedObjectContext+MagicalSaves.m in Sources */, - C7CF9754174976AF008D9D13 /* NSManagedObjectContext+MagicalThreading.m in Sources */, - C7CF9755174976AF008D9D13 /* NSManagedObjectModel+MagicalRecord.m in Sources */, - C7CF9756174976AF008D9D13 /* NSPersistentStore+MagicalRecord.m in Sources */, - C7CF9757174976AF008D9D13 /* NSPersistentStoreCoordinator+MagicalRecord.m in Sources */, - C7CF9758174976AF008D9D13 /* MagicalRecord+Actions.m in Sources */, - C7CF9759174976AF008D9D13 /* MagicalRecord+ErrorHandling.m in Sources */, - C7CF975A174976AF008D9D13 /* MagicalRecord+iCloud.m in Sources */, - C7CF975B174976AF008D9D13 /* MagicalRecord+Options.m in Sources */, - C7CF975C174976AF008D9D13 /* MagicalRecord+Setup.m in Sources */, - C7CF975D174976AF008D9D13 /* MagicalRecord+ShorthandSupport.m in Sources */, - C7CF975E174976B0008D9D13 /* MagicalRecord.m in Sources */, C7CF976117497858008D9D13 /* ImageToDataTransformer.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -712,12 +693,17 @@ C7CF9652174966C4008D9D13 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; }; name = Debug; }; C7CF9653174966C4008D9D13 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; + SDKROOT = iphoneos; }; name = Release; }; @@ -725,8 +711,6 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -735,15 +719,11 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Library/Frameworks\"", - ); GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "Application/Support/Recipies-Prefix.pch"; + GCC_PREFIX_HEADER = "Application/Support/Recipes-Prefix.pch"; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", @@ -752,11 +732,11 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = "Application/Support/Recipies-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 6.1; + HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../../MagicalRecord\"/**"; + INFOPLIST_FILE = "Application/Support/Recipes-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 7.1; ONLY_ACTIVE_ARCH = YES; PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = iphoneos; WRAPPER_EXTENSION = app; }; name = Debug; @@ -765,8 +745,6 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -775,21 +753,17 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Library/Frameworks\"", - ); GCC_C_LANGUAGE_STANDARD = gnu99; GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "Application/Support/Recipies-Prefix.pch"; + GCC_PREFIX_HEADER = "Application/Support/Recipes-Prefix.pch"; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = "Application/Support/Recipies-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 6.1; + HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../../MagicalRecord\"/**"; + INFOPLIST_FILE = "Application/Support/Recipes-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 7.1; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; WRAPPER_EXTENSION = app; }; @@ -807,7 +781,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - C7CF967C17496EDC008D9D13 /* Build configuration list for PBXNativeTarget "Recipies" */ = { + C7CF967C17496EDC008D9D13 /* Build configuration list for PBXNativeTarget "Recipes" */ = { isa = XCConfigurationList; buildConfigurations = ( C7CF967A17496EDC008D9D13 /* Debug */, diff --git a/Support/Info.plist b/Support/Info.plist new file mode 100644 index 000000000..b1658c9eb --- /dev/null +++ b/Support/Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + com.magicalpanda.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSHumanReadableCopyright + Copyright © 2015 Magical Panda Software LLC. All rights reserved. + NSPrincipalClass + + + diff --git a/Support/Scripts/GenerateShorthandAliases.rb b/Support/Scripts/GenerateShorthandAliases.rb new file mode 100755 index 000000000..5401f2481 --- /dev/null +++ b/Support/Scripts/GenerateShorthandAliases.rb @@ -0,0 +1,270 @@ +#!/usr/bin/env ruby +# +# ProcessHeader.rb +# Magical Record +# +# Created by Saul Mora on 11/14/11. +# Copyright 2011 Magical Panda Software LLC. All rights reserved. +# + +require 'pp' + +def processImplementation(headerFile) + unless headerFile.end_with? ".h" + puts "#{headerFile} not a header" + return + end + + puts "Reading #{headerFile}" + + method_match_expression = /^(?[\+|\-]\s*\([a-zA-Z\s\*]*\)\s*)(?\w+)(?\:?.*)/ + category_match_expression = /^\s*(?@[[:alnum:]]+)\s*(?[[:alnum:]]+)\s*(\((?\w+)\))?/ + + lines = File.readlines(headerFile) + non_prefixed_methods = [] + processed_methods_count = 0 + objects_to_process = ["NSManagedObject", "NSManagedObjectContext", "NSManagedObjectModel", "NSPersistentStoreCoordinator", "NSPersistentStore"] + + lines.each { |line| + processed_line = nil + if line.start_with?("@interface") + matches = category_match_expression.match(line) + if objects_to_process.include?(matches[:ObjectName]) + processed_line = "\n@implementation #{matches[:ObjectName]} (#{matches[:Category]}ShortHand)\n" + else + puts "Skipping #{headerFile} because it didn't match any of the approved classes" + non_prefixed_methods = nil + return + end + end + + if processed_line == nil + matches = method_match_expression.match(line) + + if matches + + if matches[:MethodName].start_with?("MR_") + ++processed_methods_count + methodName = matches[:MethodName].sub("MR_", "") + methodStart = matches[:Start].gsub(/^[\-|\+].*/, '') + methodEnd = matches[:End].gsub(/\sNS_[^\s]+/, '').gsub(/\sMR_DEPRECATED_IN_3_0_PLEASE_USE.*$/, '') + + selfcall = "#{methodStart}#{matches[:MethodName]}#{methodEnd}" + + pp selfcall + selfcall = selfcall.gsub(/;$/, '') + selfcall = selfcall.gsub(/(\([^\)]+\)+)/, '') + + processed_line = <[\+|\-]\s*\([a-zA-Z\s\*]*\)\s*)(?\w+)(?\:?.*)/ + category_match_expression = /^\s*(?@[[:alnum:]]+)\s*(?[[:alnum:]]+)\s*(\((?\w+)\))?/ + + lines = File.readlines(headerFile) + non_prefixed_methods = [] + processed_methods_count = 0 + objects_to_process = ["NSManagedObject", "NSManagedObjectContext", "NSManagedObjectModel", "NSPersistentStoreCoordinator", "NSPersistentStore"] + + lines.each { |line| + processed_line = nil + if line.start_with?("@interface") + matches = category_match_expression.match(line) + if objects_to_process.include?(matches[:ObjectName]) + processed_line = "\n#{matches[:Interface]} #{matches[:ObjectName]} (#{matches[:Category]}ShortHand)\n" + else + puts "Skipping #{headerFile} because it didn't match any of the approved classes" + non_prefixed_methods = nil + return + end + end + + if processed_line == nil + matches = method_match_expression.match(line) + + if matches + if matches[:MethodName].start_with?("MR_") + ++processed_methods_count + methodName = matches[:MethodName].sub("MR_", "") + methodStart = matches[:Start].gsub(/^([\-|\+]).*/, '\1') + methodEnd = matches[:End] + + methodSuffix = nil + unless include_deprecation_warnings == false or methodEnd.include? "MR_DEPRECATED_IN_3_0_PLEASE_USE" + methodEnd = methodEnd.sub(";", '') + deprecationNoticeMethod = methodEnd.gsub(/:(\([^\)]+\)[\w]+)|:(\(.+)/, ':') + deprecationNoticeMethod = deprecationNoticeMethod.gsub(/:\s/, ':') + deprecationNoticeMethod = deprecationNoticeMethod.gsub(/ NS_[^\s]+/, '') + deprecationNoticeMethod = deprecationNoticeMethod.gsub(/;$/, '') + + methodSuffix = " MR_DEPRECATED_IN_3_0_PLEASE_USE(\"#{matches[:MethodName]}\");" + end + + processed_line = "#{matches[:Start]}#{methodName}#{methodEnd}#{methodSuffix}" + + if processed_line.include? "NSFetchedResultsController" + processed_line = "\n#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR\n\n#{processed_line}\n\n#endif /* TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR */" + end + else + non_prefixed_methods = nil + return + puts "Skipping #{headerFile} : #{matches[:MethodName]} because it doesn't start with MR_" + end + end + end + + if processed_line == nil + if line.start_with?("@end") + processed_line = "\n@end\n" + end + end + + unless processed_line == nil + non_prefixed_methods << processed_line + end + } + + non_prefixed_methods.compact +end + +def processDirectoryForHeaders(path, include_deprecation_warnings) + + headers = File.join(path, "**", "*+*.h") + processedHeaders = [] + + Dir.glob(headers).each { |file| + puts "Processing #{file}" + + processDirectory(file) if File.directory?(file) + if file.end_with?(".h") + processedHeaders << processHeader(file, include_deprecation_warnings) + end + } + + processedHeaders +end + +def processDirectoryForImplementations(path) + + headers = File.join(path, "**", "*+*.h") + processedHeaders = [] + + Dir.glob(headers).each { |file| + puts "Processing #{file}" + + processDirectory(file) if File.directory?(file) + if file.end_with?(".h") + processedHeaders << processImplementation(file) + end + } + + processedHeaders +end + + +def generateHeaders(startingPoint, include_deprecation_warnings) + + processedHeaders = [] + if startingPoint + path = File.expand_path(startingPoint) + + if path.end_with?(".h") + processedHeaders << processHeader(path, include_deprecation_warnings) + else + puts "Processing Headers in #{path}" + processedHeaders << processDirectoryForHeaders(path, include_deprecation_warnings) + end + + else + processedHeaders << processDirectoryForHeaders(startingPoint || Dir.getwd(), include_deprecation_warnings) + end + + processedHeaders +end + +def generateImplementations(startingPoint) + + processedHeaders = [] + if startingPoint + path = File.expand_path(startingPoint) + + if path.end_with?(".h") + processedHeaders << processImplementation(path) + else + puts "Processing Headers in #{path}" + processedHeaders << processDirectoryForImplementations(path) + end + + else + processedHeaders << processDirectoryForImplementations(startingPoint || Dir.getwd()) + end + + processedHeaders +end + + +puts "Input dir: #{File.expand_path(ARGV[0])}" + +output_file = ARGV[1] +puts "Output file: #{File.expand_path(output_file)}" + +unless output_file + puts "Need an output file specified" + return +else + puts "Generating shorthand headers" +end + +headers = generateHeaders(ARGV[0], false).collect &:compact +# implementations = generateImplementations(ARGV[0]).collect &:compact + +File.open("#{output_file}.h", "w") { |file| + file.write("#import \n") + file.write("#import \n\n") + file.write(headers.compact.join("\n")) +} + +# File.open("#{output_file}.m", "w") { |file| +# file.write("#ifdef MR_SHORTHAND\n\n") +# file.write("#import \"#{output_file}.h\"\n") +# file.write("#import \"MagicalRecord.h\"\n\n") +# file.write(implementations.compact.join("\n")) +# file.write("#endif\n") +# } diff --git a/Support/Scripts/objc-build-scripts/LICENSE.md b/Support/Scripts/objc-build-scripts/LICENSE.md new file mode 100644 index 000000000..8d9238408 --- /dev/null +++ b/Support/Scripts/objc-build-scripts/LICENSE.md @@ -0,0 +1,18 @@ +**Copyright (c) 2013 Justin Spahr-Summers** + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Support/Scripts/objc-build-scripts/README.md b/Support/Scripts/objc-build-scripts/README.md new file mode 100644 index 000000000..f66206fb3 --- /dev/null +++ b/Support/Scripts/objc-build-scripts/README.md @@ -0,0 +1,82 @@ +# objc-build-scripts + +This project is a collection of scripts created with two goals: + + 1. To standardize how Objective-C projects are bootstrapped after cloning + 1. To easily build Objective-C projects on continuous integration servers + +## Scripts + +Right now, there are two important scripts: [`bootstrap`](#bootstrap) and +[`cibuild`](#cibuild). Both are Bash scripts, to maximize compatibility and +eliminate pesky system configuration issues (like setting up a working Ruby +environment). + +The structure of the scripts on disk is meant to follow that of a typical Ruby +project: + +``` +script/ + bootstrap + cibuild +``` + +### bootstrap + +This script is responsible for bootstrapping (initializing) your project after +it's been checked out. Here, you should install or clone any dependencies that +are required for a working build and development environment. + +By default, the script will verify that [xctool][] is installed, then initialize +and update submodules recursively. If any submodules contain `script/bootstrap`, +that will be run as well. + +To check that other tools are installed, you can set the `REQUIRED_TOOLS` +environment variable before running `script/bootstrap`, or edit it within the +script directly. Note that no installation is performed automatically, though +this can always be added within your specific project. + +### cibuild + +This script is responsible for building the project, as you would want it built +for continuous integration. This is preferable to putting the logic on the CI +server itself, since it ensures that any changes are versioned along with the +source. + +By default, the script will run [`bootstrap`](#bootstrap), look for any Xcode +workspace or project in the working directory, then build all targets/schemes +(as found by `xcodebuild -list`) using [xctool][]. + +You can also specify the schemes to build by passing them into the script: + +```sh +script/cibuild ReactiveCocoa-Mac ReactiveCocoa-iOS +``` + +As with the `bootstrap` script, there are several environment variables that can +be used to customize behavior. They can be set on the command line before +invoking the script, or the defaults changed within the script directly. + +## Getting Started + +To add the scripts to your project, read the contents of this repository into +a `script` folder: + +``` +$ git remote add objc-build-scripts https://github.com/jspahrsummers/objc-build-scripts.git +$ git fetch objc-build-scripts +$ git read-tree --prefix=script/ -u objc-build-scripts/master +``` + +Then commit the changes, to incorporate the scripts into your own repository's +history. You can also freely tweak the scripts for your specific project's +needs. + +To merge in upstream changes later: + +``` +$ git fetch -p objc-build-scripts +$ git merge --ff --squash -Xsubtree=script objc-build-scripts/master +``` + +[xctool]: https://github.com/facebook/xctool diff --git a/Support/Scripts/objc-build-scripts/bootstrap b/Support/Scripts/objc-build-scripts/bootstrap new file mode 100755 index 000000000..d61c863b7 --- /dev/null +++ b/Support/Scripts/objc-build-scripts/bootstrap @@ -0,0 +1,47 @@ +#!/bin/bash + +export SCRIPT_DIR=$(dirname "$0") + +## +## Bootstrap Process +## + +main () +{ + local submodules=$(git submodule status) + local result=$? + + if [ "$result" -ne "0" ] + then + exit $result + fi + + if [ -n "$submodules" ] + then + echo "*** Updating submodules..." + update_submodules + fi +} + +bootstrap_submodule () +{ + local bootstrap="script/bootstrap" + + if [ -e "$bootstrap" ] + then + echo "*** Bootstrapping $name..." + "$bootstrap" >/dev/null + else + update_submodules + fi +} + +update_submodules () +{ + git submodule sync --quiet && git submodule update --init && git submodule foreach --quiet bootstrap_submodule +} + +export -f bootstrap_submodule +export -f update_submodules + +main diff --git a/Support/Scripts/objc-build-scripts/cibuild b/Support/Scripts/objc-build-scripts/cibuild new file mode 100755 index 000000000..33b512934 --- /dev/null +++ b/Support/Scripts/objc-build-scripts/cibuild @@ -0,0 +1,173 @@ +#!/bin/bash + +export SCRIPT_DIR=$(dirname "$0") + +## +## Configuration Variables +## + +SCHEMES="$@" + +config () +{ + # The workspace to build. + # + # If not set and no workspace is found, the -workspace flag will not be passed + # to `xctool`. + # + # Only one of `XCWORKSPACE` and `XCODEPROJ` needs to be set. The former will + # take precedence. + : ${XCWORKSPACE=$(find_pattern "*.xcworkspace")} + + # The project to build. + # + # If not set and no project is found, the -project flag will not be passed + # to `xctool`. + # + # Only one of `XCWORKSPACE` and `XCODEPROJ` needs to be set. The former will + # take precedence. + : ${XCODEPROJ=$(find_pattern "*.xcodeproj")} + + # A bootstrap script to run before building. + # + # If this file does not exist, it is not considered an error. + : ${BOOTSTRAP="$SCRIPT_DIR/bootstrap"} + + # Extra options to pass to xctool. + : ${XCTOOL_OPTIONS="RUN_CLANG_STATIC_ANALYZER=NO"} + + # A whitespace-separated list of default schemes to build. + # + # Individual names can be quoted to avoid word splitting. + : ${SCHEMES:=$(xcodebuild -list -project "$XCODEPROJ" 2>/dev/null | awk -f "$SCRIPT_DIR/schemes.awk")} + + # A whitespace-separated list of executables that must be present and locatable. + : ${REQUIRED_TOOLS="xctool"} + + export XCWORKSPACE + export XCODEPROJ + export BOOTSTRAP + export XCTOOL_OPTIONS + export SCHEMES + export REQUIRED_TOOLS +} + +## +## Build Process +## + +main () +{ + config + + if [ -n "$REQUIRED_TOOLS" ] + then + echo "*** Checking dependencies..." + check_deps + fi + + if [ -f "$BOOTSTRAP" ] + then + echo "*** Bootstrapping..." + "$BOOTSTRAP" || exit $? + fi + + echo "*** The following schemes will be built:" + echo "$SCHEMES" | xargs -n 1 echo " " + echo + + echo "$SCHEMES" | xargs -n 1 | ( + local status=0 + + while read scheme + do + build_scheme "$scheme" || status=1 + done + + exit $status + ) +} + +check_deps () +{ + for tool in $REQUIRED_TOOLS + do + which -s "$tool" + if [ "$?" -ne "0" ] + then + echo "*** Error: $tool not found. Please install it and cibuild again." + exit 1 + fi + done +} + +find_pattern () +{ + ls -d $1 2>/dev/null | head -n 1 +} + +run_xctool () +{ + if [ -n "$XCWORKSPACE" ] + then + xctool -workspace "$XCWORKSPACE" $XCTOOL_OPTIONS "$@" 2>&1 + elif [ -n "$XCODEPROJ" ] + then + xctool -project "$XCODEPROJ" $XCTOOL_OPTIONS "$@" 2>&1 + else + echo "*** No workspace or project file found." + exit 1 + fi +} + +parse_build () +{ + awk -f "$SCRIPT_DIR/xctool.awk" 2>&1 >/dev/null +} + +build_scheme () +{ + local scheme=$1 + + echo "*** Building and testing $scheme..." + echo + + local sdkflag= + local action=test + + # Determine whether we can run unit tests for this target. + run_xctool -scheme "$scheme" run-tests | parse_build + + local awkstatus=$? + + if [ "$awkstatus" -eq "1" ] + then + # SDK not found, try for iphonesimulator. + sdkflag="-sdk iphonesimulator" + + # Determine whether the unit tests will run with iphonesimulator + run_xctool $sdkflag -scheme "$scheme" run-tests | parse_build + + awkstatus=$? + + if [ "$awkstatus" -ne "0" ] + then + # Unit tests will not run on iphonesimulator. + sdkflag="" + fi + fi + + if [ "$awkstatus" -ne "0" ] + then + # Unit tests aren't supported. + action=build + fi + + run_xctool $sdkflag -scheme "$scheme" $action +} + +export -f build_scheme +export -f run_xctool +export -f parse_build + +main diff --git a/Support/Scripts/objc-build-scripts/schemes.awk b/Support/Scripts/objc-build-scripts/schemes.awk new file mode 100644 index 000000000..b58ef7833 --- /dev/null +++ b/Support/Scripts/objc-build-scripts/schemes.awk @@ -0,0 +1,11 @@ +BEGIN { + FS = "\n"; +} + +/Schemes:/ { + while (getline && $0 != "") { + if ($0 !~ /MagicalRecord/) continue; + sub(/^ +/, ""); + print "'" $0 "'"; + } +} diff --git a/Support/Scripts/objc-build-scripts/xctool.awk b/Support/Scripts/objc-build-scripts/xctool.awk new file mode 100644 index 000000000..f6132589d --- /dev/null +++ b/Support/Scripts/objc-build-scripts/xctool.awk @@ -0,0 +1,25 @@ +# Exit statuses: +# +# 0 - No errors found. +# 1 - Wrong SDK. Retry with SDK `iphonesimulator`. +# 2 - Missing target. + +BEGIN { + status = 0; +} + +{ + print; +} + +/Testing with the '(.+)' SDK is not yet supported/ { + status = 1; +} + +/does not contain a target named/ { + status = 2; +} + +END { + exit status; +} diff --git a/Tests/Core/MagicalRecord+ActionsTests.m b/Tests/Core/MagicalRecord+ActionsTests.m new file mode 100644 index 000000000..9ec1b7351 --- /dev/null +++ b/Tests/Core/MagicalRecord+ActionsTests.m @@ -0,0 +1,258 @@ +// +// Created by Tony Arnold on 25/03/2014. +// Copyright (c) 2014 Magical Panda Software LLC. All rights reserved. +// + +#import "MagicalRecordTestBase.h" +#import "SingleEntityWithNoRelationships.h" + +@interface MagicalRecordActionsTests : MagicalRecordTestBase + +@end + +@implementation MagicalRecordActionsTests + +#pragma mark - Synchronous Saves + +- (void)testSynchronousSaveActionSaves +{ + __block NSManagedObjectID *objectId; + + [MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) { + NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createEntityInContext:localContext]; + + expect([inserted hasChanges]).to.beTruthy(); + + [localContext obtainPermanentIDsForObjects:@[inserted] error:nil]; + objectId = [inserted objectID]; + }]; + + expect(objectId).toNot.beNil(); + + XCTestExpectation *rootSavingExpectation = [self expectationWithDescription:@"Root Saving Context Fetch Object"]; + NSManagedObjectContext *rootSavingContext = [NSManagedObjectContext MR_rootSavingContext]; + + [rootSavingContext performBlock:^{ + NSError *fetchError; + NSManagedObject *fetchedObject = [rootSavingContext existingObjectWithID:objectId error:&fetchError]; + + expect(fetchedObject).toNot.beNil(); + expect(fetchError).to.beNil(); + expect([fetchedObject hasChanges]).to.beFalsy(); + + [rootSavingExpectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:5.0f handler:nil]; +} + +- (void)testSynchronousSaveActionMakesInsertedEntitiesAvailableInTheDefaultContext +{ + __block NSManagedObjectID *objectId; + + [MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) { + NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createEntityInContext:localContext]; + + expect([inserted hasChanges]).to.beTruthy(); + + [localContext obtainPermanentIDsForObjects:@[inserted] error:nil]; + objectId = [inserted objectID]; + }]; + + expect(objectId).toNot.beNil(); + + XCTestExpectation *rootSavingExpectation = [self expectationWithDescription:@"Root Saving Context Fetch Object"]; + NSManagedObjectContext *rootSavingContext = [NSManagedObjectContext MR_rootSavingContext]; + + [rootSavingContext performBlock:^{ + NSError *fetchError; + NSManagedObject *fetchedObject = [rootSavingContext existingObjectWithID:objectId error:&fetchError]; + + expect(fetchedObject).toNot.beNil(); + expect(fetchError).to.beNil(); + expect([fetchedObject hasChanges]).to.beFalsy(); + + [rootSavingExpectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:5.0f handler:nil]; +} + +- (void)testSynchronousSaveActionMakesUpdatesToEntitiesAvailableToTheDefaultContext +{ + __block NSManagedObjectID *objectId; + __block NSManagedObject *fetchedObject; + + NSString *const kTestAttributeKey = @"booleanTestAttribute"; + + [MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) { + NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createEntityInContext:localContext]; + + [inserted setValue:@YES forKey:kTestAttributeKey]; + + expect([inserted hasChanges]).to.beTruthy(); + + [localContext obtainPermanentIDsForObjects:@[inserted] error:nil]; + objectId = [inserted objectID]; + }]; + + XCTestExpectation *rootSavingExpectation = [self expectationWithDescription:@"Root Saving Context Fetch Object"]; + NSManagedObjectContext *rootSavingContext = [NSManagedObjectContext MR_rootSavingContext]; + + [rootSavingContext performBlock:^{ + fetchedObject = [rootSavingContext objectWithID:objectId]; + expect([fetchedObject valueForKey:kTestAttributeKey]).to.beTruthy(); + + [rootSavingExpectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:5.0f handler:nil]; + + [MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) { + NSManagedObject *changed = [localContext objectWithID:objectId]; + + [changed setValue:@NO forKey:kTestAttributeKey]; + }]; + + rootSavingExpectation = [self expectationWithDescription:@"Root Saving Context Fetch Object"]; + + [rootSavingContext performBlock:^{ + fetchedObject = [rootSavingContext objectWithID:objectId]; + + // Async since the merge to the main thread context after persistence + expect([fetchedObject valueForKey:kTestAttributeKey]).to.beFalsy(); + + [rootSavingExpectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:5.0f handler:nil]; +} + +#pragma mark - Asynchronous Saves + +- (void)testAsynchronousSaveActionSaves +{ + XCTestExpectation *expectation = [self expectationWithDescription:@"Save Completed"]; + + __block BOOL saveSuccessState = NO; + __block NSError *saveError; + __block NSManagedObjectID *objectId; + + [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) { + NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createEntityInContext:localContext]; + + expect([inserted hasChanges]).to.beTruthy(); + + expect([localContext obtainPermanentIDsForObjects:@[inserted] error:nil]).to.beTruthy(); + objectId = [inserted objectID]; + + expect(objectId).toNot.beNil(); + expect(objectId.isTemporaryID).to.beFalsy(); + } completion:^(BOOL contextDidSave, NSError *error) { + saveSuccessState = contextDidSave; + saveError = error; + + expect(saveSuccessState).to.beTruthy(); + expect(saveError).to.beNil(); + + NSManagedObjectContext *rootSavingContext = [NSManagedObjectContext MR_rootSavingContext]; + + [rootSavingContext performBlockAndWait:^{ + NSError *existingObjectError; + NSManagedObject *existingObject = [rootSavingContext existingObjectWithID:objectId error:&existingObjectError]; + + expect(existingObject).toNot.beNil(); + expect([existingObject hasChanges]).to.beFalsy(); + expect(existingObjectError).to.beNil(); + + [expectation fulfill]; + }]; + }]; + + [self waitForExpectationsWithTimeout:5.0f handler:nil]; +} + +- (void)testAsynchronousSaveActionCallsCompletionBlockOnTheMainThread +{ + XCTestExpectation *expectation = [self expectationWithDescription:@"Save Completed"]; + + [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) { + [SingleEntityWithNoRelationships MR_createEntityInContext:localContext]; + } completion:^(BOOL contextDidSave, NSError *error) { + expect([NSThread isMainThread]).to.beTruthy(); + + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:5.0f handler:nil]; +} + +- (void)testAsynchronousSaveActionMakesInsertedEntitiesAvailableInTheDefaultContext +{ + __block NSManagedObjectID *objectId; + + XCTestExpectation *contextSavedExpectation = [self expectationWithDescription:@"Context Did Save"]; + + [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) { + NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createEntityInContext:localContext]; + + expect([inserted hasChanges]).to.beTruthy(); + + [localContext obtainPermanentIDsForObjects:@[inserted] error:nil]; + objectId = [inserted objectID]; + } completion:^(BOOL contextDidSave, NSError *error) { + expect(contextDidSave).to.beTruthy(); + + NSManagedObjectContext *rootSavingContext = [NSManagedObjectContext MR_rootSavingContext]; + + [rootSavingContext performBlock:^{ + NSManagedObject *fetchedObject = [rootSavingContext objectWithID:objectId]; + expect(fetchedObject).toNot.beNil(); + expect([fetchedObject hasChanges]).to.beFalsy(); + + [contextSavedExpectation fulfill]; + }]; + }]; + + [self waitForExpectationsWithTimeout:5.0f handler:nil]; +} + +- (void)testAsynchronousSaveActionMakesUpdatesToEntitiesAvailableToTheDefaultContext +{ + __block NSManagedObjectID *objectId; + __block NSManagedObject *fetchedObject; + + NSString *const kTestAttributeKey = @"booleanTestAttribute"; + + [MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) { + NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createEntityInContext:localContext]; + + [inserted setValue:@YES forKey:kTestAttributeKey]; + + expect([inserted hasChanges]).to.beTruthy(); + + [localContext obtainPermanentIDsForObjects:@[inserted] error:nil]; + objectId = [inserted objectID]; + }]; + + NSManagedObjectContext *rootSavingContext = [NSManagedObjectContext MR_rootSavingContext]; + + [rootSavingContext performBlockAndWait:^{ + fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectWithID:objectId]; + expect([fetchedObject valueForKey:kTestAttributeKey]).to.beTruthy(); + }]; + + [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) { + NSManagedObject *changed = [localContext objectWithID:objectId]; + + [changed setValue:@NO forKey:kTestAttributeKey]; + } completion:^(BOOL contextDidSave, NSError *error) { + [rootSavingContext performBlockAndWait:^{ + fetchedObject = [rootSavingContext objectWithID:objectId]; + expect(fetchedObject).toNot.beNil(); + expect([fetchedObject valueForKey:kTestAttributeKey]).to.beFalsy(); + }]; + }]; +} + +@end diff --git a/Tests/Core/MagicalRecord+StackTests.m b/Tests/Core/MagicalRecord+StackTests.m new file mode 100644 index 000000000..2813f5d25 --- /dev/null +++ b/Tests/Core/MagicalRecord+StackTests.m @@ -0,0 +1,114 @@ +// +// Created by Saul Mora on 7/15/11. +// Copyright 2011 Magical Panda Software LLC. All rights reserved. +// + +#import +#import +#import + +#import +#import "MagicalRecordTestHelpers.h" + +@interface MagicalRecordTests : XCTestCase + +@end + + +@protocol MagicalRecordErrorHandlerProtocol + +- (void) testHandlingError:(NSError *)error; + +@end + +@implementation MagicalRecordTests +{ + BOOL errorHandlerWasCalled_; +} + +- (void) assertDefaultStack +{ + XCTAssertNotNil([NSManagedObjectContext MR_defaultContext], @"Default context cannot be nil"); + XCTAssertNotNil([NSManagedObjectModel MR_defaultManagedObjectModel], @"Default managed object model cannot be nil"); + XCTAssertNotNil([NSPersistentStoreCoordinator MR_defaultStoreCoordinator], @"Default store coordinator cannot be nil"); + XCTAssertNotNil([NSPersistentStore MR_defaultPersistentStore], @"Default persistent store cannot be nil"); +} + +- (void) testCreateDefaultCoreDataStack +{ + [MagicalRecord setupCoreDataStack]; + + [self assertDefaultStack]; + + NSPersistentStore *defaultStore = [NSPersistentStore MR_defaultPersistentStore]; + NSURL *defaultStoreURL = defaultStore.URL; + + XCTAssertTrue([[defaultStoreURL absoluteString] hasSuffix:@".sqlite"], @"Default store URL must have an extension of 'sqlite'"); + XCTAssertEqual([defaultStore type], NSSQLiteStoreType, @"Default store should be of type NSSQLiteStoreType"); + + [MagicalRecord cleanUp]; + [MagicalRecordTestHelpers removeStoreFilesForStoreAtURL:defaultStoreURL]; +} + +- (void) testCreateInMemoryCoreDataStack +{ + [MagicalRecord setupCoreDataStackWithInMemoryStore]; + + [self assertDefaultStack]; + + NSPersistentStore *defaultStore = [NSPersistentStore MR_defaultPersistentStore]; + XCTAssertEqual([defaultStore type], NSInMemoryStoreType, @"Default store should be of type NSInMemoryStoreType"); + + [MagicalRecord cleanUp]; +} + +- (void) testCreateSqliteStackWithCustomName +{ + NSString *testStoreName = @"MyTestDataStore.sqlite"; + NSURL *testStoreURL = [NSPersistentStore MR_urlForStoreName:testStoreName]; + + [MagicalRecord setupCoreDataStackWithStoreNamed:testStoreName]; + + [self assertDefaultStack]; + + NSPersistentStore *defaultStore = [NSPersistentStore MR_defaultPersistentStore]; + XCTAssertEqual([defaultStore type], NSSQLiteStoreType, @"Default store should be of type NSSQLiteStoreType"); + XCTAssertEqualObjects(defaultStore.URL, testStoreURL, @"Default store should have the same URL as the one that was passed to it"); + XCTAssertTrue([[[defaultStore URL] absoluteString] hasSuffix:testStoreName], @"Default store URL expects to have a suffix of '%@'", testStoreName); + + [MagicalRecord cleanUp]; + [MagicalRecordTestHelpers removeStoreFilesForStoreAtURL:testStoreURL]; +} + +- (void) customErrorHandler:(id)error; +{ +} + +- (void) testCanSetAUserSpecifiedErrorHandler +{ + [MagicalRecord setErrorHandlerTarget:self action:@selector(customErrorHandler:)]; + + XCTAssertEqualObjects([MagicalRecord errorHandlerTarget], self, @"Error handler should be self"); + XCTAssertEqualObjects(NSStringFromSelector([MagicalRecord errorHandlerAction]), NSStringFromSelector(@selector(customErrorHandler:)), @"Error handler action expected to be `customErrorHandler:`"); +} + +- (void) magicalRecordErrorHandlerTest:(NSError *)error +{ + XCTAssertNotNil(error, @"Expected a non-nil error object"); + XCTAssertEqualObjects([error domain], @"MRTests", @"Expected an error domain of 'MRTests'"); + XCTAssertEqual([error code], (NSInteger)1000, @"Expected an error code of '1000'"); + errorHandlerWasCalled_ = YES; +} + +- (void) testUserSpecifiedErrorHandlersAreTriggeredOnError +{ + errorHandlerWasCalled_ = NO; + [MagicalRecord setErrorHandlerTarget:self action:@selector(magicalRecordErrorHandlerTest:)]; + + NSError *testError = [NSError errorWithDomain:@"MRTests" code:1000 userInfo:nil]; + [MagicalRecord handleErrors:testError]; + + XCTAssertTrue(errorHandlerWasCalled_, @"Expected error handler to have been called"); +} + +@end diff --git a/Tests/Core/MagicalRecordTestBase.h b/Tests/Core/MagicalRecordTestBase.h new file mode 100644 index 000000000..d0371e78f --- /dev/null +++ b/Tests/Core/MagicalRecordTestBase.h @@ -0,0 +1,13 @@ +// +// Created by Tony Arnold on 21/12/2013. +// Copyright (c) 2013 Magical Panda Software LLC. All rights reserved. +// + +#import +#import +#import +#import + +@interface MagicalRecordTestBase : XCTestCase + +@end diff --git a/Tests/Core/MagicalRecordTestBase.m b/Tests/Core/MagicalRecordTestBase.m new file mode 100644 index 000000000..2c58f437d --- /dev/null +++ b/Tests/Core/MagicalRecordTestBase.m @@ -0,0 +1,32 @@ +// +// Created by Tony Arnold on 21/12/2013. +// Copyright (c) 2013 Magical Panda Software LLC. All rights reserved. +// + +#import "MagicalRecordTestBase.h" +#import "MagicalRecordLogging.h" + +@implementation MagicalRecordTestBase + +- (void)setUp +{ + [super setUp]; + + // Don't pollute the tests with logging + [MagicalRecord setLoggingLevel:MagicalRecordLoggingLevelError]; + + // Setup the default model from the current class' bundle + [MagicalRecord setDefaultModelFromClass:[self class]]; + + // Setup a default in-memory store + [MagicalRecord setupCoreDataStackWithInMemoryStore]; +} + +- (void)tearDown +{ + [MagicalRecord cleanUp]; + + [super tearDown]; +} + +@end diff --git a/Tests/Core/NSManagedObject+MagicalRecordTests.m b/Tests/Core/NSManagedObject+MagicalRecordTests.m new file mode 100644 index 000000000..8c762a33e --- /dev/null +++ b/Tests/Core/NSManagedObject+MagicalRecordTests.m @@ -0,0 +1,31 @@ +// +// Created by Tony Arnold on 11/04/2014. +// Copyright (c) 2014 Magical Panda Software LLC. All rights reserved. +// + +#import "MagicalRecordTestBase.h" +#import "NSManagedObject+MagicalRecord.h" + +#import "DifferentClassNameMapping.h" +#import "EntityWithoutEntityNameMethod.h" + +@interface NSManagedObjectMagicalRecord : MagicalRecordTestBase + +@end + +@implementation NSManagedObjectMagicalRecord + +- (void)testThatInternalEntityNameReturnsClassNameWhenEntityNameMethodIsNotImplemented +{ + expect([EntityWithoutEntityNameMethod MR_entityName]).toNot.beNil(); + expect([EntityWithoutEntityNameMethod MR_entityName]).to.equal(NSStringFromClass([EntityWithoutEntityNameMethod class])); +} + +- (void)testThatInternalEntityNameReturnsProvidedNameWhenEntityNameMethodIsImplemented +{ + expect([EntityWithoutEntityNameMethod MR_entityName]).toNot.beNil(); + expect([DifferentClassNameMapping MR_entityName]).toNot.equal(NSStringFromClass([DifferentClassNameMapping class])); + expect([DifferentClassNameMapping MR_entityName]).to.equal([DifferentClassNameMapping entityName]); +} + +@end diff --git a/Tests/Core/NSManagedObjectContext+ChainSaveTests.m b/Tests/Core/NSManagedObjectContext+ChainSaveTests.m new file mode 100644 index 000000000..3c5742d1d --- /dev/null +++ b/Tests/Core/NSManagedObjectContext+ChainSaveTests.m @@ -0,0 +1,56 @@ +// +// NSManagedObjectContext+ChainSaveTests.m +// MagicalRecord +// +// Created by Lee on 12/1/14. +// Copyright (c) 2014 Magical Panda Software LLC. All rights reserved. +// + +#import "MagicalRecordTestBase.h" +#import "NSManagedObjectContext+MagicalChainSave.h" +#import "SingleEntityWithNoRelationships.h" + +@interface NSManagedObjectContext_ChainSaveTests : MagicalRecordTestBase + +@end + +@implementation NSManagedObjectContext_ChainSaveTests + +- (void)testChainSave +{ + //Test if a new Object can save from child context to parent context + __block NSManagedObjectID *childObjectID; + + NSManagedObjectContext *defaultContext = [NSManagedObjectContext MR_defaultContext]; + + [defaultContext MR_saveWithBlock:^(NSManagedObjectContext *localContext) { + SingleEntityWithNoRelationships *insertedObject = [SingleEntityWithNoRelationships MR_createEntityInContext:localContext]; + + expect([insertedObject hasChanges]).to.beTruthy(); + + NSError *obtainIDsError; + BOOL obtainIDsResult = [localContext obtainPermanentIDsForObjects:@[ insertedObject ] error:&obtainIDsError]; + + expect(obtainIDsResult).to.beTruthy(); + expect(obtainIDsError).to.beNil(); + + childObjectID = [insertedObject objectID]; + + expect(childObjectID).toNot.beNil(); + expect([childObjectID isTemporaryID]).to.beFalsy(); + + } completion:^(BOOL success, NSError *error) { + + //test parent and root saving context + SingleEntityWithNoRelationships *parentObject = (SingleEntityWithNoRelationships *)[defaultContext objectWithID:childObjectID]; + + expect(parentObject).toNot.beNil(); + + SingleEntityWithNoRelationships *rootObject = (SingleEntityWithNoRelationships *)[[NSManagedObjectContext MR_rootSavingContext] objectWithID:childObjectID]; + + expect(rootObject).toNot.beNil(); + + }]; +} + +@end diff --git a/Tests/Core/NSManagedObjectContext+MagicalSavesTests.m b/Tests/Core/NSManagedObjectContext+MagicalSavesTests.m new file mode 100644 index 000000000..f830d5b92 --- /dev/null +++ b/Tests/Core/NSManagedObjectContext+MagicalSavesTests.m @@ -0,0 +1,265 @@ +// +// Created by Tony Arnold on 25/03/2014. +// Copyright (c) 2014 Magical Panda Software LLC. All rights reserved. +// + +#import "MagicalRecordTestBase.h" +#import "SingleEntityWithNoRelationships.h" + +@interface NSManagedObjectContextMagicalSavesTests : MagicalRecordTestBase + +@end + +@implementation NSManagedObjectContextMagicalSavesTests + +- (void)testSaveToSelfOnlyWhenSaveIsSynchronous +{ + NSManagedObjectContext *parentContext = [NSManagedObjectContext MR_defaultContext]; + NSManagedObjectContext *childContext = [NSManagedObjectContext MR_contextWithParent:parentContext]; + + XCTestExpectation *childContextSavedExpectation = [self expectationWithDescription:@"Child Context Did Save"]; + + __block NSManagedObjectID *insertedObjectID; + + [childContext performBlockAndWait:^{ + SingleEntityWithNoRelationships *insertedObject = [SingleEntityWithNoRelationships MR_createEntityInContext:childContext]; + + expect([insertedObject hasChanges]).to.beTruthy(); + + NSError *obtainIDsError; + BOOL obtainIDsResult = [childContext obtainPermanentIDsForObjects:@[insertedObject] error:&obtainIDsError]; + + expect(obtainIDsResult).to.beTruthy(); + expect(obtainIDsError).to.beNil(); + + insertedObjectID = [insertedObject objectID]; + + expect(insertedObjectID).toNot.beNil(); + expect([insertedObjectID isTemporaryID]).to.beFalsy(); + + [childContext MR_saveOnlySelfAndWait]; + + [childContextSavedExpectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:5.0f handler:nil]; + + XCTestExpectation *parentContextSavedExpectation = [self expectationWithDescription:@"Parent Context Did Save"]; + childContextSavedExpectation = [self expectationWithDescription:@"Child Context Did Save"]; + + [parentContext performBlockAndWait:^{ + NSManagedObject *parentContextFetchedObject = [parentContext objectRegisteredForID:insertedObjectID]; + + // Saving a child context moves the saved changes up to the parent, but does + // not save them, leaving the parent context with changes + expect(parentContextFetchedObject).toNot.beNil(); + expect([parentContextFetchedObject hasChanges]).to.beTruthy(); + + [childContext performBlockAndWait:^{ + NSManagedObject *childContextFetchedObject = [childContext objectRegisteredForID:insertedObjectID]; + + // The child context should not have changes after the save + expect(childContextFetchedObject).toNot.beNil(); + expect([childContextFetchedObject hasChanges]).to.beFalsy(); + + [childContextSavedExpectation fulfill]; + }]; + + [parentContextSavedExpectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:5.0f handler:nil]; +} + +- (void)testSaveToSelfOnlyWhenSaveIsAsynchronous +{ + NSManagedObjectContext *parentContext = [NSManagedObjectContext MR_defaultContext]; + NSManagedObjectContext *childContext = [NSManagedObjectContext MR_contextWithParent:parentContext]; + + XCTestExpectation *childContextExpectation = [self expectationWithDescription:@"Child Context Completed Work"]; + XCTestExpectation *childContextSaveExpectation = [self expectationWithDescription:@"Child Context Saved"]; + XCTestExpectation *parentContextExpectation = [self expectationWithDescription:@"Parent Context Completed Work"]; + + [childContext performBlock:^{ + SingleEntityWithNoRelationships *insertedObject = [SingleEntityWithNoRelationships MR_createEntityInContext:childContext]; + + expect([insertedObject hasChanges]).to.beTruthy(); + + NSError *obtainIDsError; + BOOL obtainIDsResult = [childContext obtainPermanentIDsForObjects:@[insertedObject] error:&obtainIDsError]; + + expect(obtainIDsResult).to.beTruthy(); + expect(obtainIDsError).to.beNil(); + + NSManagedObjectID *insertedObjectID = [insertedObject objectID]; + + expect(insertedObjectID).toNot.beNil(); + expect([insertedObjectID isTemporaryID]).to.beFalsy(); + + [childContext MR_saveOnlySelfWithCompletion:^(BOOL contextDidSave, NSError *error) { + expect(contextDidSave).to.beTruthy(); + expect(error).to.beNil(); + + [childContext performBlock:^{ + // The child context should not have changes after the save + expect([childContext hasChanges]).to.beFalsy(); + + [childContextSaveExpectation fulfill]; + }]; + + [parentContext performBlock:^{ + NSManagedObject *parentContextFetchedObject = [parentContext objectRegisteredForID:insertedObjectID]; + + // Saving a child context moves the saved changes up to the parent, but does + // not save them, leaving the parent context with changes + expect(parentContextFetchedObject).toNot.beNil(); + expect([parentContextFetchedObject hasChanges]).to.beTruthy(); + + [parentContextExpectation fulfill]; + }]; + }]; + + [childContextExpectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:5.0f handler:nil]; +} + +- (void)testSaveToSelfOnlyWhenSaveIsAsynchronousCallsMainThreadOnCompletion +{ + NSManagedObjectContext *defaultContext = [NSManagedObjectContext MR_defaultContext]; + NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createEntityInContext:defaultContext]; + + expect([inserted hasChanges]).to.beTruthy(); + + XCTestExpectation *contextSavedExpectation = [self expectationWithDescription:@"Context Did Save"]; + + [defaultContext MR_saveOnlySelfWithCompletion:^(BOOL contextDidSave, NSError *error) { + expect([NSThread isMainThread]).to.beTruthy(); + + [contextSavedExpectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:5.0f handler:nil]; +} + +- (void)testSaveToPersistentStoreWhenSaveIsSynchronous +{ + NSManagedObjectContext *parentContext = [NSManagedObjectContext MR_defaultContext]; + NSManagedObjectContext *childContext = [NSManagedObjectContext MR_contextWithParent:parentContext]; + + XCTestExpectation *childContextExpectation = [self expectationWithDescription:@"Child Context Completed Work"]; + XCTestExpectation *parentContextExpectation = [self expectationWithDescription:@"Parent Context Completed Work"]; + + [childContext performBlock:^{ + SingleEntityWithNoRelationships *insertedObject = [SingleEntityWithNoRelationships MR_createEntityInContext:childContext]; + + expect([insertedObject hasChanges]).to.beTruthy(); + + NSError *obtainIDsError; + BOOL obtainIDsResult = [childContext obtainPermanentIDsForObjects:@[insertedObject] error:&obtainIDsError]; + + expect(obtainIDsResult).to.beTruthy(); + expect(obtainIDsError).to.beNil(); + + NSManagedObjectID *insertedObjectID = [insertedObject objectID]; + + expect(insertedObjectID).toNot.beNil(); + expect([insertedObjectID isTemporaryID]).to.beFalsy(); + + [childContext MR_saveToPersistentStoreAndWait]; + + [parentContext performBlock:^{ + NSError *fetchExistingObjectFromParentContextError; + NSManagedObject *parentContextFetchedObject = [parentContext existingObjectWithID:insertedObjectID error:&fetchExistingObjectFromParentContextError]; + + // Saving to the persistent store should save to all parent contexts, + // leaving no changes + expect(fetchExistingObjectFromParentContextError).to.beNil(); + expect(parentContextFetchedObject).toNot.beNil(); + expect([parentContextFetchedObject hasChanges]).to.beFalsy(); + + [parentContextExpectation fulfill]; + }]; + + NSManagedObject *childContextFetchedObject = [childContext objectRegisteredForID:insertedObjectID]; + + // The child context should not have changes after the save + expect(childContextFetchedObject).toNot.beNil(); + expect([childContextFetchedObject hasChanges]).to.beFalsy(); + + [childContextExpectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:5.0f handler:nil]; +} + +- (void)testSaveToPersistentStoreWhenSaveIsAsynchronous +{ + NSManagedObjectContext *parentContext = [NSManagedObjectContext MR_defaultContext]; + NSManagedObjectContext *childContext = [NSManagedObjectContext MR_contextWithParent:parentContext]; + + XCTestExpectation *childContextExpectation = [self expectationWithDescription:@"Child Context Completed Work"]; + XCTestExpectation *childContextSavedExpectation = [self expectationWithDescription:@"Child Context Saved"]; + + [childContext performBlock:^{ + SingleEntityWithNoRelationships *insertedObject = [SingleEntityWithNoRelationships MR_createEntityInContext:childContext]; + + expect([insertedObject hasChanges]).to.beTruthy(); + + NSError *obtainIDsError; + BOOL obtainIDsResult = [childContext obtainPermanentIDsForObjects:@[insertedObject] error:&obtainIDsError]; + + expect(obtainIDsResult).to.beTruthy(); + expect(obtainIDsError).to.beNil(); + + NSManagedObjectID *insertedObjectID = [insertedObject objectID]; + + expect(insertedObjectID).toNot.beNil(); + expect([insertedObjectID isTemporaryID]).to.beFalsy(); + + [childContext MR_saveToPersistentStoreWithCompletion:^(BOOL contextDidSave, NSError *error) { + expect(contextDidSave).to.beTruthy(); + expect(error).to.beNil(); + + [parentContext performBlockAndWait:^{ + NSError *fetchExistingObjectFromParentContextError; + NSManagedObject *parentContextFetchedObject = [parentContext existingObjectWithID:insertedObjectID error:&fetchExistingObjectFromParentContextError]; + + // Saving to the persistent store should save to all parent contexts, + // leaving no changes + expect(fetchExistingObjectFromParentContextError).to.beNil(); + expect(parentContextFetchedObject).toNot.beNil(); + expect([parentContextFetchedObject hasChanges]).to.beFalsy(); + }]; + + [childContext performBlockAndWait:^{ + // The child context should not have changes after the save + expect([childContext hasChanges]).to.beFalsy(); + }]; + + [childContextSavedExpectation fulfill]; + }]; + + [childContextExpectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:5.0f handler:nil]; +} + +- (void)testThatSavedObjectsHavePermanentIDs +{ + NSManagedObjectContext *defaultContext = [NSManagedObjectContext MR_defaultContext]; + + [defaultContext performBlockAndWait:^{ + SingleEntityWithNoRelationships *entity = [SingleEntityWithNoRelationships MR_createEntityInContext:defaultContext]; + + expect([[entity objectID] isTemporaryID]).to.beTruthy(); + + [defaultContext MR_saveOnlySelfAndWait]; + + expect([[entity objectID] isTemporaryID]).to.beFalsy(); + }]; +} + +@end diff --git a/Project Files/Tests/Core/NSManagedObjectContextHelperTests.m b/Tests/Core/NSManagedObjectContextHelperTests.m similarity index 53% rename from Project Files/Tests/Core/NSManagedObjectContextHelperTests.m rename to Tests/Core/NSManagedObjectContextHelperTests.m index 0f53a643b..c080fe9b1 100644 --- a/Project Files/Tests/Core/NSManagedObjectContextHelperTests.m +++ b/Tests/Core/NSManagedObjectContextHelperTests.m @@ -6,42 +6,42 @@ // Copyright 2011 Magical Panda Software LLC. All rights reserved. // -#import "NSManagedObjectContextHelperTests.h" -#import "SingleEntityWithNoRelationships.h"; -@implementation NSManagedObjectContextHelperTests +#import "MagicalRecordTestBase.h" +#import "SingleEntityWithNoRelationships.h" -- (void) setUp -{ - [MagicalRecord setupCoreDataStackWithInMemoryStore]; -} +@interface NSManagedObjectContextHelperTests : MagicalRecordTestBase -- (void) tearDown -{ - [MagicalRecord cleanUp]; -} +@end + + +@implementation NSManagedObjectContextHelperTests - (void) testCanCreateContextForCurrentThead { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" NSManagedObjectContext *firstContext = [NSManagedObjectContext MR_contextForCurrentThread]; NSManagedObjectContext *secondContext = [NSManagedObjectContext MR_contextForCurrentThread]; - - assertThat(firstContext, is(equalTo(secondContext))); +#pragma clang diagnostic pop + + XCTAssertEqualObjects(firstContext, secondContext, @"Contexts should be equal"); } - (void) testCanNotifyDefaultContextOnSave { NSManagedObjectContext *testContext = [NSManagedObjectContext MR_contextWithParent:[NSManagedObjectContext MR_defaultContext]]; - assertThat([testContext parentContext], is(equalTo([NSManagedObjectContext MR_defaultContext]))); + XCTAssertEqualObjects([testContext parentContext], [NSManagedObjectContext MR_defaultContext], @"Parent context should be the default context"); } - (void) testThatSavedObjectsHavePermanentIDs { NSManagedObjectContext *context = [NSManagedObjectContext MR_defaultContext]; - SingleEntityWithNoRelationships *entity = [SingleEntityWithNoRelationships MR_createInContext:context]; - assertThatBool([[entity objectID] isTemporaryID], equalToBool(YES)); + SingleEntityWithNoRelationships *entity = [SingleEntityWithNoRelationships MR_createEntityInContext:context]; + + XCTAssertTrue([[entity objectID] isTemporaryID], @"Entity should have a temporary ID before saving"); [context MR_saveOnlySelfAndWait]; - assertThatBool([[entity objectID] isTemporaryID], equalToBool(NO)); + XCTAssertFalse([[entity objectID] isTemporaryID], @"Entity should not have a temporary ID after saving"); } diff --git a/Tests/Core/NSManagedObjectHelperTests.m b/Tests/Core/NSManagedObjectHelperTests.m new file mode 100644 index 000000000..d127b1484 --- /dev/null +++ b/Tests/Core/NSManagedObjectHelperTests.m @@ -0,0 +1,160 @@ +// +// NSManagedObjectHelperTests.m +// Magical Record +// +// Created by Saul Mora on 7/15/11. +// Copyright 2011 Magical Panda Software LLC. All rights reserved. +// + +#import "MagicalRecordTestBase.h" +#import "SingleRelatedEntity.h" + +@interface NSManagedObjectHelperTests : MagicalRecordTestBase + +@end + +@implementation NSManagedObjectHelperTests + +- (void)testCreateFetchRequestForEntity +{ + NSFetchRequest *testRequest = [SingleRelatedEntity MR_requestAll]; + + XCTAssertEqualObjects([[testRequest entity] name], NSStringFromClass([SingleRelatedEntity class]), @"Entity name should be the string representation of the entity's class"); +} + +- (void)testCanRequestFirstEntityWithPredicate +{ + NSPredicate *testPredicate = [NSPredicate predicateWithFormat:@"mappedStringAttribute = 'Test Predicate'"]; + NSFetchRequest *testRequest = [SingleRelatedEntity MR_requestFirstWithPredicate:testPredicate]; + + XCTAssertEqual([testRequest fetchLimit], (NSUInteger)1, @"Fetch limit should be 1, got: %tu", [testRequest fetchLimit]); + XCTAssertEqualObjects([testRequest predicate], testPredicate, @"Predicate objects should be equal"); +} + +- (void)testCreateRequestForFirstEntity +{ + NSFetchRequest *testRequest = [SingleRelatedEntity MR_requestFirstByAttribute:@"mappedStringAttribute" withValue:nil]; + + XCTAssertEqualObjects([[testRequest entity] name], NSStringFromClass([SingleRelatedEntity class]), @"Entity name should be the string representation of the entity's class"); + XCTAssertEqual([testRequest fetchLimit], (NSUInteger)1, @"Fetch limit should be 1, got: %tu", [testRequest fetchLimit]); + XCTAssertEqual([testRequest fetchOffset], (NSUInteger)0, @"Fetch offset should be 0, got: %tu", [testRequest fetchOffset]); + XCTAssertEqualObjects([testRequest predicate], [NSPredicate predicateWithFormat:@"mappedStringAttribute = nil"], @"Predicate objects should be equal"); +} + +- (void)testCanGetEntityDescriptionFromEntityClass +{ + NSEntityDescription *testDescription = [SingleRelatedEntity MR_entityDescription]; + + XCTAssertNotNil(testDescription, @"Entity description should not be nil"); +} + +- (void)testCanCreateEntityInstance +{ + id testEntity = [SingleRelatedEntity MR_createEntity]; + + XCTAssertNotNil(testEntity, @"Entity should not be nil"); +} + +- (void)testCanDeleteEntityInstance +{ + id testEntity = [SingleRelatedEntity MR_createEntity]; + + [[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait]; + + XCTAssertFalse([testEntity isDeleted], @"Entity should not return true for isDeleted before MR_deleteEntity is sent"); + + [testEntity MR_deleteEntity]; + + XCTAssertNotNil(testEntity, @"Entity should not be nil after calling MR_deleteEntity"); + XCTAssertTrue([testEntity isDeleted], @"Entity should return true for isDeleted before MR_deleteEntity is sent"); +} + +- (void)testCanSearchForNumberOfAllEntities +{ + NSInteger numberOfTestEntitiesToCreate = 20; + + NSManagedObjectContext *context = [NSManagedObjectContext MR_defaultContext]; + [self p_createSampleData:numberOfTestEntitiesToCreate inContext:context]; + + [context performBlockAndWait:^{ + NSNumber *entityCount = [SingleRelatedEntity MR_numberOfEntitiesWithContext:context]; + XCTAssertEqualObjects(entityCount, @(numberOfTestEntitiesToCreate), @"Expected numberOfEntities to be %zd, got %@", numberOfTestEntitiesToCreate, entityCount); + }]; +} + +- (void)testCanSearchForNumberOfEntitiesWithPredicate +{ + NSInteger numberOfTestEntitiesToCreate = 20; + + NSManagedObjectContext *context = [NSManagedObjectContext MR_defaultContext]; + [self p_createSampleData:numberOfTestEntitiesToCreate inContext:context]; + + [context performBlockAndWait:^{ + NSPredicate *searchFilter = [NSPredicate predicateWithFormat:@"mappedStringAttribute = '1'"]; + NSNumber *entityCount = [SingleRelatedEntity MR_numberOfEntitiesWithPredicate:searchFilter inContext:context]; + XCTAssertEqualObjects(entityCount, @5, @"Should return a count of 5, got %@", entityCount); + }]; +} + +- (void)testRetrieveInstanceOfManagedObjectFromAnotherContextHasAPermanentObjectID +{ + NSManagedObjectContext *defaultContext = [NSManagedObjectContext MR_defaultContext]; + NSManagedObject *insertedEntity = [SingleRelatedEntity MR_createEntityInContext:defaultContext]; + + XCTAssertTrue(insertedEntity.objectID.isTemporaryID, @"Object ID should be temporary until saved"); + + [defaultContext MR_saveToPersistentStoreAndWait]; + + XCTAssertFalse(insertedEntity.objectID.isTemporaryID, @"Object ID should be permanent after save"); + + [MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) { + NSManagedObject *localEntity = [insertedEntity MR_inContext:localContext]; + XCTAssertNotNil(localEntity, @"Object should not be nil"); + XCTAssertFalse([[localEntity objectID] isTemporaryID], @"Object ID should not be temporary after save"); + }]; +} + +- (void)testCanDeleteEntityInstanceInOtherContext +{ + NSManagedObjectContext *defaultContext = [NSManagedObjectContext MR_defaultContext]; + + [defaultContext performBlockAndWait:^{ + NSManagedObject *testEntity = [SingleRelatedEntity MR_createEntityInContext:defaultContext]; + + [defaultContext MR_saveToPersistentStoreAndWait]; + + XCTAssertFalse([testEntity isDeleted], @"Entity should not be deleted at this point"); + + [MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) { + NSManagedObject *otherEntity = [testEntity MR_inContext:localContext]; + + XCTAssertNotNil(otherEntity, @"Entity should not be nil"); + XCTAssertFalse([otherEntity isDeleted], @"Entity should not be deleted at this point"); + + // Delete the object in the other context + [testEntity MR_deleteEntityInContext:localContext]; + [localContext processPendingChanges]; + + // The nested context entity should now be deleted + XCTAssertTrue([localContext.deletedObjects containsObject:otherEntity], @"Entity should be listed as being deleted in the context"); + XCTAssertTrue([otherEntity isDeleted], @"Entity should now be deleted"); + }]; + }]; +} + +#pragma mark - Private Methods + +- (void)p_createSampleData:(NSInteger)numberOfTestEntitiesToCreate inContext:(NSManagedObjectContext *)context +{ + [context performBlockAndWait:^{ + for (int i = 0; i < numberOfTestEntitiesToCreate; i++) + { + SingleRelatedEntity *testEntity = [SingleRelatedEntity MR_createEntityInContext:context]; + testEntity.mappedStringAttribute = [NSString stringWithFormat:@"%d", i / 5]; + } + + [context MR_saveOnlySelfAndWait]; + }]; +} + +@end diff --git a/Tests/Core/NSPersistentStoreCoordinatorHelperTests.m b/Tests/Core/NSPersistentStoreCoordinatorHelperTests.m new file mode 100644 index 000000000..08ae00ee1 --- /dev/null +++ b/Tests/Core/NSPersistentStoreCoordinatorHelperTests.m @@ -0,0 +1,109 @@ +// +// NSPersistentStoreCoordinatorHelperTests.m +// Magical Record +// +// Created by Saul Mora on 7/15/11. +// Copyright 2011 Magical Panda Software LLC. All rights reserved. +// + +#import +#import +#import "MagicalRecordTestHelpers.h" + +@interface NSPersistentStoreCoordinatorHelperTests : XCTestCase + +@end + +@implementation NSPersistentStoreCoordinatorHelperTests + +- (void) setUp +{ + [super setUp]; + + NSURL *testStoreURL = [NSPersistentStore MR_urlForStoreName:@"TestStore.sqlite"]; + [MagicalRecordTestHelpers removeStoreFilesForStoreAtURL:testStoreURL]; +} + +- (void) tearDown +{ + [super tearDown]; + + NSURL *testStoreURL = [NSPersistentStore MR_urlForStoreName:@"TestStore.sqlite"]; + [MagicalRecordTestHelpers removeStoreFilesForStoreAtURL:testStoreURL]; +} + +- (void) testCreateCoodinatorWithSqlitePersistentStoreNamed +{ + NSPersistentStoreCoordinator *testCoordinator = [NSPersistentStoreCoordinator MR_coordinatorWithSqliteStoreNamed:@"TestStore.sqlite"]; + + NSUInteger persistentStoreCount = [[testCoordinator persistentStores] count]; + XCTAssertEqual(persistentStoreCount, (NSUInteger)1, @"Expected there to be 1 persistent store, sadly there are %tu", persistentStoreCount); + + NSPersistentStore *store = [[testCoordinator persistentStores] firstObject]; + NSString *storeType = [store type]; + XCTAssertEqualObjects(storeType, NSSQLiteStoreType, @"Store type should be NSSQLiteStoreType, instead is %@", storeType); +} + +- (void) testCreateCoodinatorWithSqlitePersistentStoreAtURL +{ + NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; + path = [path stringByAppendingPathComponent:@"TestStore.sqlite"]; + + NSPersistentStoreCoordinator *testCoordinator = [NSPersistentStoreCoordinator MR_coordinatorWithSqliteStoreAtURL:[NSURL fileURLWithPath:path]]; + + NSUInteger persistentStoreCount = [[testCoordinator persistentStores] count]; + XCTAssertEqual(persistentStoreCount, (NSUInteger)1, @"Expected there to be 1 persistent store, sadly there are %tu", persistentStoreCount); + + NSPersistentStore *store = [[testCoordinator persistentStores] firstObject]; + NSString *storeType = [store type]; + XCTAssertEqualObjects(storeType, NSSQLiteStoreType, @"Store type should be NSSQLiteStoreType, instead is %@", storeType); +} + +- (void) testCreateCoordinatorWithInMemoryStore +{ + NSPersistentStoreCoordinator *testCoordinator = [NSPersistentStoreCoordinator MR_coordinatorWithInMemoryStore]; + + NSUInteger persistentStoreCount = [[testCoordinator persistentStores] count]; + XCTAssertEqual(persistentStoreCount, (NSUInteger)1, @"Expected there to be 1 persistent store, sadly there are %tu", persistentStoreCount); + + NSPersistentStore *store = [[testCoordinator persistentStores] firstObject]; + NSString *storeType = [store type]; + XCTAssertEqualObjects(storeType, NSInMemoryStoreType, @"Store type should be NSInMemoryStoreType, instead is %@", storeType); +} + +- (void) testCanAddAnInMemoryStoreToAnExistingCoordinator +{ + NSPersistentStoreCoordinator *testCoordinator = [NSPersistentStoreCoordinator MR_coordinatorWithSqliteStoreNamed:@"TestStore.sqlite"]; + + NSUInteger persistentStoreCount = [[testCoordinator persistentStores] count]; + XCTAssertEqual(persistentStoreCount, (NSUInteger)1, @"Expected there to be 1 persistent store, sadly there are %tu", persistentStoreCount); + + NSPersistentStore *firstStore = [[testCoordinator persistentStores] firstObject]; + NSString *firstStoreType = [firstStore type]; + XCTAssertEqualObjects(firstStoreType, NSSQLiteStoreType, @"First store type should be NSSQLiteStoreType, instead is %@", firstStoreType); + + [testCoordinator MR_addInMemoryStore]; + + persistentStoreCount = [[testCoordinator persistentStores] count]; + XCTAssertEqual(persistentStoreCount, (NSUInteger)2, @"Expected there to be 2 persistent store, sadly there are %tu", persistentStoreCount); + + NSPersistentStore *secondStore = [[testCoordinator persistentStores] objectAtIndex:1]; + NSString *secondStoreType = [secondStore type]; + XCTAssertEqualObjects(secondStoreType, NSInMemoryStoreType, @"Second store type should be NSInMemoryStoreType, instead is %@", secondStoreType); +} + +#pragma mark - Private + +- (void)removeAllStoreFiles +{ + NSURL *testStoreURL = [NSPersistentStore MR_urlForStoreName:@"TestStore.sqlite"]; + NSString *rawURL = [testStoreURL absoluteString]; + NSURL *shmSidecar = [NSURL URLWithString:[rawURL stringByAppendingString:@"-shm"]]; + NSURL *walSidecar = [NSURL URLWithString:[rawURL stringByAppendingString:@"-wal"]]; + + [[NSFileManager defaultManager] removeItemAtURL:testStoreURL error:nil]; + [[NSFileManager defaultManager] removeItemAtURL:shmSidecar error:nil]; + [[NSFileManager defaultManager] removeItemAtURL:walSidecar error:nil]; +} + +@end diff --git a/Tests/Core/NSPersistentStoreHelperTests.m b/Tests/Core/NSPersistentStoreHelperTests.m new file mode 100644 index 000000000..4a373d901 --- /dev/null +++ b/Tests/Core/NSPersistentStoreHelperTests.m @@ -0,0 +1,84 @@ +// +// NSPersisentStoreHelperTests.m +// Magical Record +// +// Created by Saul Mora on 7/15/11. +// Copyright 2011 Magical Panda Software LLC. All rights reserved. +// + +#import +#import +#import "MagicalRecordTestHelpers.h" + +@interface NSPersisentStoreHelperTests : XCTestCase + +@end + +@implementation NSPersisentStoreHelperTests + +- (NSString *) applicationStorageDirectory +{ + return [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) firstObject]; +} + +#if TARGET_OS_IPHONE + +- (void) testDefaultStoreFolderForiOSDevicesIsTheApplicationSupportFolder +{ + NSString *applicationLibraryDirectory = [self applicationStorageDirectory]; + NSString *expectedStorePath = [applicationLibraryDirectory stringByAppendingPathComponent:kMagicalRecordDefaultStoreFileName]; + NSURL *expectedStoreUrl = [NSURL fileURLWithPath:expectedStorePath]; + NSURL *defaultStoreUrl = [NSPersistentStore MR_defaultLocalStoreUrl]; + + XCTAssertEqualObjects(defaultStoreUrl, expectedStoreUrl, @"Store URL should be %@, actually is %@", [expectedStoreUrl absoluteString], [defaultStoreUrl absoluteString]); +} + +- (void) testCanFindAURLInTheLibraryForiOSForASpecifiedStoreName +{ + NSString *storeFileName = @"NotTheDefaultStoreName.storefile"; + NSString *applicationLibraryDirectory = [self applicationStorageDirectory]; + NSString *expectedStorePath = [applicationLibraryDirectory stringByAppendingPathComponent:storeFileName]; + + BOOL fileWasCreated = [[NSFileManager defaultManager] createFileAtPath:expectedStorePath contents:[storeFileName dataUsingEncoding:NSUTF8StringEncoding] attributes:nil]; + XCTAssertTrue(fileWasCreated, @"Expected file to have been created"); + + NSURL *expectedFoundStoreUrl = [NSURL fileURLWithPath:expectedStorePath]; + NSURL *foundStoreUrl = [NSPersistentStore MR_urlForStoreName:storeFileName]; + + XCTAssertEqualObjects(foundStoreUrl, expectedFoundStoreUrl, @"Found store URL should be %@, actually is %@", [expectedFoundStoreUrl absoluteString], [foundStoreUrl absoluteString]); + + [MagicalRecordTestHelpers removeStoreFilesForStoreAtURL:[NSURL fileURLWithPath:expectedStorePath]]; +} + +#else + +- (void) testDefaultStoreFolderForMacIsTheApplicationSupportDirectory +{ + NSString *applicationSupportDirectory = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) lastObject]; + NSString *expectedStorePath = [applicationSupportDirectory stringByAppendingPathComponent:kMagicalRecordDefaultStoreFileName]; + NSURL *expectedStoreUrl = [NSURL fileURLWithPath:expectedStorePath]; + NSURL *defaultStoreUrl = [NSPersistentStore MR_defaultLocalStoreUrl]; + + XCTAssertEqualObjects(defaultStoreUrl, expectedStoreUrl, @"Store URL should be %@, actually is %@", [expectedStoreUrl absoluteString], [defaultStoreUrl absoluteString]); +} + +- (void) testCanFindAURLInTheApplicationSupportLibraryForMacForASpecifiedStoreName +{ + NSString *storeFileName = @"NotTheDefaultStoreName.storefile"; + NSString *applicationSupportDirectory = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) lastObject]; + NSString *expectedStorePath = [applicationSupportDirectory stringByAppendingPathComponent:storeFileName]; + + BOOL fileWasCreated = [[NSFileManager defaultManager] createFileAtPath:expectedStorePath contents:[storeFileName dataUsingEncoding:NSUTF8StringEncoding] attributes:nil]; + XCTAssertTrue(fileWasCreated, @"Expected file to have been created"); + + NSURL *expectedStoreUrl = [NSURL fileURLWithPath:expectedStorePath]; + NSURL *foundStoreUrl = [NSPersistentStore MR_urlForStoreName:storeFileName]; + + XCTAssertEqualObjects(foundStoreUrl, expectedStoreUrl, @"Found store URL should be %@, actually is %@", [expectedStoreUrl absoluteString], [foundStoreUrl absoluteString]); + + [MagicalRecordTestHelpers removeStoreFilesForStoreAtURL:[NSURL fileURLWithPath:expectedStorePath]]; +} + +#endif + +@end diff --git a/Tests/DataImport/ImportMultipleEntitiesWithNoPrimaryKeyTests.m b/Tests/DataImport/ImportMultipleEntitiesWithNoPrimaryKeyTests.m new file mode 100644 index 000000000..2cfd93e41 --- /dev/null +++ b/Tests/DataImport/ImportMultipleEntitiesWithNoPrimaryKeyTests.m @@ -0,0 +1,40 @@ +// +// ImportMultipleEntitiesWithNoPrimaryKeyTests.m +// MagicalRecord +// +// Created by Sérgio Estêvão on 09/01/2014. +// Copyright (c) 2014 Magical Panda Software LLC. All rights reserved. +// + +#import "MagicalDataImportTestCase.h" +#import +#import "FixtureHelpers.h" +#import "SingleEntityWithNoRelationships.h" + +@interface ImportMultipleEntitiesWithNoPrimaryKeyTests : MagicalDataImportTestCase + +@property (nonatomic, retain) NSArray * arrayOfTestEntity; + +@end + +@implementation ImportMultipleEntitiesWithNoPrimaryKeyTests + +- (void)setUp +{ + [super setUp]; + + self.arrayOfTestEntity = [SingleEntityWithNoRelationships MR_importFromArray:self.testEntityData]; +} + +- (void)tearDown +{ + [super tearDown]; +} + +- (void)testImportOfMultipleEntities +{ + XCTAssertNotNil(self.arrayOfTestEntity, @"arrayOfTestEntity should not be nil"); + XCTAssertEqual(self.arrayOfTestEntity.count, (NSUInteger)4, @"arrayOfTestEntity should have 4 entities"); +} + +@end diff --git a/Project Files/Tests/DataImport/ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m b/Tests/DataImport/ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m similarity index 74% rename from Project Files/Tests/DataImport/ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m rename to Tests/DataImport/ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m index 0e314fbb2..4e5df3290 100644 --- a/Project Files/Tests/DataImport/ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m +++ b/Tests/DataImport/ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m @@ -15,18 +15,21 @@ @interface ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTes @implementation ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests -- (Class) testEntityClass +- (Class)testEntityClass { return [SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey class]; } -- (void) testImportData +- (void)testImportData { SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey *entity = [[self testEntityClass] MR_importFromObject:self.testEntityData]; + [[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait]; - - assertThat(entity, is(notNilValue())); - assertThat(entity.mappedEntities, hasCountOf(4)); + + XCTAssertNotNil(entity, @"Entity should not be nil"); + + NSUInteger mappedEntitiesCount = [entity.mappedEntities count]; + XCTAssertEqual(mappedEntitiesCount, (NSUInteger)4, @"Expected 4 mapped entities, received %zd", mappedEntitiesCount); } @end diff --git a/Project Files/Tests/DataImport/ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m b/Tests/DataImport/ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m similarity index 50% rename from Project Files/Tests/DataImport/ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m rename to Tests/DataImport/ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m index f1af2909f..39e317c48 100644 --- a/Project Files/Tests/DataImport/ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m +++ b/Tests/DataImport/ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m @@ -16,50 +16,43 @@ @interface ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests : MagicalDa @implementation ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests --(Class) testEntityClass +- (Class)testEntityClass { return [SingleEntityRelatedToMappedEntityUsingDefaults class]; } -- (void) setupTestData +- (void)setupTestData { NSManagedObjectContext *context = [NSManagedObjectContext MR_defaultContext]; - - MappedEntity *testMappedEntity = [MappedEntity createInContext:context]; - testMappedEntity.mappedEntityIDValue = 42; + + MappedEntity *testMappedEntity = [MappedEntity MR_createEntityInContext:context]; + + testMappedEntity.mappedEntityID = @42; testMappedEntity.sampleAttribute = @"This attribute created as part of the test case setup"; - - SingleEntityRelatedToMappedEntityUsingDefaults *entity = [SingleEntityRelatedToMappedEntityUsingDefaults createInContext:context]; - entity.singleEntityRelatedToMappedEntityUsingDefaultsIDValue = 24; - + + SingleEntityRelatedToMappedEntityUsingDefaults *entity = [SingleEntityRelatedToMappedEntityUsingDefaults MR_createEntityInContext:context]; + entity.singleEntityRelatedToMappedEntityUsingDefaultsID = @24; + [context MR_saveToPersistentStoreAndWait]; } -- (void) testImportMappedEntityViaToOneRelationship +- (void)testImportMappedEntityViaToOneRelationship { SingleEntityRelatedToMappedEntityUsingDefaults *entity = [[self testEntityClass] MR_importFromObject:self.testEntityData]; - + [[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait]; id testRelatedEntity = entity.mappedEntity; - - assertThat(testRelatedEntity, is(notNilValue())); - assertThat([testRelatedEntity sampleAttribute], containsString(@"sample json file")); - - assertThat([MappedEntity numberOfEntities], is(equalToInteger(1))); -} -//- (void) testUpdateMappedEntity -//{ -// SingleEntityRelatedToMappedEntityUsingDefaults *testEntity = -// [SingleEntityRelatedToMappedEntityUsingDefaults findFirstByAttribute:@"singleEntityRelatedToMappedEntityUsingDefaultsID" withValue:[NSNumber numberWithInt:24]]; -// -// [testEntity MR_updateValuesForKeysWithObject:self.testEntityData]; -// -// assertThat([MappedEntity numberOfEntities], is(equalToInteger(1))); -// -// assertThat(testEntity, is(notNilValue())); -// -//} + XCTAssertNotNil(testRelatedEntity, @"Entity should not be nil"); + + NSString *string = [testRelatedEntity sampleAttribute]; + NSRange stringRange = [string rangeOfString:@"sample json file"]; + + XCTAssert(stringRange.length > 0, @"Could not find 'sample json file' in '%@'", string); + + NSNumber *numberOfEntities = [MappedEntity MR_numberOfEntities]; + XCTAssertEqualObjects(numberOfEntities, @1, @"Expected 1 entity, got %@", numberOfEntities); +} @end diff --git a/Tests/DataImport/ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m b/Tests/DataImport/ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m new file mode 100644 index 000000000..4132babf8 --- /dev/null +++ b/Tests/DataImport/ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m @@ -0,0 +1,91 @@ +// +// ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m +// Magical Record +// +// Created by Saul Mora on 8/11/11. +// Copyright (c) 2011 Magical Panda Software LLC. All rights reserved. +// + +#import "MappedEntity.h" +#import "SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.h" +#import "MagicalDataImportTestCase.h" + +@interface ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests : MagicalDataImportTestCase + +@end + +@implementation ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests + +- (void)setupTestData +{ + NSManagedObjectContext *context = [NSManagedObjectContext MR_defaultContext]; + + MappedEntity *testMappedEntity = [MappedEntity MR_createEntityInContext:context]; + + testMappedEntity.testMappedEntityID = @42; + testMappedEntity.sampleAttribute = @"This attribute created as part of the test case setup"; + + [context MR_saveToPersistentStoreAndWait]; +} + +- (Class)testEntityClass +{ + return [SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey class]; +} + +- (void)testImportMappedEntityRelatedViaToOneRelationship +{ + SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey *entity = [[self testEntityClass] MR_importFromObject:self.testEntityData]; + + [[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait]; + + id testRelatedEntity = entity.mappedEntity; + + //verify mapping in relationship description userinfo + NSEntityDescription *mappedEntity = [entity entity]; + NSRelationshipDescription *testRelationship = [[mappedEntity propertiesByName] valueForKey:@"mappedEntity"]; + XCTAssertEqualObjects([[testRelationship userInfo] valueForKey:kMagicalRecordImportRelationshipMapKey], @"someRandomAttributeName", @"Expected 'someRandomAttributeName' got '%@'", [[testRelationship userInfo] valueForKey:kMagicalRecordImportRelationshipMapKey]); + + NSNumber *numberOfEntities = [SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey MR_numberOfEntities]; + XCTAssertEqualObjects(numberOfEntities, @1, @"Expected count of 1 entity, got %@", numberOfEntities); + + NSNumber *numberOfMappedEntities = [MappedEntity MR_numberOfEntities]; + XCTAssertEqualObjects(numberOfMappedEntities, @1, @"Expected count of 1 entity, got %@", numberOfMappedEntities); + + XCTAssertNotNil(testRelatedEntity, @"testRelatedEntity should not be nil"); + + NSRange stringRange = [[testRelatedEntity sampleAttribute] rangeOfString:@"sample json file"]; + + XCTAssertTrue(stringRange.length > 0, @"Did not find 'sample json file' in %@", [testRelatedEntity sampleAttribute]); +} + +- (void)testImportMappedEntityUsingPrimaryRelationshipKey +{ + SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey *entity = [[self testEntityClass] MR_importFromObject:self.testEntityData]; + + [[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait]; + + id testRelatedEntity = entity.mappedEntity; + + //verify mapping in relationship description userinfo + NSEntityDescription *mappedEntity = [entity entity]; + NSRelationshipDescription *testRelationship = [[mappedEntity propertiesByName] valueForKey:@"mappedEntity"]; + NSString *mapKey = [[testRelationship userInfo] valueForKey:kMagicalRecordImportRelationshipMapKey]; + XCTAssertEqualObjects(mapKey, @"someRandomAttributeName", @"Expected 'someRandomAttributeName' got '%@'", mapKey); + + NSNumber *entityCount = [SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey MR_numberOfEntities]; + XCTAssertEqualObjects(entityCount, @1, @"Expected count of 1 entity, got %@", entityCount); + + NSNumber *mappedEntityCount = [MappedEntity MR_numberOfEntities]; + XCTAssertEqualObjects(mappedEntityCount, @1, @"Expected count of 1 entity, got %@", mappedEntityCount); + + NSNumber *mappedEntityID = [testRelatedEntity testMappedEntityID]; + XCTAssertEqualObjects(mappedEntityID, @42, @"Expected testMappedEntityID to be '42', got '%@'", mappedEntityID); + + XCTAssertNotNil(testRelatedEntity, @"testRelatedEntity should not be nil"); + + NSRange stringRange = [[testRelatedEntity sampleAttribute] rangeOfString:@"sample json file"]; + XCTAssertTrue(stringRange.length > 0, @"Did not find 'sample json file' in %@", [testRelatedEntity sampleAttribute]); +} + +@end diff --git a/Project Files/Tests/DataImport/ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m b/Tests/DataImport/ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m similarity index 63% rename from Project Files/Tests/DataImport/ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m rename to Tests/DataImport/ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m index aee9afb02..5477ffd71 100644 --- a/Project Files/Tests/DataImport/ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m +++ b/Tests/DataImport/ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m @@ -6,7 +6,6 @@ // Copyright (c) 2011 Magical Panda Software LLC. All rights reserved. // - #import "MagicalDataImportTestCase.h" #import "MappedEntity.h" #import "SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.h" @@ -17,19 +16,22 @@ @interface ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTest @implementation ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests -- (Class) testEntityClass +- (Class)testEntityClass { return [SingleEntityRelatedToMappedEntityWithNestedMappedAttributes class]; } -- (void) testDataImport +- (void)testDataImport { SingleEntityRelatedToMappedEntityWithNestedMappedAttributes *entity = [[self testEntityClass] MR_importFromObject:self.testEntityData]; + [[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait]; - - assertThat(entity.mappedEntity, is(notNilValue())); - assertThat(entity.mappedEntity.mappedEntityID, is(equalToInteger(42))); - assertThat(entity.mappedEntity.nestedAttribute, containsString(@"nested value")); + + XCTAssertNotNil(entity.mappedEntity, @"mappedEntity should not be nil"); + XCTAssertEqualObjects(entity.mappedEntity.mappedEntityID, @42, @"Expected mappedEntityID to be 42, got %@", entity.mappedEntity.mappedEntityID); + + NSRange stringRange = [entity.mappedEntity.nestedAttribute rangeOfString:@"nested value"]; + XCTAssertTrue(stringRange.length > 0, @"nestedAttribute did not contain 'nested value': %@", entity.mappedEntity.nestedAttribute); } @end diff --git a/Project Files/Tests/DataImport/ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m b/Tests/DataImport/ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m similarity index 67% rename from Project Files/Tests/DataImport/ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m rename to Tests/DataImport/ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m index 15520cf30..1c9c1d4f0 100644 --- a/Project Files/Tests/DataImport/ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m +++ b/Tests/DataImport/ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m @@ -15,18 +15,21 @@ @interface ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests : M @implementation ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests -- (Class) testEntityClass +- (Class)testEntityClass { return [SingleEntityRelatedToMappedEntityWithSecondaryMappings class]; } -- (void) testImportMappedAttributeUsingSecondaryMappedKeyName +- (void)testImportMappedAttributeUsingSecondaryMappedKeyName { SingleEntityRelatedToMappedEntityWithSecondaryMappings *entity = [[self testEntityClass] MR_importFromObject:self.testEntityData]; + [[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait]; - - assertThat(entity, is(notNilValue())); - assertThat([entity secondaryMappedAttribute], containsString(@"sample json file")); + + XCTAssertNotNil(entity, @"Entity should not be nil"); + + NSRange stringRange = [[entity secondaryMappedAttribute] rangeOfString:@"sample json file"]; + XCTAssertTrue(stringRange.length > 0, @"Expected string not contained withing secondary mapped attribute. Got %@", [entity secondaryMappedAttribute]); } @end diff --git a/Tests/DataImport/ImportSingleEntityWithNoRelationshipsTests.m b/Tests/DataImport/ImportSingleEntityWithNoRelationshipsTests.m new file mode 100644 index 000000000..0abd301b8 --- /dev/null +++ b/Tests/DataImport/ImportSingleEntityWithNoRelationshipsTests.m @@ -0,0 +1,236 @@ +// +// DataImportTests.m +// Magical Record +// +// Created by Saul Mora on 7/15/11. +// Copyright 2011 Magical Panda Software LLC. All rights reserved. +// + +#import +#import +#import "FixtureHelpers.h" +#import "SingleEntityWithNoRelationships.h" + +@interface ImportSingleEntityWithNoRelationshipsTests : XCTestCase + +@property (nonatomic, strong) SingleEntityWithNoRelationships *testEntity; + +@end + +@implementation ImportSingleEntityWithNoRelationshipsTests + +@synthesize testEntity; + +- (void)setUp +{ + [super setUp]; + + [MagicalRecord setDefaultModelFromClass:[self class]]; + [MagicalRecord setupCoreDataStackWithInMemoryStore]; + + id singleEntity = [self dataFromJSONFixture]; + + NSManagedObjectContext *context = [NSManagedObjectContext MR_defaultContext]; + [context performBlockAndWait:^{ + self.testEntity = [SingleEntityWithNoRelationships MR_importFromObject:singleEntity inContext:context]; + }]; +} + +- (void)tearDown +{ + [super tearDown]; + + [MagicalRecord cleanUp]; +} + +- (void)testImportASingleEntity +{ + [testEntity.managedObjectContext performBlockAndWait:^{ + XCTAssertNotNil(testEntity, @"testEntity should not be nil"); + }]; +} + +- (void)testImportStringAttributeToEntity +{ + [testEntity.managedObjectContext performBlockAndWait:^{ + XCTAssertEqualObjects(testEntity.stringTestAttribute, @"This is a test value", @"stringTestAttribute did not contain expected value, instead found '%@'", testEntity.stringTestAttribute); + }]; +} + +- (void)testImportInt16AttributeToEntity +{ + [testEntity.managedObjectContext performBlockAndWait:^{ + XCTAssertEqualObjects(testEntity.int16TestAttribute, @256, @"int16TestAttribute did not contain expected value, instead found: %@", testEntity.int16TestAttribute); + }]; +} + +- (void)testImportInt32AttributeToEntity +{ + [testEntity.managedObjectContext performBlockAndWait:^{ + XCTAssertEqualObjects(testEntity.int32TestAttribute, @32, @"int32TestAttribute did not contain expected value, instead found: %@", testEntity.int32TestAttribute); + }]; +} + +- (void)testImportInt64AttributeToEntity +{ + [testEntity.managedObjectContext performBlockAndWait:^{ + XCTAssertEqualObjects(testEntity.int64TestAttribute, @42, @"int64TestAttribute did not contain expected value, instead found: %@", testEntity.int64TestAttribute); + }]; +} + +- (void)testImportDecimalAttributeToEntity +{ + [testEntity.managedObjectContext performBlockAndWait:^{ + XCTAssertEqualObjects(testEntity.decimalTestAttribute, @1.2, @"decimalTestAttribute did not contain expected value, instead found: %@", testEntity.decimalTestAttribute); + }]; +} + +- (void)testImportDoubleAttributeToEntity +{ + [testEntity.managedObjectContext performBlockAndWait:^{ + XCTAssertEqualObjects(testEntity.doubleTestAttribute, @124.3, @"doubleTestAttribute did not contain expected value, instead found: %@", testEntity.doubleTestAttribute); + }]; +} + +- (void)testImportFloatAttributeToEntity +{ + [testEntity.managedObjectContext performBlockAndWait:^{ + XCTAssertEqualObjects(testEntity.floatTestAttribute, @10000000000, @"floatTestAttribute did not contain expected value, instead found: %@", testEntity.floatTestAttribute); + }]; +} + +- (void)testImportBooleanAttributeToEntity +{ + [testEntity.managedObjectContext performBlockAndWait:^{ + XCTAssertFalse([testEntity.booleanTestAttribute boolValue], @"booleanTestAttribute did not contain expected value, instead found: %@", testEntity.booleanTestAttribute); + }]; +} + +- (void)testImportMappedStringAttributeToEntity +{ + [testEntity.managedObjectContext performBlockAndWait:^{ + XCTAssertEqualObjects(testEntity.mappedStringAttribute, @"Mapped value", @"mappedStringAttribute did not contain expected value, instead found: %@", testEntity.mappedStringAttribute); + }]; +} + +- (void)testImportStringAttributeWithNullValue +{ + [testEntity.managedObjectContext performBlockAndWait:^{ + XCTAssertNil(testEntity.nullTestAttribute, @"nullTestAttribute did not contain expected value, instead found: %@", testEntity.nullTestAttribute); + }]; +} + +- (void)testImportNumberAsStringAttributeToEntity +{ + [testEntity.managedObjectContext performBlockAndWait:^{ + XCTAssertEqualObjects(testEntity.numberAsStringTestAttribute, @"10248909829", @"numberAsStringTestAttribute did not contain expected value, instead found: %@", testEntity.numberAsStringTestAttribute); + }]; +} + +- (void)testImportBooleanAsStringAttributeToEntity +{ + [testEntity.managedObjectContext performBlockAndWait:^{ + XCTAssertTrue(testEntity.booleanAsStringTestAttribute, @"booleanFromStringTestAttribute did not contain expected value, instead found: %@", testEntity.booleanAsStringTestAttribute); + }]; +} + +- (void)testImportAttributeNotInJsonData +{ + [testEntity.managedObjectContext performBlockAndWait:^{ + NSRange rangeOfString = [testEntity.notInJsonAttribute rangeOfString:@"Core Data Model"]; + + XCTAssertNotEqual(@(rangeOfString.length), @0, @"notInJsonAttribute did not contain expected string, instead received: %@", testEntity.notInJsonAttribute); + }]; +} + +#if TARGET_OS_IPHONE + +#if defined(__IPHONE_5_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_5_0 + +- (void)testImportUIColorAttributeToEntity +{ + [testEntity.managedObjectContext performBlockAndWait:^{ + UIColor *actualColor = testEntity.colorTestAttribute; + + if ([actualColor respondsToSelector:@selector(getRed:green:blue:alpha:)]) + { + CGFloat red, blue, green, alpha; + [actualColor getRed:&red green:&green blue:&blue alpha:&alpha]; + + XCTAssertEqual(alpha, (CGFloat)1.0, @"Unexpected value returned: %f", alpha); + XCTAssertEqual(red, (CGFloat)(64.0f / 255.0f), @"Unexpected value returned: %f", red); + XCTAssertEqual(green, (CGFloat)(128.0f / 255.0f), @"Unexpected value returned: %f", green); + XCTAssertEqual(blue, (CGFloat)(225.0f / 255.0f), @"Unexpected value returned: %f", blue); + } + }]; +} +#endif + +- (NSDate *)dateFromString:(NSString *)date +{ + NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; + + formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss ZZZ"; + formatter.timeZone = [NSTimeZone timeZoneWithName:@"GMT"]; + formatter.locale = [NSLocale currentLocale]; + + NSDate *expectedDate = [formatter dateFromString:date]; + + return expectedDate; +} + +#else + +- (void)testImportNSColorAttributeToEntity +{ + [testEntity.managedObjectContext performBlockAndWait:^{ + NSColor *actualColor = testEntity.colorTestAttribute; + + XCTAssertEqual([actualColor alphaComponent], (CGFloat)(255.0 / 255.0), @"Unexpected value returned"); + XCTAssertEqual([actualColor redComponent], (CGFloat)(64.0f / 255.0f), @"Unexpected value returned"); + XCTAssertEqual([actualColor greenComponent], (CGFloat)(128.0f / 255.0f), @"Unexpected value returned"); + XCTAssertEqual([actualColor blueComponent], (CGFloat)(225.0f / 255.0f), @"Unexpected value returned"); + }]; +} + +- (NSDate *)dateFromString:(NSString *)date +{ + NSDate *expectedDate = [NSDate dateWithString:date]; + + return expectedDate; +} +#endif /* if TARGET_OS_IPHONE */ + +- (void)testImportDateAttributeToEntity +{ + NSDate *expectedDate = [self dateFromString:@"2011-07-23 22:30:40 +0000"]; + + [testEntity.managedObjectContext performBlockAndWait:^{ + XCTAssertEqualObjects(testEntity.dateTestAttribute, expectedDate, @"Unexpected value returned"); + }]; +} + +- (void)testImportDateAttributeWithCustomFormat +{ + NSDate *expectedDate = [self dateFromString:@"2011-08-05 01:56:04 +0000"]; + + [testEntity.managedObjectContext performBlockAndWait:^{ + XCTAssertEqualObjects(testEntity.dateWithCustomFormat, expectedDate, @"Unexpected value returned"); + }]; +} + +- (void)testImportEpochDate +{ + [testEntity.managedObjectContext performBlockAndWait:^{ + XCTAssertEqualObjects(testEntity.unixTimeTestAttribute, [NSDate dateWithTimeIntervalSince1970:1388349428], @"unixTimeTestAttribute did not contain the expected value, instead found: %@", testEntity.unixTimeTestAttribute); + }]; +} + +- (void)testImportEpochDate13 +{ + [testEntity.managedObjectContext performBlockAndWait:^{ + XCTAssertEqualObjects(testEntity.unixTime13TestAttribute, [NSDate dateWithTimeIntervalSince1970:1388349427.543], @"unixTimeTest13Attribute did not contain the expected value, instead found: %@", testEntity.unixTime13TestAttribute); + }]; +} + +@end diff --git a/Tests/DataImport/ImportSingleRelatedEntityTests.m b/Tests/DataImport/ImportSingleRelatedEntityTests.m new file mode 100644 index 000000000..f8c515068 --- /dev/null +++ b/Tests/DataImport/ImportSingleRelatedEntityTests.m @@ -0,0 +1,108 @@ +// +// ImportSingleEntityWithRelatedEntitiesTests.m +// Magical Record +// +// Created by Saul Mora on 7/23/11. +// Copyright 2011 Magical Panda Software LLC. All rights reserved. +// + +#import "MagicalDataImportTestCase.h" +#import "SingleRelatedEntity.h" +#import "AbstractRelatedEntity.h" +#import "ConcreteRelatedEntity.h" +#import "MappedEntity.h" + +@interface ImportSingleRelatedEntityTests : MagicalDataImportTestCase + +@property (nonatomic, retain) SingleRelatedEntity *singleTestEntity; + +@end + +@implementation ImportSingleRelatedEntityTests + +@synthesize singleTestEntity = _singleTestEntity; + +- (void)setupTestData +{ + NSManagedObjectContext *context = [NSManagedObjectContext MR_defaultContext]; + + MappedEntity *testMappedEntity = [MappedEntity MR_createEntityInContext:context]; + + testMappedEntity.testMappedEntityID = @42; + testMappedEntity.sampleAttribute = @"This attribute created as part of the test case setup"; + + [context MR_saveToPersistentStoreAndWait]; +} + +- (void)setUp +{ + [super setUp]; + + self.singleTestEntity = [SingleRelatedEntity MR_importFromObject:self.testEntityData]; + [[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait]; +} + +- (void)testImportAnEntityRelatedToAbstractEntityViaToOneRelationshop +{ + XCTAssertNotNil(self.singleTestEntity, @"singleTestEntity should not be nil"); + + id testRelatedEntity = self.singleTestEntity.testAbstractToOneRelationship; + + XCTAssertNotNil(testRelatedEntity, @"testRelatedEntity should not be nil"); + + NSRange stringRange = [[testRelatedEntity sampleBaseAttribute] rangeOfString:@"BASE"]; + XCTAssertTrue(stringRange.length > 0, @"Expected to find 'BASE' in string '%@' but did not", [testRelatedEntity sampleBaseAttribute]); + + XCTAssertFalse([testRelatedEntity respondsToSelector:@selector(sampleConcreteAttribute)], @"testRelatedEntity should respond to selector sampleConcreteAttribute"); +} + +- (void)testImportAnEntityRelatedToAbstractEntityViaToManyRelationship +{ + XCTAssertNotNil(self.singleTestEntity, @"singleTestEntity should not be nil"); + + NSUInteger relationshipCount = [self.singleTestEntity.testAbstractToManyRelationship count]; + XCTAssertEqual(relationshipCount, (NSUInteger)2, @"Expected relationship count to be 2, received %zd", relationshipCount); + + id testRelatedEntity = [self.singleTestEntity.testAbstractToManyRelationship anyObject]; + + XCTAssertNotNil(testRelatedEntity, @"testRelatedEntity should not be nil"); + + NSRange stringRange = [[testRelatedEntity sampleBaseAttribute] rangeOfString:@"BASE"]; + XCTAssertTrue(stringRange.length > 0, @"Expected to find 'BASE' in string '%@' but did not", [testRelatedEntity sampleBaseAttribute]); + + XCTAssertFalse([testRelatedEntity respondsToSelector:@selector(sampleConcreteAttribute)], @"testRelatedEntity should respond to selector sampleConcreteAttribute"); +} + +#pragma mark - Subentity tests + +- (void)testImportAnEntityRelatedToAConcreteSubEntityViaToOneRelationship +{ + id testRelatedEntity = self.singleTestEntity.testConcreteToOneRelationship; + + XCTAssertNotNil(testRelatedEntity, @"testRelatedEntity should not be nil"); + + NSRange stringRange = [[testRelatedEntity sampleBaseAttribute] rangeOfString:@"BASE"]; + XCTAssertTrue(stringRange.length > 0, @"Expected to find 'BASE' in string '%@' but did not", [testRelatedEntity sampleBaseAttribute]); + + stringRange = [[testRelatedEntity sampleConcreteAttribute] rangeOfString:@"DESCENDANT"]; + XCTAssertTrue(stringRange.length > 0, @"Expected to find 'DESCENDANT' in string '%@' but did not", [testRelatedEntity sampleConcreteAttribute]); +} + +- (void)testImportAnEntityRelatedToASubEntityViaToManyRelationship +{ + NSUInteger relationshipCount = [self.singleTestEntity.testConcreteToManyRelationship count]; + XCTAssertEqual(relationshipCount, (NSUInteger)3, @"Expected relationship count to be 3, received %zd", relationshipCount); + + id testRelatedEntity = [self.singleTestEntity.testConcreteToManyRelationship anyObject]; + XCTAssertNotNil(testRelatedEntity, @"testRelatedEntity should not be nil"); + + NSRange stringRange = [[testRelatedEntity sampleBaseAttribute] rangeOfString:@"BASE"]; + XCTAssertTrue(stringRange.length > 0, @"Expected to find 'BASE' in string '%@' but did not", [testRelatedEntity sampleBaseAttribute]); + + stringRange = [[testRelatedEntity sampleConcreteAttribute] rangeOfString:@"DESCENDANT"]; + XCTAssertTrue(stringRange.length > 0, @"Expected to find 'DESCENDANT' in string '%@' but did not", [testRelatedEntity sampleConcreteAttribute]); +} + +// TODO: Test ordered to many relationships + +@end diff --git a/Tests/DataImport/MagicalDataImportTestCase.h b/Tests/DataImport/MagicalDataImportTestCase.h new file mode 100644 index 000000000..0f9851aab --- /dev/null +++ b/Tests/DataImport/MagicalDataImportTestCase.h @@ -0,0 +1,19 @@ +// +// MagicalDataImportTestCase.h +// Magical Record +// +// Created by Saul Mora on 8/16/11. +// Copyright (c) 2011 Magical Panda Software LLC. All rights reserved. +// + +#import "MagicalRecordTestBase.h" + +@interface MagicalDataImportTestCase : MagicalRecordTestBase + +@property (nonatomic, strong) id testEntityData; +@property (nonatomic, strong) id testEntity; + +- (Class) testEntityClass; +- (void) setupTestData; + +@end diff --git a/Tests/DataImport/MagicalDataImportTestCase.m b/Tests/DataImport/MagicalDataImportTestCase.m new file mode 100644 index 000000000..852445fc5 --- /dev/null +++ b/Tests/DataImport/MagicalDataImportTestCase.m @@ -0,0 +1,33 @@ +// +// MagicalDataImportTestCase.m +// Magical Record +// +// Created by Saul Mora on 8/16/11. +// Copyright (c) 2011 Magical Panda Software LLC. All rights reserved. +// + +#import "MagicalDataImportTestCase.h" +#import "FixtureHelpers.h" + +@implementation MagicalDataImportTestCase + +- (void)setUp +{ + [super setUp]; + + [self setupTestData]; + + self.testEntityData = [self dataFromJSONFixture]; +} + +- (Class)testEntityClass; +{ + return [NSManagedObject class]; +} + +- (void)setupTestData +{ + // Implement this in your subclasses +} + +@end diff --git a/Project Files/Tests/Fixtures/FixtureHelpers.h b/Tests/Fixtures/FixtureHelpers.h similarity index 85% rename from Project Files/Tests/Fixtures/FixtureHelpers.h rename to Tests/Fixtures/FixtureHelpers.h index 98f9a03b1..365240cf9 100644 --- a/Project Files/Tests/Fixtures/FixtureHelpers.h +++ b/Tests/Fixtures/FixtureHelpers.h @@ -6,6 +6,8 @@ // Copyright 2011 Magical Panda Software LLC. All rights reserved. // +#import + @interface FixtureHelpers : NSObject + (id) dataFromPListFixtureNamed:(NSString *)fixtureName; @@ -13,8 +15,7 @@ @end - -@interface GHTestCase (FixtureHelpers) +@interface XCTest (FixtureHelpers) - (id) dataFromJSONFixture; diff --git a/Project Files/Tests/Fixtures/FixtureHelpers.m b/Tests/Fixtures/FixtureHelpers.m similarity index 56% rename from Project Files/Tests/Fixtures/FixtureHelpers.m rename to Tests/Fixtures/FixtureHelpers.m index ed1cda3b7..644275e2d 100644 --- a/Project Files/Tests/Fixtures/FixtureHelpers.m +++ b/Tests/Fixtures/FixtureHelpers.m @@ -7,13 +7,13 @@ // #import "FixtureHelpers.h" -#import "JSONKit.h" @implementation FixtureHelpers + (id) dataFromPListFixtureNamed:(NSString *)fixtureName { - NSString *resource = [[NSBundle mainBundle] pathForResource:fixtureName ofType:@"plist"]; + NSBundle *testBundle = [NSBundle bundleForClass:[self class]]; + NSString *resource = [testBundle pathForResource:fixtureName ofType:@"plist"]; NSData *plistData = [NSData dataWithContentsOfFile:resource]; return [NSPropertyListSerialization propertyListWithData:plistData options:NSPropertyListImmutable format:nil error:nil]; @@ -21,30 +21,23 @@ + (id) dataFromPListFixtureNamed:(NSString *)fixtureName + (id) dataFromJSONFixtureNamed:(NSString *)fixtureName { - NSString *resource = [[NSBundle mainBundle] pathForResource:fixtureName ofType:@"json"]; - - if (NSClassFromString(@"NSJSONSerialization")) - { - NSInputStream *inputStream = [NSInputStream inputStreamWithFileAtPath:resource]; - [inputStream open]; - - return [NSJSONSerialization JSONObjectWithStream:inputStream options:0 error:nil]; - } - else - { - NSData *jsonData = [NSData dataWithContentsOfFile:resource]; - return [jsonData objectFromJSONData]; - } + NSBundle *testBundle = [NSBundle bundleForClass:[self class]]; + NSString *resource = [testBundle pathForResource:fixtureName ofType:@"json"]; + NSInputStream *inputStream = [NSInputStream inputStreamWithFileAtPath:resource]; + [inputStream open]; + + return [NSJSONSerialization JSONObjectWithStream:inputStream options:0 error:nil]; } @end -@implementation GHTestCase (FixtureHelpers) +@implementation XCTest (FixtureHelpers) - (id) dataFromJSONFixture; { NSString *className = NSStringFromClass([self class]); className = [className stringByReplacingOccurrencesOfString:@"Import" withString:@""]; + className = [className stringByReplacingOccurrencesOfString:@"Spec" withString:@""]; className = [className stringByReplacingOccurrencesOfString:@"Tests" withString:@""]; return [FixtureHelpers dataFromJSONFixtureNamed:className]; } diff --git a/Project Files/Tests/Fixtures/ImportSingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeysTests.m b/Tests/Fixtures/ImportSingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeysTests.m similarity index 100% rename from Project Files/Tests/Fixtures/ImportSingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeysTests.m rename to Tests/Fixtures/ImportSingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeysTests.m diff --git a/Tests/Fixtures/MultipleEntitiesWithNoPrimaryKey.json b/Tests/Fixtures/MultipleEntitiesWithNoPrimaryKey.json new file mode 100644 index 000000000..3350ca08a --- /dev/null +++ b/Tests/Fixtures/MultipleEntitiesWithNoPrimaryKey.json @@ -0,0 +1,14 @@ +[ + { + "stringTestAttribute": "This is a test value", + }, + { + "stringTestAttribute": "This is a test value", + }, + { + "stringTestAttribute": "This is a test value", + }, + { + "stringTestAttribute": "This is a test value", + } +] \ No newline at end of file diff --git a/Project Files/Tests/Fixtures/SampleJSONDataForImport.json b/Tests/Fixtures/SampleJSONDataForImport.json similarity index 100% rename from Project Files/Tests/Fixtures/SampleJSONDataForImport.json rename to Tests/Fixtures/SampleJSONDataForImport.json diff --git a/Project Files/Tests/Fixtures/SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json b/Tests/Fixtures/SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json similarity index 100% rename from Project Files/Tests/Fixtures/SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json rename to Tests/Fixtures/SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json diff --git a/Project Files/Tests/Fixtures/SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json b/Tests/Fixtures/SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json similarity index 100% rename from Project Files/Tests/Fixtures/SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json rename to Tests/Fixtures/SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json diff --git a/Project Files/Tests/Fixtures/SingleEntityRelatedToMappedEntityUsingDefaults.json b/Tests/Fixtures/SingleEntityRelatedToMappedEntityUsingDefaults.json similarity index 100% rename from Project Files/Tests/Fixtures/SingleEntityRelatedToMappedEntityUsingDefaults.json rename to Tests/Fixtures/SingleEntityRelatedToMappedEntityUsingDefaults.json diff --git a/Project Files/Tests/Fixtures/SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json b/Tests/Fixtures/SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json similarity index 100% rename from Project Files/Tests/Fixtures/SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json rename to Tests/Fixtures/SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json diff --git a/Project Files/Tests/Fixtures/SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json b/Tests/Fixtures/SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json similarity index 100% rename from Project Files/Tests/Fixtures/SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json rename to Tests/Fixtures/SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json diff --git a/Project Files/Tests/Fixtures/SingleEntityRelatedToMappedEntityWithSecondaryMappings.json b/Tests/Fixtures/SingleEntityRelatedToMappedEntityWithSecondaryMappings.json similarity index 100% rename from Project Files/Tests/Fixtures/SingleEntityRelatedToMappedEntityWithSecondaryMappings.json rename to Tests/Fixtures/SingleEntityRelatedToMappedEntityWithSecondaryMappings.json diff --git a/Project Files/Tests/Fixtures/SingleEntityWithNoRelationships.json b/Tests/Fixtures/SingleEntityWithNoRelationships.json similarity index 75% rename from Project Files/Tests/Fixtures/SingleEntityWithNoRelationships.json rename to Tests/Fixtures/SingleEntityWithNoRelationships.json index d41e5b282..861f89b2a 100644 --- a/Project Files/Tests/Fixtures/SingleEntityWithNoRelationships.json +++ b/Tests/Fixtures/SingleEntityWithNoRelationships.json @@ -10,7 +10,7 @@ "dateTestAttribute": "2011-07-23T22:30:40Z", "colorTestAttribute": "rgba(64,128,225,1)", "mappedAttributeWithStringValue": "Mapped value", - "dateWithCustomFormat": "8/5/2011 1-56-04 AM", + "dateWithCustomFormat": "8/5/2011 1-56-04", "nullTestAttribute": null, "int64AsStringTestAttribute": "42", "int32AsStringTestAttribute": "32", @@ -18,5 +18,8 @@ "decimalAsStringTestAttribute": "1.2", "doubleAsStringTestAttribute": "124.3", "floatAsStringTestAttribute": "10000000000", - + "numberAsStringTestAttribute" : 10248909829, + "booleanAsStringTestAttribute": "true", + "unixTimeTestAttribute" : 1388349428, + "unixTime13TestAttribute" : 1388349427543 } \ No newline at end of file diff --git a/Project Files/Tests/Fixtures/SingleEntityWithNoRelationships.plist b/Tests/Fixtures/SingleEntityWithNoRelationships.plist similarity index 87% rename from Project Files/Tests/Fixtures/SingleEntityWithNoRelationships.plist rename to Tests/Fixtures/SingleEntityWithNoRelationships.plist index 932a050a3..6f6aba999 100644 --- a/Project Files/Tests/Fixtures/SingleEntityWithNoRelationships.plist +++ b/Tests/Fixtures/SingleEntityWithNoRelationships.plist @@ -2,6 +2,8 @@ + numberAsStringTestAttribute + 10248909829 int64TestAttribute 42 stringTestAttribute @@ -28,5 +30,7 @@ 8/5/2011 1-56-04 AM nullTestAttribte + booleanAsStringTestAttribute + true diff --git a/Project Files/Tests/Fixtures/SingleRelatedEntity.json b/Tests/Fixtures/SingleRelatedEntity.json similarity index 66% rename from Project Files/Tests/Fixtures/SingleRelatedEntity.json rename to Tests/Fixtures/SingleRelatedEntity.json index 4cd19687c..531f04e6c 100644 --- a/Project Files/Tests/Fixtures/SingleRelatedEntity.json +++ b/Tests/Fixtures/SingleRelatedEntity.json @@ -2,43 +2,43 @@ "testAbstractToOneRelationship": { "sampleBaseAttribute": "This should be imported as: BASE ATTRIBUTE TEST", - "sampleConcreteAttribute": "This should be imported as: DECENDANT ATTRIBUTE TEST" + "sampleConcreteAttribute": "This should be imported as: DESCENDANT ATTRIBUTE TEST" } , "testAbstractToManyRelationship": [ { "sampleBaseAttribute": "Import as BASE ATTRIBUTE TEST 1", - "sampleConcreteAttribute": "Import as DECENDANT ATTRIBUTE TEST 1" + "sampleConcreteAttribute": "Import as DESCENDANT ATTRIBUTE TEST 1" } , { "sampleBaseAttribute": "Import as BASE ATTRIBUTE TEST 2", - "sampleConcreteAttribute": "Import as DECENDANT ATTRIBUTE TEST 2" + "sampleConcreteAttribute": "Import as DESCENDANT ATTRIBUTE TEST 2" } ] , "testConcreteToOneRelationship": { "sampleBaseAttribute": "Import as BASE ATTRIBUTE TEST", - "sampleConcreteAttribute": "Import as DECENDANT ATTRIBUTE TEST" + "sampleConcreteAttribute": "Import as DESCENDANT ATTRIBUTE TEST" } , "testConcreteToManyRelationship": [ { "sampleBaseAttribute": "Import as BASE ATTRIBUTE TEST 1", - "sampleConcreteAttribute": "Import as DECENDANT ATTRIBUTE TEST 1" + "sampleConcreteAttribute": "Import as DESCENDANT ATTRIBUTE TEST 1" } , { "sampleBaseAttribute": "Import as BASE ATTRIBUTE TEST 2", - "sampleConcreteAttribute": "Import as DECENDANT ATTRIBUTE TEST 2" + "sampleConcreteAttribute": "Import as DESCENDANT ATTRIBUTE TEST 2" } , { "sampleBaseAttribute": "Import as BASE ATTRIBUTE TEST 3", - "sampleConcreteAttribute": "Import as DECENDANT ATTRIBUTE TEST 3" + "sampleConcreteAttribute": "Import as DESCENDANT ATTRIBUTE TEST 3" } ] } \ No newline at end of file diff --git a/Project Files/Tests/Fixtures/Mac/TestModel.xcdatamodeld/TestModel.xcdatamodel/contents b/Tests/Fixtures/TestModel.xcdatamodeld/TestModel.xcdatamodel/contents similarity index 51% rename from Project Files/Tests/Fixtures/Mac/TestModel.xcdatamodeld/TestModel.xcdatamodel/contents rename to Tests/Fixtures/TestModel.xcdatamodeld/TestModel.xcdatamodel/contents index 96b8e08d7..d2b14ac47 100644 --- a/Project Files/Tests/Fixtures/Mac/TestModel.xcdatamodeld/TestModel.xcdatamodel/contents +++ b/Tests/Fixtures/TestModel.xcdatamodeld/TestModel.xcdatamodel/contents @@ -1,33 +1,22 @@ - - - - - - - - - - - - + + + - - + + - - - - - + + + + + - - - - + + @@ -36,11 +25,9 @@ - - - - - + + + @@ -49,125 +36,109 @@ - - - - - - - - + + + - - + + - - - - - - + + - - + + + - + - - - - - - - - - - + + + + + + + + - + - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - - - - - + + + + + + + + - + - - - - - - + + + + + + - - + + + + - - + + + + - - + + + + - - - - - - - - - - - - + + + + + + + + + + + + - + \ No newline at end of file diff --git a/Tests/Fixtures/TestModel/AbstractRelatedEntity.h b/Tests/Fixtures/TestModel/AbstractRelatedEntity.h new file mode 100644 index 000000000..4f7f6fec7 --- /dev/null +++ b/Tests/Fixtures/TestModel/AbstractRelatedEntity.h @@ -0,0 +1,5 @@ +#import "_AbstractRelatedEntity.h" + +@interface AbstractRelatedEntity : _AbstractRelatedEntity {} +// Custom logic goes here. +@end diff --git a/Tests/Fixtures/TestModel/AbstractRelatedEntity.m b/Tests/Fixtures/TestModel/AbstractRelatedEntity.m new file mode 100644 index 000000000..04ec3486f --- /dev/null +++ b/Tests/Fixtures/TestModel/AbstractRelatedEntity.m @@ -0,0 +1,13 @@ +#import "AbstractRelatedEntity.h" + +@interface AbstractRelatedEntity () + +// Private interface goes here. + +@end + +@implementation AbstractRelatedEntity + +// Custom logic goes here. + +@end diff --git a/Tests/Fixtures/TestModel/ConcreteRelatedEntity.h b/Tests/Fixtures/TestModel/ConcreteRelatedEntity.h new file mode 100644 index 000000000..777c32b0e --- /dev/null +++ b/Tests/Fixtures/TestModel/ConcreteRelatedEntity.h @@ -0,0 +1,5 @@ +#import "_ConcreteRelatedEntity.h" + +@interface ConcreteRelatedEntity : _ConcreteRelatedEntity {} +// Custom logic goes here. +@end diff --git a/Tests/Fixtures/TestModel/ConcreteRelatedEntity.m b/Tests/Fixtures/TestModel/ConcreteRelatedEntity.m new file mode 100644 index 000000000..7743abb2e --- /dev/null +++ b/Tests/Fixtures/TestModel/ConcreteRelatedEntity.m @@ -0,0 +1,13 @@ +#import "ConcreteRelatedEntity.h" + +@interface ConcreteRelatedEntity () + +// Private interface goes here. + +@end + +@implementation ConcreteRelatedEntity + +// Custom logic goes here. + +@end diff --git a/Tests/Fixtures/TestModel/DifferentClassNameMapping.h b/Tests/Fixtures/TestModel/DifferentClassNameMapping.h new file mode 100644 index 000000000..49f743bd6 --- /dev/null +++ b/Tests/Fixtures/TestModel/DifferentClassNameMapping.h @@ -0,0 +1,5 @@ +#import "_DifferentClassNameMapping.h" + +@interface DifferentClassNameMapping : _DifferentClassNameMapping {} +// Custom logic goes here. +@end diff --git a/Tests/Fixtures/TestModel/DifferentClassNameMapping.m b/Tests/Fixtures/TestModel/DifferentClassNameMapping.m new file mode 100644 index 000000000..eac2c0123 --- /dev/null +++ b/Tests/Fixtures/TestModel/DifferentClassNameMapping.m @@ -0,0 +1,13 @@ +#import "DifferentClassNameMapping.h" + +@interface DifferentClassNameMapping () + +// Private interface goes here. + +@end + +@implementation DifferentClassNameMapping + +// Custom logic goes here. + +@end diff --git a/Tests/Fixtures/TestModel/EntityWithoutEntityNameMethod.h b/Tests/Fixtures/TestModel/EntityWithoutEntityNameMethod.h new file mode 100644 index 000000000..dc8f78141 --- /dev/null +++ b/Tests/Fixtures/TestModel/EntityWithoutEntityNameMethod.h @@ -0,0 +1,10 @@ +// +// Created by Tony Arnold on 11/04/2014. +// Copyright (c) 2014 Magical Panda Software LLC. All rights reserved. +// + +#import + +@interface EntityWithoutEntityNameMethod : NSManagedObject + +@end diff --git a/Tests/Fixtures/TestModel/EntityWithoutEntityNameMethod.m b/Tests/Fixtures/TestModel/EntityWithoutEntityNameMethod.m new file mode 100644 index 000000000..6b16d2ec3 --- /dev/null +++ b/Tests/Fixtures/TestModel/EntityWithoutEntityNameMethod.m @@ -0,0 +1,10 @@ +// +// Created by Tony Arnold on 11/04/2014. +// Copyright (c) 2014 Magical Panda Software LLC. All rights reserved. +// + +#import "EntityWithoutEntityNameMethod.h" + +@implementation EntityWithoutEntityNameMethod + +@end diff --git a/Tests/Fixtures/TestModel/MappedEntity.h b/Tests/Fixtures/TestModel/MappedEntity.h new file mode 100644 index 000000000..1a10afa58 --- /dev/null +++ b/Tests/Fixtures/TestModel/MappedEntity.h @@ -0,0 +1,5 @@ +#import "_MappedEntity.h" + +@interface MappedEntity : _MappedEntity {} +// Custom logic goes here. +@end diff --git a/Tests/Fixtures/TestModel/MappedEntity.m b/Tests/Fixtures/TestModel/MappedEntity.m new file mode 100644 index 000000000..9580b9ae8 --- /dev/null +++ b/Tests/Fixtures/TestModel/MappedEntity.m @@ -0,0 +1,13 @@ +#import "MappedEntity.h" + +@interface MappedEntity () + +// Private interface goes here. + +@end + +@implementation MappedEntity + +// Custom logic goes here. + +@end diff --git a/Tests/Fixtures/TestModel/SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.h b/Tests/Fixtures/TestModel/SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.h new file mode 100644 index 000000000..184960d3e --- /dev/null +++ b/Tests/Fixtures/TestModel/SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.h @@ -0,0 +1,5 @@ +#import "_SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.h" + +@interface SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey : _SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey {} +// Custom logic goes here. +@end diff --git a/Tests/Fixtures/TestModel/SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m b/Tests/Fixtures/TestModel/SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m new file mode 100644 index 000000000..a9b2268db --- /dev/null +++ b/Tests/Fixtures/TestModel/SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m @@ -0,0 +1,13 @@ +#import "SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.h" + +@interface SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey () + +// Private interface goes here. + +@end + +@implementation SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey + +// Custom logic goes here. + +@end diff --git a/Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityUsingDefaults.h b/Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityUsingDefaults.h new file mode 100644 index 000000000..c4754c431 --- /dev/null +++ b/Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityUsingDefaults.h @@ -0,0 +1,5 @@ +#import "_SingleEntityRelatedToMappedEntityUsingDefaults.h" + +@interface SingleEntityRelatedToMappedEntityUsingDefaults : _SingleEntityRelatedToMappedEntityUsingDefaults {} +// Custom logic goes here. +@end diff --git a/Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityUsingDefaults.m b/Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityUsingDefaults.m new file mode 100644 index 000000000..12dc3dbfe --- /dev/null +++ b/Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityUsingDefaults.m @@ -0,0 +1,13 @@ +#import "SingleEntityRelatedToMappedEntityUsingDefaults.h" + +@interface SingleEntityRelatedToMappedEntityUsingDefaults () + +// Private interface goes here. + +@end + +@implementation SingleEntityRelatedToMappedEntityUsingDefaults + +// Custom logic goes here. + +@end diff --git a/Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.h b/Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.h new file mode 100644 index 000000000..402219cb2 --- /dev/null +++ b/Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.h @@ -0,0 +1,5 @@ +#import "_SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.h" + +@interface SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey : _SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey {} +// Custom logic goes here. +@end diff --git a/Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m b/Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m new file mode 100644 index 000000000..b64213c54 --- /dev/null +++ b/Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m @@ -0,0 +1,13 @@ +#import "SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.h" + +@interface SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey () + +// Private interface goes here. + +@end + +@implementation SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey + +// Custom logic goes here. + +@end diff --git a/Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.h b/Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.h new file mode 100644 index 000000000..2a10620d2 --- /dev/null +++ b/Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.h @@ -0,0 +1,5 @@ +#import "_SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.h" + +@interface SingleEntityRelatedToMappedEntityWithNestedMappedAttributes : _SingleEntityRelatedToMappedEntityWithNestedMappedAttributes {} +// Custom logic goes here. +@end diff --git a/Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m b/Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m new file mode 100644 index 000000000..bc3243065 --- /dev/null +++ b/Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m @@ -0,0 +1,13 @@ +#import "SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.h" + +@interface SingleEntityRelatedToMappedEntityWithNestedMappedAttributes () + +// Private interface goes here. + +@end + +@implementation SingleEntityRelatedToMappedEntityWithNestedMappedAttributes + +// Custom logic goes here. + +@end diff --git a/Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityWithSecondaryMappings.h b/Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityWithSecondaryMappings.h new file mode 100644 index 000000000..6f69cb8b2 --- /dev/null +++ b/Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityWithSecondaryMappings.h @@ -0,0 +1,5 @@ +#import "_SingleEntityRelatedToMappedEntityWithSecondaryMappings.h" + +@interface SingleEntityRelatedToMappedEntityWithSecondaryMappings : _SingleEntityRelatedToMappedEntityWithSecondaryMappings {} +// Custom logic goes here. +@end diff --git a/Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityWithSecondaryMappings.m b/Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityWithSecondaryMappings.m new file mode 100644 index 000000000..a09583294 --- /dev/null +++ b/Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityWithSecondaryMappings.m @@ -0,0 +1,13 @@ +#import "SingleEntityRelatedToMappedEntityWithSecondaryMappings.h" + +@interface SingleEntityRelatedToMappedEntityWithSecondaryMappings () + +// Private interface goes here. + +@end + +@implementation SingleEntityRelatedToMappedEntityWithSecondaryMappings + +// Custom logic goes here. + +@end diff --git a/Tests/Fixtures/TestModel/SingleEntityWithNoRelationships.h b/Tests/Fixtures/TestModel/SingleEntityWithNoRelationships.h new file mode 100644 index 000000000..ff028184a --- /dev/null +++ b/Tests/Fixtures/TestModel/SingleEntityWithNoRelationships.h @@ -0,0 +1,5 @@ +#import "_SingleEntityWithNoRelationships.h" + +@interface SingleEntityWithNoRelationships : _SingleEntityWithNoRelationships {} +// Custom logic goes here. +@end diff --git a/Tests/Fixtures/TestModel/SingleEntityWithNoRelationships.m b/Tests/Fixtures/TestModel/SingleEntityWithNoRelationships.m new file mode 100644 index 000000000..3ce2ef079 --- /dev/null +++ b/Tests/Fixtures/TestModel/SingleEntityWithNoRelationships.m @@ -0,0 +1,13 @@ +#import "SingleEntityWithNoRelationships.h" + +@interface SingleEntityWithNoRelationships () + +// Private interface goes here. + +@end + +@implementation SingleEntityWithNoRelationships + +// Custom logic goes here. + +@end diff --git a/Tests/Fixtures/TestModel/SingleRelatedEntity.h b/Tests/Fixtures/TestModel/SingleRelatedEntity.h new file mode 100644 index 000000000..27e7f176e --- /dev/null +++ b/Tests/Fixtures/TestModel/SingleRelatedEntity.h @@ -0,0 +1,5 @@ +#import "_SingleRelatedEntity.h" + +@interface SingleRelatedEntity : _SingleRelatedEntity {} +// Custom logic goes here. +@end diff --git a/Tests/Fixtures/TestModel/SingleRelatedEntity.m b/Tests/Fixtures/TestModel/SingleRelatedEntity.m new file mode 100644 index 000000000..0975f82f1 --- /dev/null +++ b/Tests/Fixtures/TestModel/SingleRelatedEntity.m @@ -0,0 +1,13 @@ +#import "SingleRelatedEntity.h" + +@interface SingleRelatedEntity () + +// Private interface goes here. + +@end + +@implementation SingleRelatedEntity + +// Custom logic goes here. + +@end diff --git a/Tests/Fixtures/TestModel/_AbstractRelatedEntity.h b/Tests/Fixtures/TestModel/_AbstractRelatedEntity.h new file mode 100644 index 000000000..6e02cb6c9 --- /dev/null +++ b/Tests/Fixtures/TestModel/_AbstractRelatedEntity.h @@ -0,0 +1,30 @@ +// DO NOT EDIT. This file is machine-generated and constantly overwritten. +// Make changes to AbstractRelatedEntity.h instead. + +#import + +extern const struct AbstractRelatedEntityAttributes { + __unsafe_unretained NSString *sampleBaseAttribute; +} AbstractRelatedEntityAttributes; + +@interface AbstractRelatedEntityID : NSManagedObjectID {} +@end + +@interface _AbstractRelatedEntity : NSManagedObject {} ++ (id)insertInManagedObjectContext:(NSManagedObjectContext*)moc_; ++ (NSString*)entityName; ++ (NSEntityDescription*)entityInManagedObjectContext:(NSManagedObjectContext*)moc_; +- (AbstractRelatedEntityID*)objectID; + +@property (nonatomic, strong) NSString* sampleBaseAttribute; + +//- (BOOL)validateSampleBaseAttribute:(id*)value_ error:(NSError**)error_; + +@end + +@interface _AbstractRelatedEntity (CoreDataGeneratedPrimitiveAccessors) + +- (NSString*)primitiveSampleBaseAttribute; +- (void)setPrimitiveSampleBaseAttribute:(NSString*)value; + +@end diff --git a/Tests/Fixtures/TestModel/_AbstractRelatedEntity.m b/Tests/Fixtures/TestModel/_AbstractRelatedEntity.m new file mode 100644 index 000000000..bcbb8620b --- /dev/null +++ b/Tests/Fixtures/TestModel/_AbstractRelatedEntity.m @@ -0,0 +1,36 @@ +// DO NOT EDIT. This file is machine-generated and constantly overwritten. +// Make changes to AbstractRelatedEntity.m instead. + +#import "_AbstractRelatedEntity.h" + +const struct AbstractRelatedEntityAttributes AbstractRelatedEntityAttributes = { + .sampleBaseAttribute = @"sampleBaseAttribute", +}; + +@implementation AbstractRelatedEntityID +@end + +@implementation _AbstractRelatedEntity + ++ (id)insertInManagedObjectContext:(NSManagedObjectContext*)moc_ { + NSParameterAssert(moc_); + return [NSEntityDescription insertNewObjectForEntityForName:@"AbstractRelatedEntity" inManagedObjectContext:moc_]; +} + ++ (NSString*)entityName { + return @"AbstractRelatedEntity"; +} + ++ (NSEntityDescription*)entityInManagedObjectContext:(NSManagedObjectContext*)moc_ { + NSParameterAssert(moc_); + return [NSEntityDescription entityForName:@"AbstractRelatedEntity" inManagedObjectContext:moc_]; +} + +- (AbstractRelatedEntityID*)objectID { + return (AbstractRelatedEntityID*)[super objectID]; +} + +@dynamic sampleBaseAttribute; + +@end + diff --git a/Tests/Fixtures/TestModel/_ConcreteRelatedEntity.h b/Tests/Fixtures/TestModel/_ConcreteRelatedEntity.h new file mode 100644 index 000000000..9b1f5f65a --- /dev/null +++ b/Tests/Fixtures/TestModel/_ConcreteRelatedEntity.h @@ -0,0 +1,31 @@ +// DO NOT EDIT. This file is machine-generated and constantly overwritten. +// Make changes to ConcreteRelatedEntity.h instead. + +#import +#import "AbstractRelatedEntity.h" + +extern const struct ConcreteRelatedEntityAttributes { + __unsafe_unretained NSString *sampleConcreteAttribute; +} ConcreteRelatedEntityAttributes; + +@interface ConcreteRelatedEntityID : AbstractRelatedEntityID {} +@end + +@interface _ConcreteRelatedEntity : AbstractRelatedEntity {} ++ (id)insertInManagedObjectContext:(NSManagedObjectContext*)moc_; ++ (NSString*)entityName; ++ (NSEntityDescription*)entityInManagedObjectContext:(NSManagedObjectContext*)moc_; +- (ConcreteRelatedEntityID*)objectID; + +@property (nonatomic, strong) NSString* sampleConcreteAttribute; + +//- (BOOL)validateSampleConcreteAttribute:(id*)value_ error:(NSError**)error_; + +@end + +@interface _ConcreteRelatedEntity (CoreDataGeneratedPrimitiveAccessors) + +- (NSString*)primitiveSampleConcreteAttribute; +- (void)setPrimitiveSampleConcreteAttribute:(NSString*)value; + +@end diff --git a/Tests/Fixtures/TestModel/_ConcreteRelatedEntity.m b/Tests/Fixtures/TestModel/_ConcreteRelatedEntity.m new file mode 100644 index 000000000..167a298f5 --- /dev/null +++ b/Tests/Fixtures/TestModel/_ConcreteRelatedEntity.m @@ -0,0 +1,36 @@ +// DO NOT EDIT. This file is machine-generated and constantly overwritten. +// Make changes to ConcreteRelatedEntity.m instead. + +#import "_ConcreteRelatedEntity.h" + +const struct ConcreteRelatedEntityAttributes ConcreteRelatedEntityAttributes = { + .sampleConcreteAttribute = @"sampleConcreteAttribute", +}; + +@implementation ConcreteRelatedEntityID +@end + +@implementation _ConcreteRelatedEntity + ++ (id)insertInManagedObjectContext:(NSManagedObjectContext*)moc_ { + NSParameterAssert(moc_); + return [NSEntityDescription insertNewObjectForEntityForName:@"ConcreteRelatedEntity" inManagedObjectContext:moc_]; +} + ++ (NSString*)entityName { + return @"ConcreteRelatedEntity"; +} + ++ (NSEntityDescription*)entityInManagedObjectContext:(NSManagedObjectContext*)moc_ { + NSParameterAssert(moc_); + return [NSEntityDescription entityForName:@"ConcreteRelatedEntity" inManagedObjectContext:moc_]; +} + +- (ConcreteRelatedEntityID*)objectID { + return (ConcreteRelatedEntityID*)[super objectID]; +} + +@dynamic sampleConcreteAttribute; + +@end + diff --git a/Tests/Fixtures/TestModel/_DifferentClassNameMapping.h b/Tests/Fixtures/TestModel/_DifferentClassNameMapping.h new file mode 100644 index 000000000..ca8ff57bf --- /dev/null +++ b/Tests/Fixtures/TestModel/_DifferentClassNameMapping.h @@ -0,0 +1,19 @@ +// DO NOT EDIT. This file is machine-generated and constantly overwritten. +// Make changes to DifferentClassNameMapping.h instead. + +#import + +@interface DifferentClassNameMappingID : NSManagedObjectID {} +@end + +@interface _DifferentClassNameMapping : NSManagedObject {} ++ (id)insertInManagedObjectContext:(NSManagedObjectContext*)moc_; ++ (NSString*)entityName; ++ (NSEntityDescription*)entityInManagedObjectContext:(NSManagedObjectContext*)moc_; +- (DifferentClassNameMappingID*)objectID; + +@end + +@interface _DifferentClassNameMapping (CoreDataGeneratedPrimitiveAccessors) + +@end diff --git a/Tests/Fixtures/TestModel/_DifferentClassNameMapping.m b/Tests/Fixtures/TestModel/_DifferentClassNameMapping.m new file mode 100644 index 000000000..97cb22852 --- /dev/null +++ b/Tests/Fixtures/TestModel/_DifferentClassNameMapping.m @@ -0,0 +1,30 @@ +// DO NOT EDIT. This file is machine-generated and constantly overwritten. +// Make changes to DifferentClassNameMapping.m instead. + +#import "_DifferentClassNameMapping.h" + +@implementation DifferentClassNameMappingID +@end + +@implementation _DifferentClassNameMapping + ++ (id)insertInManagedObjectContext:(NSManagedObjectContext*)moc_ { + NSParameterAssert(moc_); + return [NSEntityDescription insertNewObjectForEntityForName:@"EntityWithDifferentClassName" inManagedObjectContext:moc_]; +} + ++ (NSString*)entityName { + return @"EntityWithDifferentClassName"; +} + ++ (NSEntityDescription*)entityInManagedObjectContext:(NSManagedObjectContext*)moc_ { + NSParameterAssert(moc_); + return [NSEntityDescription entityForName:@"EntityWithDifferentClassName" inManagedObjectContext:moc_]; +} + +- (DifferentClassNameMappingID*)objectID { + return (DifferentClassNameMappingID*)[super objectID]; +} + +@end + diff --git a/Tests/Fixtures/TestModel/_MappedEntity.h b/Tests/Fixtures/TestModel/_MappedEntity.h new file mode 100644 index 000000000..dfb50c369 --- /dev/null +++ b/Tests/Fixtures/TestModel/_MappedEntity.h @@ -0,0 +1,58 @@ +// DO NOT EDIT. This file is machine-generated and constantly overwritten. +// Make changes to MappedEntity.h instead. + +#import + +extern const struct MappedEntityAttributes { + __unsafe_unretained NSString *mappedEntityID; + __unsafe_unretained NSString *nestedAttribute; + __unsafe_unretained NSString *sampleAttribute; + __unsafe_unretained NSString *testMappedEntityID; +} MappedEntityAttributes; + +extern const struct MappedEntityUserInfo { + __unsafe_unretained NSString *relatedByAttribute; +} MappedEntityUserInfo; + +@interface MappedEntityID : NSManagedObjectID {} +@end + +@interface _MappedEntity : NSManagedObject {} ++ (id)insertInManagedObjectContext:(NSManagedObjectContext*)moc_; ++ (NSString*)entityName; ++ (NSEntityDescription*)entityInManagedObjectContext:(NSManagedObjectContext*)moc_; +- (MappedEntityID*)objectID; + +@property (nonatomic, strong) NSNumber* mappedEntityID; + +//- (BOOL)validateMappedEntityID:(id*)value_ error:(NSError**)error_; + +@property (nonatomic, strong) NSString* nestedAttribute; + +//- (BOOL)validateNestedAttribute:(id*)value_ error:(NSError**)error_; + +@property (nonatomic, strong) NSString* sampleAttribute; + +//- (BOOL)validateSampleAttribute:(id*)value_ error:(NSError**)error_; + +@property (nonatomic, strong) NSNumber* testMappedEntityID; + +//- (BOOL)validateTestMappedEntityID:(id*)value_ error:(NSError**)error_; + +@end + +@interface _MappedEntity (CoreDataGeneratedPrimitiveAccessors) + +- (NSNumber*)primitiveMappedEntityID; +- (void)setPrimitiveMappedEntityID:(NSNumber*)value; + +- (NSString*)primitiveNestedAttribute; +- (void)setPrimitiveNestedAttribute:(NSString*)value; + +- (NSString*)primitiveSampleAttribute; +- (void)setPrimitiveSampleAttribute:(NSString*)value; + +- (NSNumber*)primitiveTestMappedEntityID; +- (void)setPrimitiveTestMappedEntityID:(NSNumber*)value; + +@end diff --git a/Tests/Fixtures/TestModel/_MappedEntity.m b/Tests/Fixtures/TestModel/_MappedEntity.m new file mode 100644 index 000000000..997507062 --- /dev/null +++ b/Tests/Fixtures/TestModel/_MappedEntity.m @@ -0,0 +1,49 @@ +// DO NOT EDIT. This file is machine-generated and constantly overwritten. +// Make changes to MappedEntity.m instead. + +#import "_MappedEntity.h" + +const struct MappedEntityAttributes MappedEntityAttributes = { + .mappedEntityID = @"mappedEntityID", + .nestedAttribute = @"nestedAttribute", + .sampleAttribute = @"sampleAttribute", + .testMappedEntityID = @"testMappedEntityID", +}; + +const struct MappedEntityUserInfo MappedEntityUserInfo = { + .relatedByAttribute = @"mapped", +}; + +@implementation MappedEntityID +@end + +@implementation _MappedEntity + ++ (id)insertInManagedObjectContext:(NSManagedObjectContext*)moc_ { + NSParameterAssert(moc_); + return [NSEntityDescription insertNewObjectForEntityForName:@"MappedEntity" inManagedObjectContext:moc_]; +} + ++ (NSString*)entityName { + return @"MappedEntity"; +} + ++ (NSEntityDescription*)entityInManagedObjectContext:(NSManagedObjectContext*)moc_ { + NSParameterAssert(moc_); + return [NSEntityDescription entityForName:@"MappedEntity" inManagedObjectContext:moc_]; +} + +- (MappedEntityID*)objectID { + return (MappedEntityID*)[super objectID]; +} + +@dynamic mappedEntityID; + +@dynamic nestedAttribute; + +@dynamic sampleAttribute; + +@dynamic testMappedEntityID; + +@end + diff --git a/Tests/Fixtures/TestModel/_SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.h b/Tests/Fixtures/TestModel/_SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.h new file mode 100644 index 000000000..285275f75 --- /dev/null +++ b/Tests/Fixtures/TestModel/_SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.h @@ -0,0 +1,54 @@ +// DO NOT EDIT. This file is machine-generated and constantly overwritten. +// Make changes to SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.h instead. + +#import + +extern const struct SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyAttributes { + __unsafe_unretained NSString *testPrimaryKey; +} SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyAttributes; + +extern const struct SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyRelationships { + __unsafe_unretained NSString *mappedEntities; +} SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyRelationships; + +extern const struct SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyUserInfo { + __unsafe_unretained NSString *relatedByAttribute; +} SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyUserInfo; + +@class MappedEntity; + +@interface SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyID : NSManagedObjectID {} +@end + +@interface _SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey : NSManagedObject {} ++ (id)insertInManagedObjectContext:(NSManagedObjectContext*)moc_; ++ (NSString*)entityName; ++ (NSEntityDescription*)entityInManagedObjectContext:(NSManagedObjectContext*)moc_; +- (SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyID*)objectID; + +@property (nonatomic, strong) NSNumber* testPrimaryKey; + +//- (BOOL)validateTestPrimaryKey:(id*)value_ error:(NSError**)error_; + +@property (nonatomic, strong) NSSet *mappedEntities; + +- (NSMutableSet*)mappedEntitiesSet; + +@end + +@interface _SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey (MappedEntitiesCoreDataGeneratedAccessors) +- (void)addMappedEntities:(NSSet*)value_; +- (void)removeMappedEntities:(NSSet*)value_; +- (void)addMappedEntitiesObject:(MappedEntity*)value_; +- (void)removeMappedEntitiesObject:(MappedEntity*)value_; +@end + +@interface _SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey (CoreDataGeneratedPrimitiveAccessors) + +- (NSNumber*)primitiveTestPrimaryKey; +- (void)setPrimitiveTestPrimaryKey:(NSNumber*)value; + +- (NSMutableSet*)primitiveMappedEntities; +- (void)setPrimitiveMappedEntities:(NSMutableSet*)value; + +@end diff --git a/Tests/Fixtures/TestModel/_SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m b/Tests/Fixtures/TestModel/_SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m new file mode 100644 index 000000000..c69115070 --- /dev/null +++ b/Tests/Fixtures/TestModel/_SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m @@ -0,0 +1,55 @@ +// DO NOT EDIT. This file is machine-generated and constantly overwritten. +// Make changes to SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m instead. + +#import "_SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.h" + +const struct SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyAttributes SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyAttributes = { + .testPrimaryKey = @"testPrimaryKey", +}; + +const struct SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyRelationships SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyRelationships = { + .mappedEntities = @"mappedEntities", +}; + +const struct SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyUserInfo SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyUserInfo = { + .relatedByAttribute = @"testPrimaryKey", +}; + +@implementation SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyID +@end + +@implementation _SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey + ++ (id)insertInManagedObjectContext:(NSManagedObjectContext*)moc_ { + NSParameterAssert(moc_); + return [NSEntityDescription insertNewObjectForEntityForName:@"SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey" inManagedObjectContext:moc_]; +} + ++ (NSString*)entityName { + return @"SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey"; +} + ++ (NSEntityDescription*)entityInManagedObjectContext:(NSManagedObjectContext*)moc_ { + NSParameterAssert(moc_); + return [NSEntityDescription entityForName:@"SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey" inManagedObjectContext:moc_]; +} + +- (SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyID*)objectID { + return (SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyID*)[super objectID]; +} + +@dynamic testPrimaryKey; + +@dynamic mappedEntities; + +- (NSMutableSet*)mappedEntitiesSet { + [self willAccessValueForKey:@"mappedEntities"]; + + NSMutableSet *result = (NSMutableSet*)[self mutableSetValueForKey:@"mappedEntities"]; + + [self didAccessValueForKey:@"mappedEntities"]; + return result; +} + +@end + diff --git a/Tests/Fixtures/TestModel/_SingleEntityRelatedToMappedEntityUsingDefaults.h b/Tests/Fixtures/TestModel/_SingleEntityRelatedToMappedEntityUsingDefaults.h new file mode 100644 index 000000000..114c97571 --- /dev/null +++ b/Tests/Fixtures/TestModel/_SingleEntityRelatedToMappedEntityUsingDefaults.h @@ -0,0 +1,43 @@ +// DO NOT EDIT. This file is machine-generated and constantly overwritten. +// Make changes to SingleEntityRelatedToMappedEntityUsingDefaults.h instead. + +#import + +extern const struct SingleEntityRelatedToMappedEntityUsingDefaultsAttributes { + __unsafe_unretained NSString *singleEntityRelatedToMappedEntityUsingDefaultsID; +} SingleEntityRelatedToMappedEntityUsingDefaultsAttributes; + +extern const struct SingleEntityRelatedToMappedEntityUsingDefaultsRelationships { + __unsafe_unretained NSString *mappedEntity; +} SingleEntityRelatedToMappedEntityUsingDefaultsRelationships; + +@class MappedEntity; + +@interface SingleEntityRelatedToMappedEntityUsingDefaultsID : NSManagedObjectID {} +@end + +@interface _SingleEntityRelatedToMappedEntityUsingDefaults : NSManagedObject {} ++ (id)insertInManagedObjectContext:(NSManagedObjectContext*)moc_; ++ (NSString*)entityName; ++ (NSEntityDescription*)entityInManagedObjectContext:(NSManagedObjectContext*)moc_; +- (SingleEntityRelatedToMappedEntityUsingDefaultsID*)objectID; + +@property (nonatomic, strong) NSNumber* singleEntityRelatedToMappedEntityUsingDefaultsID; + +//- (BOOL)validateSingleEntityRelatedToMappedEntityUsingDefaultsID:(id*)value_ error:(NSError**)error_; + +@property (nonatomic, strong) MappedEntity *mappedEntity; + +//- (BOOL)validateMappedEntity:(id*)value_ error:(NSError**)error_; + +@end + +@interface _SingleEntityRelatedToMappedEntityUsingDefaults (CoreDataGeneratedPrimitiveAccessors) + +- (NSNumber*)primitiveSingleEntityRelatedToMappedEntityUsingDefaultsID; +- (void)setPrimitiveSingleEntityRelatedToMappedEntityUsingDefaultsID:(NSNumber*)value; + +- (MappedEntity*)primitiveMappedEntity; +- (void)setPrimitiveMappedEntity:(MappedEntity*)value; + +@end diff --git a/Tests/Fixtures/TestModel/_SingleEntityRelatedToMappedEntityUsingDefaults.m b/Tests/Fixtures/TestModel/_SingleEntityRelatedToMappedEntityUsingDefaults.m new file mode 100644 index 000000000..17253045d --- /dev/null +++ b/Tests/Fixtures/TestModel/_SingleEntityRelatedToMappedEntityUsingDefaults.m @@ -0,0 +1,42 @@ +// DO NOT EDIT. This file is machine-generated and constantly overwritten. +// Make changes to SingleEntityRelatedToMappedEntityUsingDefaults.m instead. + +#import "_SingleEntityRelatedToMappedEntityUsingDefaults.h" + +const struct SingleEntityRelatedToMappedEntityUsingDefaultsAttributes SingleEntityRelatedToMappedEntityUsingDefaultsAttributes = { + .singleEntityRelatedToMappedEntityUsingDefaultsID = @"singleEntityRelatedToMappedEntityUsingDefaultsID", +}; + +const struct SingleEntityRelatedToMappedEntityUsingDefaultsRelationships SingleEntityRelatedToMappedEntityUsingDefaultsRelationships = { + .mappedEntity = @"mappedEntity", +}; + +@implementation SingleEntityRelatedToMappedEntityUsingDefaultsID +@end + +@implementation _SingleEntityRelatedToMappedEntityUsingDefaults + ++ (id)insertInManagedObjectContext:(NSManagedObjectContext*)moc_ { + NSParameterAssert(moc_); + return [NSEntityDescription insertNewObjectForEntityForName:@"SingleEntityRelatedToMappedEntityUsingDefaults" inManagedObjectContext:moc_]; +} + ++ (NSString*)entityName { + return @"SingleEntityRelatedToMappedEntityUsingDefaults"; +} + ++ (NSEntityDescription*)entityInManagedObjectContext:(NSManagedObjectContext*)moc_ { + NSParameterAssert(moc_); + return [NSEntityDescription entityForName:@"SingleEntityRelatedToMappedEntityUsingDefaults" inManagedObjectContext:moc_]; +} + +- (SingleEntityRelatedToMappedEntityUsingDefaultsID*)objectID { + return (SingleEntityRelatedToMappedEntityUsingDefaultsID*)[super objectID]; +} + +@dynamic singleEntityRelatedToMappedEntityUsingDefaultsID; + +@dynamic mappedEntity; + +@end + diff --git a/Tests/Fixtures/TestModel/_SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.h b/Tests/Fixtures/TestModel/_SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.h new file mode 100644 index 000000000..337267617 --- /dev/null +++ b/Tests/Fixtures/TestModel/_SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.h @@ -0,0 +1,32 @@ +// DO NOT EDIT. This file is machine-generated and constantly overwritten. +// Make changes to SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.h instead. + +#import + +extern const struct SingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyRelationships { + __unsafe_unretained NSString *mappedEntity; +} SingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyRelationships; + +@class MappedEntity; + +@interface SingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyID : NSManagedObjectID {} +@end + +@interface _SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey : NSManagedObject {} ++ (id)insertInManagedObjectContext:(NSManagedObjectContext*)moc_; ++ (NSString*)entityName; ++ (NSEntityDescription*)entityInManagedObjectContext:(NSManagedObjectContext*)moc_; +- (SingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyID*)objectID; + +@property (nonatomic, strong) MappedEntity *mappedEntity; + +//- (BOOL)validateMappedEntity:(id*)value_ error:(NSError**)error_; + +@end + +@interface _SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey (CoreDataGeneratedPrimitiveAccessors) + +- (MappedEntity*)primitiveMappedEntity; +- (void)setPrimitiveMappedEntity:(MappedEntity*)value; + +@end diff --git a/Tests/Fixtures/TestModel/_SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m b/Tests/Fixtures/TestModel/_SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m new file mode 100644 index 000000000..58c64c865 --- /dev/null +++ b/Tests/Fixtures/TestModel/_SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m @@ -0,0 +1,36 @@ +// DO NOT EDIT. This file is machine-generated and constantly overwritten. +// Make changes to SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m instead. + +#import "_SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.h" + +const struct SingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyRelationships SingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyRelationships = { + .mappedEntity = @"mappedEntity", +}; + +@implementation SingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyID +@end + +@implementation _SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey + ++ (id)insertInManagedObjectContext:(NSManagedObjectContext*)moc_ { + NSParameterAssert(moc_); + return [NSEntityDescription insertNewObjectForEntityForName:@"SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey" inManagedObjectContext:moc_]; +} + ++ (NSString*)entityName { + return @"SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey"; +} + ++ (NSEntityDescription*)entityInManagedObjectContext:(NSManagedObjectContext*)moc_ { + NSParameterAssert(moc_); + return [NSEntityDescription entityForName:@"SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey" inManagedObjectContext:moc_]; +} + +- (SingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyID*)objectID { + return (SingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyID*)[super objectID]; +} + +@dynamic mappedEntity; + +@end + diff --git a/Tests/Fixtures/TestModel/_SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.h b/Tests/Fixtures/TestModel/_SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.h new file mode 100644 index 000000000..2ee76dffc --- /dev/null +++ b/Tests/Fixtures/TestModel/_SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.h @@ -0,0 +1,32 @@ +// DO NOT EDIT. This file is machine-generated and constantly overwritten. +// Make changes to SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.h instead. + +#import + +extern const struct SingleEntityRelatedToMappedEntityWithNestedMappedAttributesRelationships { + __unsafe_unretained NSString *mappedEntity; +} SingleEntityRelatedToMappedEntityWithNestedMappedAttributesRelationships; + +@class MappedEntity; + +@interface SingleEntityRelatedToMappedEntityWithNestedMappedAttributesID : NSManagedObjectID {} +@end + +@interface _SingleEntityRelatedToMappedEntityWithNestedMappedAttributes : NSManagedObject {} ++ (id)insertInManagedObjectContext:(NSManagedObjectContext*)moc_; ++ (NSString*)entityName; ++ (NSEntityDescription*)entityInManagedObjectContext:(NSManagedObjectContext*)moc_; +- (SingleEntityRelatedToMappedEntityWithNestedMappedAttributesID*)objectID; + +@property (nonatomic, strong) MappedEntity *mappedEntity; + +//- (BOOL)validateMappedEntity:(id*)value_ error:(NSError**)error_; + +@end + +@interface _SingleEntityRelatedToMappedEntityWithNestedMappedAttributes (CoreDataGeneratedPrimitiveAccessors) + +- (MappedEntity*)primitiveMappedEntity; +- (void)setPrimitiveMappedEntity:(MappedEntity*)value; + +@end diff --git a/Tests/Fixtures/TestModel/_SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m b/Tests/Fixtures/TestModel/_SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m new file mode 100644 index 000000000..1e6a653f3 --- /dev/null +++ b/Tests/Fixtures/TestModel/_SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m @@ -0,0 +1,36 @@ +// DO NOT EDIT. This file is machine-generated and constantly overwritten. +// Make changes to SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m instead. + +#import "_SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.h" + +const struct SingleEntityRelatedToMappedEntityWithNestedMappedAttributesRelationships SingleEntityRelatedToMappedEntityWithNestedMappedAttributesRelationships = { + .mappedEntity = @"mappedEntity", +}; + +@implementation SingleEntityRelatedToMappedEntityWithNestedMappedAttributesID +@end + +@implementation _SingleEntityRelatedToMappedEntityWithNestedMappedAttributes + ++ (id)insertInManagedObjectContext:(NSManagedObjectContext*)moc_ { + NSParameterAssert(moc_); + return [NSEntityDescription insertNewObjectForEntityForName:@"SingleEntityRelatedToMappedEntityWithNestedMappedAttributes" inManagedObjectContext:moc_]; +} + ++ (NSString*)entityName { + return @"SingleEntityRelatedToMappedEntityWithNestedMappedAttributes"; +} + ++ (NSEntityDescription*)entityInManagedObjectContext:(NSManagedObjectContext*)moc_ { + NSParameterAssert(moc_); + return [NSEntityDescription entityForName:@"SingleEntityRelatedToMappedEntityWithNestedMappedAttributes" inManagedObjectContext:moc_]; +} + +- (SingleEntityRelatedToMappedEntityWithNestedMappedAttributesID*)objectID { + return (SingleEntityRelatedToMappedEntityWithNestedMappedAttributesID*)[super objectID]; +} + +@dynamic mappedEntity; + +@end + diff --git a/Tests/Fixtures/TestModel/_SingleEntityRelatedToMappedEntityWithSecondaryMappings.h b/Tests/Fixtures/TestModel/_SingleEntityRelatedToMappedEntityWithSecondaryMappings.h new file mode 100644 index 000000000..899726385 --- /dev/null +++ b/Tests/Fixtures/TestModel/_SingleEntityRelatedToMappedEntityWithSecondaryMappings.h @@ -0,0 +1,51 @@ +// DO NOT EDIT. This file is machine-generated and constantly overwritten. +// Make changes to SingleEntityRelatedToMappedEntityWithSecondaryMappings.h instead. + +#import + +extern const struct SingleEntityRelatedToMappedEntityWithSecondaryMappingsAttributes { + __unsafe_unretained NSString *secondaryMappedAttribute; + __unsafe_unretained NSString *notImportedAttribute; +} SingleEntityRelatedToMappedEntityWithSecondaryMappingsAttributes; + +extern const struct SingleEntityRelatedToMappedEntityWithSecondaryMappingsRelationships { + __unsafe_unretained NSString *mappedRelationship; +} SingleEntityRelatedToMappedEntityWithSecondaryMappingsRelationships; + +@class MappedEntity; + +@interface SingleEntityRelatedToMappedEntityWithSecondaryMappingsID : NSManagedObjectID {} +@end + +@interface _SingleEntityRelatedToMappedEntityWithSecondaryMappings : NSManagedObject {} ++ (id)insertInManagedObjectContext:(NSManagedObjectContext*)moc_; ++ (NSString*)entityName; ++ (NSEntityDescription*)entityInManagedObjectContext:(NSManagedObjectContext*)moc_; +- (SingleEntityRelatedToMappedEntityWithSecondaryMappingsID*)objectID; + +@property (nonatomic, strong) NSString* secondaryMappedAttribute; + +//- (BOOL)validateSecondaryMappedAttribute:(id*)value_ error:(NSError**)error_; + +@property (nonatomic, strong) NSNumber *notImportedAttribute; + +//- (BOOL)validateNotImportedAttribute:(id*)value_ error:(NSError**)error_; + +@property (nonatomic, strong) MappedEntity *mappedRelationship; + +//- (BOOL)validateMappedRelationship:(id*)value_ error:(NSError**)error_; + +@end + +@interface _SingleEntityRelatedToMappedEntityWithSecondaryMappings (CoreDataGeneratedPrimitiveAccessors) + +- (NSNumber*)primitiveNotImportedAttribute; +- (void)setPrimitiveNotImportedAttribute:(NSNumber*)value; + +- (NSString*)primitiveSecondaryMappedAttribute; +- (void)setPrimitiveSecondaryMappedAttribute:(NSString*)value; + +- (MappedEntity*)primitiveMappedRelationship; +- (void)setPrimitiveMappedRelationship:(MappedEntity*)value; + +@end diff --git a/Tests/Fixtures/TestModel/_SingleEntityRelatedToMappedEntityWithSecondaryMappings.m b/Tests/Fixtures/TestModel/_SingleEntityRelatedToMappedEntityWithSecondaryMappings.m new file mode 100644 index 000000000..8e517bebf --- /dev/null +++ b/Tests/Fixtures/TestModel/_SingleEntityRelatedToMappedEntityWithSecondaryMappings.m @@ -0,0 +1,59 @@ +// DO NOT EDIT. This file is machine-generated and constantly overwritten. +// Make changes to SingleEntityRelatedToMappedEntityWithSecondaryMappings.m instead. + +#import "_SingleEntityRelatedToMappedEntityWithSecondaryMappings.h" + +const struct SingleEntityRelatedToMappedEntityWithSecondaryMappingsAttributes SingleEntityRelatedToMappedEntityWithSecondaryMappingsAttributes = { + .secondaryMappedAttribute = @"secondaryMappedAttribute", + .notImportedAttribute = @"notImportedAttribute", +}; + +const struct SingleEntityRelatedToMappedEntityWithSecondaryMappingsRelationships SingleEntityRelatedToMappedEntityWithSecondaryMappingsRelationships = { + .mappedRelationship = @"mappedRelationship", +}; + +@implementation SingleEntityRelatedToMappedEntityWithSecondaryMappingsID +@end + +@implementation _SingleEntityRelatedToMappedEntityWithSecondaryMappings + ++ (id)insertInManagedObjectContext:(NSManagedObjectContext*)moc_ { + NSParameterAssert(moc_); + return [NSEntityDescription insertNewObjectForEntityForName:@"SingleEntityRelatedToMappedEntityWithSecondaryMappings" inManagedObjectContext:moc_]; +} + ++ (NSString*)entityName { + return @"SingleEntityRelatedToMappedEntityWithSecondaryMappings"; +} + ++ (NSEntityDescription*)entityInManagedObjectContext:(NSManagedObjectContext*)moc_ { + NSParameterAssert(moc_); + return [NSEntityDescription entityForName:@"SingleEntityRelatedToMappedEntityWithSecondaryMappings" inManagedObjectContext:moc_]; +} + +- (SingleEntityRelatedToMappedEntityWithSecondaryMappingsID*)objectID { + return (SingleEntityRelatedToMappedEntityWithSecondaryMappingsID*)[super objectID]; +} + +- (id)valueForUndefinedKey:(NSString *)key +{ + if ([key isEqualToString:@"secondaryMappedAttribute"]) + { + return self.secondaryMappedAttribute; + } + else if ([key isEqualToString:@"notImportedAttribute"]) + { + return self.notImportedAttribute; + } + + return nil; +} + +@dynamic secondaryMappedAttribute; + +@dynamic notImportedAttribute; + +@dynamic mappedRelationship; + +@end + diff --git a/Tests/Fixtures/TestModel/_SingleEntityWithNoRelationships.h b/Tests/Fixtures/TestModel/_SingleEntityWithNoRelationships.h new file mode 100644 index 000000000..703750b8e --- /dev/null +++ b/Tests/Fixtures/TestModel/_SingleEntityWithNoRelationships.h @@ -0,0 +1,181 @@ +// DO NOT EDIT. This file is machine-generated and constantly overwritten. +// Make changes to SingleEntityWithNoRelationships.h instead. + +#import +#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR +#import +#import +#else +#import +#endif + +extern const struct SingleEntityWithNoRelationshipsAttributes { + __unsafe_unretained NSString *booleanAsStringTestAttribute; + __unsafe_unretained NSString *booleanTestAttribute; + __unsafe_unretained NSString *colorTestAttribute; + __unsafe_unretained NSString *dateTestAttribute; + __unsafe_unretained NSString *dateWithCustomFormat; + __unsafe_unretained NSString *decimalTestAttribute; + __unsafe_unretained NSString *doubleTestAttribute; + __unsafe_unretained NSString *floatTestAttribute; + __unsafe_unretained NSString *int16TestAttribute; + __unsafe_unretained NSString *int32TestAttribute; + __unsafe_unretained NSString *int64TestAttribute; + __unsafe_unretained NSString *mappedStringAttribute; + __unsafe_unretained NSString *notInJsonAttribute; + __unsafe_unretained NSString *nullTestAttribute; + __unsafe_unretained NSString *numberAsStringTestAttribute; + __unsafe_unretained NSString *stringTestAttribute; + __unsafe_unretained NSString *unixTime13TestAttribute; + __unsafe_unretained NSString *unixTimeTestAttribute; +} SingleEntityWithNoRelationshipsAttributes; + +@interface SingleEntityWithNoRelationshipsID : NSManagedObjectID {} +@end + +@interface _SingleEntityWithNoRelationships : NSManagedObject {} ++ (id)insertInManagedObjectContext:(NSManagedObjectContext*)moc_; ++ (NSString*)entityName; ++ (NSEntityDescription*)entityInManagedObjectContext:(NSManagedObjectContext*)moc_; +- (SingleEntityWithNoRelationshipsID*)objectID; + +@property (nonatomic, strong) NSNumber* booleanAsStringTestAttribute; + +//- (BOOL)validateBooleanAsStringTestAttribute:(id*)value_ error:(NSError**)error_; + +@property (nonatomic, strong) NSNumber* booleanTestAttribute; + +//- (BOOL)validateBooleanTestAttribute:(id*)value_ error:(NSError**)error_; + +#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR +@property (nonatomic, strong) UIColor *colorTestAttribute; +#else +@property (nonatomic, strong) NSColor *colorTestAttribute; +#endif + +//- (BOOL)validateColorTestAttribute:(id*)value_ error:(NSError**)error_; + +@property (nonatomic, strong) NSDate* dateTestAttribute; + +//- (BOOL)validateDateTestAttribute:(id*)value_ error:(NSError**)error_; + +@property (nonatomic, strong) NSDate* dateWithCustomFormat; + +//- (BOOL)validateDateWithCustomFormat:(id*)value_ error:(NSError**)error_; + +@property (nonatomic, strong) NSDecimalNumber* decimalTestAttribute; + +//- (BOOL)validateDecimalTestAttribute:(id*)value_ error:(NSError**)error_; + +@property (nonatomic, strong) NSNumber* doubleTestAttribute; + +//- (BOOL)validateDoubleTestAttribute:(id*)value_ error:(NSError**)error_; + +@property (nonatomic, strong) NSNumber* floatTestAttribute; + +//- (BOOL)validateFloatTestAttribute:(id*)value_ error:(NSError**)error_; + +@property (nonatomic, strong) NSNumber* int16TestAttribute; + +//- (BOOL)validateInt16TestAttribute:(id*)value_ error:(NSError**)error_; + +@property (nonatomic, strong) NSNumber* int32TestAttribute; + +//- (BOOL)validateInt32TestAttribute:(id*)value_ error:(NSError**)error_; + +@property (nonatomic, strong) NSNumber* int64TestAttribute; + +//- (BOOL)validateInt64TestAttribute:(id*)value_ error:(NSError**)error_; + +@property (nonatomic, strong) NSString* mappedStringAttribute; + +//- (BOOL)validateMappedStringAttribute:(id*)value_ error:(NSError**)error_; + +@property (nonatomic, strong) NSString* notInJsonAttribute; + +//- (BOOL)validateNotInJsonAttribute:(id*)value_ error:(NSError**)error_; + +@property (nonatomic, strong) NSNumber* nullTestAttribute; + +//- (BOOL)validateNullTestAttribute:(id*)value_ error:(NSError**)error_; + +@property (nonatomic, strong) NSString* numberAsStringTestAttribute; + +//- (BOOL)validateNumberAsStringTestAttribute:(id*)value_ error:(NSError**)error_; + +@property (nonatomic, strong) NSString* stringTestAttribute; + +//- (BOOL)validateStringTestAttribute:(id*)value_ error:(NSError**)error_; + +@property (nonatomic, strong) NSDate* unixTime13TestAttribute; + +//- (BOOL)validateUnixTime13TestAttribute:(id*)value_ error:(NSError**)error_; + +@property (nonatomic, strong) NSDate* unixTimeTestAttribute; + +//- (BOOL)validateUnixTimeTestAttribute:(id*)value_ error:(NSError**)error_; + +@end + +@interface _SingleEntityWithNoRelationships (CoreDataGeneratedPrimitiveAccessors) + +- (NSNumber*)primitiveBooleanAsStringTestAttribute; +- (void)setPrimitiveBooleanAsStringTestAttribute:(NSNumber*)value; + +- (NSNumber*)primitiveBooleanTestAttribute; +- (void)setPrimitiveBooleanTestAttribute:(NSNumber*)value; + +#if TARGET_OS_IPHONE +- (UIColor *)primitiveColorTestAttribute; +- (void)setPrimitiveColorTestAttribute:(UIColor *)value; +#else +- (NSColor *)primitiveColorTestAttribute; +- (void)setPrimitiveColorTestAttribute:(NSColor *)value; +#endif + +- (NSDate*)primitiveDateTestAttribute; +- (void)setPrimitiveDateTestAttribute:(NSDate*)value; + +- (NSDate*)primitiveDateWithCustomFormat; +- (void)setPrimitiveDateWithCustomFormat:(NSDate*)value; + +- (NSDecimalNumber*)primitiveDecimalTestAttribute; +- (void)setPrimitiveDecimalTestAttribute:(NSDecimalNumber*)value; + +- (NSNumber*)primitiveDoubleTestAttribute; +- (void)setPrimitiveDoubleTestAttribute:(NSNumber*)value; + +- (NSNumber*)primitiveFloatTestAttribute; +- (void)setPrimitiveFloatTestAttribute:(NSNumber*)value; + +- (NSNumber*)primitiveInt16TestAttribute; +- (void)setPrimitiveInt16TestAttribute:(NSNumber*)value; + +- (NSNumber*)primitiveInt32TestAttribute; +- (void)setPrimitiveInt32TestAttribute:(NSNumber*)value; + +- (NSNumber*)primitiveInt64TestAttribute; +- (void)setPrimitiveInt64TestAttribute:(NSNumber*)value; + +- (NSString*)primitiveMappedStringAttribute; +- (void)setPrimitiveMappedStringAttribute:(NSString*)value; + +- (NSString*)primitiveNotInJsonAttribute; +- (void)setPrimitiveNotInJsonAttribute:(NSString*)value; + +- (NSNumber*)primitiveNullTestAttribute; +- (void)setPrimitiveNullTestAttribute:(NSNumber*)value; + +- (NSString*)primitiveNumberAsStringTestAttribute; +- (void)setPrimitiveNumberAsStringTestAttribute:(NSString*)value; + +- (NSString*)primitiveStringTestAttribute; +- (void)setPrimitiveStringTestAttribute:(NSString*)value; + +- (NSDate*)primitiveUnixTime13TestAttribute; +- (void)setPrimitiveUnixTime13TestAttribute:(NSDate*)value; + +- (NSDate*)primitiveUnixTimeTestAttribute; +- (void)setPrimitiveUnixTimeTestAttribute:(NSDate*)value; + +@end diff --git a/Tests/Fixtures/TestModel/_SingleEntityWithNoRelationships.m b/Tests/Fixtures/TestModel/_SingleEntityWithNoRelationships.m new file mode 100644 index 000000000..48a4bc681 --- /dev/null +++ b/Tests/Fixtures/TestModel/_SingleEntityWithNoRelationships.m @@ -0,0 +1,87 @@ +// DO NOT EDIT. This file is machine-generated and constantly overwritten. +// Make changes to SingleEntityWithNoRelationships.m instead. + +#import "_SingleEntityWithNoRelationships.h" + +const struct SingleEntityWithNoRelationshipsAttributes SingleEntityWithNoRelationshipsAttributes = { + .booleanAsStringTestAttribute = @"booleanAsStringTestAttribute", + .booleanTestAttribute = @"booleanTestAttribute", + .colorTestAttribute = @"colorTestAttribute", + .dateTestAttribute = @"dateTestAttribute", + .dateWithCustomFormat = @"dateWithCustomFormat", + .decimalTestAttribute = @"decimalTestAttribute", + .doubleTestAttribute = @"doubleTestAttribute", + .floatTestAttribute = @"floatTestAttribute", + .int16TestAttribute = @"int16TestAttribute", + .int32TestAttribute = @"int32TestAttribute", + .int64TestAttribute = @"int64TestAttribute", + .mappedStringAttribute = @"mappedStringAttribute", + .notInJsonAttribute = @"notInJsonAttribute", + .nullTestAttribute = @"nullTestAttribute", + .numberAsStringTestAttribute = @"numberAsStringTestAttribute", + .stringTestAttribute = @"stringTestAttribute", + .unixTime13TestAttribute = @"unixTime13TestAttribute", + .unixTimeTestAttribute = @"unixTimeTestAttribute", +}; + +@implementation SingleEntityWithNoRelationshipsID +@end + +@implementation _SingleEntityWithNoRelationships + ++ (id)insertInManagedObjectContext:(NSManagedObjectContext*)moc_ { + NSParameterAssert(moc_); + return [NSEntityDescription insertNewObjectForEntityForName:@"SingleEntityWithNoRelationships" inManagedObjectContext:moc_]; +} + ++ (NSString*)entityName { + return @"SingleEntityWithNoRelationships"; +} + ++ (NSEntityDescription*)entityInManagedObjectContext:(NSManagedObjectContext*)moc_ { + NSParameterAssert(moc_); + return [NSEntityDescription entityForName:@"SingleEntityWithNoRelationships" inManagedObjectContext:moc_]; +} + +- (SingleEntityWithNoRelationshipsID*)objectID { + return (SingleEntityWithNoRelationshipsID*)[super objectID]; +} + +@dynamic booleanAsStringTestAttribute; + +@dynamic booleanTestAttribute; + +@dynamic colorTestAttribute; + +@dynamic dateTestAttribute; + +@dynamic dateWithCustomFormat; + +@dynamic decimalTestAttribute; + +@dynamic doubleTestAttribute; + +@dynamic floatTestAttribute; + +@dynamic int16TestAttribute; + +@dynamic int32TestAttribute; + +@dynamic int64TestAttribute; + +@dynamic mappedStringAttribute; + +@dynamic notInJsonAttribute; + +@dynamic nullTestAttribute; + +@dynamic numberAsStringTestAttribute; + +@dynamic stringTestAttribute; + +@dynamic unixTime13TestAttribute; + +@dynamic unixTimeTestAttribute; + +@end + diff --git a/Tests/Fixtures/TestModel/_SingleRelatedEntity.h b/Tests/Fixtures/TestModel/_SingleRelatedEntity.h new file mode 100644 index 000000000..672f9ac48 --- /dev/null +++ b/Tests/Fixtures/TestModel/_SingleRelatedEntity.h @@ -0,0 +1,84 @@ +// DO NOT EDIT. This file is machine-generated and constantly overwritten. +// Make changes to SingleRelatedEntity.h instead. + +#import + +extern const struct SingleRelatedEntityAttributes { + __unsafe_unretained NSString *mappedStringAttribute; +} SingleRelatedEntityAttributes; + +extern const struct SingleRelatedEntityRelationships { + __unsafe_unretained NSString *testAbstractToManyRelationship; + __unsafe_unretained NSString *testAbstractToOneRelationship; + __unsafe_unretained NSString *testConcreteToManyRelationship; + __unsafe_unretained NSString *testConcreteToOneRelationship; +} SingleRelatedEntityRelationships; + +@class AbstractRelatedEntity; +@class AbstractRelatedEntity; +@class ConcreteRelatedEntity; +@class ConcreteRelatedEntity; + +@interface SingleRelatedEntityID : NSManagedObjectID {} +@end + +@interface _SingleRelatedEntity : NSManagedObject {} ++ (id)insertInManagedObjectContext:(NSManagedObjectContext*)moc_; ++ (NSString*)entityName; ++ (NSEntityDescription*)entityInManagedObjectContext:(NSManagedObjectContext*)moc_; +- (SingleRelatedEntityID*)objectID; + +@property (nonatomic, strong) NSString* mappedStringAttribute; + +//- (BOOL)validateMappedStringAttribute:(id*)value_ error:(NSError**)error_; + +@property (nonatomic, strong) NSSet *testAbstractToManyRelationship; + +- (NSMutableSet*)testAbstractToManyRelationshipSet; + +@property (nonatomic, strong) AbstractRelatedEntity *testAbstractToOneRelationship; + +//- (BOOL)validateTestAbstractToOneRelationship:(id*)value_ error:(NSError**)error_; + +@property (nonatomic, strong) NSSet *testConcreteToManyRelationship; + +- (NSMutableSet*)testConcreteToManyRelationshipSet; + +@property (nonatomic, strong) ConcreteRelatedEntity *testConcreteToOneRelationship; + +//- (BOOL)validateTestConcreteToOneRelationship:(id*)value_ error:(NSError**)error_; + +@end + +@interface _SingleRelatedEntity (TestAbstractToManyRelationshipCoreDataGeneratedAccessors) +- (void)addTestAbstractToManyRelationship:(NSSet*)value_; +- (void)removeTestAbstractToManyRelationship:(NSSet*)value_; +- (void)addTestAbstractToManyRelationshipObject:(AbstractRelatedEntity*)value_; +- (void)removeTestAbstractToManyRelationshipObject:(AbstractRelatedEntity*)value_; +@end + +@interface _SingleRelatedEntity (TestConcreteToManyRelationshipCoreDataGeneratedAccessors) +- (void)addTestConcreteToManyRelationship:(NSSet*)value_; +- (void)removeTestConcreteToManyRelationship:(NSSet*)value_; +- (void)addTestConcreteToManyRelationshipObject:(ConcreteRelatedEntity*)value_; +- (void)removeTestConcreteToManyRelationshipObject:(ConcreteRelatedEntity*)value_; +@end + +@interface _SingleRelatedEntity (CoreDataGeneratedPrimitiveAccessors) + +- (NSString*)primitiveMappedStringAttribute; +- (void)setPrimitiveMappedStringAttribute:(NSString*)value; + +- (NSMutableSet*)primitiveTestAbstractToManyRelationship; +- (void)setPrimitiveTestAbstractToManyRelationship:(NSMutableSet*)value; + +- (AbstractRelatedEntity*)primitiveTestAbstractToOneRelationship; +- (void)setPrimitiveTestAbstractToOneRelationship:(AbstractRelatedEntity*)value; + +- (NSMutableSet*)primitiveTestConcreteToManyRelationship; +- (void)setPrimitiveTestConcreteToManyRelationship:(NSMutableSet*)value; + +- (ConcreteRelatedEntity*)primitiveTestConcreteToOneRelationship; +- (void)setPrimitiveTestConcreteToOneRelationship:(ConcreteRelatedEntity*)value; + +@end diff --git a/Tests/Fixtures/TestModel/_SingleRelatedEntity.m b/Tests/Fixtures/TestModel/_SingleRelatedEntity.m new file mode 100644 index 000000000..31281da7e --- /dev/null +++ b/Tests/Fixtures/TestModel/_SingleRelatedEntity.m @@ -0,0 +1,69 @@ +// DO NOT EDIT. This file is machine-generated and constantly overwritten. +// Make changes to SingleRelatedEntity.m instead. + +#import "_SingleRelatedEntity.h" + +const struct SingleRelatedEntityAttributes SingleRelatedEntityAttributes = { + .mappedStringAttribute = @"mappedStringAttribute", +}; + +const struct SingleRelatedEntityRelationships SingleRelatedEntityRelationships = { + .testAbstractToManyRelationship = @"testAbstractToManyRelationship", + .testAbstractToOneRelationship = @"testAbstractToOneRelationship", + .testConcreteToManyRelationship = @"testConcreteToManyRelationship", + .testConcreteToOneRelationship = @"testConcreteToOneRelationship", +}; + +@implementation SingleRelatedEntityID +@end + +@implementation _SingleRelatedEntity + ++ (id)insertInManagedObjectContext:(NSManagedObjectContext*)moc_ { + NSParameterAssert(moc_); + return [NSEntityDescription insertNewObjectForEntityForName:@"SingleRelatedEntity" inManagedObjectContext:moc_]; +} + ++ (NSString*)entityName { + return @"SingleRelatedEntity"; +} + ++ (NSEntityDescription*)entityInManagedObjectContext:(NSManagedObjectContext*)moc_ { + NSParameterAssert(moc_); + return [NSEntityDescription entityForName:@"SingleRelatedEntity" inManagedObjectContext:moc_]; +} + +- (SingleRelatedEntityID*)objectID { + return (SingleRelatedEntityID*)[super objectID]; +} + +@dynamic mappedStringAttribute; + +@dynamic testAbstractToManyRelationship; + +- (NSMutableSet*)testAbstractToManyRelationshipSet { + [self willAccessValueForKey:@"testAbstractToManyRelationship"]; + + NSMutableSet *result = (NSMutableSet*)[self mutableSetValueForKey:@"testAbstractToManyRelationship"]; + + [self didAccessValueForKey:@"testAbstractToManyRelationship"]; + return result; +} + +@dynamic testAbstractToOneRelationship; + +@dynamic testConcreteToManyRelationship; + +- (NSMutableSet*)testConcreteToManyRelationshipSet { + [self willAccessValueForKey:@"testConcreteToManyRelationship"]; + + NSMutableSet *result = (NSMutableSet*)[self mutableSetValueForKey:@"testConcreteToManyRelationship"]; + + [self didAccessValueForKey:@"testConcreteToManyRelationship"]; + return result; +} + +@dynamic testConcreteToOneRelationship; + +@end + diff --git a/Tests/Support/MagicalRecordTestHelpers.h b/Tests/Support/MagicalRecordTestHelpers.h new file mode 100644 index 000000000..62426570b --- /dev/null +++ b/Tests/Support/MagicalRecordTestHelpers.h @@ -0,0 +1,10 @@ +// +// Copyright (c) 2015 Magical Panda Software LLC. All rights reserved. + +#import + +@interface MagicalRecordTestHelpers : NSObject + ++ (BOOL)removeStoreFilesForStoreAtURL:(NSURL *)storeURL; + +@end diff --git a/Tests/Support/MagicalRecordTestHelpers.m b/Tests/Support/MagicalRecordTestHelpers.m new file mode 100644 index 000000000..70d4411f0 --- /dev/null +++ b/Tests/Support/MagicalRecordTestHelpers.m @@ -0,0 +1,23 @@ +// +// Copyright (c) 2015 Magical Panda Software LLC. All rights reserved. + +#import "MagicalRecordTestHelpers.h" + +@implementation MagicalRecordTestHelpers + ++ (BOOL)removeStoreFilesForStoreAtURL:(NSURL *)storeURL +{ + NSString *rawURL = [storeURL absoluteString]; + NSURL *shmSidecar = [NSURL URLWithString:[rawURL stringByAppendingString:@"-shm"]]; + NSURL *walSidecar = [NSURL URLWithString:[rawURL stringByAppendingString:@"-wal"]]; + + BOOL success = YES; + success &= [[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil]; + success &= [[NSFileManager defaultManager] removeItemAtURL:shmSidecar error:nil]; + success &= [[NSFileManager defaultManager] removeItemAtURL:walSidecar error:nil]; + + return success; +} + + +@end diff --git a/Project Files/Tests/Support/MagicalRecordTests-OSX-Info.plist b/Tests/Support/MagicalRecordTests-OSX-Info.plist similarity index 100% rename from Project Files/Tests/Support/MagicalRecordTests-OSX-Info.plist rename to Tests/Support/MagicalRecordTests-OSX-Info.plist diff --git a/Project Files/Tests/Support/MagicalRecordTests-OSX-Prefix.pch b/Tests/Support/MagicalRecordTests-OSX-Prefix.pch similarity index 81% rename from Project Files/Tests/Support/MagicalRecordTests-OSX-Prefix.pch rename to Tests/Support/MagicalRecordTests-OSX-Prefix.pch index 209e9b824..a5293804e 100644 --- a/Project Files/Tests/Support/MagicalRecordTests-OSX-Prefix.pch +++ b/Tests/Support/MagicalRecordTests-OSX-Prefix.pch @@ -4,5 +4,5 @@ #ifdef __OBJC__ #import - #import "CoreData+MagicalRecord.h" + #import "MagicalRecord.h" #endif diff --git a/Project Files/Tests/Support/MagicalRecordTests-iOS-Info.plist b/Tests/Support/MagicalRecordTests-iOS-Info.plist similarity index 100% rename from Project Files/Tests/Support/MagicalRecordTests-iOS-Info.plist rename to Tests/Support/MagicalRecordTests-iOS-Info.plist diff --git a/Project Files/Tests/Support/MagicalRecordTests-iOS-Prefix.pch b/Tests/Support/MagicalRecordTests-iOS-Prefix.pch similarity index 82% rename from Project Files/Tests/Support/MagicalRecordTests-iOS-Prefix.pch rename to Tests/Support/MagicalRecordTests-iOS-Prefix.pch index 40a4a588c..cc019d3ec 100644 --- a/Project Files/Tests/Support/MagicalRecordTests-iOS-Prefix.pch +++ b/Tests/Support/MagicalRecordTests-iOS-Prefix.pch @@ -5,5 +5,5 @@ #ifdef __OBJC__ #import #import - #import "CoreData+MagicalRecord.h" + #import #endif diff --git a/circle.yml b/circle.yml new file mode 100644 index 000000000..2729d278c --- /dev/null +++ b/circle.yml @@ -0,0 +1,49 @@ +machine: + xcode: + version: "6.3.1" + +checkout: + post: + - git submodule sync + - git submodule update --init + +test: + override: + - xcodebuild + -resultBundlePath "$CIRCLE_TEST_REPORTS/xcode/results-ios-framework" + CODE_SIGNING_REQUIRED=NO + CODE_SIGN_IDENTITY= + PROVISIONING_PROFILE= + -sdk iphonesimulator + -destination 'platform=iOS Simulator,name=iPhone 6,OS=latest' + -project MagicalRecord.xcodeproj + -scheme "MagicalRecord for iOS" + build test + - xcodebuild + -resultBundlePath "$CIRCLE_TEST_REPORTS/xcode/results-osx-framework" + CODE_SIGNING_REQUIRED=NO + CODE_SIGN_IDENTITY= + PROVISIONING_PROFILE= + -sdk macosx + -project MagicalRecord.xcodeproj + -scheme "MagicalRecord for OS X" + build test + - xcodebuild + -resultBundlePath "$CIRCLE_TEST_REPORTS/xcode/results-ios-static-library" + CODE_SIGNING_REQUIRED=NO + CODE_SIGN_IDENTITY= + PROVISIONING_PROFILE= + -sdk iphonesimulator + -destination 'platform=iOS Simulator,name=iPhone 6,OS=latest' + -project MagicalRecord.xcodeproj + -scheme "libMagicalRecord for iOS" + build test + - xcodebuild + -resultBundlePath "$CIRCLE_TEST_REPORTS/xcode/results-osx-dynamic-library" + CODE_SIGNING_REQUIRED=NO + CODE_SIGN_IDENTITY= + PROVISIONING_PROFILE= + -sdk macosx + -project MagicalRecord.xcodeproj + -scheme "libMagicalRecord for OS X" + build test