Showing preview only (1,131K chars total). Download the full file or copy to clipboard to get everything.
Repository: magicalpanda/MagicalRecord
Branch: master
Commit: 6031f608b79c
Files: 244
Total size: 1.0 MB
Directory structure:
gitextract_odjxe54k/
├── .clang-format
├── .cocoadocs.yml
├── .gitignore
├── .travis.yml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── Docs/
│ ├── Creating-Entities.md
│ ├── Deleting-Entities.md
│ ├── Fetching-Entities.md
│ ├── Getting-Started.md
│ ├── Importing-Data.md
│ ├── Installing-MagicalRecord.md
│ ├── Logging.md
│ ├── Other-Resources.md
│ ├── Saving-Entities.md
│ ├── Threads.md
│ └── Working-with-Managed-Object-Contexts.md
├── LICENSE
├── MagicalRecord/
│ ├── Categories/
│ │ ├── DataImport/
│ │ │ ├── MagicalImportFunctions.h
│ │ │ ├── MagicalImportFunctions.m
│ │ │ ├── NSAttributeDescription+MagicalDataImport.h
│ │ │ ├── NSAttributeDescription+MagicalDataImport.m
│ │ │ ├── NSEntityDescription+MagicalDataImport.h
│ │ │ ├── NSEntityDescription+MagicalDataImport.m
│ │ │ ├── NSNumber+MagicalDataImport.h
│ │ │ ├── NSNumber+MagicalDataImport.m
│ │ │ ├── NSObject+MagicalDataImport.h
│ │ │ ├── NSObject+MagicalDataImport.m
│ │ │ ├── NSRelationshipDescription+MagicalDataImport.h
│ │ │ ├── NSRelationshipDescription+MagicalDataImport.m
│ │ │ ├── NSString+MagicalDataImport.h
│ │ │ └── NSString+MagicalDataImport.m
│ │ ├── NSManagedObject/
│ │ │ ├── NSManagedObject+MagicalAggregation.h
│ │ │ ├── NSManagedObject+MagicalAggregation.m
│ │ │ ├── NSManagedObject+MagicalDataImport.h
│ │ │ ├── NSManagedObject+MagicalDataImport.m
│ │ │ ├── NSManagedObject+MagicalFinders.h
│ │ │ ├── NSManagedObject+MagicalFinders.m
│ │ │ ├── NSManagedObject+MagicalRecord.h
│ │ │ ├── NSManagedObject+MagicalRecord.m
│ │ │ ├── NSManagedObject+MagicalRequests.h
│ │ │ └── NSManagedObject+MagicalRequests.m
│ │ ├── NSManagedObjectContext/
│ │ │ ├── NSManagedObjectContext+MagicalChainSave.h
│ │ │ ├── NSManagedObjectContext+MagicalChainSave.m
│ │ │ ├── NSManagedObjectContext+MagicalObserving.h
│ │ │ ├── NSManagedObjectContext+MagicalObserving.m
│ │ │ ├── NSManagedObjectContext+MagicalRecord.h
│ │ │ ├── NSManagedObjectContext+MagicalRecord.m
│ │ │ ├── NSManagedObjectContext+MagicalSaves.h
│ │ │ ├── NSManagedObjectContext+MagicalSaves.m
│ │ │ ├── NSManagedObjectContext+MagicalThreading.h
│ │ │ └── NSManagedObjectContext+MagicalThreading.m
│ │ ├── NSManagedObjectModel+MagicalRecord.h
│ │ ├── NSManagedObjectModel+MagicalRecord.m
│ │ ├── NSPersistentStore+MagicalRecord.h
│ │ ├── NSPersistentStore+MagicalRecord.m
│ │ ├── NSPersistentStoreCoordinator+MagicalRecord.h
│ │ └── NSPersistentStoreCoordinator+MagicalRecord.m
│ ├── Core/
│ │ ├── MagicalRecord+Actions.h
│ │ ├── MagicalRecord+Actions.m
│ │ ├── MagicalRecord+ErrorHandling.h
│ │ ├── MagicalRecord+ErrorHandling.m
│ │ ├── MagicalRecord+Options.h
│ │ ├── MagicalRecord+Options.m
│ │ ├── MagicalRecord+Setup.h
│ │ ├── MagicalRecord+Setup.m
│ │ ├── MagicalRecord+ShorthandMethods.h
│ │ ├── MagicalRecord+ShorthandMethods.m
│ │ ├── MagicalRecord+iCloud.h
│ │ ├── MagicalRecord+iCloud.m
│ │ ├── MagicalRecordDeprecationMacros.h
│ │ ├── MagicalRecordInternal.h
│ │ ├── MagicalRecordInternal.m
│ │ ├── MagicalRecordLogging.h
│ │ ├── MagicalRecordShorthandMethodAliases.h
│ │ └── MagicalRecordXcode7CompatibilityMacros.h
│ └── MagicalRecord.h
├── MagicalRecord.podspec
├── MagicalRecord.xcodeproj/
│ ├── project.pbxproj
│ └── xcshareddata/
│ └── xcschemes/
│ ├── MagicalRecord for OS X.xcscheme
│ ├── MagicalRecord for iOS.xcscheme
│ ├── MagicalRecord for tvOS.xcscheme
│ ├── libMagicalRecord for OS X.xcscheme
│ ├── libMagicalRecord for iOS.xcscheme
│ └── libMagicalRecord for tvOS.xcscheme
├── README.md
├── Samples/
│ └── iOS/
│ ├── Application/
│ │ ├── Categories/
│ │ │ ├── ImageToDataTransformer.h
│ │ │ └── ImageToDataTransformer.m
│ │ ├── Controllers/
│ │ │ ├── AddressBook_Prefix.pch
│ │ │ ├── EditingTableViewCell.h
│ │ │ ├── EditingTableViewCell.m
│ │ │ ├── ImperialPickerController.h
│ │ │ ├── ImperialPickerController.m
│ │ │ ├── IngredientDetailViewController.h
│ │ │ ├── IngredientDetailViewController.m
│ │ │ ├── InstructionsViewController.h
│ │ │ ├── InstructionsViewController.m
│ │ │ ├── MetricPickerController.h
│ │ │ ├── MetricPickerController.m
│ │ │ ├── RecipeAddViewController.h
│ │ │ ├── RecipeAddViewController.m
│ │ │ ├── RecipeDetailViewController.h
│ │ │ ├── RecipeDetailViewController.m
│ │ │ ├── RecipeListTableViewController.h
│ │ │ ├── RecipeListTableViewController.m
│ │ │ ├── RecipePhotoViewController.h
│ │ │ ├── RecipePhotoViewController.m
│ │ │ ├── RecipeTableViewCell.h
│ │ │ ├── RecipeTableViewCell.m
│ │ │ ├── TemperatureCell.h
│ │ │ ├── TemperatureCell.m
│ │ │ ├── TemperatureConverterViewController.h
│ │ │ ├── TemperatureConverterViewController.m
│ │ │ ├── TypeSelectionViewController.h
│ │ │ ├── TypeSelectionViewController.m
│ │ │ ├── UnitConverterTableViewController.h
│ │ │ ├── UnitConverterTableViewController.m
│ │ │ ├── WeightConverterViewController.h
│ │ │ └── WeightConverterViewController.m
│ │ ├── Delegate/
│ │ │ ├── MGPRecipesAppDelegate.h
│ │ │ └── MGPRecipesAppDelegate.m
│ │ ├── Models/
│ │ │ ├── Recipes.xcdatamodeld/
│ │ │ │ ├── .xccurrentversion
│ │ │ │ ├── Recipes 2.xcdatamodel/
│ │ │ │ │ ├── elements
│ │ │ │ │ └── layout
│ │ │ │ └── Recipes.xcdatamodel/
│ │ │ │ ├── elements
│ │ │ │ └── layout
│ │ │ ├── entities/
│ │ │ │ ├── Ingredient.h
│ │ │ │ ├── Ingredient.m
│ │ │ │ ├── Recipe.h
│ │ │ │ └── Recipe.m
│ │ │ └── generated/
│ │ │ ├── _Ingredient.h
│ │ │ ├── _Ingredient.m
│ │ │ ├── _Recipe.h
│ │ │ └── _Recipe.m
│ │ ├── Support/
│ │ │ ├── Recipes-Info.plist
│ │ │ ├── Recipes-Prefix.pch
│ │ │ ├── en.lproj/
│ │ │ │ └── InfoPlist.strings
│ │ │ └── main.m
│ │ └── Views/
│ │ ├── DetailHeaderView.xib
│ │ ├── EditingTableViewCell.xib
│ │ ├── InstructionsView.xib
│ │ ├── MainWindow.xib
│ │ ├── RecipeAddView.xib
│ │ ├── TemperatureCell.xib
│ │ ├── TemperatureConverter.xib
│ │ └── WeightConverter.xib
│ ├── MagicalRecordRecipes.xcodeproj/
│ │ └── project.pbxproj
│ └── Resources/
│ ├── RecipeData/
│ │ └── TemperatureData.plist
│ └── images/
│ └── iTunesArtwork
├── Support/
│ ├── Info.plist
│ └── Scripts/
│ ├── GenerateShorthandAliases.rb
│ ├── push_podspec.sh
│ └── set_version_information.sh
└── Tests/
├── Core/
│ ├── MagicalRecord+ActionsTests.m
│ ├── MagicalRecord+ShorthandTests.m
│ ├── MagicalRecord+StackTests.m
│ ├── MagicalRecordTestBase.h
│ ├── MagicalRecordTestBase.m
│ ├── NSManagedObject+MagicalRecordTests.m
│ ├── NSManagedObject+MagicalRequestTests.m
│ ├── NSManagedObjectContext+ChainSaveTests.m
│ ├── NSManagedObjectContext+MagicalSavesTests.m
│ ├── NSManagedObjectContextHelperTests.m
│ ├── NSManagedObjectHelperTests.m
│ ├── NSPersistentStoreCoordinatorHelperTests.m
│ └── NSPersistentStoreHelperTests.m
├── DataImport/
│ ├── ImportMultipleEntitiesWithNoPrimaryKeyTests.m
│ ├── ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m
│ ├── ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m
│ ├── ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m
│ ├── ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m
│ ├── ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m
│ ├── ImportSingleEntityWithNoRelationshipsTests.m
│ ├── ImportSingleRelatedEntityTests.m
│ ├── MagicalDataImportTestCase.h
│ └── MagicalDataImportTestCase.m
├── Fixtures/
│ ├── FixtureHelpers.h
│ ├── FixtureHelpers.m
│ ├── ImportSingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeysTests.m
│ ├── MultipleEntitiesWithNoPrimaryKey.json
│ ├── SampleJSONDataForImport.json
│ ├── SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json
│ ├── SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json
│ ├── SingleEntityRelatedToMappedEntityUsingDefaults.json
│ ├── SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json
│ ├── SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json
│ ├── SingleEntityRelatedToMappedEntityWithSecondaryMappings.json
│ ├── SingleEntityWithNoRelationships.json
│ ├── SingleEntityWithNoRelationships.plist
│ ├── SingleRelatedEntity.json
│ ├── TestModel/
│ │ ├── AbstractRelatedEntity.h
│ │ ├── AbstractRelatedEntity.m
│ │ ├── ConcreteRelatedEntity.h
│ │ ├── ConcreteRelatedEntity.m
│ │ ├── DifferentClassNameMapping.h
│ │ ├── DifferentClassNameMapping.m
│ │ ├── EntityWithoutEntityNameMethod.h
│ │ ├── EntityWithoutEntityNameMethod.m
│ │ ├── MappedEntity.h
│ │ ├── MappedEntity.m
│ │ ├── SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.h
│ │ ├── SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m
│ │ ├── SingleEntityRelatedToMappedEntityUsingDefaults.h
│ │ ├── SingleEntityRelatedToMappedEntityUsingDefaults.m
│ │ ├── SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.h
│ │ ├── SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m
│ │ ├── SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.h
│ │ ├── SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m
│ │ ├── SingleEntityRelatedToMappedEntityWithSecondaryMappings.h
│ │ ├── SingleEntityRelatedToMappedEntityWithSecondaryMappings.m
│ │ ├── SingleEntityWithNoRelationships.h
│ │ ├── SingleEntityWithNoRelationships.m
│ │ ├── SingleRelatedEntity.h
│ │ ├── SingleRelatedEntity.m
│ │ ├── _AbstractRelatedEntity.h
│ │ ├── _AbstractRelatedEntity.m
│ │ ├── _ConcreteRelatedEntity.h
│ │ ├── _ConcreteRelatedEntity.m
│ │ ├── _DifferentClassNameMapping.h
│ │ ├── _DifferentClassNameMapping.m
│ │ ├── _MappedEntity.h
│ │ ├── _MappedEntity.m
│ │ ├── _SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.h
│ │ ├── _SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m
│ │ ├── _SingleEntityRelatedToMappedEntityUsingDefaults.h
│ │ ├── _SingleEntityRelatedToMappedEntityUsingDefaults.m
│ │ ├── _SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.h
│ │ ├── _SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m
│ │ ├── _SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.h
│ │ ├── _SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m
│ │ ├── _SingleEntityRelatedToMappedEntityWithSecondaryMappings.h
│ │ ├── _SingleEntityRelatedToMappedEntityWithSecondaryMappings.m
│ │ ├── _SingleEntityWithNoRelationships.h
│ │ ├── _SingleEntityWithNoRelationships.m
│ │ ├── _SingleRelatedEntity.h
│ │ └── _SingleRelatedEntity.m
│ └── TestModel.xcdatamodeld/
│ └── TestModel.xcdatamodel/
│ └── contents
└── Support/
├── MagicalRecordTestHelpers.h
├── MagicalRecordTestHelpers.m
├── MagicalRecordTests-OSX-Info.plist
├── MagicalRecordTests-OSX-Prefix.pch
├── MagicalRecordTests-iOS-Info.plist
├── MagicalRecordTests-iOS-Prefix.pch
└── MagicalRecordTests-tvOS-Info.plist
================================================
FILE CONTENTS
================================================
================================================
FILE: .clang-format
================================================
BasedOnStyle: Chromium
AlignTrailingComments: true
BraceWrapping:
AfterClass: true
AfterControlStatement: true
AfterEnum: true
AfterFunction: true
AfterNamespace: true
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: false
BeforeCatch: true
BeforeElse: true
IndentBraces: false
BreakBeforeBraces: Allman
ColumnLimit: 0
IndentCaseLabels: true
IndentWidth: 4
KeepEmptyLinesAtTheStartOfBlocks: false
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBlockIndentWidth: 4
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true
PointerAlignment: Right
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Auto
TabWidth: 4
UseTab: Never
================================================
FILE: .cocoadocs.yml
================================================
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
================================================
FILE: .gitignore
================================================
# Finder
.DS_Store
# Xcode
build/*
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
*.xcworkspace
!default.xcworkspace
xcuserdata
profile
*.moved-aside
DerivedData
Carthage/Build
*.gcno
*.gcda
MagicalRecord.framework.zip
================================================
FILE: .travis.yml
================================================
language: objective-c
xcode_project: MagicalRecord.xcodeproj
matrix:
include:
- osx_image: xcode11.1
xcode_scheme: MagicalRecord for iOS
xcode_destination: platform=iOS Simulator,OS=13.1,name=iPhone 11 Pro Max
env: DEVICE="iPhone 11 Pro Max (13.1)"
- osx_image: xcode11.1
xcode_scheme: libMagicalRecord for iOS
xcode_destination: platform=iOS Simulator,OS=13.1,name=iPhone 11 Pro Max
env: DEVICE="iPhone 11 Pro Max (13.1)"
- osx_image: xcode10.3
xcode_scheme: MagicalRecord for iOS
xcode_destination: platform=iOS Simulator,OS=12.4,name=iPhone Xʀ
env: DEVICE="iPhone Xʀ (12.4)"
- osx_image: xcode10.3
xcode_scheme: libMagicalRecord for iOS
xcode_destination: platform=iOS Simulator,OS=12.4,name=iPhone Xʀ
env: DEVICE="iPhone Xʀ (12.4)"
#- osx_image: xcode10.3
# xcode_scheme: MagicalRecord for iOS
# xcode_destination: platform=iOS Simulator,OS=11.4,name=iPhone X
# env: DEVICE="iPhone X (11.4)"
#- osx_image: xcode10.3
# xcode_scheme: libMagicalRecord for iOS
# xcode_destination: platform=iOS Simulator,OS=11.4,name=iPhone X
# env: DEVICE="iPhone X (11.4)"
#- osx_image: xcode10.3
# xcode_scheme: MagicalRecord for iOS
# xcode_destination: platform=iOS Simulator,OS=10.3.1,name=iPhone 7 Plus
# env: DEVICE="iPhone 7 Plus (10.3.1)"
#- osx_image: xcode10.3
# xcode_scheme: libMagicalRecord for iOS
# xcode_destination: platform=iOS Simulator,OS=10.3.1,name=iPhone 7 Plus
# env: DEVICE="iPhone 7 Plus (10.3.1)"
#- osx_image: xcode10.3
# xcode_scheme: MagicalRecord for iOS
# xcode_destination: platform=iOS Simulator,OS=9.3,name=iPhone 6s Plus
# env: DEVICE="iPhone 6s Plus (9.3)"
#- osx_image: xcode10.3
# xcode_scheme: libMagicalRecord for iOS
# xcode_destination: platform=iOS Simulator,OS=9.3,name=iPhone 6s Plus
# env: DEVICE="iPhone 6s Plus (9.3)"
- osx_image: xcode10.1
xcode_scheme: MagicalRecord for iOS
xcode_destination: platform=iOS Simulator,OS=8.1,name=iPhone 4s
env: DEVICE="iPhone 4s (8.1)"
- osx_image: xcode10.1
xcode_scheme: libMagicalRecord for iOS
xcode_destination: platform=iOS Simulator,OS=8.1,name=iPhone 4s
env: DEVICE="iPhone 4s (8.1)"
- osx_image: xcode11.1
xcode_scheme: MagicalRecord for OS X
xcode_destination: platform=macOS
env: DEVICE="OS X 10.15"
- osx_image: xcode11.1
xcode_scheme: libMagicalRecord for OS X
xcode_destination: platform=macOS
env: DEVICE="OS X 10.15"
#- osx_image: xcode10.3
# xcode_scheme: MagicalRecord for OS X
# xcode_destination: platform=macOS
# env: DEVICE="OS X 10.14"
#- osx_image: xcode10.3
# xcode_scheme: libMagicalRecord for OS X
# xcode_destination: platform=macOS
# env: DEVICE="OS X 10.14"
#- osx_image: xcode9.4
# xcode_scheme: MagicalRecord for OS X
# xcode_destination: platform=macOS
# env: DEVICE="OS X 10.13"
#- osx_image: xcode9.4
# xcode_scheme: libMagicalRecord for OS X
# xcode_destination: platform=macOS
# env: DEVICE="OS X 10.13"
#- osx_image: xcode8.3
# xcode_scheme: MagicalRecord for OS X
# xcode_destination: platform=macOS
# env: DEVICE="OS X 10.12"
#- osx_image: xcode8.3
# xcode_scheme: libMagicalRecord for OS X
# xcode_destination: platform=macOS
# env: DEVICE="OS X 10.12"
- osx_image: xcode7.3
xcode_scheme: MagicalRecord for OS X
xcode_destination: platform=OS X
env: DEVICE="OS X 10.11"
- osx_image: xcode7.3
xcode_scheme: libMagicalRecord for OS X
xcode_destination: platform=OS X
env: DEVICE="OS X 10.11"
- osx_image: xcode11.1
xcode_scheme: MagicalRecord for tvOS
xcode_destination: platform=tvOS Simulator,OS=13.0,name=Apple TV 4K (at 1080p)
env: DEVICE="Apple TV 4K (at 1080p) (13.0)"
- osx_image: xcode11.1
xcode_scheme: libMagicalRecord for tvOS
xcode_destination: platform=tvOS Simulator,OS=13.0,name=Apple TV 4K (at 1080p)
env: DEVICE="Apple TV 4K (at 1080p) (13.0)"
# Xcode 7.3 gives "Platform 'appletvos' is not yet supported.", so we use Xcode 8.0 as minimal requirement
- osx_image: xcode8.0
xcode_scheme: MagicalRecord for tvOS
xcode_destination: platform=tvOS Simulator,OS=9.0,name=Apple TV 1080p
env: DEVICE="Apple TV 1080p (9.0)"
# Xcode 7.3 gives "Platform 'appletvos' is not yet supported.", so we use Xcode 8.0 as minimal requirement
- osx_image: xcode8.0
xcode_scheme: libMagicalRecord for tvOS
xcode_destination: platform=tvOS Simulator,OS=9.0,name=Apple TV 1080p
env: DEVICE="Apple TV 1080p (9.0)"
env:
global:
- FRAMEWORK_NAME=MagicalRecord
- secure: WIm8vwQHOrBPCkWGmV0YMV+k92Dva6ORd0hfi96UzGRC/FTghzrelvLmTzr5kJXCeStv5ZxCNCUvJZm8q4J4y+6UdMQu5FPnx4+EKoogC4quJV8H1pXlXmoetITQdK7t2ldRH1EOuELdmpx2g5hydinu5Z5KMHb0vgLqtn9PvAc=
# before_script:
# - carthage bootstrap
before_deploy:
- carthage build --no-skip-current
- carthage archive $FRAMEWORK_NAME
deploy:
provider: script
script: ./Support/Scripts/push_podspec.sh
on:
repo: magicalpanda/MagicalRecord
tags: true
deploy:
provider: releases
api_key:
secure: 1exCONwRvGbV+hi1N4n1VSbqJYpOaJW9zloj17Lxx14dQCyv7p2cSwB79A3RVOifJQg9pgC7eeyn4njKaIB9SZiDznhAiUlvFhNcuOdVrwmjqyxiYFByXNr4f0GVa7opIn9s/WDqGW8qQUQSOdoql5U9B/n5Mt86Jt5cws1BoYE=
file: "$FRAMEWORK_NAME.framework.zip"
skip_cleanup: true
on:
repo: magicalpanda/MagicalRecord
tags: true
================================================
FILE: CHANGELOG.md
================================================
# Changelog
## Version 2.4.0
* Adding tvOS support (Cœur, #1362)
* Adding watchOS support, CocoaPods only (Cœur, #1363)
* Updating CocoaLumberjack for 3.x support (LaurentiuUngur, #1352)
* Fix date format parsing when local isn't US (Cœur, #964)
* Importing 'NSNull' for relationship sets its value to 'nil' instead of ignoring it. (burczyk, #1194)
* Fix honouring multiple sort flags (deanWombourne, #1251)
* CGFloat precision for `MR_colorFromString()` (Cœur, #1324)
* To allow custom options like Data Protection level on the Core Data store files, we expose `MR_coordinatorWithSqliteStoreNamed:withOptions:` and `MR_coordinatorWithAutoMigratingSqliteStoreNamed:withOptions:` (leslie-lei, #1185)
* Documentation in Swift (ssuhanov, #1295)
* Removed obsolete expecta matchers for tests (Cœur)
* Fixed and improved CI tests (Cœur)
## Version 2.3.2
This release fixes an issue where the OS X framework was being built with instrumentation data, and included in the binary builds posted to GitHub. It contains no other fixes over MagicalRecord v2.3.1.
## Version 2.3.1
- CocoaPods users who want to use:
- Shorthand method aliases should add `pod 'MagicalRecord/ShorthandMethodAliases'` to their Podfile, and run `pod update`
- CocoaLumberjack should add `pod 'MagicalRecord/CocoaLumberjack'` to their Podfile, and run `pod update`
- Fixed a Core Data multithreading violation when setting a context's working name
- Fixed the check for whether `NSPersistentStoreUbiquitousContentNameKey` is valid when using iCloud containers
- Attempting to delete a `nil` managed object, or a managed object not present in the context will do nothing (previously it crashed)
- Add a fix for CocoaLumberjack reporting duplicate definitions of LOG_MAYBE
- Added error logging when the passed value for `relatedByAttribute` is invalid during a relationship import
- Added more lightweight generics and nullability annotations
## 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 <MagicalRecord/MagicalRecord.h>
#import <MagicalRecord/MagicalRecord+ShorthandMethods.h>
#import <MagicalRecord/MagicalRecordShorthandMethodAliases.h>
```
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
* Using contextDidSave notifications to perform merges - r-peck
* Included CoreDataRecipies sample application updated to use Magical Record - [Saul Mora](mailto:saul@magicalpanda.com)
## Version 2.1.0
* Fixed issue #287 - MR_findByAttribute:withValue:andOrderBy:ascending:inContext does not pass context through `4b97d0e` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Adding changelog `da70884` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Cleanup contextWillSave method Update deleting incompatible store `2eaec27` - [Saul Mora](mailto:saul@magicalpanda.com)
* don't check the error, rely only on the return value of methods to determine success `64a81c6` - [Saul Mora](mailto:saul@magicalpanda.com)
* removed MR_saveErrorHandler, as it and MR_saveWithErrorCallback were essentially duplicates MR_save now only saves the current context (it was essentially doing a MR_saveNestedContexts). If you need to save all the way out to disk, use MR_saveNestedContexts. Removed the action queue, unnecessary since core data introduced it's own queue support `f7c4350` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Separate printing context chain method into its own method change contextWorkingName to property workingName `0fb7d36` - [Saul Mora](mailto:saul@magicalpanda.com)
* Added fetchAllWithDelegate: method for NSFRC `c0a1657` - [Saul Mora](mailto:saul@magicalpanda.com)
* Fixed Issue #294 - MR_requestAllSortedBy:ascending:inContext: did not use correct context `3656e74` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Bumping podspec version `fb81b5b` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Updating changelog `20f02ba` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Re-Added obtaining permanent ids automatically `cfccd40` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Minor formatting updates `1440623` - [Saul Mora](mailto:saul@magicalpanda.com)
* Pass errorCallback through convenience method `5376700` - [Tony Arnold](mailto:tony@thecocoabots.com)
* Implement new save methods `4f35e4e` - [Tony Arnold](mailto:tony@thecocoabots.com)
* Update existing save tests to reflect save changes. Also begin adding tests for deprecated methods to ensure consistent behaviour in unmodified code. `c763d4a` - [Tony Arnold](mailto:tony@thecocoabots.com)
* Fix compilation problems under latest Xcode. `af84aff` - [Tony Arnold](mailto:tony@thecocoabots.com)
* Update gitignore and remove user specific xcuserdata `d0e771d` - [Tony Arnold](mailto:tony@thecocoabots.com)
* Add Kiwi for saner asynchronous testing and remove existing GHUnit tests for save methods `55af799` - [Tony Arnold](mailto:tony@thecocoabots.com)
* Flesh out tests for MagicalRecord+Actions and the NSManagedObjectContext+MagicalSaves category `a28d421` - [Tony Arnold](mailto:tony@thecocoabots.com)
* The deprecated saveWithBlock: method should do it's work on the current thread `2c66056` - [Tony Arnold](mailto:tony@thecocoabots.com)
* All deprecated and non-deprecated methods have tests to ensure their function `c2fa8c4` - [Tony Arnold](mailto:tony@thecocoabots.com)
* Update README with details of the changes in this branch `4316422` - [Tony Arnold](mailto:tony@thecocoabots.com)
* Update shorthand methods and import the magical saves category so that MRSaveCompletionHandler resolves `1af1201` - [Tony Arnold](mailto:tony@thecocoabots.com)
* Updated podspec to 2.1.beta.1 `5ed45f6` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Minor text editing. `710d643` - [nerdery-isaac](mailto:isaac.greenspan@nerdery.com)
* Added additional case that will trigger persistent store cleanup `36d1630` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Alter saveWithBlock: so that it runs asynchronously. Fixes #349. `357b62e` - [Tony Arnold](mailto:tony@thecocoabots.com)
* Execute save completion blocks on the main dispatch queue. `065352d` - [Tony Arnold](mailto:tony@thecocoabots.com)
* Fix broken GHUnit tests after recent changes to the save methods `0c83121` - [Tony Arnold](mailto:tony@thecocoabots.com)
* Add Clang-style documentation for the MagicalSaves category. Also add Clang's -Wdocumentation warning to assist in writing in future documentation. `eb8865a` - [Tony Arnold](mailto:tony@thecocoabots.com)
* Remove unused notification constant `5a40bcc` - [Tony Arnold](mailto:tony@thecocoabots.com)
* Finalise documentation for MagicalRecord 2.1.0 `f370cdb` - [Tony Arnold](mailto:tony@thecocoabots.com)
* Update pod spec to MagicalRecord 2.1.0 `46b6004` - [Tony Arnold](mailto:tony@thecocoabots.com)
## Version 2.0.8
* Fixed issue #287 - MR_findByAttribute:withValue:andOrderBy:ascending:inContext does not pass context through `4b97d0e` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Adding changelog `da70884` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Cleanup contextWillSave method Update deleting incompatible store `2eaec27` - [Saul Mora](mailto:saul@magicalpanda.com)
* don't check the error, rely only on the return value of methods to determine success `64a81c6` - [Saul Mora](mailto:saul@magicalpanda.com)
* removed MR_saveErrorHandler, as it and MR_saveWithErrorCallback were essentially duplicates MR_save now only saves the current context (it was essentially do
* Separate printing context chain method into its own method change contextWorkingName to property workingName `0fb7d36` - [Saul Mora](mailto:saul@magicalpanda
* Added fetchAllWithDelegate: method for NSFRC `c0a1657` - [Saul Mora](mailto:saul@magicalpanda.com)
* Fixed Issue #294 - MR_requestAllSortedBy:ascending:inContext: did not use correct context `3656e74` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Bumping podspec version `fb81b5b` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
## 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)
* Call completion handler on main thread. - [Brandon Williams](mailto:brandon@opetopic.com)
* Persist changes to disk when using: - [NSManagedObjectContext MR_saveInBackgroundErrorHandler:completion:] methods, AND the context is the default context - [MagicalRecord saveInBackground…] methods - [Saul Mora](mailto:saul@magicalpanda.com)
* [NSManagedObjectContext MR_saveInBackgroundErrorHandler:completion:] - [Jwie](mailto:joey.daman@twoup.eu)
* [NSManagedObjectContext MR_saveInBackgroundErrorHandler:completion:] - [Jwie](mailto:joey.daman@twoup.eu)
* update - [Peter Paulis](mailto:peterpaulis@Admins- acBook-Air-2.local)
* Correct typo - [Ryan Maxwell](mailto:ryanm@xwell.co.nz)
* Update MR_SHORTHAND installation note to match main readme - [Ryan Maxwell](mailto:ryanm@xwell.co.nz)
* Correct typo of "persistent" in method name - m[Ryan Maxwell](mailto:ryanm@xwell.co.nz)
* Make all requestAllSortedBy* methods consistent (allows sortTerms with commas) - [vguerci](mailto:vguerci@gmail.com)
* dispatch_release is not needed by the <REDACTED> compiler - [Saul Mora](mailto:saul@magicalpanda.com)
* Don't run completion block if non specified - [Saul Mora](mailto:saul@magicalpanda.com)
* Make platform requirements more explicit - [Saul Mora](mailto:saul@magicalpanda.com)
* Update MagicalRecord/Core/MagicalRecordShorthand.h - [Ryan Maxwell](mailto:ryanm@xwell.co.nz)
* Added automatic store deletion if the store does not match the model - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Missed the configuration - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Updating readme with a short blurb - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Cleanup code is now debug-only - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Clarified the DEBUG only nature of the fix - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Making background save asynchronous and fix the callback not firing - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Added expecta matchers for tests - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Fixing formatting issues to match project style - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Fixed KVC relationship mapping bug. - [Joshua Greene](mailto:jrg.developer@gmail.com)
* Fixed an issue with aggregate actions not being performed in the specified context - [Brian King](mailto:bking@agamatrix.com)
* Adding an observer to check for icloud being setup after default context has been set. Should fix race condition in Issue #241 - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Updated test model to actually build - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Clean up comments - [Saul Mora](mailto:saul@magicalpanda.com)
* Remove compile warnings - [Saul Mora](mailto:saul@magicalpanda.com)
* Cleaning up iCloud setup observer code some - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Removes dispatch_release when iOS >= 6 || OSX >= 1080 - [Rod Wilhelmy](mailto:rwilhelmy@gmail.com)
* Modifiying generateShorthand.rb to use user specified ruby - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Automatically obtain permanent IDs when saving the default context. This should fix several crashes the community is hitting - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Making all relevant contexts obtain a permanent id before saving - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Adding recommended journalling mode - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* fixup compiler warnings in Xcode 4.5 - [Saul Mora](mailto:saul@magicalpanda.com)
* Fix compile warnings once and for all :/ - [Saul Mora](mailto:saul@magicalpanda.com)
* refactor internal method names to match more general objects to traverse fix another compile warning - [Saul Mora](mailto:saul@magicalpanda.com)
* - auto- igration options bug fix - [Alexander Belyavskiy](mailto:diejmon@me.com)
* Don't adjust incoming NSDates for DST - [Saul Mora](mailto:saul@magicalpanda.com)
* fix compile error with pragma option - [Saul Mora](mailto:saul@magicalpanda.com)
* Add findFirstOrderedByAttribute:ascending:context: method for getting min/max values easier - [Saul Mora](mailto:saul@magicalpanda.com)
* Bumping podspec to 2.0.4 - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Added new nestedContextSave method with completion handler - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Bumping podspec with bugfix - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Fixing rookie mistake :/ - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Require ARC in podspec (was compiling with retain/release in pod installations) - [Ryan Maxwell](mailto:ryanm@xwell.co.nz)
* Bump tag to 2.0.6 - [Ryan Maxwell](mailto:ryanm@xwell.co.nz)
* Properly removing existing on-save notifications before replacing the default or root contexts - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Fixing potential concurrency issue with creating the actionQueue - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Cherry picking changes that make the context description more... descriptive - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Rolled back a commit that broke things if cleanup was used. It created the action_queue in a dispatch_once block, and never recreated it after a cleanup - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* saveWithBlock was not saving parent contexts - [Tony Arnold](mailto:tony@thecocoabots.com)
* Test that the current thread saveWith method actually saves - [Tony Arnold](mailto:tony@thecocoabots.com)
* Bumped podspec to 2.0.7 - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
================================================
FILE: CONTRIBUTING.md
================================================
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](https://stackoverflow.com/). We monitor the [**MagicalRecord** tag](https://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.
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](https://github.com/magicalpanda/MagicalRecord/wiki/Coding-Conventions).
Thanks for reading the guidelines!
================================================
FILE: Docs/Creating-Entities.md
================================================
# Creating Entities
To create and insert a new instance of an Entity in the default context, you can use:
```objective-c
// Objective-C
Person *myPerson = [Person MR_createEntity];
```
```swift
// Swift
let myPerson = Person.mr_createEntity()
```
To create and insert an entity into specific context:
```objective-c
// Objective-C
Person *myPerson = [Person MR_createEntityInContext:otherContext];
```
```swift
// Swift
let myPerson = Person.mr_createEntity(in: otherContext)
```
================================================
FILE: Docs/Deleting-Entities.md
================================================
# Deleting Entities
To delete a single entity in the default context:
```objective-c
// Objective-C
[myPerson MR_deleteEntity];
```
```swift
// Swift
myPerson.mr_deleteEntity()
```
To delete the entity from a specific context:
```objective-c
// Objective-C
[myPerson MR_deleteEntityInContext:otherContext];
```
```swift
// Swift
myPerson.mr_deleteEntity(in: otherContext)
```
To truncate all entities from the default context:
```objective-c
// Objective-C
[Person MR_truncateAll];
```
```swift
// Swift
Person.mr_truncateAll()
```
To truncate all entities in a specific context:
```objective-c
// Objective-C
[Person MR_truncateAllInContext:otherContext];
```
```swift
// Swift
Person.mr_truncateAll(in: otherContext)
```
================================================
FILE: Docs/Fetching-Entities.md
================================================
# 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](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreData/nsfetchedresultscontroller.html)), you can retrieve all of the *Person* entities from your persistent store using the following method:
```objective-c
// Objective-C
NSArray *people = [Person MR_findAll];
```
```swift
// Swift
let people = Person.mr_findAll()
```
To return the same entities sorted by a specific attribute:
```objective-c
// Objective-C
NSArray *peopleSorted = [Person MR_findAllSortedBy:@"LastName"
ascending:YES];
```
```swift
// Swift
let peopleSorted = Person.mr_findAllSorted(by: "LastName", ascending: true)
```
To return the entities sorted by multiple attributes:
```objective-c
// Objective-C
NSArray *peopleSorted = [Person MR_findAllSortedBy:@"LastName,FirstName"
ascending:YES];
```
```swift
// Swift
let peopleSorted = Person.mr_findAllSorted(by: "LastName,FirstName", ascending: true)
```
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
// Objective-C
NSArray *peopleSorted = [Person MR_findAllSortedBy:@"LastName:NO,FirstName"
ascending:YES];
// OR
NSArray *peopleSorted = [Person MR_findAllSortedBy:@"LastName,FirstName:YES"
ascending:NO];
```
```swift
// Swift
let peopleSorted = Person.mr_findAllSorted(by: "LastName:NO,FirstName", ascending: true)
// OR
let peopleSorted = Person.mr_findAllSorted(by: "LastName,FirstName:YES", ascending: false)
```
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
// Objective-C
Person *person = [Person MR_findFirstByAttribute:@"FirstName"
withValue:@"Forrest"];
```
```swift
// Swift
let person = Person.mr_findFirst(byAttribute: "FirstName", withValue: "Forrest")
```
#### Advanced Finding
If you want to be more specific with your search, you can use a predicate:
```objective-c
// Objective-C
NSPredicate *peopleFilter = [NSPredicate predicateWithFormat:@"Department IN %@", @[dept1, dept2]];
NSArray *people = [Person MR_findAllWithPredicate:peopleFilter];
```
```swift
// Swift
let peopleFilter = NSPredicate(format: "Department IN %@", [dept1, dept2])
let people = Person.mr_findAll(with: peopleFilter)
```
#### Returning an NSFetchRequest
```objective-c
// Objective-C
NSPredicate *peopleFilter = [NSPredicate predicateWithFormat:@"Department IN %@", departments];
NSFetchRequest *people = [Person MR_requestAllWithPredicate:peopleFilter];
```
```swift
// Swift
let peopleFilter = NSPredicate(format: "Department IN %@", departments)
let people = Person.mr_requestAll(with: peopleFilter)
```
For each of these single line calls, an `NSFetchRequest` and `NSSortDescriptor`s for any sorting criteria are created.
#### Customizing the Request
```objective-c
// Objective-C
NSPredicate *peopleFilter = [NSPredicate predicateWithFormat:@"Department IN %@", departments];
NSFetchRequest *peopleRequest = [Person MR_requestAllWithPredicate:peopleFilter];
[peopleRequest setReturnsDistinctResults:NO];
[peopleRequest setPropertiesToFetch:@[@"FirstName", @"LastName"]];
NSArray *people = [Person MR_executeFetchRequest:peopleRequest];
```
```swift
// Swift
let peopleFilter = NSPredicate(format: "Department IN %@", departments)
let peopleRequest = Person.mr_requestAll(with: peopleFilter)
peopleRequest.returnsDistinctResults = false
peopleRequest.propertiesToFetch = ["FirstName", "LastName"]
let people = Person.mr_executeFetchRequest(peopleRequest)
```
#### Find excluding subentities
To fetch all sorted, excluding subentities:
```objective-c
// Objective-C
NSFetchRequest *peopleRequest = [Person MR_requestAllSortedBy:@"LastName" ascending:YES withPredicate:nil];
NSFetchedResultsController *controller = [Person MR_fetchController:peopleRequest delegate:nil useFileCache:NO groupedBy:nil inContext:[NSManagedObjectContext MR_defaultContext]];
controller.fetchRequest.includesSubentities = NO;
[Person MR_performFetch:controller];
NSArray *people = controller.fetchedObjects;
```
```swift
// Swift
let peopleRequest = Person.mr_requestAllSorted(by: "LastName", ascending: true, with: nil)
let controller = Person.mr_fetchController(peopleRequest, delegate: nil, useFileCache: false, groupedBy: nil, in: NSManagedObjectContext.mr_default())
controller.fetchRequest.includesSubentities = false
Person.mr_performFetch(controller)
let people = controller.fetchedObjects
```
Note: `MR_defaultContext`/`mr_default()` is for main thread. See `Working-with-Managed-Object-Contexts.md` for other contexts.
#### Find the number of entities
You can also perform a count of all entities of a specific type in your persistent store:
```objective-c
// Objective-C
NSNumber *count = [Person MR_numberOfEntities];
```
```swift
// Swift
let count = Person.mr_numberOfEntities()
```
Or, if you're looking for a count of entities based on a predicate or some filter:
```objective-c
// Objective-C
NSNumber *count = [Person MR_numberOfEntitiesWithPredicate:...];
```
```swift
// Swift
let count = Person.mr_numberOfEntities(with: ...)
```
There are also complementary methods which return `NSUInteger` (`UInt` in Swift) rather than `NSNumber` instances:
```objective-c
// Objective-C
+ (NSUInteger) MR_countOfEntities;
+ (NSUInteger) MR_countOfEntitiesWithContext:(NSManagedObjectContext *)context;
+ (NSUInteger) MR_countOfEntitiesWithPredicate:(NSPredicate *)searchFilter;
+ (NSUInteger) MR_countOfEntitiesWithPredicate:(NSPredicate *)searchFilter
inContext:(NSManagedObjectContext *)context;
```
```swift
// Swift
open class func mr_countOfEntities() -> UInt
open class func mr_countOfEntities(with context: NSManagedObjectContext) -> UInt
open class func mr_countOfEntities(with searchFilter: NSPredicate?) -> UInt
open class func mr_countOfEntities(with searchFilter: NSPredicate?,
in context: NSManagedObjectContext) -> UInt
```
#### Aggregate Operations
```objective-c
// 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"];
```
```swift
// Swift
let totalCalories = CTFoodDiaryEntry.mr_aggregateOperation("sum:",
onAttribute: "calories",
with: predicate)
let mostCalories = CTFoodDiaryEntry.mr_aggregateOperation("max:",
onAttribute: "calories",
with: predicate)
let caloriesByMonth = CTFoodDiaryEntry.mr_aggregateOperation("sum:",
onAttribute: "calories",
with: 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
// Objective-C
NSArray *peopleFromAnotherContext = [Person MR_findAllInContext:someOtherContext];
Person *personFromContext = [Person MR_findFirstByAttribute:@"lastName"
withValue:@"Gump"
inContext:someOtherContext];
NSUInteger count = [Person MR_numberOfEntitiesWithContext:someOtherContext];
```
```swift
// Swift
let peopleFromAnotherContext = Person.mr_findAll(in: someOtherContext)
let personFromContext = Person.mr_findFirst(byAttribute: "lastName",
withValue: "Gump",
in: someOtherContext)
let count = Person.mr_numberOfEntities(with: someOtherContext)
```
================================================
FILE: Docs/Getting-Started.md
================================================
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 <MagicalRecord/MagicalRecord.h>
```
```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
// Objective-C
+ (void)setupCoreDataStack;
+ (void)setupAutoMigratingCoreDataStack;
+ (void)setupCoreDataStackWithInMemoryStore;
+ (void)setupCoreDataStackWithStoreNamed:(NSString *)storeName;
+ (void)setupCoreDataStackWithAutoMigratingSqliteStoreNamed:(NSString *)storeName;
+ (void)setupCoreDataStackWithStoreAtURL:(NSURL *)storeURL;
+ (void)setupCoreDataStackWithAutoMigratingSqliteStoreAtURL:(NSURL *)storeURL;
```
```swift
// Swift
open class func setupCoreDataStack()
open class func setupCoreDataStackWithInMemoryStore()
open class func setupAutoMigratingCoreDataStack()
open class func setupCoreDataStack(withStoreNamed storeName: String)
open class func setupCoreDataStack(withAutoMigratingSqliteStoreNamed storeName: String)
open class func setupCoreDataStackWithStore(at storeURL: URL)
open class func setupCoreDataStackWithAutoMigratingSqliteStore(at storeURL: URL)
```
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
// Objective-C
[MagicalRecord cleanUp];
```
```swift
// Swift
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
// 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;
```
```swift
// Swift
open class func setupCoreDataStackWithiCloudContainer(_ containerID: String,
localStoreNamed localStore: String)
open class func setupCoreDataStackWithiCloudContainer(_ containerID: String,
contentNameKey: String?,
localStoreNamed localStoreName: String,
cloudStorePathComponent pathSubcomponent: String?)
open class func setupCoreDataStackWithiCloudContainer(_ containerID: String,
contentNameKey: String?,
localStoreNamed localStoreName: String,
cloudStorePathComponent pathSubcomponent: String?,
completion: (() -> Swift.Void)? = nil)
open class func setupCoreDataStackWithiCloudContainer(_ containerID: String,
localStoreAt storeURL: URL)
open class func setupCoreDataStackWithiCloudContainer(_ containerID: String,
contentNameKey: String?,
localStoreAt storeURL: URL,
cloudStorePathComponent pathSubcomponent: String?)
open class func setupCoreDataStackWithiCloudContainer(_ containerID: String,
contentNameKey: String?,
localStoreAt storeURL: URL,
cloudStorePathComponent pathSubcomponent: String?,
completion: (() -> Swift.Void)? = nil)
```
For further details, please refer to [Apple's "iCloud Programming Guide for Core Data"](https://developer.apple.com/library/archive/documentation/DataManagement/Conceptual/UsingCoreDataWithiCloudPG/Introduction/Introduction.html).
### 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`):
================================================
FILE: Docs/Importing-Data.md
================================================
# 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.
>
> <cite>MagicalRecord Team</cite>
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.
<p align="center">
<img src="https://cl.ly/image/1e333E3W2Y3E/datamodeller_userinfogroup.png" alt="Xcode's 'User Info' group in the data modeller" width="324" height="374" style="margin: 0 auto;" />
</p>
> **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 <kbd>⌥⌘3</kbd> 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
// Objective-C
NSDictionary *contactInfo = // Result from JSON parser or some other source
Person *importedPerson = [Person MR_importFromObject:contactInfo];
```
```swift
// Swift
let contactInfo = // Dictionary from JSON parser or some other source
let importedPerson = Person.mr_import(from: contactInfo)
```
You can also use a two-stage approach:
```objective-c
// 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];
```
```swift
// Swift
let contactInfo = // Dictionary from JSON parser or some other source
if let person = Person.mr_createEntity() { // This doesn't have to be a new entity
person.mr_importValuesForKeys(with: 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
// Objective-C
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *)localContext {
Person *importedPerson = [Person MR_importFromObject:personRecord inContext:localContext];
}];
```
```swift
// Swift
MagicalRecord.save({ (localContext) in
let importedPerson = Person.mr_import(from: personRecord, in: 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
// Objective-C
NSArray *arrayOfPeopleData = /// result from JSON parser
NSArray *people = [Person MR_importFromArray:arrayOfPeopleData];
```
```swift
// Swift
let arrayOfPeopleData = /// result from JSON parser
let people = Person.mr_import(from: 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:(id)data;`<br><br>`func shouldImport(_ data: Any) -> Bool` | Called before an data is imported. Use this to cancel importing data on a specific instance of an entity by returning `NO` (`false` in Swift).
`- (void) willImport:(id)data;`<br><br>`func willImport(_ data: Any)` | Called immediately before data is imported.
`- (void) didImport:(id)data;`<br><br>`func didImport(_ data: Any)` | 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:
```objective-c
// Objective-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
```
```swift
// Swift
class MyGreatEntity: NSManagedObject {
var identifier: String?
override func didImport(_ data: Any) {
guard let dataDictionary = data as? [String: AnyObject] else {
return
}
let identifierValue = dataDictionary["my_identifier"]
if let numberValue = identifierValue as? NSNumber {
self.identifier = numberValue.stringValue
}
}
}
```
### 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
// 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];
```
```swift
// Swift
let arrayOfPeopleData = /// result from JSON parser
let people = Person.mr_import(from: arrayOfPeopleData)
let idList = arrayOfPeopleData.map { $0.id }
let predicate = NSPredicate(format: "NOT(id IN %@)", idList)
Person.mr_deleteAll(matching: 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
// 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];
}
```
```swift
// Swift
class Person: NSManagedObject {
override func willImport(_ data: Any) {
if let data = data as? [String: AnyObject],
let dataPosts = data["posts"] as? [Person] {
let idList = dataPosts.map { $0.id }
let predicate = NSPredicate(format: "NOT(id IN %@) AND person.id == %@", idList, self.id)
Post.mr_deleteAll(matching: predicate)
}
}
}
```
Source: https://stackoverflow.com/a/24252825/401092
================================================
FILE: Docs/Installing-MagicalRecord.md
================================================
# 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](https://cocoapods.org/):
1. Add the following line to your `Podfile`:
a. Plain
````ruby
pod 'MagicalRecord', :git => 'https://github.com/magicalpanda/MagicalRecord'
````
b. With CocoaLumberjack as Logger
````ruby
pod 'MagicalRecord/CocoaLumberjack', :git => 'https://github.com/magicalpanda/MagicalRecord'
````
2. In your project directory, run `pod update`
3. You should now be able to add `#import <MagicalRecord/MagicalRecord.h>` 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 <MagicalRecord/MagicalRecord.h>` 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/archive/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
// Objective-C
#import <MagicalRecord/MagicalRecord.h>
#import <MagicalRecord/MagicalRecord+ShorthandMethods.h>
#import <MagicalRecord/MagicalRecordShorthandMethodAliases.h>
```
```swift
// Swift
import MagicalRecord
```
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
// Objective-C
- (void)theMethodWhereYouSetupMagicalRecord
{
[MagicalRecord enableShorthandMethods];
// Setup MagicalRecord as per usual
}
```
```swift
// Swift
func 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.
================================================
FILE: Docs/Logging.md
================================================
## Logging
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.
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 <CocoaLumberjack/CocoaLumberjack.h>
#import <MagicalRecord/MagicalRecord.h>
```
```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`.
================================================
FILE: Docs/Other-Resources.md
================================================
# Resources
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](https://web.archive.org/web/20120702085039/http://ablfx.com/blog/2012/03/using-coredata-magicalrecord/)
* [Super Happy Easy Fetching in Core Data](http://www.cimgf.com/2011/03/13/super-happy-easy-fetching-in-core-data/)
* [Core Data and Threads, without the Headache](http://www.cimgf.com/2011/05/04/core-data-and-threads-without-the-headache/)
* [Unit Testing with Core Data](http://www.cimgf.com/2012/05/15/unit-testing-with-core-data/)
* [Using MagicalRecord with Swift](https://www.raywenderlich.com/1696-getting-started-with-magicalrecord)
================================================
FILE: Docs/Saving-Entities.md
================================================
# 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
// 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;
}];
````
````swift
// Swift
MagicalRecord.save({ (localContext) in
// Do your work to be saved here, against the `localContext` instance
// Everything you do in this block will occur on a background thread
}) { (success, error) in
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
// 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;
}];
````
````swift
// Swift
let application = UIApplication.shared
var bgTask = application.beginBackgroundTask {
application.endBackgroundTask(bgTask)
bgTask = UIBackgroundTaskInvalid
}
MagicalRecord.save({ (localContext) in
// Do your work to be saved here
}) { (success, error) in
application.endBackgroundTask(bgTask)
bgTask = UIBackgroundTaskInvalid
}
````
Be sure to carefully [read the documentation for `beginBackgroundTaskWithExpirationHandler`](https://developer.apple.com/documentation/uikit/uiapplication/1623031-beginbackgroundtaskwithexpiratio), 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
// 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"];
}];
````
````swift
// Swift
let processInfo = NSProcessInfo.processInfo()
processInfo.disableSuddenTermination()
processInfo.disableAutomaticTermination("Application is currently saving to persistent store")
MagicalRecord.save({ (localContext) in
// Do your work to be saved here
}) { (success, error) in
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/documentation/foundation/nsprocessinfo) 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](https://web.archive.org/web/20161024234224/http://saulmora.com/coredata/magicalrecord/2013/09/15/why-contextforcurrentthread-doesn-t-work-in-magicalrecord.html)".
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
// Objective-C
[MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) {
NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createEntity];
// …
}];
```
```swift
// Swift
MagicalRecord.save(blockAndWait: { (localContext) in
let inserted = SingleEntityWithNoRelationships.mr_createEntity()
// …
})
```
You should now use:
```objective-c
// Objective-C
[MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) {
NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createEntityInContext:localContext];
// …
}];
```
```swift
// Swift
MagicalRecord.save(blockAndWait: { (localContext) in
let inserted = SingleEntityWithNoRelationships.mr_createEntity(in: 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;`
================================================
FILE: Docs/Threads.md
================================================
## 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.
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
// Objective-C
Person *person; // Retrieve person entity
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
Person *localPerson = [person MR_inContext:localContext];
localPerson.firstName = @"John";
localPerson.lastName = @"Appleseed";
}];
```
```swift
// Swift
let person = Person() // Retrieve person entity
MagicalRecord.save({ (localContext) in
if let localPerson = person.mr_(in: 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
// 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];
}];
```
```swift
// Swift
let person = Person() // Retrieve person entity
MagicalRecord.save({ (localContext) in
if let localPerson = person.mr_(in: localContext) {
localPerson.firstName = "John"
localPerson.lastName = "Appleseed"
}
}) { (success, error) in
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.
================================================
FILE: Docs/Working-with-Managed-Object-Contexts.md
================================================
# Working with Managed Object Contexts
## Creating New Contexts
A variety of simple class methods are provided to help you create new contexts:
- `+ [NSManagedObjectContext MR_context]`: 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_contextWithParent:…]`: Allows you to specify the parent context that will be set. Has a concurrency type of **NSPrivateQueueConcurrencyType**.
- `+ [NSManagedObjectContext MR_contextWithStoreCoordinator:…]`: 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
// Objective-C
NSManagedObjectContext *defaultContext = [NSManagedObjectContext MR_defaultContext];
```
```swift
// Swift
let defaultContext = NSManagedObjectContext.mr_default()
```
This context will be used throughout MagicalRecord in any method that uses a context, but does not provide 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
// Objective-C
NSManagedObjectContext *myNewContext = [NSManagedObjectContext MR_context];
```
```swift
// Swift
let myNewContext = NSManagedObjectContext.mr_()
```
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
// Objective-C
[NSManagedObjectContext MR_initializeDefaultContextWithCoordinator:myNewContext.persistentStoreCoordinator];
```
```swift
// Swift
NSManagedObjectContext.mr_initializeDefaultContext(with: myNewContext.persistentStoreCoordinator!)
```
> **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
// Objective-C
Person *person = ...;
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext){
Person *localPerson = [person MR_inContext:localContext];
localPerson.firstName = @"John";
localPerson.lastName = @"Appleseed";
}];
```
```swift
// Swift
let person = ...
MagicalRecord.save({ (localContext) in
if let localPerson = person.mr_(in: 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
// 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];
}];
```
```swift
// Swift
let person = ...
MagicalRecord.save({ (localContext) in
if let localPerson = person.mr_(in: localContext) {
localPerson.firstName = "John"
localPerson.lastName = "Appleseed"
}
}) { (success, error) in
self.everyoneInTheDepartment = Person.findAll()
}
```
This completion block is called on the main thread (queue), so this is also safe for triggering UI updates.
================================================
FILE: LICENSE
================================================
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
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:
* Link to the MagicalRecord Repository at https://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
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.
================================================
FILE: MagicalRecord/Categories/DataImport/MagicalImportFunctions.h
================================================
//
// MagicalImportFunctions.h
// Magical Record
//
// Created by Saul Mora on 3/7/12.
// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
NSDate * __MR_nonnull MR_adjustDateForDST(NSDate *__MR_nonnull date);
NSDate * __MR_nonnull MR_dateFromString(NSString *__MR_nonnull value, NSString *__MR_nonnull format);
NSDate * __MR_nonnull MR_dateFromNumber(NSNumber *__MR_nonnull value, BOOL milliseconds);
NSNumber * __MR_nonnull MR_numberFromString(NSString *__MR_nonnull value);
NSString * __MR_nonnull MR_attributeNameFromString(NSString *__MR_nonnull value);
NSString * __MR_nonnull MR_primaryKeyNameFromString(NSString *__MR_nonnull value);
#if TARGET_OS_IPHONE
#import <UIKit/UIKit.h>
UIColor * __MR_nullable MR_colorFromString(NSString *__MR_nonnull serializedColor);
#else
#import <AppKit/AppKit.h>
NSColor * __MR_nullable MR_colorFromString(NSString *__MR_nonnull serializedColor);
#endif
NSInteger * __MR_nullable MR_newColorComponentsFromString(NSString *__MR_nonnull serializedColor);
================================================
FILE: MagicalRecord/Categories/DataImport/MagicalImportFunctions.m
================================================
//
// MagicalImportFunctions.m
// Magical Record
//
// Created by Saul Mora on 3/7/12.
// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved.
//
#import "MagicalImportFunctions.h"
#pragma mark - Data import helper functions
NSString * MR_attributeNameFromString(NSString *value)
{
NSString *firstCharacter = [[value substringToIndex:1] capitalizedString];
return [firstCharacter stringByAppendingString:[value substringFromIndex:1]];
}
NSString * MR_primaryKeyNameFromString(NSString *value)
{
NSString *firstCharacter = [[value substringToIndex:1] lowercaseString];
return [firstCharacter stringByAppendingFormat:@"%@ID", [value substringFromIndex:1]];
}
NSDate * MR_adjustDateForDST(NSDate *date)
{
NSTimeInterval dstOffset = [[NSTimeZone localTimeZone] daylightSavingTimeOffsetForDate:date];
NSDate *actualDate = [date dateByAddingTimeInterval:dstOffset];
return actualDate;
}
NSDate * MR_dateFromString(NSString *value, NSString *format)
{
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
[formatter setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]];
[formatter setDateFormat:format];
NSDate *parsedDate = [formatter dateFromString:value];
if (parsedDate == nil) {
// fallback to legacy behavior from MagicalRecord 2.3 and older
[formatter setLocale:[NSLocale currentLocale]];
parsedDate = [formatter dateFromString:value];
}
return parsedDate;
}
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* 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:@"(,)"];
NSInteger *componentValue = componentValues;
while (![colorScanner isAtEnd])
{
[colorScanner scanCharactersFromSet:rgbaCharacterSet intoString:nil];
[colorScanner scanInteger:componentValue];
componentValue++;
}
}
return componentValues;
}
#if TARGET_OS_IPHONE
UIColor * MR_colorFromString(NSString *serializedColor)
{
NSInteger *componentValues = MR_newColorComponentsFromString(serializedColor);
if (componentValues == NULL)
{
return nil;
}
UIColor *color = [UIColor colorWithRed:(componentValues[0] / (CGFloat)255.)
green:(componentValues[1] / (CGFloat)255.)
blue:(componentValues[2] / (CGFloat)255.)
alpha:componentValues[3]];
free(componentValues);
return color;
}
#else
NSColor * MR_colorFromString(NSString *serializedColor)
{
NSInteger *componentValues = MR_newColorComponentsFromString(serializedColor);
if (componentValues == NULL)
{
return nil;
}
NSColor *color = [NSColor colorWithDeviceRed:(componentValues[0] / (CGFloat)255.)
green:(componentValues[1] / (CGFloat)255.)
blue:(componentValues[2] / (CGFloat)255.)
alpha:componentValues[3]];
free(componentValues);
return color;
}
#endif
================================================
FILE: MagicalRecord/Categories/DataImport/NSAttributeDescription+MagicalDataImport.h
================================================
//
// NSAttributeDescription+MagicalDataImport.h
// Magical Record
//
// Created by Saul Mora on 9/4/11.
// Copyright 2011 Magical Panda Software LLC. All rights reserved.
//
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@interface NSAttributeDescription (MagicalRecord_DataImport)
- (MR_nullable NSString *) MR_primaryKey;
- (MR_nullable id) MR_valueForKeyPath:(MR_nonnull NSString *)keyPath fromObjectData:(MR_nonnull id)objectData;
@end
================================================
FILE: MagicalRecord/Categories/DataImport/NSAttributeDescription+MagicalDataImport.m
================================================
//
// NSAttributeDescription+MagicalDataImport.m
// Magical Record
//
// Created by Saul Mora on 9/4/11.
// Copyright 2011 Magical Panda Software LLC. All rights reserved.
//
#import "NSAttributeDescription+MagicalDataImport.h"
#import "NSManagedObject+MagicalDataImport.h"
#import "MagicalImportFunctions.h"
@implementation NSAttributeDescription (MagicalRecord_DataImport)
- (NSString *) MR_primaryKey
{
return nil;
}
- (id) MR_valueForKeyPath:(NSString *)keyPath fromObjectData:(id)objectData
{
id value = [objectData valueForKeyPath:keyPath];
NSAttributeType attributeType = [self attributeType];
NSString *desiredAttributeType = [[self userInfo] objectForKey:kMagicalRecordImportAttributeValueClassNameKey];
if (desiredAttributeType)
{
if ([desiredAttributeType hasSuffix:@"Color"])
{
value = MR_colorFromString(value);
}
}
else
{
if (attributeType == NSDateAttributeType)
{
if (![value isKindOfClass:[NSDate class]])
{
NSString *dateFormat = [[self userInfo] objectForKey:kMagicalRecordImportCustomDateFormatKey];
if ([value isKindOfClass:[NSNumber class]]) {
value = MR_dateFromNumber(value, [dateFormat isEqualToString:kMagicalRecordImportUnixTimeString]);
}
else {
value = MR_dateFromString([value description], dateFormat ?: kMagicalRecordImportDefaultDateFormatString);
}
}
}
else if (attributeType == NSInteger16AttributeType ||
attributeType == NSInteger32AttributeType ||
attributeType == NSInteger64AttributeType ||
attributeType == NSDecimalAttributeType ||
attributeType == NSDoubleAttributeType ||
attributeType == NSFloatAttributeType) {
if (![value isKindOfClass:[NSNumber class]] && value != [NSNull null]) {
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];
}
}
}
return value == [NSNull null] ? nil : value;
}
@end
================================================
FILE: MagicalRecord/Categories/DataImport/NSEntityDescription+MagicalDataImport.h
================================================
//
// NSEntityDescription+MagicalDataImport.h
// Magical Record
//
// Created by Saul Mora on 9/5/11.
// Copyright 2011 Magical Panda Software LLC. All rights reserved.
//
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@interface NSEntityDescription (MagicalRecord_DataImport)
- (MR_nullable NSAttributeDescription *) MR_primaryAttributeToRelateBy;
- (MR_nonnull NSManagedObject *) MR_createInstanceInContext:(MR_nonnull 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
*/
- (MR_nullable NSAttributeDescription *) MR_attributeDescriptionForName:(MR_nonnull NSString *)name;
@end
================================================
FILE: MagicalRecord/Categories/DataImport/NSEntityDescription+MagicalDataImport.m
================================================
//
// NSEntityDescription+MagicalDataImport.m
// Magical Record
//
// Created by Saul Mora on 9/5/11.
// Copyright 2011 Magical Panda Software LLC. All rights reserved.
//
#import "NSEntityDescription+MagicalDataImport.h"
#import "NSManagedObject+MagicalDataImport.h"
#import "NSManagedObject+MagicalRecord.h"
#import "MagicalImportFunctions.h"
#import "MagicalRecordLogging.h"
@implementation NSEntityDescription (MagicalRecord_DataImport)
- (NSAttributeDescription *) MR_primaryAttributeToRelateBy
{
NSString *lookupKey = [[self userInfo] objectForKey:kMagicalRecordImportRelationshipLinkedByKey] ?: MR_primaryKeyNameFromString([self name]);
NSAttributeDescription *attributeDescription = [self MR_attributeDescriptionForName:lookupKey];
if (attributeDescription == nil)
{
MRLogError(
@"Invalid value for key '%@' in '%@' entity. Remove this key or add attribute '%@'\n",
kMagicalRecordImportRelationshipLinkedByKey,
self.name,
lookupKey);
}
return attributeDescription;
}
- (NSManagedObject *) MR_createInstanceInContext:(NSManagedObjectContext *)context
{
Class relatedClass = NSClassFromString([self managedObjectClassName]);
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
================================================
FILE: MagicalRecord/Categories/DataImport/NSNumber+MagicalDataImport.h
================================================
//
// NSNumber+MagicalDataImport.h
// Magical Record
//
// Created by Saul Mora on 9/4/11.
// Copyright 2011 Magical Panda Software LLC. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@interface NSNumber (MagicalRecord_DataImport)
- (MR_nullable NSString *)MR_lookupKeyForAttribute:(MR_nonnull NSAttributeDescription *)attributeInfo;
- (MR_nonnull id)MR_relatedValueForRelationship:(MR_nonnull NSRelationshipDescription *)relationshipInfo;
@end
================================================
FILE: MagicalRecord/Categories/DataImport/NSNumber+MagicalDataImport.m
================================================
//
// NSNumber+MagicalDataImport.m
// Magical Record
//
// Created by Saul Mora on 9/4/11.
// Copyright 2011 Magical Panda Software LLC. All rights reserved.
//
#import "NSNumber+MagicalDataImport.h"
@implementation NSNumber (MagicalRecord_DataImport)
- (NSString *)MR_lookupKeyForAttribute:(NSAttributeDescription *)attributeInfo
{
return nil;
}
- (id)MR_relatedValueForRelationship:(NSRelationshipDescription *)relationshipInfo
{
return self;
}
@end
================================================
FILE: MagicalRecord/Categories/DataImport/NSObject+MagicalDataImport.h
================================================
//
// NSDictionary+MagicalDataImport.h
// Magical Record
//
// Created by Saul Mora on 9/4/11.
// Copyright 2011 Magical Panda Software LLC. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@interface NSObject (MagicalRecord_DataImport)
- (MR_nullable NSString *) MR_lookupKeyForAttribute:(MR_nonnull NSAttributeDescription *)attributeInfo;
- (MR_nullable id) MR_valueForAttribute:(MR_nonnull NSAttributeDescription *)attributeInfo;
- (MR_nullable NSString *) MR_lookupKeyForRelationship:(MR_nonnull NSRelationshipDescription *)relationshipInfo;
- (MR_nullable id) MR_relatedValueForRelationship:(MR_nonnull NSRelationshipDescription *)relationshipInfo;
@end
================================================
FILE: MagicalRecord/Categories/DataImport/NSObject+MagicalDataImport.m
================================================
//
// NSDictionary+MagicalDataImport.m
// Magical Record
//
// Created by Saul Mora on 9/4/11.
// Copyright 2011 Magical Panda Software LLC. All rights reserved.
//
#import "NSObject+MagicalDataImport.h"
#import "NSAttributeDescription+MagicalDataImport.h"
#import "NSEntityDescription+MagicalDataImport.h"
#import "NSManagedObject+MagicalDataImport.h"
#import "NSRelationshipDescription+MagicalDataImport.h"
#import "MagicalRecordLogging.h"
NSUInteger const kMagicalRecordImportMaximumAttributeFailoverDepth = 10;
@implementation NSObject (MagicalRecord_DataImport)
- (NSString *) MR_lookupKeyForAttribute:(NSAttributeDescription *)attributeInfo
{
NSString *attributeName = [attributeInfo name];
NSString *lookupKey = [[attributeInfo userInfo] objectForKey:kMagicalRecordImportAttributeKeyMapKey] ?: attributeName;
id value = [self valueForKeyPath:lookupKey];
for (NSUInteger i = 1; i < kMagicalRecordImportMaximumAttributeFailoverDepth && value == nil; i++)
{
attributeName = [NSString stringWithFormat:@"%@.%lu", kMagicalRecordImportAttributeKeyMapKey, (unsigned long)i];
lookupKey = [[attributeInfo userInfo] objectForKey:attributeName];
if (lookupKey == nil)
{
return nil;
}
value = [self valueForKeyPath:lookupKey];
}
return value != nil ? lookupKey : nil;
}
- (id) MR_valueForAttribute:(NSAttributeDescription *)attributeInfo
{
NSString *lookupKey = [self MR_lookupKeyForAttribute:attributeInfo];
return lookupKey ? [self valueForKeyPath:lookupKey] : nil;
}
- (NSString *) MR_lookupKeyForRelationship:(NSRelationshipDescription *)relationshipInfo
{
NSEntityDescription *destinationEntity = [relationshipInfo destinationEntity];
if (destinationEntity == nil)
{
MRLogError(@"Unable to find entity for type '%@'", [self valueForKey:kMagicalRecordImportRelationshipTypeKey]);
return nil;
}
NSString *primaryKeyName = [relationshipInfo MR_primaryKey];
NSAttributeDescription *primaryKeyAttribute = [destinationEntity MR_attributeDescriptionForName:primaryKeyName];
NSString *lookupKey = [self MR_lookupKeyForAttribute:primaryKeyAttribute] ?: [primaryKeyAttribute name];
return lookupKey;
}
- (id) MR_relatedValueForRelationship:(NSRelationshipDescription *)relationshipInfo
{
NSString *lookupKey = [self MR_lookupKeyForRelationship:relationshipInfo];
return lookupKey ? [self valueForKeyPath:lookupKey] : nil;
}
@end
================================================
FILE: MagicalRecord/Categories/DataImport/NSRelationshipDescription+MagicalDataImport.h
================================================
//
// NSRelationshipDescription+MagicalDataImport.h
// Magical Record
//
// Created by Saul Mora on 9/4/11.
// Copyright 2011 Magical Panda Software LLC. All rights reserved.
//
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@interface NSRelationshipDescription (MagicalRecord_DataImport)
- (MR_nonnull NSString *) MR_primaryKey;
@end
================================================
FILE: MagicalRecord/Categories/DataImport/NSRelationshipDescription+MagicalDataImport.m
================================================
//
// NSRelationshipDescription+MagicalDataImport.m
// Magical Record
//
// Created by Saul Mora on 9/4/11.
// Copyright 2011 Magical Panda Software LLC. All rights reserved.
//
#import "NSRelationshipDescription+MagicalDataImport.h"
#import "NSManagedObject+MagicalDataImport.h"
#import "MagicalImportFunctions.h"
@implementation NSRelationshipDescription (MagicalRecord_DataImport)
- (NSString *) MR_primaryKey
{
NSString *primaryKeyName = [[self userInfo] objectForKey:kMagicalRecordImportRelationshipLinkedByKey] ?:
MR_primaryKeyNameFromString([[self destinationEntity] name]);
return primaryKeyName;
}
@end
================================================
FILE: MagicalRecord/Categories/DataImport/NSString+MagicalDataImport.h
================================================
//
// NSString+MagicalDataImport.h
// Magical Record
//
// Created by Saul Mora on 12/10/11.
// Copyright (c) 2011 Magical Panda Software LLC. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@interface NSString (MagicalRecord_DataImport)
- (MR_nonnull NSString *) MR_capitalizedFirstCharacterString;
@end
================================================
FILE: MagicalRecord/Categories/DataImport/NSString+MagicalDataImport.m
================================================
//
// NSString+MagicalDataImport.m
// Magical Record
//
// Created by Saul Mora on 12/10/11.
// Copyright (c) 2011 Magical Panda Software LLC. All rights reserved.
//
#import "NSString+MagicalDataImport.h"
@implementation NSString (MagicalRecord_DataImport)
- (NSString *) MR_capitalizedFirstCharacterString
{
if ([self length] > 0)
{
NSString *firstChar = [[self substringToIndex:1] capitalizedString];
return [firstChar stringByAppendingString:[self substringFromIndex:1]];
}
return self;
}
- (id) MR_relatedValueForRelationship:(NSRelationshipDescription *)relationshipInfo
{
return self;
}
- (NSString *) MR_lookupKeyForAttribute:(NSAttributeDescription *)attributeInfo
{
return nil;
}
@end
================================================
FILE: MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalAggregation.h
================================================
//
// NSManagedObject+MagicalAggregation.h
// Magical Record
//
// Created by Saul Mora on 3/7/12.
// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved.
//
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@interface NSManagedObject (MagicalAggregation)
+ (MR_nonnull NSNumber *) MR_numberOfEntities;
+ (MR_nonnull NSNumber *) MR_numberOfEntitiesWithContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSNumber *) MR_numberOfEntitiesWithPredicate:(MR_nullable NSPredicate *)searchTerm;
+ (MR_nonnull NSNumber *) MR_numberOfEntitiesWithPredicate:(MR_nullable NSPredicate *)searchTerm inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (NSUInteger) MR_countOfEntities;
+ (NSUInteger) MR_countOfEntitiesWithContext:(MR_nonnull NSManagedObjectContext *)context;
+ (NSUInteger) MR_countOfEntitiesWithPredicate:(MR_nullable NSPredicate *)searchFilter;
+ (NSUInteger) MR_countOfEntitiesWithPredicate:(MR_nullable NSPredicate *)searchFilter inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (BOOL) MR_hasAtLeastOneEntity;
+ (BOOL) MR_hasAtLeastOneEntityInContext:(MR_nonnull NSManagedObjectContext *)context;
- (MR_nullable id) MR_minValueFor:(MR_nonnull NSString *)property;
- (MR_nullable id) MR_maxValueFor:(MR_nonnull NSString *)property;
+ (MR_nullable id) MR_aggregateOperation:(MR_nonnull NSString *)function onAttribute:(MR_nonnull NSString *)attributeName withPredicate:(MR_nullable NSPredicate *)predicate inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable id) MR_aggregateOperation:(MR_nonnull NSString *)function onAttribute:(MR_nonnull NSString *)attributeName withPredicate:(MR_nullable 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
*/
+ (MR_nullable NSArray *) MR_aggregateOperation:(MR_nonnull NSString *)collectionOperator onAttribute:(MR_nonnull NSString *)attributeName withPredicate:(MR_nullable NSPredicate *)predicate groupBy:(MR_nullable NSString*)groupingKeyPath inContext:(MR_nonnull 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
*/
+ (MR_nullable NSArray *) MR_aggregateOperation:(MR_nonnull NSString *)collectionOperator onAttribute:(MR_nonnull NSString *)attributeName withPredicate:(MR_nullable NSPredicate *)predicate groupBy:(MR_nullable NSString*)groupingKeyPath;
- (MR_nullable instancetype) MR_objectWithMinValueFor:(MR_nonnull NSString *)property;
- (MR_nullable instancetype) MR_objectWithMinValueFor:(MR_nonnull NSString *)property inContext:(MR_nonnull NSManagedObjectContext *)context;
@end
================================================
FILE: MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalAggregation.m
================================================
//
// NSManagedObject+MagicalAggregation.m
// Magical Record
//
// Created by Saul Mora on 3/7/12.
// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved.
//
#import "NSManagedObject+MagicalAggregation.h"
#import "NSEntityDescription+MagicalDataImport.h"
#import "NSManagedObjectContext+MagicalRecord.h"
#import "NSManagedObjectContext+MagicalThreading.h"
#import "NSManagedObject+MagicalRequests.h"
#import "NSManagedObject+MagicalRecord.h"
#import "NSManagedObject+MagicalFinders.h"
#import "MagicalRecord+ErrorHandling.h"
@implementation NSManagedObject (MagicalAggregation)
#pragma mark -
#pragma mark Number of Entities
+ (NSNumber *) MR_numberOfEntitiesWithContext:(NSManagedObjectContext *)context
{
return [NSNumber numberWithUnsignedInteger:[self MR_countOfEntitiesWithContext: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
{
return [self MR_countOfEntitiesWithPredicate:nil inContext:context];
}
+ (NSUInteger) MR_countOfEntitiesWithPredicate:(NSPredicate *)searchFilter
{
#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];
if (searchFilter)
{
[request setPredicate:searchFilter];
}
NSUInteger count = [context countForFetchRequest:request error:&error];
[MagicalRecord handleErrors:error];
return count;
}
+ (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
{
return [[self MR_numberOfEntitiesWithContext:context] intValue] > 0;
}
- (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];
}
- (id) MR_objectWithMinValueFor:(NSString *)property inContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [[self class] MR_createFetchRequestInContext:context];
NSPredicate *searchFor = [NSPredicate predicateWithFormat:@"SELF = %@ AND %K = min(%@)", self, property, property];
[request setPredicate:searchFor];
return [[self class] MR_executeFetchRequestAndReturnFirstObject:request inContext:context];
}
- (id) MR_objectWithMinValueFor:(NSString *)property
{
return [self MR_objectWithMinValueFor:property inContext:[self managedObjectContext]];
}
+ (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]]];
NSExpressionDescription *ed = [[NSExpressionDescription alloc] init];
[ed setName:@"result"];
[ed setExpression:ex];
// determine the type of attribute, required to set the expression return type
NSAttributeDescription *attributeDescription = [[self MR_entityDescriptionInContext:context] MR_attributeDescriptionForName:attributeName];
[ed setExpressionResultType:[attributeDescription attributeType]];
NSArray *properties = [NSArray arrayWithObject:ed];
NSFetchRequest *request = [self MR_requestAllWithPredicate:predicate inContext:context];
[request setPropertiesToFetch:properties];
[request setResultType:NSDictionaryResultType];
NSDictionary *resultsDictionary = [self MR_executeFetchRequestAndReturnFirstObject:request inContext:context];
return [resultsDictionary objectForKey:@"result"];
}
+ (id) MR_aggregateOperation:(NSString *)function onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_aggregateOperation:function
onAttribute:attributeName
withPredicate:predicate
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 = @[groupingKeyPath, expressionDescription];
NSFetchRequest *fetchRequest = [self MR_requestAllWithPredicate:predicate inContext:context];
[fetchRequest setPropertiesToFetch:properties];
[fetchRequest setResultType:NSDictionaryResultType];
[fetchRequest setPropertiesToGroupBy:@[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
================================================
FILE: MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalDataImport.h
================================================
//
// NSManagedObject+MagicalDataImport.h
//
// Created by Saul Mora on 6/28/11.
// Copyright 2011 Magical Panda Software LLC. All rights reserved.
//
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
OBJC_EXPORT NSString * __MR_nonnull const kMagicalRecordImportCustomDateFormatKey;
OBJC_EXPORT NSString * __MR_nonnull const kMagicalRecordImportDefaultDateFormatString;
OBJC_EXPORT NSString * __MR_nonnull const kMagicalRecordImportUnixTimeString;
OBJC_EXPORT NSString * __MR_nonnull const kMagicalRecordImportAttributeKeyMapKey;
OBJC_EXPORT NSString * __MR_nonnull const kMagicalRecordImportAttributeValueClassNameKey;
OBJC_EXPORT NSString * __MR_nonnull const kMagicalRecordImportRelationshipMapKey;
OBJC_EXPORT NSString * __MR_nonnull const kMagicalRecordImportRelationshipLinkedByKey;
OBJC_EXPORT NSString * __MR_nonnull const kMagicalRecordImportRelationshipTypeKey;
@protocol MagicalRecordDataImportProtocol <NSObject>
@optional
- (BOOL) shouldImport:(MR_nonnull id)data;
- (void) willImport:(MR_nonnull id)data;
- (void) didImport:(MR_nonnull id)data;
@end
@interface NSManagedObject (MagicalRecord_DataImport) <MagicalRecordDataImportProtocol>
- (BOOL) MR_importValuesForKeysWithObject:(MR_nonnull id)objectData;
+ (MR_nonnull instancetype) MR_importFromObject:(MR_nonnull id)data;
+ (MR_nonnull instancetype) MR_importFromObject:(MR_nonnull id)data inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull MR_NSArrayOfNSManagedObjects) MR_importFromArray:(MR_nonnull MR_GENERIC(NSArray, NSDictionary *) *)listOfObjectData;
+ (MR_nonnull MR_NSArrayOfNSManagedObjects) MR_importFromArray:(MR_nonnull MR_GENERIC(NSArray, NSDictionary *) *)listOfObjectData inContext:(MR_nonnull NSManagedObjectContext *)context;
@end
================================================
FILE: MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalDataImport.m
================================================
//
// NSManagedObject+MagicalDataImport.m
//
// Created by Saul Mora on 6/28/11.
// Copyright 2011 Magical Panda Software LLC. All rights reserved.
//
#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 <objc/runtime.h>
NSString * const kMagicalRecordImportCustomDateFormatKey = @"dateFormat";
NSString * const kMagicalRecordImportDefaultDateFormatString = @"yyyy-MM-dd'T'HH:mm:ssz";
NSString * const kMagicalRecordImportUnixTimeString = @"UnixTime";
NSString * const kMagicalRecordImportAttributeKeyMapKey = @"mappedKeyName";
NSString * const kMagicalRecordImportAttributeValueClassNameKey = @"attributeValueClassName";
NSString * const kMagicalRecordImportRelationshipMapKey = @"mappedKeyName";
NSString * const kMagicalRecordImportRelationshipLinkedByKey = @"relatedByAttribute";
NSString * const kMagicalRecordImportRelationshipTypeKey = @"type"; //this needs to be revisited
NSString * const kMagicalRecordImportAttributeUseDefaultValueWhenNotPresent = @"useDefaultValueWhenNotPresent";
@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])
{
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;
}
- (void) MR_setAttributes:(NSDictionary *)attributes forKeysWithObject:(id)objectData
{
for (NSString *attributeName in attributes)
{
NSAttributeDescription *attributeInfo = [attributes valueForKey:attributeName];
NSString *lookupKeyPath = [objectData MR_lookupKeyForAttribute:attributeInfo];
if (lookupKeyPath)
{
id value = [attributeInfo MR_valueForKeyPath:lookupKeyPath fromObjectData:objectData];
if (![self MR_importValue:value forKey:attributeName])
{
[self setValue:value forKey:attributeName];
}
}
else
{
if ([[[attributeInfo userInfo] objectForKey:kMagicalRecordImportAttributeUseDefaultValueWhenNotPresent] boolValue])
{
id value = [attributeInfo defaultValue];
if (![self MR_importValue:value forKey:attributeName])
{
[self setValue:value forKey:attributeName];
}
}
}
}
}
- (NSManagedObject *) MR_findObjectForRelationship:(NSRelationshipDescription *)relationshipInfo withData:(id)singleRelatedObjectData
{
NSEntityDescription *destinationEntity = [relationshipInfo destinationEntity];
NSManagedObject *objectForRelationship = nil;
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];
}
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] isKindOfEntity:[relationshipInfo destinationEntity]], @"related object entity %@ not same as destination entity %@", [relatedObject entity], [relationshipInfo destinationEntity]);
//add related object to set
NSString *addRelationMessageFormat = @"set%@:";
id relationshipSource = self;
if ([relationshipInfo isToMany])
{
addRelationMessageFormat = @"add%@Object:";
if ([relationshipInfo respondsToSelector:@selector(isOrdered)] && [relationshipInfo isOrdered])
{
//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, MR_attributeNameFromString([relationshipInfo name])];
SEL selector = NSSelectorFromString(addRelatedObjectToSetMessage);
@try
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[relationshipSource performSelector:selector withObject:relatedObject];
#pragma clang diagnostic pop
}
@catch (NSException *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
{
for (NSString *relationshipName in relationships)
{
SEL shouldImportSelector = NSSelectorFromString([NSString stringWithFormat:@"shouldImport%@:", [relationshipName MR_capitalizedFirstCharacterString]]);
BOOL implementsShouldImport = (BOOL)[self respondsToSelector:shouldImportSelector];
NSRelationshipDescription *relationshipInfo = [relationships valueForKey:relationshipName];
NSString *lookupKey = [[relationshipInfo userInfo] objectForKey:kMagicalRecordImportRelationshipMapKey] ?: relationshipName;
id relatedObjectData;
@try
{
relatedObjectData = [relationshipData valueForKeyPath:lookupKey];
}
@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 (relatedObjectData == nil)
{
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 ([relatedObjectData isEqual:[NSNull null]])
{
[self setValue:nil forKey:relationshipName];
continue;
}
if ([relationshipInfo isToMany] && [relatedObjectData isKindOfClass:[NSArray class]])
{
for (id singleRelatedObjectData in relatedObjectData)
{
setRelationshipBlock(relationshipInfo, singleRelatedObjectData);
}
}
else
{
setRelationshipBlock(relationshipInfo, relatedObjectData);
}
}
}
- (BOOL) MR_preImport:(id)objectData
{
if ([self respondsToSelector:@selector(shouldImport:)])
{
BOOL shouldImport = (BOOL)[self shouldImport:objectData];
if (!shouldImport)
{
return NO;
}
}
if ([self respondsToSelector:@selector(willImport:)])
{
[self willImport:objectData];
}
return YES;
}
- (BOOL) MR_postImport:(id)objectData
{
if ([self respondsToSelector:@selector(didImport:)])
{
[self performSelector:@selector(didImport:) withObject:objectData];
}
return YES;
}
- (BOOL) MR_performDataImportFromObject:(id)objectData relationshipBlock:(void(^)(NSRelationshipDescription*, id))relationshipBlock
{
BOOL didStartImporting = [self MR_preImport:objectData];
if (!didStartImporting) return NO;
NSDictionary *attributes = [[self entity] attributesByName];
[self MR_setAttributes:attributes forKeysWithObject:objectData];
NSDictionary *relationships = [[self entity] relationshipsByName];
[self MR_setRelationships:relationships forKeysWithObject:objectData withBlock:relationshipBlock];
return [self MR_postImport:objectData];
}
- (BOOL)MR_importValuesForKeysWithObject:(id)objectData
{
__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]];
}
if ([localObjectData isKindOfClass:[NSDictionary class]])
{
[relatedObject MR_importValuesForKeysWithObject:localObjectData];
}
else if (localObjectData)
{
NSString *relatedByAttribute = [relationshipInfo MR_primaryKey];
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
{
__block NSManagedObject *managedObject;
[context performBlockAndWait:^{
NSAttributeDescription *primaryAttribute = [[self MR_entityDescriptionInContext:context] MR_primaryAttributeToRelateBy];
if (primaryAttribute != nil)
{
id value = [objectData MR_valueForAttribute:primaryAttribute];
managedObject = [self MR_findFirstByAttribute:[primaryAttribute name] withValue:value inContext:context];
}
if (managedObject == nil)
{
managedObject = [self MR_createEntityInContext:context];
}
[managedObject MR_importValuesForKeysWithObject:objectData];
}];
return managedObject;
}
+ (id) MR_importFromObject:(id)objectData
{
#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
{
#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 *dataObjects = [NSMutableArray array];
[listOfObjectData enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop)
{
NSDictionary *objectData = (NSDictionary *)obj;
NSManagedObject *dataObject = [self MR_importFromObject:objectData inContext:context];
[dataObjects addObject:dataObject];
}];
return dataObjects;
}
@end
================================================
FILE: MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalFinders.h
================================================
//
// NSManagedObject+MagicalFinders.h
// Magical Record
//
// Created by Saul Mora on 3/7/12.
// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved.
//
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@interface NSManagedObject (MagicalFinders)
+ (MR_nullable MR_NSArrayOfNSManagedObjects) MR_findAll;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) MR_findAllInContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) MR_findAllSortedBy:(MR_nonnull NSString *)sortTerm ascending:(BOOL)ascending;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) MR_findAllSortedBy:(MR_nonnull NSString *)sortTerm ascending:(BOOL)ascending inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) MR_findAllSortedBy:(MR_nonnull NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(MR_nullable NSPredicate *)searchTerm;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) MR_findAllSortedBy:(MR_nonnull NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(MR_nullable NSPredicate *)searchTerm inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) MR_findAllWithPredicate:(MR_nullable NSPredicate *)searchTerm;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) MR_findAllWithPredicate:(MR_nullable NSPredicate *)searchTerm inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable instancetype) MR_findFirst;
+ (MR_nullable instancetype) MR_findFirstInContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable instancetype) MR_findFirstWithPredicate:(MR_nullable NSPredicate *)searchTerm;
+ (MR_nullable instancetype) MR_findFirstWithPredicate:(MR_nullable NSPredicate *)searchTerm inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable instancetype) MR_findFirstWithPredicate:(MR_nullable NSPredicate *)searchTerm sortedBy:(MR_nullable NSString *)property ascending:(BOOL)ascending;
+ (MR_nullable instancetype) MR_findFirstWithPredicate:(MR_nullable NSPredicate *)searchTerm sortedBy:(MR_nullable NSString *)property ascending:(BOOL)ascending inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable instancetype) MR_findFirstWithPredicate:(MR_nullable NSPredicate *)searchTerm andRetrieveAttributes:(MR_nullable NSArray *)attributes;
+ (MR_nullable instancetype) MR_findFirstWithPredicate:(MR_nullable NSPredicate *)searchTerm andRetrieveAttributes:(MR_nullable NSArray *)attributes inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable instancetype) MR_findFirstWithPredicate:(MR_nullable NSPredicate *)searchTerm sortedBy:(MR_nullable NSString *)sortBy ascending:(BOOL)ascending andRetrieveAttributes:(MR_nullable id)attributes, ...;
+ (MR_nullable instancetype) MR_findFirstWithPredicate:(MR_nullable NSPredicate *)searchTerm sortedBy:(MR_nullable NSString *)sortBy ascending:(BOOL)ascending inContext:(MR_nonnull NSManagedObjectContext *)context andRetrieveAttributes:(MR_nullable id)attributes, ...;
+ (MR_nullable instancetype) MR_findFirstByAttribute:(MR_nonnull NSString *)attribute withValue:(MR_nonnull id)searchValue;
+ (MR_nullable instancetype) MR_findFirstByAttribute:(MR_nonnull NSString *)attribute withValue:(MR_nonnull id)searchValue inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable instancetype) MR_findFirstOrderedByAttribute:(MR_nonnull NSString *)attribute ascending:(BOOL)ascending;
+ (MR_nullable instancetype) MR_findFirstOrderedByAttribute:(MR_nonnull NSString *)attribute ascending:(BOOL)ascending inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull instancetype) MR_findFirstOrCreateByAttribute:(MR_nonnull NSString *)attribute withValue:(MR_nonnull id)searchValue;
+ (MR_nonnull instancetype) MR_findFirstOrCreateByAttribute:(MR_nonnull NSString *)attribute withValue:(MR_nonnull id)searchValue inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) MR_findByAttribute:(MR_nonnull NSString *)attribute withValue:(MR_nonnull id)searchValue;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) MR_findByAttribute:(MR_nonnull NSString *)attribute withValue:(MR_nonnull id)searchValue inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) MR_findByAttribute:(MR_nonnull NSString *)attribute withValue:(MR_nonnull id)searchValue andOrderBy:(MR_nullable NSString *)sortTerm ascending:(BOOL)ascending;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) MR_findByAttribute:(MR_nonnull NSString *)attribute withValue:(MR_nonnull id)searchValue andOrderBy:(MR_nullable NSString *)sortTerm ascending:(BOOL)ascending inContext:(MR_nonnull NSManagedObjectContext *)context;
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
+ (MR_nonnull NSFetchedResultsController *) MR_fetchController:(MR_nonnull NSFetchRequest *)request delegate:(MR_nullable id<NSFetchedResultsControllerDelegate>)delegate useFileCache:(BOOL)useFileCache groupedBy:(MR_nullable NSString *)groupKeyPath inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSFetchedResultsController *) MR_fetchAllWithDelegate:(MR_nullable id<NSFetchedResultsControllerDelegate>)delegate;
+ (MR_nonnull NSFetchedResultsController *) MR_fetchAllWithDelegate:(MR_nullable id<NSFetchedResultsControllerDelegate>)delegate inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSFetchedResultsController *) MR_fetchAllSortedBy:(MR_nullable NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(MR_nullable NSPredicate *)searchTerm groupBy:(MR_nullable NSString *)groupingKeyPath delegate:(MR_nullable id<NSFetchedResultsControllerDelegate>)delegate;
+ (MR_nonnull NSFetchedResultsController *) MR_fetchAllSortedBy:(MR_nullable NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(MR_nullable NSPredicate *)searchTerm groupBy:(MR_nullable NSString *)groupingKeyPath delegate:(MR_nullable id<NSFetchedResultsControllerDelegate>)delegate inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSFetchedResultsController *) MR_fetchAllGroupedBy:(MR_nullable NSString *)group withPredicate:(MR_nullable NSPredicate *)searchTerm sortedBy:(MR_nullable NSString *)sortTerm ascending:(BOOL)ascending;
+ (MR_nonnull NSFetchedResultsController *) MR_fetchAllGroupedBy:(MR_nullable NSString *)group withPredicate:(MR_nullable NSPredicate *)searchTerm sortedBy:(MR_nullable NSString *)sortTerm ascending:(BOOL)ascending inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSFetchedResultsController *) MR_fetchAllGroupedBy:(MR_nullable NSString *)group withPredicate:(MR_nullable NSPredicate *)searchTerm sortedBy:(MR_nullable NSString *)sortTerm ascending:(BOOL)ascending delegate:(MR_nullable id<NSFetchedResultsControllerDelegate>)delegate;
+ (MR_nonnull NSFetchedResultsController *) MR_fetchAllGroupedBy:(MR_nullable NSString *)group withPredicate:(MR_nullable NSPredicate *)searchTerm sortedBy:(MR_nullable NSString *)sortTerm ascending:(BOOL)ascending delegate:(MR_nullable id<NSFetchedResultsControllerDelegate>)delegate inContext:(MR_nonnull NSManagedObjectContext *)context;
#endif
@end
================================================
FILE: MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalFinders.m
================================================
//
// NSManagedObject+MagicalFinders.m
// Magical Record
//
// Created by Saul Mora on 3/7/12.
// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved.
//
#import "NSManagedObject+MagicalFinders.h"
#import "NSManagedObject+MagicalRequests.h"
#import "NSManagedObject+MagicalRecord.h"
#import "NSManagedObjectContext+MagicalThreading.h"
@implementation NSManagedObject (MagicalFinders)
#pragma mark - Finding Data
+ (NSArray *) MR_findAllInContext:(NSManagedObjectContext *)context
{
return [self MR_executeFetchRequest:[self MR_requestAllInContext:context] inContext: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
{
NSFetchRequest *request = [self MR_requestAllSortedBy:sortTerm ascending:ascending inContext:context];
return [self MR_executeFetchRequest:request inContext:context];
}
+ (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
{
NSFetchRequest *request = [self MR_requestAllSortedBy:sortTerm
ascending:ascending
withPredicate:searchTerm
inContext:context];
return [self MR_executeFetchRequest:request inContext:context];
}
+ (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
}
+ (NSArray *) MR_findAllWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [self MR_createFetchRequestInContext:context];
[request setPredicate:searchTerm];
return [self MR_executeFetchRequest:request
inContext:context];
}
+ (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
}
+ (instancetype) MR_findFirstInContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [self MR_createFetchRequestInContext:context];
return [self MR_executeFetchRequestAndReturnFirstObject:request inContext:context];
}
+ (instancetype) MR_findFirst
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_findFirstInContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (instancetype) MR_findFirstByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [self MR_requestFirstByAttribute:attribute withValue:searchValue inContext:context];
return [self MR_executeFetchRequestAndReturnFirstObject:request inContext:context];
}
+ (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
}
+ (instancetype) MR_findFirstOrderedByAttribute:(NSString *)attribute ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [self MR_requestAllSortedBy:attribute ascending:ascending inContext:context];
[request setFetchLimit:1];
return [self MR_executeFetchRequestAndReturnFirstObject:request inContext:context];
}
+ (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
}
+ (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
}
+ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [self MR_requestFirstWithPredicate:searchTerm inContext:context];
return [self MR_executeFetchRequestAndReturnFirstObject:request inContext: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];
}
+ (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
}
+ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchTerm andRetrieveAttributes:(NSArray *)attributes inContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [self MR_createFetchRequestInContext:context];
[request setPredicate:searchTerm];
[request setPropertiesToFetch:attributes];
return [self MR_executeFetchRequestAndReturnFirstObject:request inContext:context];
}
+ (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
}
+ (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 inContext:context]];
return [self MR_executeFetchRequestAndReturnFirstObject:request inContext:context];
}
+ (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
{
NSFetchRequest *request = [self MR_requestAllWhere:attribute isEqualTo:searchValue inContext:context];
return [self MR_executeFetchRequest:request inContext:context];
}
+ (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
{
NSPredicate *searchTerm = [NSPredicate predicateWithFormat:@"%K = %@", attribute, searchValue];
NSFetchRequest *request = [self MR_requestAllSortedBy:sortTerm ascending:ascending withPredicate:searchTerm inContext:context];
return [self MR_executeFetchRequest:request inContext:context];
}
+ (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
}
#pragma mark -
#pragma mark NSFetchedResultsController helpers
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
+ (NSFetchedResultsController *) MR_fetchController:(NSFetchRequest *)request delegate:(id<NSFetchedResultsControllerDelegate>)delegate useFileCache:(BOOL)useFileCache groupedBy:(NSString *)groupKeyPath inContext:(NSManagedObjectContext *)context
{
NSString *cacheName = useFileCache ? [NSString stringWithFormat:@"MagicalRecord-Cache-%@", NSStringFromClass([self class])] : nil;
NSFetchedResultsController *controller =
[[NSFetchedResultsController alloc] initWithFetchRequest:request
managedObjectContext:context
sectionNameKeyPath:groupKeyPath
cacheName:cacheName];
controller.delegate = delegate;
return controller;
}
+ (NSFetchedResultsController *) MR_fetchAllWithDelegate:(id<NSFetchedResultsControllerDelegate>)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<NSFetchedResultsControllerDelegate>)delegate inContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [self MR_requestAllInContext:context];
NSFetchedResultsController *controller = [self MR_fetchController:request delegate:delegate useFileCache:NO groupedBy:nil inContext:context];
[self MR_performFetch:controller];
return controller;
}
+ (NSFetchedResultsController *) MR_fetchAllGroupedBy:(NSString *)group withPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortTerm ascending:(BOOL)ascending delegate:(id<NSFetchedResultsControllerDelegate>)delegate inContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [self MR_requestAllSortedBy:sortTerm
ascending:ascending
withPredicate:searchTerm
inContext:context];
NSFetchedResultsController *controller = [self MR_fetchController:request
delegate:delegate
useFileCache:NO
groupedBy:group
inContext:context];
[self MR_performFetch:controller];
return controller;
}
+ (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
{
return [self MR_fetchAllGroupedBy:group
withPredicate:searchTerm
sortedBy:sortTerm
ascending:ascending
delegate:nil
inContext:context];
}
+ (NSFetchedResultsController *) MR_fetchAllGroupedBy:(NSString *)group withPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortTerm ascending:(BOOL)ascending
{
#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
}
+ (NSFetchedResultsController *) MR_fetchAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm groupBy:(NSString *)groupingKeyPath inContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [self MR_requestAllSortedBy:sortTerm
ascending:ascending
withPredicate:searchTerm
inContext:context];
NSFetchedResultsController *controller = [self MR_fetchController:request
delegate:nil
useFileCache:NO
groupedBy:groupingKeyPath
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<NSFetchedResultsControllerDelegate>)delegate inContext:(NSManagedObjectContext *)context
{
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<NSFetchedResultsControllerDelegate>)delegate
{
#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
@end
================================================
FILE: MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalRecord.h
================================================
//
//
// Created by Saul Mora on 11/15/09.
// Copyright 2010 Magical Panda Software, LLC All rights reserved.
//
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordDeprecationMacros.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@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
*/
+ (MR_nonnull NSString *) MR_entityName;
+ (NSUInteger) MR_defaultBatchSize;
+ (void) MR_setDefaultBatchSize:(NSUInteger)newBatchSize;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) MR_executeFetchRequest:(MR_nonnull NSFetchRequest *)request;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) MR_executeFetchRequest:(MR_nonnull NSFetchRequest *)request inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable instancetype) MR_executeFetchRequestAndReturnFirstObject:(MR_nonnull NSFetchRequest *)request;
+ (MR_nullable instancetype) MR_executeFetchRequestAndReturnFirstObject:(MR_nonnull NSFetchRequest *)request inContext:(MR_nonnull NSManagedObjectContext *)context;
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
+ (BOOL) MR_performFetch:(MR_nonnull NSFetchedResultsController *)controller;
#endif
+ (MR_nullable NSEntityDescription *) MR_entityDescription;
+ (MR_nullable NSEntityDescription *) MR_entityDescriptionInContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable MR_GENERIC(NSArray, NSPropertyDescription *) *) MR_propertiesNamed:(MR_nonnull MR_GENERIC(NSArray, NSString *) *)properties;
+ (MR_nullable MR_GENERIC(NSArray, NSPropertyDescription *) *) MR_propertiesNamed:(MR_nonnull MR_GENERIC(NSArray, NSString *) *)properties inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable instancetype) MR_createEntity;
+ (MR_nullable instancetype) MR_createEntityInContext:(MR_nonnull NSManagedObjectContext *)context;
- (BOOL) MR_deleteEntity;
- (BOOL) MR_deleteEntityInContext:(MR_nonnull NSManagedObjectContext *)context;
+ (BOOL) MR_deleteAllMatchingPredicate:(MR_nonnull NSPredicate *)predicate;
+ (BOOL) MR_deleteAllMatchingPredicate:(MR_nonnull NSPredicate *)predicate inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (BOOL) MR_truncateAll;
+ (BOOL) MR_truncateAllInContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull MR_GENERIC(NSArray, NSSortDescriptor *) *) MR_ascendingSortDescriptors:(MR_nonnull MR_GENERIC(NSArray, NSString *) *)attributesToSortBy;
+ (MR_nonnull MR_GENERIC(NSArray, NSSortDescriptor *) *) MR_descendingSortDescriptors:(MR_nonnull MR_GENERIC(NSArray, NSString *) *)attributesToSortBy;
- (MR_nullable instancetype) MR_inContext:(MR_nonnull NSManagedObjectContext *)otherContext;
- (MR_nullable instancetype) MR_inThreadContext;
@end
@protocol MagicalRecord_MOGenerator <NSObject>
@optional
+ (MR_nonnull NSString *)entityName;
- (MR_nullable instancetype) entityInManagedObjectContext:(MR_nonnull NSManagedObjectContext *)object;
- (MR_nullable instancetype) insertInManagedObjectContext:(MR_nonnull NSManagedObjectContext *)object;
@end
#pragma mark - Deprecated Methods — DO NOT USE
@interface NSManagedObject (MagicalRecordDeprecated)
+ (MR_nullable instancetype) MR_createInContext:(MR_nonnull NSManagedObjectContext *)context MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("4.0", "MR_createEntityInContext:");
- (BOOL) MR_deleteInContext:(MR_nonnull NSManagedObjectContext *)context MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("4.0", "MR_deleteEntityInContext:");
@end
================================================
FILE: MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalRecord.m
================================================
// Created by Saul Mora on 11/15/09.
// Copyright 2010 Magical Panda Software, LLC All rights reserved.
//
#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)
{
kMagicalRecordDefaultBatchSize = newBatchSize;
}
}
+ (NSUInteger) MR_defaultBatchSize
{
return kMagicalRecordDefaultBatchSize;
}
+ (NSArray *) MR_executeFetchRequest:(NSFetchRequest *)request inContext:(NSManagedObjectContext *)context
{
__block NSArray *results = nil;
[context performBlockAndWait:^{
NSError *error = nil;
results = [context executeFetchRequest:request error:&error];
if (results == nil)
{
[MagicalRecord handleErrors:error];
}
}];
return results;
}
+ (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
{
[request setFetchLimit:1];
NSArray *results = [self MR_executeFetchRequest:request inContext:context];
if ([results count] == 0)
{
return nil;
}
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
+ (BOOL) MR_performFetch:(NSFetchedResultsController *)controller
{
NSError *error = nil;
BOOL success = [controller performFetch:&error];
if (!success)
{
[MagicalRecord handleErrors:error];
}
return success;
}
#endif
+ (NSEntityDescription *) MR_entityDescription
{
#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
{
NSString *entityName = [self MR_entityName];
return [NSEntityDescription entityForName:entityName inManagedObjectContext:context];
}
+ (NSArray *) MR_propertiesNamed:(NSArray *)properties
{
#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 inContext:(NSManagedObjectContext *)context
{
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];
if (property)
{
[propertiesWanted addObject:property];
}
else
{
MRLogWarn(@"Property '%@' not found in %lx properties for %@", propertyName, (unsigned long)[propDict count], NSStringFromClass(self));
}
}
}
return propertiesWanted;
}
+ (NSArray *) MR_sortAscending:(BOOL)ascending attributes:(NSArray *)attributesToSortBy
{
NSMutableArray *attributes = [NSMutableArray array];
for (NSString *attributeName in attributesToSortBy)
{
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:attributeName ascending:ascending];
[attributes addObject:sortDescriptor];
}
return attributes;
}
+ (NSArray *) MR_ascendingSortDescriptors:(NSArray *)attributesToSortBy
{
return [self MR_sortAscending:YES attributes:attributesToSortBy];
}
+ (NSArray *) MR_descendingSortDescriptors:(NSArray *)attributesToSortBy
{
return [self MR_sortAscending:NO attributes:attributesToSortBy];
}
#pragma mark -
+ (id) MR_createEntityInContext:(NSManagedObjectContext *)context
{
if ([self respondsToSelector:@selector(insertInManagedObjectContext:)] && context != nil)
{
id entity = [self performSelector:@selector(insertInManagedObjectContext:) withObject:context];
return entity;
}
else
{
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
{
#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_deleteEntityInContext:(NSManagedObjectContext *)context
{
NSError *error = nil;
NSManagedObject *entityInContext = [context existingObjectWithID:[self objectID] error:&error];
[MagicalRecord handleErrors:error];
if (entityInContext) {
[context deleteObject:entityInContext];
}
return YES;
}
- (BOOL) MR_deleteEntity
{
[self MR_deleteEntityInContext:[self managedObjectContext]];
return YES;
}
+ (BOOL) MR_deleteAllMatchingPredicate:(NSPredicate *)predicate inContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [self MR_requestAllWithPredicate:predicate inContext:context];
[request setReturnsObjectsAsFaults:YES];
[request setIncludesPropertyValues:NO];
NSArray *objectsToTruncate = [self MR_executeFetchRequest:request inContext:context];
for (id objectToTruncate in objectsToTruncate)
{
[objectToTruncate MR_deleteEntityInContext:context];
}
return YES;
}
+ (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
{
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)
{
[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];
return inContext;
}
- (id) MR_inThreadContext
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self 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
================================================
FILE: MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalRequests.h
================================================
//
// NSManagedObject+MagicalRequests.h
// Magical Record
//
// Created by Saul Mora on 3/7/12.
// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved.
//
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@interface NSManagedObject (MagicalRequests)
+ (MR_nonnull NSFetchRequest *) MR_createFetchRequest;
+ (MR_nonnull NSFetchRequest *) MR_createFetchRequestInContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSFetchRequest *) MR_requestAll;
+ (MR_nonnull NSFetchRequest *) MR_requestAllInContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSFetchRequest *) MR_requestAllWithPredicate:(MR_nullable NSPredicate *)searchTerm;
+ (MR_nonnull NSFetchRequest *) MR_requestAllWithPredicate:(MR_nullable NSPredicate *)searchTerm inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSFetchRequest *) MR_requestAllWhere:(MR_nonnull NSString *)property isEqualTo:(MR_nonnull id)value;
+ (MR_nonnull NSFetchRequest *) MR_requestAllWhere:(MR_nonnull NSString *)property isEqualTo:(MR_nonnull id)value inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSFetchRequest *) MR_requestFirstWithPredicate:(MR_nullable NSPredicate *)searchTerm;
+ (MR_nonnull NSFetchRequest *) MR_requestFirstWithPredicate:(MR_nullable NSPredicate *)searchTerm inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSFetchRequest *) MR_requestFirstByAttribute:(MR_nonnull NSString *)attribute withValue:(MR_nullable id)searchValue;
+ (MR_nonnull NSFetchRequest *) MR_requestFirstByAttribute:(MR_nonnull NSString *)attribute withValue:(MR_nullable id)searchValue inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSFetchRequest *) MR_requestAllSortedBy:(MR_nonnull NSString *)sortTerm ascending:(BOOL)ascending;
+ (MR_nonnull NSFetchRequest *) MR_requestAllSortedBy:(MR_nonnull NSString *)sortTerm ascending:(BOOL)ascending inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSFetchRequest *) MR_requestAllSortedBy:(MR_nonnull NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(MR_nullable NSPredicate *)searchTerm;
+ (MR_nonnull NSFetchRequest *) MR_requestAllSortedBy:(MR_nonnull NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(MR_nullable NSPredicate *)searchTerm inContext:(MR_nonnull NSManagedObjectContext *)context;
@end
================================================
FILE: MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalRequests.m
================================================
//
// NSManagedObject+MagicalRequests.m
// Magical Record
//
// Created by Saul Mora on 3/7/12.
// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved.
//
#import "NSManagedObject+MagicalRequests.h"
#import "NSManagedObject+MagicalRecord.h"
#import "NSManagedObjectContext+MagicalThreading.h"
@implementation NSManagedObject (MagicalRequests)
+ (NSFetchRequest *)MR_createFetchRequestInContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[self MR_entityDescriptionInContext:context]];
return request;
}
+ (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
{
return [self MR_createFetchRequestInContext: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
{
NSFetchRequest *request = [self MR_createFetchRequestInContext:context];
[request setPredicate:searchTerm];
return request;
}
+ (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
{
NSFetchRequest *request = [self MR_createFetchRequestInContext:context];
[request setPredicate:[NSPredicate predicateWithFormat:@"%K = %@", property, value]];
return request;
}
+ (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
{
NSFetchRequest *request = [self MR_createFetchRequestInContext:context];
[request setPredicate:searchTerm];
[request setFetchLimit:1];
return request;
}
+ (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
{
NSFetchRequest *request = [self MR_requestAllWhere:attribute isEqualTo:searchValue inContext:context];
[request setFetchLimit:1];
return request;
}
+ (NSFetchRequest *) MR_requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context
{
return [self MR_requestAllSortedBy:sortTerm
ascending:ascending
withPredicate:nil
inContext:context];
}
+ (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
{
NSFetchRequest *request = [self MR_requestAllInContext:context];
if (searchTerm)
{
[request setPredicate:searchTerm];
}
[request setFetchBatchSize:[self MR_defaultBatchSize]];
NSMutableArray* sortDescriptors = [[NSMutableArray alloc] init];
NSArray* sortKeys = [sortTerm componentsSeparatedByString:@","];
for (__strong NSString* sortKey in sortKeys)
{
BOOL localAscending = ascending;
NSArray * sortComponents = [sortKey componentsSeparatedByString:@":"];
if (sortComponents.count > 1)
{
NSString * customAscending = sortComponents.lastObject;
localAscending = customAscending.boolValue;
sortKey = sortComponents[0];
}
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:sortKey ascending:localAscending];
[sortDescriptors addObject:sortDescriptor];
}
[request setSortDescriptors:sortDescriptors];
return request;
}
+ (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;
}
@end
================================================
FILE: MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalChainSave.h
================================================
//
// NSManagedObjectContext+MagicalChainSave.h
// Magical Record
//
// Created by Lee on 8/27/14.
// Copyright (c) 2014 Magical Panda Software LLC. All rights reserved.
//
#import <CoreData/CoreData.h>
#import <MagicalRecord/NSManagedObjectContext+MagicalSaves.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@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 (^ __MR_nonnull)(NSManagedObjectContext * __MR_nonnull 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 (^ __MR_nonnull)(NSManagedObjectContext * __MR_nonnull localContext))block completion:(MR_nullable 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 (^ __MR_nonnull)(NSManagedObjectContext * __MR_nonnull localContext))block;
@end
================================================
FILE: MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalChainSave.m
================================================
//
// 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
================================================
FILE: MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalObserving.h
================================================
//
// NSManagedObjectContext+MagicalObserving.h
// Magical Record
//
// Created by Saul Mora on 3/9/12.
// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved.
//
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
OBJC_EXPORT NSString * __MR_nonnull 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:(MR_nonnull 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:(MR_nonnull 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:(MR_nonnull NSManagedObjectContext *)otherContext;
#if TARGET_OS_OSX || TARGET_OS_IOS
/**
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:(MR_nonnull 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:(MR_nonnull NSPersistentStoreCoordinator *)coordinator;
#endif
@end
================================================
FILE: MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalObserving.m
================================================
//
// NSManagedObjectContext+MagicalObserving.m
// Magical Record
//
// Created by Saul Mora on 3/9/12.
// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved.
//
#import "NSManagedObjectContext+MagicalObserving.h"
#import "NSManagedObjectContext+MagicalRecord.h"
#import "MagicalRecord+iCloud.h"
#import "MagicalRecordLogging.h"
NSString * const kMagicalRecordDidMergeChangesFromiCloudNotification = @"kMagicalRecordDidMergeChangesFromiCloudNotification";
@implementation NSManagedObjectContext (MagicalObserving)
#pragma mark - Context Observation Helpers
- (void) MR_observeContext:(NSManagedObjectContext *)otherContext
{
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self
selector:@selector(MR_mergeChangesFromNotification:)
name:NSManagedObjectContextDidSaveNotification
object:otherContext];
}
- (void) MR_stopObservingContext:(NSManagedObjectContext *)otherContext
{
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter removeObserver:self
name:NSManagedObjectContextDidSaveNotification
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:^{
MRLogVerbose(@"Merging changes From iCloud %@context%@",
self == [NSManagedObjectContext MR_defaultContext] ? @"*** DEFAULT *** " : @"",
([NSThread isMainThread] ? @" *** on Main Thread ***" : @""));
[self mergeChangesFromContextDidSaveNotification:notification];
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter postNotificationName:kMagicalRecordDidMergeChangesFromiCloudNotification
object:self
userInfo:[notification userInfo]];
}];
}
- (void) MR_mergeChangesFromNotification:(NSNotification *)notification
{
MRLogVerbose(@"Merging changes to %@context%@",
self == [NSManagedObjectContext MR_defaultContext] ? @"*** DEFAULT *** " : @"",
([NSThread isMainThread] ? @" *** on Main Thread ***" : @""));
[self mergeChangesFromContextDidSaveNotification:notification];
}
- (void) MR_mergeChangesOnMainThread:(NSNotification *)notification
{
if ([NSThread isMainThread])
{
[self MR_mergeChangesFromNotification:notification];
}
else
{
[self performSelectorOnMainThread:@selector(MR_mergeChangesFromNotification:) withObject:notification waitUntilDone:YES];
}
}
#if TARGET_OS_OSX || TARGET_OS_IOS
- (void) MR_observeiCloudChangesInCoordinator:(NSPersistentStoreCoordinator *)coordinator
{
if (![MagicalRecord isICloudEnabled]) return;
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self
selector:@selector(MR_mergeChangesFromiCloud:)
name:NSPersistentStoreDidImportUbiquitousContentChangesNotification
object:coordinator];
}
- (void) MR_stopObservingiCloudChangesInCoordinator:(NSPersistentStoreCoordinator *)coordinator
{
if (![MagicalRecord isICloudEnabled]) return;
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter removeObserver:self
name:NSPersistentStoreDidImportUbiquitousContentChangesNotification
object:coordinator];
}
#endif
@end
================================================
FILE: MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalRecord.h
================================================
//
// NSManagedObjectContext+MagicalRecord.h
//
// Created by Saul Mora on 11/23/09.
// Copyright 2010 Magical Panda Software, LLC All rights reserved.
//
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordDeprecationMacros.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@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:(MR_nonnull NSPersistentStoreCoordinator *)coordinator;
#pragma mark - Default Contexts
/**
Root context responsible for sending changes to the main persistent store coordinator that will be saved to disk.
@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
*/
+ (MR_nonnull 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
*/
+ (MR_nonnull 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
*/
+ (MR_nonnull 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
*/
+ (MR_nonnull NSManagedObjectContext *) MR_contextWithParent:(MR_nonnull 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
*/
+ (MR_nonnull NSManagedObjectContext *) MR_contextWithStoreCoordinator:(MR_nonnull NSPersistentStoreCoordinator *)coordinator;
/**
Initializes a context of type `NSMainQueueConcurrencyType`.
@return A context initialized using the `NSPrivateQueueConcurrencyType` concurrency type.
*/
+ (MR_nonnull NSManagedObjectContext *) MR_newMainQueueContext NS_RETURNS_RETAINED;
/**
Initializes a context of type `NSPrivateQueueConcurrencyType`.
@return A context initialized using the `NSPrivateQueueConcurrencyType` concurrency type.
*/
+ (MR_nonnull 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:(MR_nonnull NSString *)workingName;
/**
@return Working name for the context
*/
- (MR_nonnull NSString *) MR_workingName;
/**
@return Description of this context
*/
- (MR_nonnull NSString *) MR_description;
/**
@return Description of the parent contexts of this context
*/
- (MR_nonnull NSString *) MR_parentChain;
#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:(MR_nonnull id <NSFastEnumeration>)objects;
@end
#pragma mark - Deprecated Methods — DO NOT USE
@interface NSManagedObjectContext (MagicalRecordDeprecated)
+ (MR_nonnull NSManagedObjectContext *) MR_contextWithoutParent MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("4.0", "MR_newPrivateQueueContext");
+ (MR_nonnull NSManagedObjectContext *) MR_newContext MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("4.0", "MR_context");
+ (MR_nonnull NSManagedObjectContext *) MR_newContextWithParent:(MR_nonnull NSManagedObjectContext *)parentContext MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("4.0", "MR_contextWithParent:");
+ (MR_nonnull NSManagedObjectContext *) MR_newContextWithStoreCoordinator:(MR_nonnull NSPersistentStoreCoordinator *)coordinator MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("4.0", "MR_contextWithStoreCoordinator:");
@end
================================================
FILE: MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalRecord.m
================================================
//
// NSManagedObjectContext+MagicalRecord.m
//
// Created by Saul Mora on 11/23/09.
// Copyright 2010 Magical Panda Software, LLC All rights reserved.
//
#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 NSString * const MagicalRecordContextWorkingName = @"MagicalRecordContextWorkingName";
static NSManagedObjectContext *MagicalRecordRootSavingContext;
static NSManagedObjectContext *MagicalRecordDefaultContext;
static id MagicalRecordUbiquitySetupNotificationObserver;
@implementation NSManagedObjectContext (MagicalRecord)
#pragma mark - Setup
+ (void) MR_initializeDefaultContextWithCoordinator:(NSPersistentStoreCoordinator *)coordinator
{
NSAssert(coordinator, @"Provided coordinator cannot be nil!");
if (MagicalRecordDefaultContext == nil)
{
NSManagedObjectContext *rootContext = [self MR_contextWithStoreCoordinator:coordinator];
[self MR_setRootSavingContext:rootContext];
NSManagedObjectContext *defaultContext = [self MR_newMainQueueContext];
[self MR_setDefaultContext:defaultContext];
[defaultContext setParentContext:rootContext];
}
}
#pragma mark - Default Contexts
+ (NSManagedObjectContext *) MR_defaultContext
{
@synchronized(self) {
NSAssert(MagicalRecordDefaultContext != nil, @"Default context is nil! Did you forget to initialize the Core Data Stack?");
return MagicalRecordDefaultContext;
}
}
+ (NSManagedObjectContext *) MR_rootSavingContext
{
NSAssert(MagicalRecordRootSavingContext != nil, @"Root saving context is nil! Did you forget to initialize the Core Data Stack?");
return MagicalRecordRootSavingContext;
}
#pragma mark - Context Creation
+ (NSManagedObjectContext *) MR_context
{
return [self MR_contextWithParent:[self MR_rootSavingContext]];
}
+ (NSManagedObjectContext *) MR_contextWithParent:(NSManagedObjectContext *)parentContext
{
NSManagedObjectContext *context = [self MR_newPrivateQueueContext];
[context setParentContext:parentContext];
[context MR_obtainPermanentIDsBeforeSaving];
return context;
}
+ (NSManagedObjectContext *) MR_contextWithStoreCoordinator:(NSPersistentStoreCoordinator *)coordinator
{
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;
}
+ (NSManagedObjectContext *) MR_newMainQueueContext
{
NSManagedObjectContext *context = [[self alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
MRLogInfo(@"Created new main queue context: %@", context);
return context;
}
+ (NSManage
gitextract_odjxe54k/
├── .clang-format
├── .cocoadocs.yml
├── .gitignore
├── .travis.yml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── Docs/
│ ├── Creating-Entities.md
│ ├── Deleting-Entities.md
│ ├── Fetching-Entities.md
│ ├── Getting-Started.md
│ ├── Importing-Data.md
│ ├── Installing-MagicalRecord.md
│ ├── Logging.md
│ ├── Other-Resources.md
│ ├── Saving-Entities.md
│ ├── Threads.md
│ └── Working-with-Managed-Object-Contexts.md
├── LICENSE
├── MagicalRecord/
│ ├── Categories/
│ │ ├── DataImport/
│ │ │ ├── MagicalImportFunctions.h
│ │ │ ├── MagicalImportFunctions.m
│ │ │ ├── NSAttributeDescription+MagicalDataImport.h
│ │ │ ├── NSAttributeDescription+MagicalDataImport.m
│ │ │ ├── NSEntityDescription+MagicalDataImport.h
│ │ │ ├── NSEntityDescription+MagicalDataImport.m
│ │ │ ├── NSNumber+MagicalDataImport.h
│ │ │ ├── NSNumber+MagicalDataImport.m
│ │ │ ├── NSObject+MagicalDataImport.h
│ │ │ ├── NSObject+MagicalDataImport.m
│ │ │ ├── NSRelationshipDescription+MagicalDataImport.h
│ │ │ ├── NSRelationshipDescription+MagicalDataImport.m
│ │ │ ├── NSString+MagicalDataImport.h
│ │ │ └── NSString+MagicalDataImport.m
│ │ ├── NSManagedObject/
│ │ │ ├── NSManagedObject+MagicalAggregation.h
│ │ │ ├── NSManagedObject+MagicalAggregation.m
│ │ │ ├── NSManagedObject+MagicalDataImport.h
│ │ │ ├── NSManagedObject+MagicalDataImport.m
│ │ │ ├── NSManagedObject+MagicalFinders.h
│ │ │ ├── NSManagedObject+MagicalFinders.m
│ │ │ ├── NSManagedObject+MagicalRecord.h
│ │ │ ├── NSManagedObject+MagicalRecord.m
│ │ │ ├── NSManagedObject+MagicalRequests.h
│ │ │ └── NSManagedObject+MagicalRequests.m
│ │ ├── NSManagedObjectContext/
│ │ │ ├── NSManagedObjectContext+MagicalChainSave.h
│ │ │ ├── NSManagedObjectContext+MagicalChainSave.m
│ │ │ ├── NSManagedObjectContext+MagicalObserving.h
│ │ │ ├── NSManagedObjectContext+MagicalObserving.m
│ │ │ ├── NSManagedObjectContext+MagicalRecord.h
│ │ │ ├── NSManagedObjectContext+MagicalRecord.m
│ │ │ ├── NSManagedObjectContext+MagicalSaves.h
│ │ │ ├── NSManagedObjectContext+MagicalSaves.m
│ │ │ ├── NSManagedObjectContext+MagicalThreading.h
│ │ │ └── NSManagedObjectContext+MagicalThreading.m
│ │ ├── NSManagedObjectModel+MagicalRecord.h
│ │ ├── NSManagedObjectModel+MagicalRecord.m
│ │ ├── NSPersistentStore+MagicalRecord.h
│ │ ├── NSPersistentStore+MagicalRecord.m
│ │ ├── NSPersistentStoreCoordinator+MagicalRecord.h
│ │ └── NSPersistentStoreCoordinator+MagicalRecord.m
│ ├── Core/
│ │ ├── MagicalRecord+Actions.h
│ │ ├── MagicalRecord+Actions.m
│ │ ├── MagicalRecord+ErrorHandling.h
│ │ ├── MagicalRecord+ErrorHandling.m
│ │ ├── MagicalRecord+Options.h
│ │ ├── MagicalRecord+Options.m
│ │ ├── MagicalRecord+Setup.h
│ │ ├── MagicalRecord+Setup.m
│ │ ├── MagicalRecord+ShorthandMethods.h
│ │ ├── MagicalRecord+ShorthandMethods.m
│ │ ├── MagicalRecord+iCloud.h
│ │ ├── MagicalRecord+iCloud.m
│ │ ├── MagicalRecordDeprecationMacros.h
│ │ ├── MagicalRecordInternal.h
│ │ ├── MagicalRecordInternal.m
│ │ ├── MagicalRecordLogging.h
│ │ ├── MagicalRecordShorthandMethodAliases.h
│ │ └── MagicalRecordXcode7CompatibilityMacros.h
│ └── MagicalRecord.h
├── MagicalRecord.podspec
├── MagicalRecord.xcodeproj/
│ ├── project.pbxproj
│ └── xcshareddata/
│ └── xcschemes/
│ ├── MagicalRecord for OS X.xcscheme
│ ├── MagicalRecord for iOS.xcscheme
│ ├── MagicalRecord for tvOS.xcscheme
│ ├── libMagicalRecord for OS X.xcscheme
│ ├── libMagicalRecord for iOS.xcscheme
│ └── libMagicalRecord for tvOS.xcscheme
├── README.md
├── Samples/
│ └── iOS/
│ ├── Application/
│ │ ├── Categories/
│ │ │ ├── ImageToDataTransformer.h
│ │ │ └── ImageToDataTransformer.m
│ │ ├── Controllers/
│ │ │ ├── AddressBook_Prefix.pch
│ │ │ ├── EditingTableViewCell.h
│ │ │ ├── EditingTableViewCell.m
│ │ │ ├── ImperialPickerController.h
│ │ │ ├── ImperialPickerController.m
│ │ │ ├── IngredientDetailViewController.h
│ │ │ ├── IngredientDetailViewController.m
│ │ │ ├── InstructionsViewController.h
│ │ │ ├── InstructionsViewController.m
│ │ │ ├── MetricPickerController.h
│ │ │ ├── MetricPickerController.m
│ │ │ ├── RecipeAddViewController.h
│ │ │ ├── RecipeAddViewController.m
│ │ │ ├── RecipeDetailViewController.h
│ │ │ ├── RecipeDetailViewController.m
│ │ │ ├── RecipeListTableViewController.h
│ │ │ ├── RecipeListTableViewController.m
│ │ │ ├── RecipePhotoViewController.h
│ │ │ ├── RecipePhotoViewController.m
│ │ │ ├── RecipeTableViewCell.h
│ │ │ ├── RecipeTableViewCell.m
│ │ │ ├── TemperatureCell.h
│ │ │ ├── TemperatureCell.m
│ │ │ ├── TemperatureConverterViewController.h
│ │ │ ├── TemperatureConverterViewController.m
│ │ │ ├── TypeSelectionViewController.h
│ │ │ ├── TypeSelectionViewController.m
│ │ │ ├── UnitConverterTableViewController.h
│ │ │ ├── UnitConverterTableViewController.m
│ │ │ ├── WeightConverterViewController.h
│ │ │ └── WeightConverterViewController.m
│ │ ├── Delegate/
│ │ │ ├── MGPRecipesAppDelegate.h
│ │ │ └── MGPRecipesAppDelegate.m
│ │ ├── Models/
│ │ │ ├── Recipes.xcdatamodeld/
│ │ │ │ ├── .xccurrentversion
│ │ │ │ ├── Recipes 2.xcdatamodel/
│ │ │ │ │ ├── elements
│ │ │ │ │ └── layout
│ │ │ │ └── Recipes.xcdatamodel/
│ │ │ │ ├── elements
│ │ │ │ └── layout
│ │ │ ├── entities/
│ │ │ │ ├── Ingredient.h
│ │ │ │ ├── Ingredient.m
│ │ │ │ ├── Recipe.h
│ │ │ │ └── Recipe.m
│ │ │ └── generated/
│ │ │ ├── _Ingredient.h
│ │ │ ├── _Ingredient.m
│ │ │ ├── _Recipe.h
│ │ │ └── _Recipe.m
│ │ ├── Support/
│ │ │ ├── Recipes-Info.plist
│ │ │ ├── Recipes-Prefix.pch
│ │ │ ├── en.lproj/
│ │ │ │ └── InfoPlist.strings
│ │ │ └── main.m
│ │ └── Views/
│ │ ├── DetailHeaderView.xib
│ │ ├── EditingTableViewCell.xib
│ │ ├── InstructionsView.xib
│ │ ├── MainWindow.xib
│ │ ├── RecipeAddView.xib
│ │ ├── TemperatureCell.xib
│ │ ├── TemperatureConverter.xib
│ │ └── WeightConverter.xib
│ ├── MagicalRecordRecipes.xcodeproj/
│ │ └── project.pbxproj
│ └── Resources/
│ ├── RecipeData/
│ │ └── TemperatureData.plist
│ └── images/
│ └── iTunesArtwork
├── Support/
│ ├── Info.plist
│ └── Scripts/
│ ├── GenerateShorthandAliases.rb
│ ├── push_podspec.sh
│ └── set_version_information.sh
└── Tests/
├── Core/
│ ├── MagicalRecord+ActionsTests.m
│ ├── MagicalRecord+ShorthandTests.m
│ ├── MagicalRecord+StackTests.m
│ ├── MagicalRecordTestBase.h
│ ├── MagicalRecordTestBase.m
│ ├── NSManagedObject+MagicalRecordTests.m
│ ├── NSManagedObject+MagicalRequestTests.m
│ ├── NSManagedObjectContext+ChainSaveTests.m
│ ├── NSManagedObjectContext+MagicalSavesTests.m
│ ├── NSManagedObjectContextHelperTests.m
│ ├── NSManagedObjectHelperTests.m
│ ├── NSPersistentStoreCoordinatorHelperTests.m
│ └── NSPersistentStoreHelperTests.m
├── DataImport/
│ ├── ImportMultipleEntitiesWithNoPrimaryKeyTests.m
│ ├── ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m
│ ├── ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m
│ ├── ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m
│ ├── ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m
│ ├── ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m
│ ├── ImportSingleEntityWithNoRelationshipsTests.m
│ ├── ImportSingleRelatedEntityTests.m
│ ├── MagicalDataImportTestCase.h
│ └── MagicalDataImportTestCase.m
├── Fixtures/
│ ├── FixtureHelpers.h
│ ├── FixtureHelpers.m
│ ├── ImportSingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeysTests.m
│ ├── MultipleEntitiesWithNoPrimaryKey.json
│ ├── SampleJSONDataForImport.json
│ ├── SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json
│ ├── SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json
│ ├── SingleEntityRelatedToMappedEntityUsingDefaults.json
│ ├── SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json
│ ├── SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json
│ ├── SingleEntityRelatedToMappedEntityWithSecondaryMappings.json
│ ├── SingleEntityWithNoRelationships.json
│ ├── SingleEntityWithNoRelationships.plist
│ ├── SingleRelatedEntity.json
│ ├── TestModel/
│ │ ├── AbstractRelatedEntity.h
│ │ ├── AbstractRelatedEntity.m
│ │ ├── ConcreteRelatedEntity.h
│ │ ├── ConcreteRelatedEntity.m
│ │ ├── DifferentClassNameMapping.h
│ │ ├── DifferentClassNameMapping.m
│ │ ├── EntityWithoutEntityNameMethod.h
│ │ ├── EntityWithoutEntityNameMethod.m
│ │ ├── MappedEntity.h
│ │ ├── MappedEntity.m
│ │ ├── SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.h
│ │ ├── SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m
│ │ ├── SingleEntityRelatedToMappedEntityUsingDefaults.h
│ │ ├── SingleEntityRelatedToMappedEntityUsingDefaults.m
│ │ ├── SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.h
│ │ ├── SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m
│ │ ├── SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.h
│ │ ├── SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m
│ │ ├── SingleEntityRelatedToMappedEntityWithSecondaryMappings.h
│ │ ├── SingleEntityRelatedToMappedEntityWithSecondaryMappings.m
│ │ ├── SingleEntityWithNoRelationships.h
│ │ ├── SingleEntityWithNoRelationships.m
│ │ ├── SingleRelatedEntity.h
│ │ ├── SingleRelatedEntity.m
│ │ ├── _AbstractRelatedEntity.h
│ │ ├── _AbstractRelatedEntity.m
│ │ ├── _ConcreteRelatedEntity.h
│ │ ├── _ConcreteRelatedEntity.m
│ │ ├── _DifferentClassNameMapping.h
│ │ ├── _DifferentClassNameMapping.m
│ │ ├── _MappedEntity.h
│ │ ├── _MappedEntity.m
│ │ ├── _SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.h
│ │ ├── _SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m
│ │ ├── _SingleEntityRelatedToMappedEntityUsingDefaults.h
│ │ ├── _SingleEntityRelatedToMappedEntityUsingDefaults.m
│ │ ├── _SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.h
│ │ ├── _SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m
│ │ ├── _SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.h
│ │ ├── _SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.m
│ │ ├── _SingleEntityRelatedToMappedEntityWithSecondaryMappings.h
│ │ ├── _SingleEntityRelatedToMappedEntityWithSecondaryMappings.m
│ │ ├── _SingleEntityWithNoRelationships.h
│ │ ├── _SingleEntityWithNoRelationships.m
│ │ ├── _SingleRelatedEntity.h
│ │ └── _SingleRelatedEntity.m
│ └── TestModel.xcdatamodeld/
│ └── TestModel.xcdatamodel/
│ └── contents
└── Support/
├── MagicalRecordTestHelpers.h
├── MagicalRecordTestHelpers.m
├── MagicalRecordTests-OSX-Info.plist
├── MagicalRecordTests-OSX-Prefix.pch
├── MagicalRecordTests-iOS-Info.plist
├── MagicalRecordTests-iOS-Prefix.pch
└── MagicalRecordTests-tvOS-Info.plist
SYMBOL INDEX (55 symbols across 28 files)
FILE: Samples/iOS/Application/Controllers/TemperatureCell.h
function interface (line 49) | interface TemperatureCell : UITableViewCell {
FILE: Samples/iOS/Application/Models/entities/Ingredient.h
function interface (line 3) | interface Ingredient : _Ingredient {}
FILE: Samples/iOS/Application/Models/entities/Recipe.h
function interface (line 3) | interface Recipe : _Recipe {}
FILE: Samples/iOS/Application/Models/generated/_Ingredient.h
type IngredientAttributes (line 7) | struct IngredientAttributes {
type IngredientRelationships (line 13) | struct IngredientRelationships {
type IngredientFetchedProperties (line 17) | struct IngredientFetchedProperties {
function interface (line 26) | interface IngredientID : NSManagedObjectID {}
FILE: Samples/iOS/Application/Models/generated/_Recipe.h
type RecipeAttributes (line 7) | struct RecipeAttributes {
type RecipeRelationships (line 15) | struct RecipeRelationships {
type RecipeFetchedProperties (line 21) | struct RecipeFetchedProperties {
function interface (line 34) | interface RecipeID : NSManagedObjectID {}
FILE: Support/Scripts/GenerateShorthandAliases.rb
function processImplementation (line 12) | def processImplementation(headerFile)
function processHeader (line 90) | def processHeader(headerFile, include_deprecation_warnings)
function processDirectoryForHeaders (line 167) | def processDirectoryForHeaders(path, include_deprecation_warnings)
function processDirectoryForImplementations (line 184) | def processDirectoryForImplementations(path)
function generateHeaders (line 202) | def generateHeaders(startingPoint, include_deprecation_warnings)
function generateImplementations (line 222) | def generateImplementations(startingPoint)
FILE: Tests/Fixtures/TestModel/AbstractRelatedEntity.h
function interface (line 3) | interface AbstractRelatedEntity : _AbstractRelatedEntity {}
FILE: Tests/Fixtures/TestModel/ConcreteRelatedEntity.h
function interface (line 3) | interface ConcreteRelatedEntity : _ConcreteRelatedEntity {}
FILE: Tests/Fixtures/TestModel/DifferentClassNameMapping.h
function interface (line 3) | interface DifferentClassNameMapping : _DifferentClassNameMapping {}
FILE: Tests/Fixtures/TestModel/MappedEntity.h
function interface (line 3) | interface MappedEntity : _MappedEntity {}
FILE: Tests/Fixtures/TestModel/SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.h
function interface (line 3) | interface SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey :...
FILE: Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityUsingDefaults.h
function interface (line 3) | interface SingleEntityRelatedToMappedEntityUsingDefaults : _SingleEntity...
FILE: Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.h
function interface (line 3) | interface SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey : _Sing...
FILE: Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.h
function interface (line 3) | interface SingleEntityRelatedToMappedEntityWithNestedMappedAttributes : ...
FILE: Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityWithSecondaryMappings.h
function interface (line 3) | interface SingleEntityRelatedToMappedEntityWithSecondaryMappings : _Sing...
FILE: Tests/Fixtures/TestModel/SingleEntityWithNoRelationships.h
function interface (line 3) | interface SingleEntityWithNoRelationships : _SingleEntityWithNoRelations...
FILE: Tests/Fixtures/TestModel/SingleRelatedEntity.h
function interface (line 3) | interface SingleRelatedEntity : _SingleRelatedEntity {}
FILE: Tests/Fixtures/TestModel/_AbstractRelatedEntity.h
type AbstractRelatedEntityAttributes (line 6) | struct AbstractRelatedEntityAttributes {
function interface (line 10) | interface AbstractRelatedEntityID : NSManagedObjectID {}
FILE: Tests/Fixtures/TestModel/_ConcreteRelatedEntity.h
type ConcreteRelatedEntityAttributes (line 7) | struct ConcreteRelatedEntityAttributes {
function interface (line 11) | interface ConcreteRelatedEntityID : AbstractRelatedEntityID {}
FILE: Tests/Fixtures/TestModel/_DifferentClassNameMapping.h
function interface (line 6) | interface DifferentClassNameMappingID : NSManagedObjectID {}
FILE: Tests/Fixtures/TestModel/_MappedEntity.h
type MappedEntityAttributes (line 6) | struct MappedEntityAttributes {
type MappedEntityUserInfo (line 13) | struct MappedEntityUserInfo {
function interface (line 17) | interface MappedEntityID : NSManagedObjectID {}
FILE: Tests/Fixtures/TestModel/_SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.h
type SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyAttributes (line 6) | struct SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyAttri...
type SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyRelationships (line 10) | struct SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyRelat...
type SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyUserInfo (line 14) | struct SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyUserI...
function interface (line 20) | interface SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyID...
FILE: Tests/Fixtures/TestModel/_SingleEntityRelatedToMappedEntityUsingDefaults.h
type SingleEntityRelatedToMappedEntityUsingDefaultsAttributes (line 6) | struct SingleEntityRelatedToMappedEntityUsingDefaultsAttributes {
type SingleEntityRelatedToMappedEntityUsingDefaultsRelationships (line 10) | struct SingleEntityRelatedToMappedEntityUsingDefaultsRelationships {
function interface (line 16) | interface SingleEntityRelatedToMappedEntityUsingDefaultsID : NSManagedOb...
FILE: Tests/Fixtures/TestModel/_SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.h
type SingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyRelationships (line 6) | struct SingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyRelationshi...
function interface (line 12) | interface SingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyID : NSM...
FILE: Tests/Fixtures/TestModel/_SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.h
type SingleEntityRelatedToMappedEntityWithNestedMappedAttributesRelationships (line 6) | struct SingleEntityRelatedToMappedEntityWithNestedMappedAttributesRelati...
function interface (line 12) | interface SingleEntityRelatedToMappedEntityWithNestedMappedAttributesID ...
FILE: Tests/Fixtures/TestModel/_SingleEntityRelatedToMappedEntityWithSecondaryMappings.h
type SingleEntityRelatedToMappedEntityWithSecondaryMappingsAttributes (line 6) | struct SingleEntityRelatedToMappedEntityWithSecondaryMappingsAttributes {
type SingleEntityRelatedToMappedEntityWithSecondaryMappingsRelationships (line 11) | struct SingleEntityRelatedToMappedEntityWithSecondaryMappingsRelationshi...
function interface (line 17) | interface SingleEntityRelatedToMappedEntityWithSecondaryMappingsID : NSM...
FILE: Tests/Fixtures/TestModel/_SingleEntityWithNoRelationships.h
type SingleEntityWithNoRelationshipsAttributes (line 12) | struct SingleEntityWithNoRelationshipsAttributes {
function interface (line 33) | interface SingleEntityWithNoRelationshipsID : NSManagedObjectID {}
FILE: Tests/Fixtures/TestModel/_SingleRelatedEntity.h
type SingleRelatedEntityAttributes (line 6) | struct SingleRelatedEntityAttributes {
type SingleRelatedEntityRelationships (line 10) | struct SingleRelatedEntityRelationships {
function interface (line 22) | interface SingleRelatedEntityID : NSManagedObjectID {}
Condensed preview — 244 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,145K chars).
[
{
"path": ".clang-format",
"chars": 1001,
"preview": "BasedOnStyle: Chromium\nAlignTrailingComments: true\nBraceWrapping:\n AfterClass: true\n AfterControlStatement: true\n"
},
{
"path": ".cocoadocs.yml",
"chars": 832,
"preview": "additional_guides:\n - https://github.com/magicalpanda/MagicalRecord/wiki/Installing-MagicalRecord\n - https://github.co"
},
{
"path": ".gitignore",
"chars": 296,
"preview": "# Finder\n.DS_Store\n\n# Xcode\nbuild/*\n*.pbxuser\n!default.pbxuser\n*.mode1v3\n!default.mode1v3\n*.mode2v3\n!default.mode2v3\n*.p"
},
{
"path": ".travis.yml",
"chars": 5593,
"preview": "language: objective-c\nxcode_project: MagicalRecord.xcodeproj\nmatrix:\n include:\n - osx_image: xcode11.1\n xcode_s"
},
{
"path": "CHANGELOG.md",
"chars": 14798,
"preview": "# Changelog\n\n## Version 2.4.0\n* Adding tvOS support (Cœur, #1362)\n* Adding watchOS support, CocoaPods only (Cœur, #1363)"
},
{
"path": "CONTRIBUTING.md",
"chars": 1627,
"preview": "Thanks for contributing to this project!\n\nTo make the process as easy as possible, we've got a few guidelines that we'd "
},
{
"path": "Docs/Creating-Entities.md",
"chars": 487,
"preview": "# Creating Entities\n\nTo create and insert a new instance of an Entity in the default context, you can use:\n\n```objective"
},
{
"path": "Docs/Deleting-Entities.md",
"chars": 737,
"preview": "# Deleting Entities\n\nTo delete a single entity in the default context:\n\n```objective-c\n// Objective-C\n[myPerson MR_delet"
},
{
"path": "Docs/Fetching-Entities.md",
"chars": 9087,
"preview": "# Fetching Entities\n\n#### Basic Finding\n\nMost methods in MagicalRecord return an `NSArray` of results.\n\nAs an example, i"
},
{
"path": "Docs/Getting-Started.md",
"chars": 6952,
"preview": "To get started, import the `MagicalRecord.h` header file in your project's pch file. This will allow a global include of"
},
{
"path": "Docs/Importing-Data.md",
"chars": 12450,
"preview": "# Importing Data\n\n> We're working on updating this documentation — thanks for your patience.\n> For the moment, please re"
},
{
"path": "Docs/Installing-MagicalRecord.md",
"chars": 3875,
"preview": "# Installing MagicalRecord\n\n**Adding MagicalRecord to your project is simple**: Just choose whichever method you're most"
},
{
"path": "Docs/Logging.md",
"chars": 2135,
"preview": "## Logging\n\nMagicalRecord has logging built in to most of its interactions with Core Data. When errors occur during fetc"
},
{
"path": "Docs/Other-Resources.md",
"chars": 829,
"preview": "# Resources\n\nThe following articles highlight how to install and use aspects of MagicalRecord:\n\n* [How to make Programmi"
},
{
"path": "Docs/Saving-Entities.md",
"chars": 10500,
"preview": "# Saving Entities\n\n## When should I save?\n\nIn general, your app should save to it's persistent store(s) when data change"
},
{
"path": "Docs/Threads.md",
"chars": 3819,
"preview": "## Performing Core Data operations on Threads\n\nMagicalRecord also provides some handy methods to set up background conte"
},
{
"path": "Docs/Working-with-Managed-Object-Contexts.md",
"chars": 4995,
"preview": "# Working with Managed Object Contexts\n\n## Creating New Contexts\n\nA variety of simple class methods are provided to help"
},
{
"path": "LICENSE",
"chars": 1303,
"preview": " Copyright (c) 2010-2015, Magical Panda Software, LLC\n\n Permission is hereby granted, free of charge, to any person\n obt"
},
{
"path": "MagicalRecord/Categories/DataImport/MagicalImportFunctions.h",
"chars": 1122,
"preview": "//\n// MagicalImportFunctions.h\n// Magical Record\n//\n// Created by Saul Mora on 3/7/12.\n// Copyright (c) 2012 Magical"
},
{
"path": "MagicalRecord/Categories/DataImport/MagicalImportFunctions.m",
"chars": 3993,
"preview": "//\n// MagicalImportFunctions.m\n// Magical Record\n//\n// Created by Saul Mora on 3/7/12.\n// Copyright (c) 2012 Magical"
},
{
"path": "MagicalRecord/Categories/DataImport/NSAttributeDescription+MagicalDataImport.h",
"chars": 497,
"preview": "//\n// NSAttributeDescription+MagicalDataImport.h\n// Magical Record\n//\n// Created by Saul Mora on 9/4/11.\n// Copyrigh"
},
{
"path": "MagicalRecord/Categories/DataImport/NSAttributeDescription+MagicalDataImport.m",
"chars": 2611,
"preview": "//\n// NSAttributeDescription+MagicalDataImport.m\n// Magical Record\n//\n// Created by Saul Mora on 9/4/11.\n// Copyrigh"
},
{
"path": "MagicalRecord/Categories/DataImport/NSEntityDescription+MagicalDataImport.h",
"chars": 1204,
"preview": "//\n// NSEntityDescription+MagicalDataImport.h\n// Magical Record\n//\n// Created by Saul Mora on 9/5/11.\n// Copyright 2"
},
{
"path": "MagicalRecord/Categories/DataImport/NSEntityDescription+MagicalDataImport.m",
"chars": 1865,
"preview": "//\n// NSEntityDescription+MagicalDataImport.m\n// Magical Record\n//\n// Created by Saul Mora on 9/5/11.\n// Copyright 2"
},
{
"path": "MagicalRecord/Categories/DataImport/NSNumber+MagicalDataImport.h",
"chars": 559,
"preview": "//\n// NSNumber+MagicalDataImport.h\n// Magical Record\n//\n// Created by Saul Mora on 9/4/11.\n// Copyright 2011 Magical"
},
{
"path": "MagicalRecord/Categories/DataImport/NSNumber+MagicalDataImport.m",
"chars": 469,
"preview": "//\n// NSNumber+MagicalDataImport.m\n// Magical Record\n//\n// Created by Saul Mora on 9/4/11.\n// Copyright 2011 Magical"
},
{
"path": "MagicalRecord/Categories/DataImport/NSObject+MagicalDataImport.h",
"chars": 772,
"preview": "//\n// NSDictionary+MagicalDataImport.h\n// Magical Record\n//\n// Created by Saul Mora on 9/4/11.\n// Copyright 2011 Mag"
},
{
"path": "MagicalRecord/Categories/DataImport/NSObject+MagicalDataImport.m",
"chars": 2550,
"preview": "//\n// NSDictionary+MagicalDataImport.m\n// Magical Record\n//\n// Created by Saul Mora on 9/4/11.\n// Copyright 2011 Mag"
},
{
"path": "MagicalRecord/Categories/DataImport/NSRelationshipDescription+MagicalDataImport.h",
"chars": 391,
"preview": "//\n// NSRelationshipDescription+MagicalDataImport.h\n// Magical Record\n//\n// Created by Saul Mora on 9/4/11.\n// Copyr"
},
{
"path": "MagicalRecord/Categories/DataImport/NSRelationshipDescription+MagicalDataImport.m",
"chars": 638,
"preview": "//\n// NSRelationshipDescription+MagicalDataImport.m\n// Magical Record\n//\n// Created by Saul Mora on 9/4/11.\n// Copyr"
},
{
"path": "MagicalRecord/Categories/DataImport/NSString+MagicalDataImport.h",
"chars": 418,
"preview": "//\n// NSString+MagicalDataImport.h\n// Magical Record\n//\n// Created by Saul Mora on 12/10/11.\n// Copyright (c) 2011 M"
},
{
"path": "MagicalRecord/Categories/DataImport/NSString+MagicalDataImport.m",
"chars": 747,
"preview": "//\n// NSString+MagicalDataImport.m\n// Magical Record\n//\n// Created by Saul Mora on 12/10/11.\n// Copyright (c) 2011 M"
},
{
"path": "MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalAggregation.h",
"chars": 4031,
"preview": "//\n// NSManagedObject+MagicalAggregation.h\n// Magical Record\n//\n// Created by Saul Mora on 3/7/12.\n// Copyright (c) "
},
{
"path": "MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalAggregation.m",
"chars": 8028,
"preview": "//\n// NSManagedObject+MagicalAggregation.m\n// Magical Record\n//\n// Created by Saul Mora on 3/7/12.\n// Copyright (c) "
},
{
"path": "MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalDataImport.h",
"chars": 1796,
"preview": "//\n// NSManagedObject+MagicalDataImport.h\n//\n// Created by Saul Mora on 6/28/11.\n// Copyright 2011 Magical Panda Soft"
},
{
"path": "MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalDataImport.m",
"chars": 14279,
"preview": "//\n// NSManagedObject+MagicalDataImport.m\n//\n// Created by Saul Mora on 6/28/11.\n// Copyright 2011 Magical Panda Soft"
},
{
"path": "MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalFinders.h",
"chars": 7214,
"preview": "//\n// NSManagedObject+MagicalFinders.h\n// Magical Record\n//\n// Created by Saul Mora on 3/7/12.\n// Copyright (c) 2012"
},
{
"path": "MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalFinders.m",
"chars": 18671,
"preview": " //\n// NSManagedObject+MagicalFinders.m\n// Magical Record\n//\n// Created by Saul Mora on 3/7/12.\n// Copyright (c) "
},
{
"path": "MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalRecord.h",
"chars": 3746,
"preview": "//\n//\n// Created by Saul Mora on 11/15/09.\n// Copyright 2010 Magical Panda Software, LLC All rights reserved.\n//\n\n#imp"
},
{
"path": "MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalRecord.m",
"chars": 9076,
"preview": "\n// Created by Saul Mora on 11/15/09.\n// Copyright 2010 Magical Panda Software, LLC All rights reserved.\n//\n\n#import \""
},
{
"path": "MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalRequests.h",
"chars": 2410,
"preview": "//\n// NSManagedObject+MagicalRequests.h\n// Magical Record\n//\n// Created by Saul Mora on 3/7/12.\n// Copyright (c) 201"
},
{
"path": "MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalRequests.m",
"chars": 6296,
"preview": "//\n// NSManagedObject+MagicalRequests.m\n// Magical Record\n//\n// Created by Saul Mora on 3/7/12.\n// Copyright (c) 201"
},
{
"path": "MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalChainSave.h",
"chars": 2094,
"preview": "//\n// NSManagedObjectContext+MagicalChainSave.h\n// Magical Record\n//\n// Created by Lee on 8/27/14.\n// Copyright (c) "
},
{
"path": "MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalChainSave.m",
"chars": 1495,
"preview": "//\n// NSManagedObjectContext+MagicalChainSave.m\n// Magical Record\n//\n// Created by Lee on 8/27/14.\n// Copyright (c) "
},
{
"path": "MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalObserving.h",
"chars": 2070,
"preview": "//\n// NSManagedObjectContext+MagicalObserving.h\n// Magical Record\n//\n// Created by Saul Mora on 3/9/12.\n// Copyright"
},
{
"path": "MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalObserving.m",
"chars": 4182,
"preview": "//\n// NSManagedObjectContext+MagicalObserving.m\n// Magical Record\n//\n// Created by Saul Mora on 3/9/12.\n// Copyright"
},
{
"path": "MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalRecord.h",
"chars": 4632,
"preview": "//\n// NSManagedObjectContext+MagicalRecord.h\n//\n// Created by Saul Mora on 11/23/09.\n// Copyright 2010 Magical Panda "
},
{
"path": "MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalRecord.m",
"chars": 11583,
"preview": "//\n// NSManagedObjectContext+MagicalRecord.m\n//\n// Created by Saul Mora on 11/23/09.\n// Copyright 2010 Magical Panda "
},
{
"path": "MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalSaves.h",
"chars": 5092,
"preview": "//\n// NSManagedObjectContext+MagicalSaves.h\n// Magical Record\n//\n// Created by Saul Mora on 3/9/12.\n// Copyright (c)"
},
{
"path": "MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalSaves.m",
"chars": 6237,
"preview": "//\n// NSManagedObjectContext+MagicalSaves.m\n// Magical Record\n//\n// Created by Saul Mora on 3/9/12.\n// Copyright (c)"
},
{
"path": "MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalThreading.h",
"chars": 848,
"preview": "//\n// NSManagedObjectContext+MagicalThreading.h\n// Magical Record\n//\n// Created by Saul Mora on 3/9/12.\n// Copyright"
},
{
"path": "MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalThreading.m",
"chars": 3306,
"preview": "//\n// NSManagedObjectContext+MagicalThreading.m\n// Magical Record\n//\n// Created by Saul Mora on 3/9/12.\n// Copyright"
},
{
"path": "MagicalRecord/Categories/NSManagedObjectModel+MagicalRecord.h",
"chars": 1088,
"preview": "//\n// NSManagedObjectModel+MagicalRecord.h\n//\n// Created by Saul Mora on 3/11/10.\n// Copyright 2010 Magical Panda Sof"
},
{
"path": "MagicalRecord/Categories/NSManagedObjectModel+MagicalRecord.m",
"chars": 2514,
"preview": "//\n// NSManagedObjectModel+MagicalRecord.m\n//\n// Created by Saul Mora on 3/11/10.\n// Copyright 2010 Magical Panda Sof"
},
{
"path": "MagicalRecord/Categories/NSPersistentStore+MagicalRecord.h",
"chars": 1026,
"preview": "//\n// NSPersistentStore+MagicalRecord.h\n//\n// Created by Saul Mora on 3/11/10.\n// Copyright 2010 Magical Panda Softwa"
},
{
"path": "MagicalRecord/Categories/NSPersistentStore+MagicalRecord.m",
"chars": 1969,
"preview": "//\n// NSPersistentStore+MagicalRecord.m\n//\n// Created by Saul Mora on 3/11/10.\n// Copyright 2010 Magical Panda Softwa"
},
{
"path": "MagicalRecord/Categories/NSPersistentStoreCoordinator+MagicalRecord.h",
"chars": 5326,
"preview": "//\n// NSPersistentStoreCoordinator+MagicalRecord.h\n//\n// Created by Saul Mora on 3/11/10.\n// Copyright 2010 Magical P"
},
{
"path": "MagicalRecord/Categories/NSPersistentStoreCoordinator+MagicalRecord.m",
"chars": 20949,
"preview": "//\n// NSPersistentStoreCoordinator+MagicalRecord.m\n//\n// Created by Saul Mora on 3/11/10.\n// Copyright 2010 Magical P"
},
{
"path": "MagicalRecord/Core/MagicalRecord+Actions.h",
"chars": 2248,
"preview": "//\n// MagicalRecord+Actions.h\n//\n// Created by Saul Mora on 2/24/11.\n// Copyright 2011 Magical Panda Software. All ri"
},
{
"path": "MagicalRecord/Core/MagicalRecord+Actions.m",
"chars": 4420,
"preview": "//\n// MagicalRecord+Actions.m\n//\n// Created by Saul Mora on 2/24/11.\n// Copyright 2011 Magical Panda Software. All ri"
},
{
"path": "MagicalRecord/Core/MagicalRecord+ErrorHandling.h",
"chars": 548,
"preview": "//\n// MagicalRecord+ErrorHandling.h\n// Magical Record\n//\n// Created by Saul Mora on 3/6/12.\n// Copyright (c) 2012 Ma"
},
{
"path": "MagicalRecord/Core/MagicalRecord+ErrorHandling.m",
"chars": 2224,
"preview": "//\n// MagicalRecord+ErrorHandling.m\n// Magical Record\n//\n// Created by Saul Mora on 3/6/12.\n// Copyright (c) 2012 Ma"
},
{
"path": "MagicalRecord/Core/MagicalRecord+Options.h",
"chars": 5074,
"preview": "//\n// MagicalRecord+Options.h\n// Magical Record\n//\n// Created by Saul Mora on 3/6/12.\n// Copyright (c) 2012 Magical "
},
{
"path": "MagicalRecord/Core/MagicalRecord+Options.m",
"chars": 1790,
"preview": "//\n// MagicalRecord+Options.m\n// Magical Record\n//\n// Created by Saul Mora on 3/6/12.\n// Copyright (c) 2012 Magical "
},
{
"path": "MagicalRecord/Core/MagicalRecord+Setup.h",
"chars": 771,
"preview": "//\n// MagicalRecord+Setup.h\n// Magical Record\n//\n// Created by Saul Mora on 3/7/12.\n// Copyright (c) 2012 Magical Pa"
},
{
"path": "MagicalRecord/Core/MagicalRecord+Setup.m",
"chars": 2874,
"preview": "//\n// MagicalRecord+Setup.m\n// Magical Record\n//\n// Created by Saul Mora on 3/7/12.\n// Copyright (c) 2012 Magical Pa"
},
{
"path": "MagicalRecord/Core/MagicalRecord+ShorthandMethods.h",
"chars": 208,
"preview": "//\n// Copyright (c) 2015 Magical Panda Software LLC. All rights reserved.\n\n#import <MagicalRecord/MagicalRecordInternal"
},
{
"path": "MagicalRecord/Core/MagicalRecord+ShorthandMethods.m",
"chars": 5233,
"preview": "//\n// Copyright (c) 2015 Magical Panda Software LLC. All rights reserved.\n\n#import \"MagicalRecord+ShorthandMethods.h\"\n#"
},
{
"path": "MagicalRecord/Core/MagicalRecord+iCloud.h",
"chars": 2251,
"preview": "//\n// MagicalRecord+iCloud.h\n// Magical Record\n//\n// Created by Saul Mora on 3/7/12.\n// Copyright (c) 2012 Magical P"
},
{
"path": "MagicalRecord/Core/MagicalRecord+iCloud.m",
"chars": 4194,
"preview": "//\n// MagicalRecord+iCloud.m\n// Magical Record\n//\n// Created by Saul Mora on 3/7/12.\n// Copyright (c) 2012 Magical P"
},
{
"path": "MagicalRecord/Core/MagicalRecordDeprecationMacros.h",
"chars": 499,
"preview": "//\n// Created by Tony Arnold on 10/04/2014.\n// Copyright (c) 2014 Magical Panda Software LLC. All rights reserved.\n//\n"
},
{
"path": "MagicalRecord/Core/MagicalRecordInternal.h",
"chars": 3034,
"preview": "//\n// MagicalRecord.h\n//\n// Created by Saul Mora on 3/11/10.\n// Copyright 2010 Magical Panda Software, LLC All rights"
},
{
"path": "MagicalRecord/Core/MagicalRecordInternal.m",
"chars": 2809,
"preview": "//\n// MagicalRecord.m\n//\n// Created by Saul Mora on 3/11/10.\n// Copyright 2010 Magical Panda Software, LLC All rights"
},
{
"path": "MagicalRecord/Core/MagicalRecordLogging.h",
"chars": 2262,
"preview": "//\n// MagicalRecordLogging.h\n// MagicalRecord\n//\n// Created by Saul Mora on 10/4/13.\n// Copyright (c) 2013 Magical P"
},
{
"path": "MagicalRecord/Core/MagicalRecordShorthandMethodAliases.h",
"chars": 26396,
"preview": "#import <MagicalRecord/MagicalRecord.h>\n#import <MagicalRecord/MagicalRecordDeprecationMacros.h>\n#import <MagicalRecord/"
},
{
"path": "MagicalRecord/Core/MagicalRecordXcode7CompatibilityMacros.h",
"chars": 1350,
"preview": "//\n// Copyright © 2015 Magical Panda Software LLC. All rights reserved.\n//\n// The following preprocessor macros can be"
},
{
"path": "MagicalRecord/MagicalRecord.h",
"chars": 2034,
"preview": "//\n// MagicalRecord.h\n//\n// Created by Saul Mora on 28/07/10.\n// Copyright 2010 Magical Panda Software, LLC All right"
},
{
"path": "MagicalRecord.podspec",
"chars": 1304,
"preview": "Pod::Spec.new do |s|\n s.default_subspec = 'Core'\n s.name = 'MagicalRecord'\n s.version = '2.4.0'\n s.license = '"
},
{
"path": "MagicalRecord.xcodeproj/project.pbxproj",
"chars": 306671,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
},
{
"path": "MagicalRecord.xcodeproj/xcshareddata/xcschemes/MagicalRecord for OS X.xcscheme",
"chars": 4039,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"0700\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "MagicalRecord.xcodeproj/xcshareddata/xcschemes/MagicalRecord for iOS.xcscheme",
"chars": 4033,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"0700\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "MagicalRecord.xcodeproj/xcshareddata/xcschemes/MagicalRecord for tvOS.xcscheme",
"chars": 4005,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"0700\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "MagicalRecord.xcodeproj/xcshareddata/xcschemes/libMagicalRecord for OS X.xcscheme",
"chars": 3269,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"0700\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "MagicalRecord.xcodeproj/xcshareddata/xcschemes/libMagicalRecord for iOS.xcscheme",
"chars": 3257,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"0700\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "MagicalRecord.xcodeproj/xcshareddata/xcschemes/libMagicalRecord for tvOS.xcscheme",
"chars": 4003,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"0700\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "README.md",
"chars": 3200,
"preview": "# "
},
{
"path": "Samples/iOS/Application/Categories/ImageToDataTransformer.h",
"chars": 200,
"preview": "//\n// ImageToDataTransformer.h\n// MagicalRecordRecipes\n//\n// Created by Saul Mora on 5/19/13.\n//\n//\n\n#import <Foundat"
},
{
"path": "Samples/iOS/Application/Categories/ImageToDataTransformer.m",
"chars": 524,
"preview": "//\n// ImageToDataTransformer.m\n// MagicalRecordRecipes\n//\n// Created by Saul Mora on 5/19/13.\n//\n//\n\n#import \"ImageTo"
},
{
"path": "Samples/iOS/Application/Controllers/AddressBook_Prefix.pch",
"chars": 264,
"preview": "//\n// Prefix header for all source files of the 'AddressBook' target in the 'AddressBook' project\n//\n\n#ifdef __OBJC__\n#i"
},
{
"path": "Samples/iOS/Application/Controllers/EditingTableViewCell.h",
"chars": 2751,
"preview": "/*\n File: EditingTableViewCell.h\n Abstract: A table view cell that displays a label and a text field so that a value"
},
{
"path": "Samples/iOS/Application/Controllers/EditingTableViewCell.m",
"chars": 2698,
"preview": "/*\n File: EditingTableViewCell.m \n Abstract: A table view cell that displays a label and a text field so that a valu"
},
{
"path": "Samples/iOS/Application/Controllers/ImperialPickerController.h",
"chars": 2754,
"preview": "/*\n File: ImperialPickerController.h\n Abstract: Controller to managed a picker view displaying imperial weights.\n \n "
},
{
"path": "Samples/iOS/Application/Controllers/ImperialPickerController.m",
"chars": 6127,
"preview": "/*\n File: ImperialPickerController.m \n Abstract: Controller to managed a picker view displaying imperial weights.\n "
},
{
"path": "Samples/iOS/Application/Controllers/IngredientDetailViewController.h",
"chars": 2852,
"preview": "/*\n File: IngredientDetailViewController.h\n Abstract: Table view controller to manage editing details of a recipe in"
},
{
"path": "Samples/iOS/Application/Controllers/IngredientDetailViewController.m",
"chars": 5995,
"preview": "/*\n File: IngredientDetailViewController.m \n Abstract: Table view controller to manage editing details of a recipe i"
},
{
"path": "Samples/iOS/Application/Controllers/InstructionsViewController.h",
"chars": 2793,
"preview": "/*\n File: InstructionsViewController.h\n Abstract: View controller to manage a text view to allow the user to edit in"
},
{
"path": "Samples/iOS/Application/Controllers/InstructionsViewController.m",
"chars": 3896,
"preview": "/*\n File: InstructionsViewController.m \n Abstract: View controller to manage a text view to allow the user to edit i"
},
{
"path": "Samples/iOS/Application/Controllers/MetricPickerController.h",
"chars": 2799,
"preview": "/*\n File: MetricPickerController.h\n Abstract: Controller to managed a picker view displaying metric weights.\n \n Ver"
},
{
"path": "Samples/iOS/Application/Controllers/MetricPickerController.m",
"chars": 8128,
"preview": "/*\n File: MetricPickerController.m \n Abstract: Controller to managed a picker view displaying metric weights.\n \n V"
},
{
"path": "Samples/iOS/Application/Controllers/RecipeAddViewController.h",
"chars": 3173,
"preview": "/*\n File: RecipeAddViewController.h\n Abstract: View controller to allow the user to add a new recipe and choose its "
},
{
"path": "Samples/iOS/Application/Controllers/RecipeAddViewController.m",
"chars": 4211,
"preview": "/*\n File: RecipeAddViewController.m \n Abstract: View controller to allow the user to add a new recipe and choose its"
},
{
"path": "Samples/iOS/Application/Controllers/RecipeDetailViewController.h",
"chars": 3263,
"preview": "/*\n File: RecipeDetailViewController.h\n Abstract: Table view controller to manage an editable table view that displa"
},
{
"path": "Samples/iOS/Application/Controllers/RecipeDetailViewController.m",
"chars": 23134,
"preview": "/*\n File: RecipeDetailViewController.m \n Abstract: Table view controller to manage an editable table view that displ"
},
{
"path": "Samples/iOS/Application/Controllers/RecipeListTableViewController.h",
"chars": 3112,
"preview": " /*\n File: RecipeListTableViewController.h\n Abstract: Table view controller to manage an editable table view that di"
},
{
"path": "Samples/iOS/Application/Controllers/RecipeListTableViewController.m",
"chars": 11586,
"preview": "/*\n File: RecipeListTableViewController.m \n Abstract: Table view controller to manage an editable table view that di"
},
{
"path": "Samples/iOS/Application/Controllers/RecipePhotoViewController.h",
"chars": 2731,
"preview": "/*\n File: RecipePhotoViewController.h\n Abstract: View controller to manage a view to display a recipe's photo.\n The "
},
{
"path": "Samples/iOS/Application/Controllers/RecipePhotoViewController.m",
"chars": 3446,
"preview": "/*\n File: RecipePhotoViewController.m \n Abstract: View controller to manage a view to display a recipe's photo.\n The"
},
{
"path": "Samples/iOS/Application/Controllers/RecipeTableViewCell.h",
"chars": 3132,
"preview": "/*\n File: RecipeTableViewCell.h\n Abstract: A table view cell that displays information about a Recipe. It uses indi"
},
{
"path": "Samples/iOS/Application/Controllers/RecipeTableViewCell.m",
"chars": 7028,
"preview": "/*\n File: RecipeTableViewCell.m \n Abstract: A table view cell that displays information about a Recipe. It uses ind"
},
{
"path": "Samples/iOS/Application/Controllers/TemperatureCell.h",
"chars": 2895,
"preview": "/*\n File: TemperatureCell.h\n Abstract: A table view cell that displays temperature in Centigrade, Fahrenheit, and Ga"
},
{
"path": "Samples/iOS/Application/Controllers/TemperatureCell.m",
"chars": 2949,
"preview": "/*\n File: TemperatureCell.m \n Abstract: A table view cell that displays temperature in Centigrade, Fahrenheit, and G"
},
{
"path": "Samples/iOS/Application/Controllers/TemperatureConverterViewController.h",
"chars": 2881,
"preview": " /*\n File: TemperatureConverterViewController.h\n Abstract: View controller to display cooking temperatures in Centig"
},
{
"path": "Samples/iOS/Application/Controllers/TemperatureConverterViewController.m",
"chars": 4674,
"preview": "/*\n File: TemperatureConverterViewController.m \n Abstract: View controller to display cooking temperatures in Centig"
},
{
"path": "Samples/iOS/Application/Controllers/TypeSelectionViewController.h",
"chars": 2955,
"preview": "/*\n File: TypeSelectionViewController.h\n Abstract: Table view controller to allow the user to select the recipe type"
},
{
"path": "Samples/iOS/Application/Controllers/TypeSelectionViewController.m",
"chars": 5894,
"preview": "/*\n File: TypeSelectionViewController.m \n Abstract: Table view controller to allow the user to select the recipe typ"
},
{
"path": "Samples/iOS/Application/Controllers/UnitConverterTableViewController.h",
"chars": 2629,
"preview": "/*\n File: UnitConverterTableViewController.h\n Abstract: Table view controller to display two table view cells to all"
},
{
"path": "Samples/iOS/Application/Controllers/UnitConverterTableViewController.m",
"chars": 4721,
"preview": "/*\n File: UnitConverterTableViewController.m \n Abstract: Table view controller to display two table view cells to al"
},
{
"path": "Samples/iOS/Application/Controllers/WeightConverterViewController.h",
"chars": 3286,
"preview": "/*\n File: WeightConverterViewController.h\n Abstract: View controller to manage conversion of metric to imperial unit"
},
{
"path": "Samples/iOS/Application/Controllers/WeightConverterViewController.m",
"chars": 3939,
"preview": "/*\n File: WeightConverterViewController.m \n Abstract: View controller to manage conversion of metric to imperial uni"
},
{
"path": "Samples/iOS/Application/Delegate/MGPRecipesAppDelegate.h",
"chars": 454,
"preview": "//\n// MGPAppDelegate.h\n// Recipes\n//\n// Created by Saul Mora on 5/19/13.\n//\n//\n\n#import <UIKit/UIKit.h>\n#import \"Reci"
},
{
"path": "Samples/iOS/Application/Delegate/MGPRecipesAppDelegate.m",
"chars": 1576,
"preview": "//\n// MGPAppDelegate.m\n// Recipes\n//\n// Created by Saul Mora on 5/19/13.\n//\n//\n\n#import \"MGPRecipesAppDelegate.h\"\n\nst"
},
{
"path": "Samples/iOS/Application/Models/Recipes.xcdatamodeld/.xccurrentversion",
"chars": 260,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Samples/iOS/Application/Models/entities/Ingredient.h",
"chars": 96,
"preview": "#import \"_Ingredient.h\"\n\n@interface Ingredient : _Ingredient {}\n// Custom logic goes here.\n@end\n"
},
{
"path": "Samples/iOS/Application/Models/entities/Ingredient.m",
"chars": 152,
"preview": "#import \"Ingredient.h\"\n\n\n@interface Ingredient ()\n\n// Private interface goes here.\n\n@end\n\n\n@implementation Ingredient\n\n/"
},
{
"path": "Samples/iOS/Application/Models/entities/Recipe.h",
"chars": 84,
"preview": "#import \"_Recipe.h\"\n\n@interface Recipe : _Recipe {}\n// Custom logic goes here.\n@end\n"
},
{
"path": "Samples/iOS/Application/Models/entities/Recipe.m",
"chars": 140,
"preview": "#import \"Recipe.h\"\n\n\n@interface Recipe ()\n\n// Private interface goes here.\n\n@end\n\n\n@implementation Recipe\n\n// Custom log"
},
{
"path": "Samples/iOS/Application/Models/generated/_Ingredient.h",
"chars": 1994,
"preview": "// DO NOT EDIT. This file is machine-generated and constantly overwritten.\n// Make changes to Ingredient.h instead.\n\n#im"
},
{
"path": "Samples/iOS/Application/Models/generated/_Ingredient.m",
"chars": 1918,
"preview": "// DO NOT EDIT. This file is machine-generated and constantly overwritten.\n// Make changes to Ingredient.m instead.\n\n#im"
},
{
"path": "Samples/iOS/Application/Models/generated/_Recipe.h",
"chars": 2996,
"preview": "// DO NOT EDIT. This file is machine-generated and constantly overwritten.\n// Make changes to Recipe.h instead.\n\n#import"
},
{
"path": "Samples/iOS/Application/Models/generated/_Recipe.m",
"chars": 1696,
"preview": "// DO NOT EDIT. This file is machine-generated and constantly overwritten.\n// Make changes to Recipe.m instead.\n\n#import"
},
{
"path": "Samples/iOS/Application/Support/Recipes-Info.plist",
"chars": 1234,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Samples/iOS/Application/Support/Recipes-Prefix.pch",
"chars": 347,
"preview": "//\n// Prefix header for all source files of the 'Recipes' target in the 'Recipes' project\n//\n\n#import <Availability.h>\n\n"
},
{
"path": "Samples/iOS/Application/Support/en.lproj/InfoPlist.strings",
"chars": 45,
"preview": "/* Localized versions of Info.plist keys */\n\n"
},
{
"path": "Samples/iOS/Application/Support/main.m",
"chars": 300,
"preview": "//\n// main.m\n// Recipes\n//\n// Created by Saul Mora on 5/19/13.\n//\n//\n\n#import <UIKit/UIKit.h>\n\n#import \"MGPRecipesApp"
},
{
"path": "Samples/iOS/Application/Views/DetailHeaderView.xib",
"chars": 6774,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"3.0\" toolsVe"
},
{
"path": "Samples/iOS/Application/Views/EditingTableViewCell.xib",
"chars": 3940,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"3.0\" toolsVe"
},
{
"path": "Samples/iOS/Application/Views/InstructionsView.xib",
"chars": 3598,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"3.0\" toolsVe"
},
{
"path": "Samples/iOS/Application/Views/MainWindow.xib",
"chars": 4556,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"3.0\" toolsVe"
},
{
"path": "Samples/iOS/Application/Views/RecipeAddView.xib",
"chars": 2749,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"3.0\" toolsVe"
},
{
"path": "Samples/iOS/Application/Views/TemperatureCell.xib",
"chars": 4272,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"3.0\" toolsVe"
},
{
"path": "Samples/iOS/Application/Views/TemperatureConverter.xib",
"chars": 4484,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"3.0\" toolsVe"
},
{
"path": "Samples/iOS/Application/Views/WeightConverter.xib",
"chars": 11504,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"3.0\" toolsVe"
},
{
"path": "Samples/iOS/MagicalRecordRecipes.xcodeproj/project.pbxproj",
"chars": 66294,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 51;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
},
{
"path": "Samples/iOS/Resources/RecipeData/TemperatureData.plist",
"chars": 2082,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Support/Info.plist",
"chars": 925,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Support/Scripts/GenerateShorthandAliases.rb",
"chars": 9135,
"preview": "#!/usr/bin/env ruby\n#\n# ProcessHeader.rb\n# Magical Record\n#\n# Created by Saul Mora on 11/14/11.\n# Copyright 2011 Mag"
},
{
"path": "Support/Scripts/push_podspec.sh",
"chars": 78,
"preview": "#!/usr/bin/env bash\n\nsource ~/.rvm/scripts/rvm\nrvm use default\npod trunk push\n"
},
{
"path": "Support/Scripts/set_version_information.sh",
"chars": 559,
"preview": "#!/bin/bash\n\ngit=$(sh /etc/profile; which git)\nnumber_of_commits=$(\"$git\" rev-list HEAD --count)\ngit_release_version=$(\""
},
{
"path": "Tests/Core/MagicalRecord+ActionsTests.m",
"chars": 9523,
"preview": "//\n// Created by Tony Arnold on 25/03/2014.\n// Copyright (c) 2014 Magical Panda Software LLC. All rights reserved.\n//\n"
},
{
"path": "Tests/Core/MagicalRecord+ShorthandTests.m",
"chars": 1111,
"preview": "//\n// Created by Tony Arnold on 28/01/2016.\n// Copyright © 2016 Magical Panda Software LLC. All rights reserved.\n\n#imp"
},
{
"path": "Tests/Core/MagicalRecord+StackTests.m",
"chars": 4099,
"preview": "//\n// Created by Saul Mora on 7/15/11.\n// Copyright 2011 Magical Panda Software LLC. All rights reserved.\n//\n\n#import "
},
{
"path": "Tests/Core/MagicalRecordTestBase.h",
"chars": 270,
"preview": "//\n// Created by Tony Arnold on 21/12/2013.\n// Copyright (c) 2013 Magical Panda Software LLC. All rights reserved.\n//\n"
},
{
"path": "Tests/Core/MagicalRecordTestBase.m",
"chars": 675,
"preview": "//\n// Created by Tony Arnold on 21/12/2013.\n// Copyright (c) 2013 Magical Panda Software LLC. All rights reserved.\n//\n"
},
{
"path": "Tests/Core/NSManagedObject+MagicalRecordTests.m",
"chars": 1260,
"preview": "//\n// Created by Tony Arnold on 11/04/2014.\n// Copyright (c) 2014 Magical Panda Software LLC. All rights reserved.\n//\n"
},
{
"path": "Tests/Core/NSManagedObject+MagicalRequestTests.m",
"chars": 1454,
"preview": "//\n// NSManagedObject+MagicalRequestTests.m\n// MagicalRecord\n//\n// Created by Sam Dean on 30/07/2016.\n// Copyright ©"
},
{
"path": "Tests/Core/NSManagedObjectContext+ChainSaveTests.m",
"chars": 2160,
"preview": "//\n// NSManagedObjectContext+ChainSaveTests.m\n// MagicalRecord\n//\n// Created by Lee on 12/1/14.\n// Copyright (c) 201"
},
{
"path": "Tests/Core/NSManagedObjectContext+MagicalSavesTests.m",
"chars": 10368,
"preview": "//\n// Created by Tony Arnold on 25/03/2014.\n// Copyright (c) 2014 Magical Panda Software LLC. All rights reserved.\n//\n"
},
{
"path": "Tests/Core/NSManagedObjectContextHelperTests.m",
"chars": 1669,
"preview": "//\n// NSManagedObjectContextHelperTests.m\n// Magical Record\n//\n// Created by Saul Mora on 7/15/11.\n// Copyright 2011"
},
{
"path": "Tests/Core/NSManagedObjectHelperTests.m",
"chars": 7331,
"preview": "//\n// NSManagedObjectHelperTests.m\n// Magical Record\n//\n// Created by Saul Mora on 7/15/11.\n// Copyright 2011 Magica"
},
{
"path": "Tests/Core/NSPersistentStoreCoordinatorHelperTests.m",
"chars": 4881,
"preview": "//\n// NSPersistentStoreCoordinatorHelperTests.m\n// Magical Record\n//\n// Created by Saul Mora on 7/15/11.\n// Copyrigh"
},
{
"path": "Tests/Core/NSPersistentStoreHelperTests.m",
"chars": 3880,
"preview": "//\n// NSPersistentStoreHelperTests.m\n// Magical Record\n//\n// Created by Saul Mora on 7/15/11.\n// Copyright 2011 Magi"
},
{
"path": "Tests/DataImport/ImportMultipleEntitiesWithNoPrimaryKeyTests.m",
"chars": 974,
"preview": "//\n// ImportMultipleEntitiesWithNoPrimaryKeyTests.m\n// MagicalRecord\n//\n// Created by Sérgio Estêvão on 09/01/2014.\n/"
},
{
"path": "Tests/DataImport/ImportSingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m",
"chars": 2572,
"preview": "//\n// Import SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKeyTests.m\n// Magical Record\n//\n// Created by S"
},
{
"path": "Tests/DataImport/ImportSingleEntityRelatedToMappedEntityUsingDefaultsTests.m",
"chars": 2341,
"preview": "//\n// ImportSingleEntityRelatedToMappedEntityUsingDefaults.m\n// Magical Record\n//\n// Created by Saul Mora on 8/11/11."
},
{
"path": "Tests/DataImport/ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKeyTests.m",
"chars": 5233,
"preview": "//\n// ImportSingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.m\n// Magical Record\n//\n// Created by Saul Mora on "
},
{
"path": "Tests/DataImport/ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m",
"chars": 1721,
"preview": "//\n// ImportSingleEntityRelatedToMappedEntityWithNestedMappedAttributesTests.m\n// Magical Record\n//\n// Created by Sau"
},
{
"path": "Tests/DataImport/ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m",
"chars": 1233,
"preview": "//\n// ImportSingleEntityRelatedToMappedEntityWithSecondaryMappingsTests.m\n// Magical Record\n//\n// Created by Saul Mor"
},
{
"path": "Tests/DataImport/ImportSingleEntityWithNoRelationshipsTests.m",
"chars": 8772,
"preview": "//\n// DataImportTests.m\n// Magical Record\n//\n// Created by Saul Mora on 7/15/11.\n// Copyright 2011 Magical Panda Sof"
},
{
"path": "Tests/DataImport/ImportSingleRelatedEntityTests.m",
"chars": 6761,
"preview": "//\n// ImportSingleEntityWithRelatedEntitiesTests.m\n// Magical Record\n//\n// Created by Saul Mora on 7/23/11.\n// Copyr"
},
{
"path": "Tests/DataImport/MagicalDataImportTestCase.h",
"chars": 419,
"preview": "//\n// MagicalDataImportTestCase.h\n// Magical Record\n//\n// Created by Saul Mora on 8/16/11.\n// Copyright (c) 2011 Mag"
},
{
"path": "Tests/DataImport/MagicalDataImportTestCase.m",
"chars": 538,
"preview": "//\n// MagicalDataImportTestCase.m\n// Magical Record\n//\n// Created by Saul Mora on 8/16/11.\n// Copyright (c) 2011 Mag"
},
{
"path": "Tests/Fixtures/FixtureHelpers.h",
"chars": 412,
"preview": "//\n// FixtureHelpers.h\n// Magical Record\n//\n// Created by Saul Mora on 7/15/11.\n// Copyright 2011 Magical Panda Soft"
},
{
"path": "Tests/Fixtures/FixtureHelpers.m",
"chars": 1512,
"preview": "//\n// FixtureHelpers.m\n// Magical Record\n//\n// Created by Saul Mora on 7/15/11.\n// Copyright 2011 Magical Panda Soft"
},
{
"path": "Tests/Fixtures/ImportSingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeysTests.m",
"chars": 3390,
"preview": "//\n// ImportSingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeysTests.m\n// Magical Record\n//\n// Created by S"
},
{
"path": "Tests/Fixtures/MultipleEntitiesWithNoPrimaryKey.json",
"chars": 274,
"preview": "[\n {\n \"stringTestAttribute\": \"This is a test value\",\n },\n {\n \"stringTestAttribute\": \"This is a te"
},
{
"path": "Tests/Fixtures/SampleJSONDataForImport.json",
"chars": 8,
"preview": "{\n \n}"
},
{
"path": "Tests/Fixtures/SingleEntityRelatedToManyMappedEntitiesUsingListOfPrimaryKeys.json",
"chars": 61,
"preview": "{\n \"mappedEntities\": [1,2,3,4],\n \"testPrimaryKey\": 84\n}"
},
{
"path": "Tests/Fixtures/SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.json",
"chars": 463,
"preview": "{\n \"mappedEntities\":\n [\n {\n \"id\": 1,\n \"sampleAttribute\": \"Sample Attribute Value 1\"\n "
},
{
"path": "Tests/Fixtures/SingleEntityRelatedToMappedEntityUsingDefaults.json",
"chars": 128,
"preview": "{\n \"mappedEntity\":\n {\n \"mappedEntityID\": 42,\n \"sampleAttribute\": \"This is from the sample json file\""
},
{
"path": "Tests/Fixtures/SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.json",
"chars": 127,
"preview": "{\n \"someRandomAttributeName\":\n {\n \"id\": 42,\n \"sampleAttribute\": \"This is from the sample json file\"\n"
},
{
"path": "Tests/Fixtures/SingleEntityRelatedToMappedEntityWithNestedMappedAttributes.json",
"chars": 163,
"preview": "{\n \"mappedEntity\":\n {\n \"mappedEntityID\": 42,\n \"attributeValue\":\n {\n \"nestedValue\":"
},
{
"path": "Tests/Fixtures/SingleEntityRelatedToMappedEntityWithSecondaryMappings.json",
"chars": 203,
"preview": "{\n \"actualMappedKey\": \"mapped value from sample json file\",\n \"actualRelatedObject\":\n {\n \"id\": 50,\n "
},
{
"path": "Tests/Fixtures/SingleEntityWithNoRelationships.json",
"chars": 969,
"preview": "{\n \"int64TestAttribute\": 10158365420975381,\n \"stringTestAttribute\": \"This is a test value\",\n \"int32TestAttribut"
},
{
"path": "Tests/Fixtures/SingleEntityWithNoRelationships.plist",
"chars": 1108,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Tests/Fixtures/SingleRelatedEntity.json",
"chars": 1405,
"preview": "{\n \"testAbstractToOneRelationship\":\n {\n \"sampleBaseAttribute\": \"This should be imported as: BASE ATTRIBUTE "
},
{
"path": "Tests/Fixtures/TestModel/AbstractRelatedEntity.h",
"chars": 129,
"preview": "#import \"_AbstractRelatedEntity.h\"\n\n@interface AbstractRelatedEntity : _AbstractRelatedEntity {}\n// Custom logic goes he"
},
{
"path": "Tests/Fixtures/TestModel/AbstractRelatedEntity.m",
"chars": 183,
"preview": "#import \"AbstractRelatedEntity.h\"\n\n@interface AbstractRelatedEntity ()\n\n// Private interface goes here.\n\n@end\n\n@implemen"
},
{
"path": "Tests/Fixtures/TestModel/ConcreteRelatedEntity.h",
"chars": 129,
"preview": "#import \"_ConcreteRelatedEntity.h\"\n\n@interface ConcreteRelatedEntity : _ConcreteRelatedEntity {}\n// Custom logic goes he"
},
{
"path": "Tests/Fixtures/TestModel/ConcreteRelatedEntity.m",
"chars": 183,
"preview": "#import \"ConcreteRelatedEntity.h\"\n\n@interface ConcreteRelatedEntity ()\n\n// Private interface goes here.\n\n@end\n\n@implemen"
},
{
"path": "Tests/Fixtures/TestModel/DifferentClassNameMapping.h",
"chars": 141,
"preview": "#import \"_DifferentClassNameMapping.h\"\n\n@interface DifferentClassNameMapping : _DifferentClassNameMapping {}\n// Custom l"
},
{
"path": "Tests/Fixtures/TestModel/DifferentClassNameMapping.m",
"chars": 195,
"preview": "#import \"DifferentClassNameMapping.h\"\n\n@interface DifferentClassNameMapping ()\n\n// Private interface goes here.\n\n@end\n\n@"
},
{
"path": "Tests/Fixtures/TestModel/EntityWithoutEntityNameMethod.h",
"chars": 217,
"preview": "//\n// Created by Tony Arnold on 11/04/2014.\n// Copyright (c) 2014 Magical Panda Software LLC. All rights reserved.\n//\n"
},
{
"path": "Tests/Fixtures/TestModel/EntityWithoutEntityNameMethod.m",
"chars": 216,
"preview": "//\n// Created by Tony Arnold on 11/04/2014.\n// Copyright (c) 2014 Magical Panda Software LLC. All rights reserved.\n//\n"
},
{
"path": "Tests/Fixtures/TestModel/MappedEntity.h",
"chars": 102,
"preview": "#import \"_MappedEntity.h\"\n\n@interface MappedEntity : _MappedEntity {}\n// Custom logic goes here.\n@end\n"
},
{
"path": "Tests/Fixtures/TestModel/MappedEntity.m",
"chars": 156,
"preview": "#import \"MappedEntity.h\"\n\n@interface MappedEntity ()\n\n// Private interface goes here.\n\n@end\n\n@implementation MappedEntit"
},
{
"path": "Tests/Fixtures/TestModel/SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.h",
"chars": 246,
"preview": "#import \"_SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.h\"\n\n@interface SingleEntityRelatedToManyMappedEnt"
},
{
"path": "Tests/Fixtures/TestModel/SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.m",
"chars": 300,
"preview": "#import \"SingleEntityRelatedToManyMappedEntitiesUsingMappedPrimaryKey.h\"\n\n@interface SingleEntityRelatedToManyMappedEnti"
},
{
"path": "Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityUsingDefaults.h",
"chars": 204,
"preview": "#import \"_SingleEntityRelatedToMappedEntityUsingDefaults.h\"\n\n@interface SingleEntityRelatedToMappedEntityUsingDefaults :"
},
{
"path": "Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityUsingDefaults.m",
"chars": 258,
"preview": "#import \"SingleEntityRelatedToMappedEntityUsingDefaults.h\"\n\n@interface SingleEntityRelatedToMappedEntityUsingDefaults ()"
},
{
"path": "Tests/Fixtures/TestModel/SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.h",
"chars": 228,
"preview": "#import \"_SingleEntityRelatedToMappedEntityUsingMappedPrimaryKey.h\"\n\n@interface SingleEntityRelatedToMappedEntityUsingMa"
}
]
// ... and 44 more files (download for full content)
About this extraction
This page contains the full source code of the magicalpanda/MagicalRecord GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 244 files (1.0 MB), approximately 288.8k tokens, and a symbol index with 55 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.