diff --git a/PSCCoreData.podspec b/PSCCoreData.podspec
new file mode 100644
index 0000000..99842e5
--- /dev/null
+++ b/PSCCoreData.podspec
@@ -0,0 +1,23 @@
+Pod::Spec.new do |s|
+ s.platform = :ios, '11.0'
+ s.ios.deployment_target = '11.0'
+ s.name = "PSCCoreData"
+ s.version = "1.0.15"
+ s.license = 'MIT'
+ s.summary = "Helper for managing the CoreData Stack."
+ s.homepage = "https://github.com/PocketScientists/PSCCoreDataStack.git"
+ s.description =
+ 'Helper for managing the CoreData Stack. Contains extensions for NSManagedObject and NSManagedObjectContext'
+ s.authors = {
+ 'Jürgen Falb' => 'j.falb@nousdigital.net',
+ 'Philip Messlehner' => 'p.messlehner@pocketscience.com'
+ }
+ s.source = { :git => "https://github.com/PocketScientists/PSCCoreDataStack.git", :tag => '1.0.15' }
+ s.source_files = 'PSCCoreDataStack/*.{h,m}', 'PSCCoreData/PSCCoreData.h'
+
+ s.public_header_files = 'PSCCoreDataStack/*.{h}', 'PSCCoreData/PSCCoreData.h'
+
+ s.frameworks = 'CoreData', 'Foundation', 'UIKit'
+
+ s.requires_arc = true
+end
diff --git a/PSCCoreData/Info.plist b/PSCCoreData/Info.plist
new file mode 100644
index 0000000..910e827
--- /dev/null
+++ b/PSCCoreData/Info.plist
@@ -0,0 +1,24 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ FMWK
+ CFBundleShortVersionString
+ 1.0.15
+ CFBundleVersion
+ $(CURRENT_PROJECT_VERSION)
+ NSPrincipalClass
+
+
+
diff --git a/PSCCoreData/PSCCoreData.h b/PSCCoreData/PSCCoreData.h
new file mode 100644
index 0000000..51a764f
--- /dev/null
+++ b/PSCCoreData/PSCCoreData.h
@@ -0,0 +1,23 @@
+//
+// PSCCoreData.h
+// PSCCoreData
+//
+// Created by Juergen Falb on 25.12.17.
+// Copyright © 2017 PocketScience. All rights reserved.
+//
+
+#import
+
+//! Project version number for PSCCoreData.
+FOUNDATION_EXPORT double PSCCoreDataVersionNumber;
+
+//! Project version string for PSCCoreData.
+FOUNDATION_EXPORT const unsigned char PSCCoreDataVersionString[];
+
+// In this header, you should import all the public headers of your framework using statements like #import
+#import
+#import
+#import
+#import
+#import
+#import
diff --git a/PSCCoreDataStack.xcodeproj/project.pbxproj b/PSCCoreDataStack.xcodeproj/project.pbxproj
index efef221..6117194 100644
--- a/PSCCoreDataStack.xcodeproj/project.pbxproj
+++ b/PSCCoreDataStack.xcodeproj/project.pbxproj
@@ -9,11 +9,6 @@
/* Begin PBXBuildFile section */
9B17A9F617025C8300DEF0B9 /* PSCPersistenceOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B17A9F517025C8300DEF0B9 /* PSCPersistenceOperation.m */; };
9B5FDB1A16FC65AB002FA5A6 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B5FDB1916FC65AB002FA5A6 /* Foundation.framework */; };
- 9B5FDB2916FC65AC002FA5A6 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B5FDB2816FC65AC002FA5A6 /* SenTestingKit.framework */; };
- 9B5FDB2C16FC65AC002FA5A6 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B5FDB1916FC65AB002FA5A6 /* Foundation.framework */; };
- 9B5FDB2F16FC65AC002FA5A6 /* libPSCCoreDataStack.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B5FDB1616FC65AB002FA5A6 /* libPSCCoreDataStack.a */; };
- 9B5FDB3516FC65AC002FA5A6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9B5FDB3316FC65AC002FA5A6 /* InfoPlist.strings */; };
- 9B5FDB3816FC65AC002FA5A6 /* PSCCoreDataStackTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B5FDB3716FC65AC002FA5A6 /* PSCCoreDataStackTests.m */; };
9B5FDB4916FC65DA002FA5A6 /* NSManagedObject+PSCCoreDataHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B5FDB4216FC65DA002FA5A6 /* NSManagedObject+PSCCoreDataHelper.m */; };
9B5FDB4A16FC65DA002FA5A6 /* NSManagedObjectContext+PSCCoreDataHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B5FDB4416FC65DA002FA5A6 /* NSManagedObjectContext+PSCCoreDataHelper.m */; };
9B5FDB4B16FC65DA002FA5A6 /* PSCContextWatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B5FDB4616FC65DA002FA5A6 /* PSCContextWatcher.m */; };
@@ -21,18 +16,24 @@
9B5FDB4E16FC660C002FA5A6 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B5FDB4D16FC660C002FA5A6 /* CoreData.framework */; };
9B5FDB5916FC7025002FA5A6 /* PSCFetchedResultsControllerUpdater.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B5FDB5816FC7025002FA5A6 /* PSCFetchedResultsControllerUpdater.m */; };
9B5FDB5B16FC7387002FA5A6 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B5FDB5A16FC7387002FA5A6 /* UIKit.framework */; };
+ A9BD92891FF15E9900F4B027 /* PSCCoreData.h in Headers */ = {isa = PBXBuildFile; fileRef = A9BD92871FF15E9900F4B027 /* PSCCoreData.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A9BD928D1FF15EC300F4B027 /* NSManagedObject+PSCCoreDataHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B5FDB4216FC65DA002FA5A6 /* NSManagedObject+PSCCoreDataHelper.m */; };
+ A9BD928E1FF15EC600F4B027 /* NSManagedObjectContext+PSCCoreDataHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B5FDB4416FC65DA002FA5A6 /* NSManagedObjectContext+PSCCoreDataHelper.m */; };
+ A9BD928F1FF15EC900F4B027 /* PSCContextWatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B5FDB4616FC65DA002FA5A6 /* PSCContextWatcher.m */; };
+ A9BD92901FF15ED000F4B027 /* PSCCoreDataStack.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B5FDB4816FC65DA002FA5A6 /* PSCCoreDataStack.m */; };
+ A9BD92911FF15ED500F4B027 /* PSCFetchedResultsControllerUpdater.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B5FDB5816FC7025002FA5A6 /* PSCFetchedResultsControllerUpdater.m */; };
+ A9BD92921FF15ED900F4B027 /* PSCPersistenceOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B17A9F517025C8300DEF0B9 /* PSCPersistenceOperation.m */; };
+ A9BD92931FF15F1100F4B027 /* NSManagedObject+PSCCoreDataHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B5FDB4116FC65DA002FA5A6 /* NSManagedObject+PSCCoreDataHelper.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A9BD92941FF15F1400F4B027 /* NSManagedObjectContext+PSCCoreDataHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B5FDB4316FC65DA002FA5A6 /* NSManagedObjectContext+PSCCoreDataHelper.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A9BD92951FF15F1700F4B027 /* PSCContextWatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B5FDB4516FC65DA002FA5A6 /* PSCContextWatcher.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A9BD92961FF15F2100F4B027 /* PSCCoreDataStack.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B5FDB4716FC65DA002FA5A6 /* PSCCoreDataStack.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A9BD92971FF15F2500F4B027 /* PSCFetchedResultsControllerUpdater.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B5FDB5716FC7025002FA5A6 /* PSCFetchedResultsControllerUpdater.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A9BD92981FF15F3000F4B027 /* PSCPersistenceOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B17A9F417025C8300DEF0B9 /* PSCPersistenceOperation.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ A9BD92991FF15F3300F4B027 /* PSCLogging.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B6B3C56170F5496004DFAD7 /* PSCLogging.h */; };
+ A9BD929A1FF15F5100F4B027 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B5FDB4D16FC660C002FA5A6 /* CoreData.framework */; };
+ A9BD929B1FF15FEE00F4B027 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B5FDB5A16FC7387002FA5A6 /* UIKit.framework */; };
/* End PBXBuildFile section */
-/* Begin PBXContainerItemProxy section */
- 9B5FDB2D16FC65AC002FA5A6 /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 9B5FDB0E16FC65AB002FA5A6 /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = 9B5FDB1516FC65AB002FA5A6;
- remoteInfo = PSCCoreDataStack;
- };
-/* End PBXContainerItemProxy section */
-
/* Begin PBXCopyFilesBuildPhase section */
9B5FDB1416FC65AB002FA5A6 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
@@ -51,7 +52,6 @@
9B5FDB1616FC65AB002FA5A6 /* libPSCCoreDataStack.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPSCCoreDataStack.a; sourceTree = BUILT_PRODUCTS_DIR; };
9B5FDB1916FC65AB002FA5A6 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
9B5FDB1D16FC65AB002FA5A6 /* Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Prefix.pch; sourceTree = ""; };
- 9B5FDB2716FC65AC002FA5A6 /* PSCCoreDataStackTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PSCCoreDataStackTests.octest; sourceTree = BUILT_PRODUCTS_DIR; };
9B5FDB2816FC65AC002FA5A6 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; };
9B5FDB3216FC65AC002FA5A6 /* PSCCoreDataStackTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "PSCCoreDataStackTests-Info.plist"; sourceTree = ""; };
9B5FDB3416FC65AC002FA5A6 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
@@ -70,6 +70,10 @@
9B5FDB5816FC7025002FA5A6 /* PSCFetchedResultsControllerUpdater.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PSCFetchedResultsControllerUpdater.m; sourceTree = ""; };
9B5FDB5A16FC7387002FA5A6 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
9B6B3C56170F5496004DFAD7 /* PSCLogging.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PSCLogging.h; sourceTree = ""; };
+ A96C0B40238A0B8300BF7682 /* PSCCoreData.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = PSCCoreData.podspec; sourceTree = ""; };
+ A9BD92851FF15E9900F4B027 /* PSCCoreData.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PSCCoreData.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ A9BD92871FF15E9900F4B027 /* PSCCoreData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PSCCoreData.h; sourceTree = ""; };
+ A9BD92881FF15E9900F4B027 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -83,13 +87,12 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
- 9B5FDB2316FC65AC002FA5A6 /* Frameworks */ = {
+ A9BD92811FF15E9900F4B027 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 9B5FDB2916FC65AC002FA5A6 /* SenTestingKit.framework in Frameworks */,
- 9B5FDB2C16FC65AC002FA5A6 /* Foundation.framework in Frameworks */,
- 9B5FDB2F16FC65AC002FA5A6 /* libPSCCoreDataStack.a in Frameworks */,
+ A9BD929B1FF15FEE00F4B027 /* UIKit.framework in Frameworks */,
+ A9BD929A1FF15F5100F4B027 /* CoreData.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -99,7 +102,9 @@
9B5FDB0D16FC65AB002FA5A6 = {
isa = PBXGroup;
children = (
+ A96C0B40238A0B8300BF7682 /* PSCCoreData.podspec */,
9B5FDB1B16FC65AB002FA5A6 /* PSCCoreDataStack */,
+ A9BD92861FF15E9900F4B027 /* PSCCoreData */,
9B5FDB1816FC65AB002FA5A6 /* Frameworks */,
9B5FDB3016FC65AC002FA5A6 /* PSCCoreDataStackTests */,
9B5FDB1716FC65AB002FA5A6 /* Products */,
@@ -110,7 +115,7 @@
isa = PBXGroup;
children = (
9B5FDB1616FC65AB002FA5A6 /* libPSCCoreDataStack.a */,
- 9B5FDB2716FC65AC002FA5A6 /* PSCCoreDataStackTests.octest */,
+ A9BD92851FF15E9900F4B027 /* PSCCoreData.framework */,
);
name = Products;
sourceTree = "";
@@ -174,8 +179,35 @@
name = "Supporting Files";
sourceTree = "";
};
+ A9BD92861FF15E9900F4B027 /* PSCCoreData */ = {
+ isa = PBXGroup;
+ children = (
+ A9BD92871FF15E9900F4B027 /* PSCCoreData.h */,
+ A9BD92881FF15E9900F4B027 /* Info.plist */,
+ );
+ path = PSCCoreData;
+ sourceTree = "";
+ };
/* End PBXGroup section */
+/* Begin PBXHeadersBuildPhase section */
+ A9BD92821FF15E9900F4B027 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A9BD92891FF15E9900F4B027 /* PSCCoreData.h in Headers */,
+ A9BD92931FF15F1100F4B027 /* NSManagedObject+PSCCoreDataHelper.h in Headers */,
+ A9BD92941FF15F1400F4B027 /* NSManagedObjectContext+PSCCoreDataHelper.h in Headers */,
+ A9BD92951FF15F1700F4B027 /* PSCContextWatcher.h in Headers */,
+ A9BD92961FF15F2100F4B027 /* PSCCoreDataStack.h in Headers */,
+ A9BD92971FF15F2500F4B027 /* PSCFetchedResultsControllerUpdater.h in Headers */,
+ A9BD92981FF15F3000F4B027 /* PSCPersistenceOperation.h in Headers */,
+ A9BD92991FF15F3300F4B027 /* PSCLogging.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
/* Begin PBXNativeTarget section */
9B5FDB1516FC65AB002FA5A6 /* PSCCoreDataStack */ = {
isa = PBXNativeTarget;
@@ -194,24 +226,23 @@
productReference = 9B5FDB1616FC65AB002FA5A6 /* libPSCCoreDataStack.a */;
productType = "com.apple.product-type.library.static";
};
- 9B5FDB2616FC65AC002FA5A6 /* PSCCoreDataStackTests */ = {
+ A9BD92841FF15E9900F4B027 /* PSCCoreData */ = {
isa = PBXNativeTarget;
- buildConfigurationList = 9B5FDB3E16FC65AC002FA5A6 /* Build configuration list for PBXNativeTarget "PSCCoreDataStackTests" */;
+ buildConfigurationList = A9BD928C1FF15E9900F4B027 /* Build configuration list for PBXNativeTarget "PSCCoreData" */;
buildPhases = (
- 9B5FDB2216FC65AC002FA5A6 /* Sources */,
- 9B5FDB2316FC65AC002FA5A6 /* Frameworks */,
- 9B5FDB2416FC65AC002FA5A6 /* Resources */,
- 9B5FDB2516FC65AC002FA5A6 /* ShellScript */,
+ A9BD92801FF15E9900F4B027 /* Sources */,
+ A9BD92811FF15E9900F4B027 /* Frameworks */,
+ A9BD92821FF15E9900F4B027 /* Headers */,
+ A9BD92831FF15E9900F4B027 /* Resources */,
);
buildRules = (
);
dependencies = (
- 9B5FDB2E16FC65AC002FA5A6 /* PBXTargetDependency */,
);
- name = PSCCoreDataStackTests;
- productName = PSCCoreDataStackTests;
- productReference = 9B5FDB2716FC65AC002FA5A6 /* PSCCoreDataStackTests.octest */;
- productType = "com.apple.product-type.bundle";
+ name = PSCCoreData;
+ productName = PSCCoreData;
+ productReference = A9BD92851FF15E9900F4B027 /* PSCCoreData.framework */;
+ productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
@@ -219,15 +250,24 @@
9B5FDB0E16FC65AB002FA5A6 /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0460;
+ LastTestingUpgradeCheck = 0510;
+ LastUpgradeCheck = 1020;
ORGANIZATIONNAME = PocketScience;
+ TargetAttributes = {
+ A9BD92841FF15E9900F4B027 = {
+ CreatedOnToolsVersion = 9.2;
+ DevelopmentTeam = Y6BEBK9HD8;
+ ProvisioningStyle = Automatic;
+ };
+ };
};
buildConfigurationList = 9B5FDB1116FC65AB002FA5A6 /* Build configuration list for PBXProject "PSCCoreDataStack" */;
compatibilityVersion = "Xcode 3.2";
- developmentRegion = English;
+ developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
+ Base,
);
mainGroup = 9B5FDB0D16FC65AB002FA5A6;
productRefGroup = 9B5FDB1716FC65AB002FA5A6 /* Products */;
@@ -235,38 +275,21 @@
projectRoot = "";
targets = (
9B5FDB1516FC65AB002FA5A6 /* PSCCoreDataStack */,
- 9B5FDB2616FC65AC002FA5A6 /* PSCCoreDataStackTests */,
+ A9BD92841FF15E9900F4B027 /* PSCCoreData */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
- 9B5FDB2416FC65AC002FA5A6 /* Resources */ = {
+ A9BD92831FF15E9900F4B027 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 9B5FDB3516FC65AC002FA5A6 /* InfoPlist.strings in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
-/* Begin PBXShellScriptBuildPhase section */
- 9B5FDB2516FC65AC002FA5A6 /* ShellScript */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n";
- };
-/* End PBXShellScriptBuildPhase section */
-
/* Begin PBXSourcesBuildPhase section */
9B5FDB1216FC65AB002FA5A6 /* Sources */ = {
isa = PBXSourcesBuildPhase;
@@ -281,24 +304,21 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
- 9B5FDB2216FC65AC002FA5A6 /* Sources */ = {
+ A9BD92801FF15E9900F4B027 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 9B5FDB3816FC65AC002FA5A6 /* PSCCoreDataStackTests.m in Sources */,
+ A9BD92901FF15ED000F4B027 /* PSCCoreDataStack.m in Sources */,
+ A9BD928D1FF15EC300F4B027 /* NSManagedObject+PSCCoreDataHelper.m in Sources */,
+ A9BD928E1FF15EC600F4B027 /* NSManagedObjectContext+PSCCoreDataHelper.m in Sources */,
+ A9BD928F1FF15EC900F4B027 /* PSCContextWatcher.m in Sources */,
+ A9BD92921FF15ED900F4B027 /* PSCPersistenceOperation.m in Sources */,
+ A9BD92911FF15ED500F4B027 /* PSCFetchedResultsControllerUpdater.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
-/* Begin PBXTargetDependency section */
- 9B5FDB2E16FC65AC002FA5A6 /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = 9B5FDB1516FC65AB002FA5A6 /* PSCCoreDataStack */;
- targetProxy = 9B5FDB2D16FC65AC002FA5A6 /* PBXContainerItemProxy */;
- };
-/* End PBXTargetDependency section */
-
/* Begin PBXVariantGroup section */
9B5FDB3316FC65AC002FA5A6 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
@@ -315,27 +335,44 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
- CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 5.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 10.0;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
};
@@ -345,20 +382,36 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
- CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = YES;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 5.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 10.0;
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
};
@@ -388,33 +441,83 @@
};
name = Release;
};
- 9B5FDB3F16FC65AC002FA5A6 /* Debug */ = {
+ A9BD928A1FF15E9900F4B027 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
- FRAMEWORK_SEARCH_PATHS = (
- "\"$(SDKROOT)/Developer/Library/Frameworks\"",
- "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"",
- );
- GCC_PRECOMPILE_PREFIX_HEADER = YES;
- GCC_PREFIX_HEADER = "PSCCoreDataStack/PSCCoreDataStack-Prefix.pch";
- INFOPLIST_FILE = "PSCCoreDataStackTests/PSCCoreDataStackTests-Info.plist";
- PRODUCT_NAME = "$(TARGET_NAME)";
- WRAPPER_EXTENSION = octest;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ DEFINES_MODULE = YES;
+ DEVELOPMENT_TEAM = Y6BEBK9HD8;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ DYLIB_INSTALL_NAME_BASE = "@rpath";
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ INFOPLIST_FILE = PSCCoreData/Info.plist;
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ IPHONEOS_DEPLOYMENT_TARGET = 10.3;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ MTL_ENABLE_DEBUG_INFO = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = com.nousdigital.PSCCoreData;
+ PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
+ SKIP_INSTALL = YES;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VERSIONING_SYSTEM = "apple-generic";
+ VERSION_INFO_PREFIX = "";
};
name = Debug;
};
- 9B5FDB4016FC65AC002FA5A6 /* Release */ = {
+ A9BD928B1FF15E9900F4B027 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
- FRAMEWORK_SEARCH_PATHS = (
- "\"$(SDKROOT)/Developer/Library/Frameworks\"",
- "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"",
- );
- GCC_PRECOMPILE_PREFIX_HEADER = YES;
- GCC_PREFIX_HEADER = "PSCCoreDataStack/PSCCoreDataStack-Prefix.pch";
- INFOPLIST_FILE = "PSCCoreDataStackTests/PSCCoreDataStackTests-Info.plist";
- PRODUCT_NAME = "$(TARGET_NAME)";
- WRAPPER_EXTENSION = octest;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
+ CODE_SIGN_STYLE = Automatic;
+ COPY_PHASE_STRIP = NO;
+ CURRENT_PROJECT_VERSION = 1;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DEFINES_MODULE = YES;
+ DEVELOPMENT_TEAM = Y6BEBK9HD8;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ DYLIB_INSTALL_NAME_BASE = "@rpath";
+ ENABLE_NS_ASSERTIONS = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ INFOPLIST_FILE = PSCCoreData/Info.plist;
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ IPHONEOS_DEPLOYMENT_TARGET = 10.3;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ MTL_ENABLE_DEBUG_INFO = NO;
+ PRODUCT_BUNDLE_IDENTIFIER = com.nousdigital.PSCCoreData;
+ PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
+ SKIP_INSTALL = YES;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VERSIONING_SYSTEM = "apple-generic";
+ VERSION_INFO_PREFIX = "";
};
name = Release;
};
@@ -439,11 +542,11 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- 9B5FDB3E16FC65AC002FA5A6 /* Build configuration list for PBXNativeTarget "PSCCoreDataStackTests" */ = {
+ A9BD928C1FF15E9900F4B027 /* Build configuration list for PBXNativeTarget "PSCCoreData" */ = {
isa = XCConfigurationList;
buildConfigurations = (
- 9B5FDB3F16FC65AC002FA5A6 /* Debug */,
- 9B5FDB4016FC65AC002FA5A6 /* Release */,
+ A9BD928A1FF15E9900F4B027 /* Debug */,
+ A9BD928B1FF15E9900F4B027 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
diff --git a/PSCCoreDataStack.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/PSCCoreDataStack.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/PSCCoreDataStack.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/PSCCoreDataStack.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/PSCCoreDataStack.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/PSCCoreDataStack.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/PSCCoreDataStack.xcodeproj/project.xcworkspace/xcshareddata/PSCCoreDataStack.xcscmblueprint b/PSCCoreDataStack.xcodeproj/project.xcworkspace/xcshareddata/PSCCoreDataStack.xcscmblueprint
new file mode 100644
index 0000000..baf20a5
--- /dev/null
+++ b/PSCCoreDataStack.xcodeproj/project.xcworkspace/xcshareddata/PSCCoreDataStack.xcscmblueprint
@@ -0,0 +1,30 @@
+{
+ "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "D261E0A4710B0DA4CAA16F150E6AB7046AB2576A",
+ "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : {
+
+ },
+ "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : {
+ "D261E0A4710B0DA4CAA16F150E6AB7046AB2576A" : 9223372036854775807,
+ "5CAD9AD776377F08EC40032FFD796FFA54F88822" : 9223372036854775807
+ },
+ "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "5385F887-07A2-4B63-A6A2-92D5CD1792C8",
+ "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : {
+ "D261E0A4710B0DA4CAA16F150E6AB7046AB2576A" : "PSCCoreDataStack\/",
+ "5CAD9AD776377F08EC40032FFD796FFA54F88822" : ""
+ },
+ "DVTSourceControlWorkspaceBlueprintNameKey" : "PSCCoreDataStack",
+ "DVTSourceControlWorkspaceBlueprintVersion" : 204,
+ "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "PSCCoreDataStack.xcodeproj",
+ "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [
+ {
+ "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/sources-headless.app.redbull.com\/scm\/fft\/bullchecker-client.git",
+ "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
+ "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "5CAD9AD776377F08EC40032FFD796FFA54F88822"
+ },
+ {
+ "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/sources-headless.app.redbull.com\/scm\/fft\/psccoredatastack.git",
+ "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
+ "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "D261E0A4710B0DA4CAA16F150E6AB7046AB2576A"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/PSCCoreDataStack.xcodeproj/xcshareddata/xcschemes/PSCCoreData.xcscheme b/PSCCoreDataStack.xcodeproj/xcshareddata/xcschemes/PSCCoreData.xcscheme
new file mode 100644
index 0000000..1bb0a44
--- /dev/null
+++ b/PSCCoreDataStack.xcodeproj/xcshareddata/xcschemes/PSCCoreData.xcscheme
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/PSCCoreDataStack/NSManagedObject+PSCCoreDataHelper.h b/PSCCoreDataStack/NSManagedObject+PSCCoreDataHelper.h
index a63857b..9825918 100644
--- a/PSCCoreDataStack/NSManagedObject+PSCCoreDataHelper.h
+++ b/PSCCoreDataStack/NSManagedObject+PSCCoreDataHelper.h
@@ -5,38 +5,41 @@
// Created by Philip Messlehner on 28.02.13.
// Copyright (c) 2013 Philip Messlehner. All rights reserved.
//
-
+#import
@class PSCContextWatcher;
-typedef void(^psc_request_block)(NSFetchRequest *fetchRequest);
+typedef void(^psc_request_block)(NSFetchRequest * _Nonnull fetchRequest);
+NS_ASSUME_NONNULL_BEGIN
@interface NSManagedObject (PSCCoreDataHelper)
@property (nonatomic, readonly) NSManagedObjectID *permanentObjectID;
-+ (instancetype)newObjectInContext:(NSManagedObjectContext *)context;
-+ (instancetype)existingOrNewObjectWithAttribute:(NSString *)attribute matchingValue:(id)value inContext:(NSManagedObjectContext *)context;
++ (instancetype _Nonnull)newObjectInContext:(NSManagedObjectContext *)context;
++ (instancetype _Nonnull)existingOrNewObjectWithAttribute:(NSString *)attribute matchingValue:(nullable id)value inContext:(NSManagedObjectContext *)context;
-+ (NSUInteger)deleteAllMatchingPredicate:(NSPredicate *)predicate
- requestConfiguration:(psc_request_block)requestConfigurationBlock
++ (NSUInteger)deleteAllMatchingPredicate:(nullable NSPredicate *)predicate
+ requestConfiguration:(nullable psc_request_block)requestConfigurationBlock
inContext:(NSManagedObjectContext *)context
- error:(NSError **)error;
-+ (NSUInteger)deleteAllMatchingPredicate:(NSPredicate *)predicate inContext:(NSManagedObjectContext *)context error:(NSError **)error;
+ error:(NSError * _Nullable * _Nullable)error;
++ (NSUInteger)deleteAllMatchingPredicate:(nullable NSPredicate *)predicate inContext:(NSManagedObjectContext *)context error:(NSError * _Nullable * _Nullable)error;
-+ (NSFetchRequest *)requestAllMatchingPredicate:(NSPredicate *)predicate error:(NSError **)error;
-+ (NSFetchRequest *)requestFirstMatchingPredicate:(NSPredicate *)predicate error:(NSError **)error;
++ (NSFetchRequest *)requestAllMatchingPredicate:(nullable NSPredicate *)predicate error:(NSError * _Nullable * _Nullable)error;
++ (NSFetchRequest *)requestBatchOfSize:(NSUInteger)batchSize atOffset:(NSUInteger)offset withMatchingPredicate:(nullable NSPredicate *)predicate error:(NSError * _Nullable *)error;
++ (NSFetchRequest *)requestFirstMatchingPredicate:(nullable NSPredicate *)predicate error:(NSError * _Nullable * _Nullable)error;
-+ (NSArray *)fetchAllMatchingPredicate:(NSPredicate *)predicate
- requestConfiguration:(psc_request_block)requestConfigurationBlock
- inContext:(NSManagedObjectContext *)context
- error:(NSError **)error;
-+ (NSArray *)fetchAllMatchingPredicate:(NSPredicate *)predicate inContext:(NSManagedObjectContext *)context error:(NSError **)error;
-+ (instancetype)fetchFirstMatchingPredicate:(NSPredicate *)predicate inContext:(NSManagedObjectContext *)context error:(NSError **)error;
++ (nullable NSArray *)fetchAllMatchingPredicate:(nullable NSPredicate *)predicate
+ requestConfiguration:(nullable psc_request_block)requestConfigurationBlock
+ inContext:(NSManagedObjectContext *)context
+ error:(NSError * _Nullable * _Nullable)error;
++ (nullable NSArray *)fetchAllMatchingPredicate:(nullable NSPredicate *)predicate inContext:(NSManagedObjectContext *)context error:(NSError * _Nullable * _Nullable)error;
++ (nullable instancetype)fetchFirstMatchingPredicate:(nullable NSPredicate *)predicate inContext:(NSManagedObjectContext *)context error:(NSError * _Nullable * _Nullable)error;
++ (NSArray *)fetchBatchOfSize:(NSUInteger)batchSize atOffset:(NSUInteger)offset withMatchingPredicate:(nullable NSPredicate *)predicate inContext:(NSManagedObjectContext *)context error:(NSError * _Nullable *)error;
-+ (NSUInteger)countOfObjectsMatchingPredicate:(NSPredicate *)predicate inContext:(NSManagedObjectContext *)context error:(NSError **)error;
++ (NSUInteger)countOfObjectsMatchingPredicate:(nullable NSPredicate *)predicate inContext:(NSManagedObjectContext *)context error:(NSError * _Nullable * _Nullable)error;
/**
High-level action to update the data in Core Data based on an array of dictionaries.
@@ -57,9 +60,9 @@ typedef void(^psc_request_block)(NSFetchRequest *fetchRequest);
deleteEntitiesNotInDictionary:(BOOL)deleteEntitiesNotInDictionary
entityKeyInDictionary:(NSString *)dictionaryIDKeyPath
entityKeyInDatabase:(NSString *)databaseIDKey
- context:(NSManagedObjectContext *)contex
+ context:(NSManagedObjectContext *)context
updateBlock:(void(^)(id managedObject, NSDictionary *data))updateBlock
- error:(NSError **)error;
+ error:(NSError * _Nullable * _Nullable)error;
- (void)reset;
- (void)deleteFromContext;
@@ -67,3 +70,5 @@ typedef void(^psc_request_block)(NSFetchRequest *fetchRequest);
- (id)userInfoValueForKey:(NSString *)key ofProperty:(NSString *)property;
@end
+
+NS_ASSUME_NONNULL_END
diff --git a/PSCCoreDataStack/NSManagedObject+PSCCoreDataHelper.m b/PSCCoreDataStack/NSManagedObject+PSCCoreDataHelper.m
index 65e03e4..d47407a 100644
--- a/PSCCoreDataStack/NSManagedObject+PSCCoreDataHelper.m
+++ b/PSCCoreDataStack/NSManagedObject+PSCCoreDataHelper.m
@@ -17,13 +17,13 @@ @implementation NSManagedObject (PSCCoreDataHelper)
#pragma mark - Class Methods
////////////////////////////////////////////////////////////////////////
-+ (instancetype)newObjectInContext:(NSManagedObjectContext *)context {
++ (instancetype _Nonnull)newObjectInContext:(NSManagedObjectContext *)context {
NSParameterAssert(context != nil);
return [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([self class]) inManagedObjectContext:context];
}
-+ (instancetype)existingOrNewObjectWithAttribute:(NSString *)attribute matchingValue:(id)value inContext:(NSManagedObjectContext *)context {
++ (instancetype _Nonnull)existingOrNewObjectWithAttribute:(NSString *)attribute matchingValue:(id)value inContext:(NSManagedObjectContext *)context {
NSParameterAssert(attribute != nil);
NSParameterAssert(context != nil);
@@ -46,7 +46,7 @@ + (instancetype)existingOrNewObjectWithAttribute:(NSString *)attribute matchingV
[object setValue:value forKey:attribute];
}
- return object;
+ return (id _Nonnull)object;
}
+ (NSUInteger)deleteAllMatchingPredicate:(NSPredicate *)predicate requestConfiguration:(psc_request_block)requestConfigurationBlock inContext:(NSManagedObjectContext *)context error:(__autoreleasing NSError **)error {
@@ -86,6 +86,16 @@ + (NSFetchRequest *)requestAllMatchingPredicate:(NSPredicate *)predicate error:(
return request;
}
++ (NSFetchRequest *)requestBatchOfSize:(NSUInteger)batchSize atOffset:(NSUInteger)offset withMatchingPredicate:(NSPredicate *)predicate error:(__autoreleasing NSError **)error {
+ NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([self class])];
+
+ request.fetchLimit = batchSize;
+ request.fetchOffset = offset;
+ request.predicate = predicate;
+
+ return request;
+}
+
+ (NSFetchRequest *)requestFirstMatchingPredicate:(NSPredicate *)predicate error:(NSError **)error {
NSFetchRequest *request = [self requestAllMatchingPredicate:predicate error:error];
@@ -109,6 +119,13 @@ + (NSArray *)fetchAllMatchingPredicate:(NSPredicate *)predicate inContext:(NSMan
return [self fetchAllMatchingPredicate:predicate requestConfiguration:nil inContext:context error:error];
}
++ (NSArray *)fetchBatchOfSize:(NSUInteger)batchSize atOffset:(NSUInteger)offset withMatchingPredicate:(NSPredicate *)predicate inContext:(NSManagedObjectContext *)context error:(__autoreleasing NSError **)error {
+ NSFetchRequest *request = [self requestBatchOfSize:batchSize atOffset:offset withMatchingPredicate:predicate error:error];
+
+ NSArray *objects = [context executeFetchRequest:request error:error];
+ return objects;
+}
+
+ (instancetype)fetchFirstMatchingPredicate:(NSPredicate *)predicate inContext:(NSManagedObjectContext *)context error:(NSError **)error {
NSFetchRequest *fetchRequest = [self requestFirstMatchingPredicate:predicate error:error];
diff --git a/PSCCoreDataStack/NSManagedObjectContext+PSCCoreDataHelper.h b/PSCCoreDataStack/NSManagedObjectContext+PSCCoreDataHelper.h
index 666081d..cab50e8 100644
--- a/PSCCoreDataStack/NSManagedObjectContext+PSCCoreDataHelper.h
+++ b/PSCCoreDataStack/NSManagedObjectContext+PSCCoreDataHelper.h
@@ -5,16 +5,20 @@
// Created by Philip Messlehner on 28.02.13.
// Copyright (c) 2013 Philip Messlehner. All rights reserved.
//
+#import
+NS_ASSUME_NONNULL_BEGIN
@interface NSManagedObjectContext (PSCCoreDataHelper)
-- (NSManagedObjectContext *)newChildContextWithConcurrencyType:(NSUInteger)concurrencyType;
+- (NSManagedObjectContext *)newChildContextWithConcurrencyType:(NSManagedObjectContextConcurrencyType)concurrencyType;
-- (BOOL)saveAndPropagateToParentContextBlocking:(BOOL)wait error:(NSError **)error __attribute__((deprecated("use 'saveAndPropagateToParentContextBlocking:success:failure' instead")));
-- (BOOL)saveAndPropagateToParentContext:(NSError **)error __attribute__((deprecated("use 'saveAndPropagateToParentContexWithSuccess:failure' instead")));
+- (void)saveAndPropagateToParentContextBlocking:(BOOL)wait error:(NSError * _Nullable * _Nullable)error __attribute__((deprecated("use 'saveAndPropagateToParentContextBlocking:success:failure' instead")));
+- (void)saveAndPropagateToParentContext:(NSError * _Nullable * _Nullable)error __attribute__((deprecated("use 'saveAndPropagateToParentContexWithSuccess:failure' instead")));
-- (BOOL)saveAndPropagateToParentContextBlocking:(BOOL)wait success:(void(^)())sucess failure:(void(^)(NSError *error))failure;
-- (BOOL)saveAndPropagateToParentContextWithSuccess:(void(^)())sucess failure:(void(^)(NSError *error))failure;
+- (void)saveAndPropagateToParentContextBlocking:(BOOL)wait success:(nullable void(^)(void))sucess failure:(nullable void(^)(NSError *error))failure;
+- (void)saveAndPropagateToParentContextWithSuccess:(nullable void(^)(void))sucess failure:(nullable void(^)(NSError *error))failure;
@end
+
+NS_ASSUME_NONNULL_END
diff --git a/PSCCoreDataStack/NSManagedObjectContext+PSCCoreDataHelper.m b/PSCCoreDataStack/NSManagedObjectContext+PSCCoreDataHelper.m
index 473546b..b0d8f6f 100644
--- a/PSCCoreDataStack/NSManagedObjectContext+PSCCoreDataHelper.m
+++ b/PSCCoreDataStack/NSManagedObjectContext+PSCCoreDataHelper.m
@@ -11,99 +11,118 @@
@implementation NSManagedObjectContext (PSCCoreDataHelper)
-- (NSManagedObjectContext *)newChildContextWithConcurrencyType:(NSUInteger)concurrencyType {
+- (NSManagedObjectContext *)newChildContextWithConcurrencyType:(NSManagedObjectContextConcurrencyType)concurrencyType {
NSManagedObjectContext *childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:concurrencyType];
childContext.parentContext = self;
return childContext;
}
-- (BOOL)saveAndPropagateToParentContextBlocking:(BOOL)wait error:(__autoreleasing NSError **)error {
- __block BOOL success = YES;
-
- if (self.hasChanges) {
- if (self.concurrencyType == NSConfinementConcurrencyType) {
- success = [self save:error];
- } else {
- [self performBlockAndWait:^{
- success = [self save:error];
+- (void)saveAndPropagateToParentContextBlocking:(BOOL)wait error:(__autoreleasing NSError **)error {
+ dispatch_block_t parentCheck = ^{
+ if (wait) {
+ [self.parentContext performBlockAndWait:^{
+ if (self.parentContext.hasChanges) {
+ [self.parentContext save:error];
+ }
}];
- }
- }
-
- if (!success) {
- return NO;
- }
-
- if (self.parentContext.hasChanges) {
- dispatch_block_t saveParent = ^{
- success = [self.parentContext save:error];
- };
-
- if (self.parentContext.concurrencyType == NSConfinementConcurrencyType) {
- saveParent();
- } else if (wait) {
- [self.parentContext performBlockAndWait:saveParent];
} else {
- [self.parentContext performBlock:saveParent];
+ [self.parentContext performBlock:^{
+ if (self.parentContext.hasChanges) {
+ [self.parentContext save:error];
+ }
+ }];
}
- }
+ };
- return success;
+ if (wait) {
+ [self performBlockAndWait:^{
+ if (self.hasChanges) {
+ if ([self save:error]) {
+ parentCheck();
+ }
+ }
+ else {
+ parentCheck();
+ }
+ }];
+ } else {
+ [self performBlock:^{
+ if (self.hasChanges) {
+ if ([self save:error]) {
+ parentCheck();
+ }
+ }
+ else {
+ parentCheck();
+ }
+ }];
+ }
}
-- (BOOL)saveAndPropagateToParentContext:(__autoreleasing NSError **)error {
- return [self saveAndPropagateToParentContextBlocking:NO error:error];
+- (void)saveAndPropagateToParentContext:(__autoreleasing NSError **)error {
+ [self saveAndPropagateToParentContextBlocking:NO error:error];
}
-- (BOOL)saveAndPropagateToParentContextBlocking:(BOOL)wait success:(void(^)())successBlock failure:(void(^)(NSError *error))failureBlock {
- __block BOOL success = YES;
- __block NSError *error = nil;
- if (self.hasChanges) {
- if (self.concurrencyType == NSConfinementConcurrencyType) {
- success = [self save:&error];
+- (void)saveAndPropagateToParentContextBlocking:(BOOL)wait success:(void(^)(void))successBlock failure:(void(^)(NSError *error))failureBlock {
+ dispatch_block_t parentCheck = ^{
+ dispatch_block_t saveParent = ^{
+ if (self.parentContext.hasChanges) {
+ NSError *error = nil;
+ if ([self.parentContext save:&error]) {
+ if (successBlock) {
+ successBlock();
+ }
+ } else if (failureBlock) {
+ failureBlock(error);
+ }
+ } else if (successBlock) {
+ successBlock();
+ }
+ };
+
+ if (wait) {
+ [self.parentContext performBlockAndWait: saveParent];
} else {
- [self performBlockAndWait:^{
- success = [self save:&error];
- }];
+ [self.parentContext performBlock: saveParent];
}
- }
+ };
- if (!success) {
- if (failureBlock) {
- failureBlock(error);
+ dispatch_block_t saveChild = ^{
+ NSError *error = nil;
+ if ([self save:&error]) {
+ parentCheck();
}
- return NO;
- }
-
- if (self.parentContext.hasChanges) {
- dispatch_block_t saveParent = ^{
- success = [self.parentContext save:&error];
- if (success) {
- if (successBlock) {
- successBlock();
- }
- } else if (failureBlock) {
+ else {
+ if (failureBlock) {
failureBlock(error);
}
- };
-
- if (self.parentContext.concurrencyType == NSConfinementConcurrencyType) {
- saveParent();
- } else if (wait) {
- [self.parentContext performBlockAndWait:saveParent];
- } else {
- [self.parentContext performBlock:saveParent];
}
- } else if (success && successBlock) {
- successBlock();
+ };
+
+ if (wait) {
+ [self performBlockAndWait:^{
+ if (self.hasChanges) {
+ saveChild();
+ }
+ else {
+ parentCheck();
+ }
+ }];
+ } else {
+ [self performBlock:^{
+ if (self.hasChanges) {
+ saveChild();
+ }
+ else {
+ parentCheck();
+ }
+ }];
}
-
- return success;
}
-- (BOOL)saveAndPropagateToParentContextWithSuccess:(void(^)())successBlock failure:(void(^)(NSError *error))failureBlock {
- return [self saveAndPropagateToParentContextBlocking:NO success:successBlock failure:failureBlock];
+- (void)saveAndPropagateToParentContextWithSuccess:(void(^)(void))successBlock failure:(void(^)(NSError *error))failureBlock {
+ [self saveAndPropagateToParentContextBlocking:NO success:successBlock failure:failureBlock];
}
@end
diff --git a/PSCCoreDataStack/PSCContextWatcher.h b/PSCCoreDataStack/PSCContextWatcher.h
index 10f2df6..d26e4b1 100644
--- a/PSCCoreDataStack/PSCContextWatcher.h
+++ b/PSCCoreDataStack/PSCContextWatcher.h
@@ -27,14 +27,16 @@
// 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.
+#import
@protocol PSCContextWatcherDelegate;
+NS_ASSUME_NONNULL_BEGIN
@interface PSCContextWatcher : NSObject
-@property (nonatomic, weak) id delegate;
+@property (nullable, nonatomic, weak) id delegate;
+ (instancetype)watcherWithContext:(NSManagedObjectContext *)context;
- (instancetype)initWithManagedObjectContext:(NSManagedObjectContext *)context;
@@ -52,9 +54,11 @@
@protocol PSCContextWatcherDelegate
- (void)contextWatcher:(PSCContextWatcher *)watcher
- observedInsertions:(NSSet *)inserts
- deletions:(NSSet *)deletions
- updates:(NSSet *)updates
+ observedInsertions:(nullable NSSet *)inserts
+ deletions:(nullable NSSet *)deletions
+ updates:(nullable NSSet *)updates
inContext:(NSManagedObjectContext *)context;
@end
+
+NS_ASSUME_NONNULL_END
diff --git a/PSCCoreDataStack/PSCCoreDataStack.h b/PSCCoreDataStack/PSCCoreDataStack.h
index c726ae9..007c833 100644
--- a/PSCCoreDataStack/PSCCoreDataStack.h
+++ b/PSCCoreDataStack/PSCCoreDataStack.h
@@ -14,28 +14,34 @@
#import "PSCFetchedResultsControllerUpdater.h"
#import "PSCPersistenceOperation.h"
+NS_ASSUME_NONNULL_BEGIN
@interface PSCCoreDataStack : NSObject
+ (void)setupWithModelURL:(NSURL *)modelURL
- storeFileName:(NSString *)storeFileName
+ storeFileName:(nullable NSString *)storeFileName
type:(NSString *)storeType
- configuration:(NSString *)configuration
- options:(NSDictionary *)options
- success:(void(^)())successBlock
- error:(void(^)(NSError *error))errorBlock;
+ storeURL:(nullable NSURL *)storeURL
+ configuration:(nullable NSString *)configuration
+ options:(nullable NSDictionary *)options
+ success:(nullable void(^)(void))successBlock
+ error:(nullable void(^)(NSError *error))errorBlock;
+ (void)setupWithModelURL:(NSURL *)modelURL
autoMigratedSQLiteStoreFileName:(NSString *)storeFileName
- success:(void(^)())successBlock error:(void(^)(NSError *error))errorBlock;
+ success:(nullable void(^)(void))successBlock error:(nullable void(^)(NSError *error))errorBlock;
+ (void)saveAndPersistContextBlocking:(BOOL)wait;
+ (void)saveAndPersistContext;
-+ (void)saveAndPersistContextBlocking:(BOOL)wait success:(void(^)())sucessBlock error:(void(^)(NSError *error))errorBlock;
-+ (void)saveAndPersistContextWithSuccess:(void(^)())sucessBlock error:(void(^)(NSError *error))errorBlock;
++ (void)saveAndPersistContextBlocking:(BOOL)wait success:(nullable void(^)(void))sucessBlock error:(nullable void(^)(NSError *error))errorBlock;
++ (void)saveAndPersistContextWithSuccess:(nullable void(^)(void))sucessBlock error:(nullable void(^)(NSError *error))errorBlock;
+ (NSManagedObjectContext *)mainContext;
+ (NSManagedObjectContext *)newChildContextWithPrivateQueue;
++ (void)migratePersistentStoreToURL:(NSURL *)storeURL;
+
@end
+
+NS_ASSUME_NONNULL_END
diff --git a/PSCCoreDataStack/PSCCoreDataStack.m b/PSCCoreDataStack/PSCCoreDataStack.m
index b8de2d7..9e15965 100644
--- a/PSCCoreDataStack/PSCCoreDataStack.m
+++ b/PSCCoreDataStack/PSCCoreDataStack.m
@@ -23,47 +23,51 @@ @implementation PSCCoreDataStack
+ (void)setupWithModelURL:(NSURL *)modelURL
storeFileName:(NSString *)storeFileName
type:(NSString *)storeType
+ storeURL:(NSURL *)storeURL
configuration:(NSString *)configuration
options:(NSDictionary *)options
- success:(void(^)())successBlock
+ success:(void(^)(void))successBlock
error:(void(^)(NSError *error))errorBlock {
-
+
NSParameterAssert(modelURL != nil);
NSParameterAssert([storeType isEqualToString:NSSQLiteStoreType] || [storeType isEqualToString:NSBinaryStoreType] || [storeType isEqualToString:NSInMemoryStoreType]);
if (![storeType isEqualToString:NSInMemoryStoreType]) {
- NSParameterAssert(storeFileName != nil);
+ NSParameterAssert((storeFileName != nil) != (storeURL != nil));
}
-
+
NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
NSAssert(model != nil, @"Failed to initialize model with URL: %@", modelURL);
-
+
NSPersistentStoreCoordinator *persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
NSAssert(persistentStoreCoordinator != nil, @"Failed to initialize persistent store coordinator with model: %@", model);
-
+
psc_privateContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
psc_privateContext.persistentStoreCoordinator = persistentStoreCoordinator;
-
+
psc_mainContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
psc_mainContext.parentContext = psc_privateContext;
-
+
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
- NSURL *storeURL = nil;
-
- if (storeFileName != nil) {
- storeURL = [[[NSFileManager new] URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] lastObject];
- storeURL = [storeURL URLByAppendingPathComponent:storeFileName];
+ __block NSURL *url = storeURL;
+
+ if (url == nil) {
+ url = [[[NSFileManager new] URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] lastObject];
+
+ if(storeFileName != nil) {
+ url = [url URLByAppendingPathComponent:storeFileName];
+ }
}
-
+
NSError *error = nil;
NSPersistentStore *store = [persistentStoreCoordinator addPersistentStoreWithType:storeType
configuration:configuration
- URL:storeURL
+ URL:url
options:options
error:&error];
-
+
if (store == nil) {
PSCCDLog(@"Error adding persistent store to coordinator %@\n%@", [error localizedDescription], [error userInfo]);
-
+
if (errorBlock != nil) {
dispatch_async(dispatch_get_main_queue(), ^{
errorBlock(error);
@@ -77,12 +81,13 @@ + (void)setupWithModelURL:(NSURL *)modelURL
});
}
-+ (void)setupWithModelURL:(NSURL *)modelURL autoMigratedSQLiteStoreFileName:(NSString *)storeFileName success:(void(^)())successBlock error:(void(^)(NSError *error))errorBlock {
++ (void)setupWithModelURL:(NSURL *)modelURL autoMigratedSQLiteStoreFileName:(NSString *)storeFileName success:(void(^)(void))successBlock error:(void(^)(NSError *error))errorBlock {
NSDictionary *options = @{NSMigratePersistentStoresAutomaticallyOption: @(YES), NSInferMappingModelAutomaticallyOption: @(YES)};
-
+
[self setupWithModelURL:modelURL
storeFileName:storeFileName
type:NSSQLiteStoreType
+ storeURL:nil
configuration:nil
options:options
success:successBlock
@@ -101,7 +106,7 @@ + (void)saveAndPersistContext {
[self saveAndPersistContextBlocking:NO];
}
-+ (void)saveAndPersistContextBlocking:(BOOL)wait success:(void(^)())sucessBlock error:(void(^)(NSError *error))errorBlock {
++ (void)saveAndPersistContextBlocking:(BOOL)wait success:(void(^)(void))sucessBlock error:(void(^)(NSError *error))errorBlock {
[[self mainContext] saveAndPropagateToParentContextBlocking:wait success:sucessBlock failure:^(NSError *error) {
PSCCDLog(@"%@ %@", [error localizedDescription], [error userInfo]);
if (errorBlock) {
@@ -110,7 +115,7 @@ + (void)saveAndPersistContextBlocking:(BOOL)wait success:(void(^)())sucessBlock
}];
}
-+ (void)saveAndPersistContextWithSuccess:(void(^)())sucessBlock error:(void(^)(NSError *error))errorBlock {
++ (void)saveAndPersistContextWithSuccess:(void(^)(void))sucessBlock error:(void(^)(NSError *error))errorBlock {
[self saveAndPersistContextBlocking:NO success:sucessBlock error:errorBlock];
}
@@ -126,4 +131,40 @@ + (NSManagedObjectContext *)newChildContextWithPrivateQueue {
return [[self mainContext] newChildContextWithConcurrencyType:NSPrivateQueueConcurrencyType];
}
+////////////////////////////////////////////////////////////////////////
+#pragma mark - Migration
+////////////////////////////////////////////////////////////////////////
+
++ (void)migratePersistentStoreToURL:(NSURL *)storeURL {
+ NSPersistentStoreCoordinator *storeCoordinator = psc_privateContext.persistentStoreCoordinator;
+ NSArray *stores = storeCoordinator.persistentStores;
+
+ NSAssert([stores count] == 1, @"PSCCoreDataStack doesn't support changing storeURL for multiple Stores");
+
+ NSPersistentStore *store = stores[0];
+
+ if (![store.URL isEqual:storeURL]) {
+ NSError *error;
+ [psc_privateContext.persistentStoreCoordinator migratePersistentStore:store toURL:storeURL options:nil withType:store.type error:&error];
+
+ NSAssert(error == nil, @"Error migrating persistent store %@ %@\n%@", psc_privateContext, [error localizedDescription], [error userInfo]);
+
+ NSFileManager *fileManager = [NSFileManager defaultManager];
+
+ if ([fileManager fileExistsAtPath:[store.URL path]]) {
+ [fileManager removeItemAtURL:store.URL error:&error];
+ }
+
+ NSURL *shm = [[store.URL URLByDeletingPathExtension] URLByAppendingPathExtension:@"sqlite-shm"];
+ if ([fileManager fileExistsAtPath:[shm path]]) {
+ [fileManager removeItemAtURL:shm error:&error];
+ }
+
+ NSURL *wal = [[store.URL URLByDeletingPathExtension] URLByAppendingPathExtension:@"sqlite-wal"];
+ if ([fileManager fileExistsAtPath:[wal path]]) {
+ [fileManager removeItemAtURL:wal error:&error];
+ }
+ }
+}
+
@end
diff --git a/PSCCoreDataStack/PSCFetchedResultsControllerUpdater.h b/PSCCoreDataStack/PSCFetchedResultsControllerUpdater.h
index 4023d46..089fd97 100644
--- a/PSCCoreDataStack/PSCFetchedResultsControllerUpdater.h
+++ b/PSCCoreDataStack/PSCFetchedResultsControllerUpdater.h
@@ -7,6 +7,8 @@
//
// Derived from MrRooni's Gist: https://gist.github.com/MrRooni/4988922
+#import
+
/**
Controller that can be used to gather information about animated updates in a UITableView/UICollectionView.
@@ -38,6 +40,8 @@
*/
+NS_ASSUME_NONNULL_BEGIN
+
extern NSString *const PSCFetchedResultsControllerUpdaterControllerDidChangeContentNotification;
@interface PSCFetchedResultsControllerUpdater : NSObject
@@ -50,10 +54,10 @@ extern NSString *const PSCFetchedResultsControllerUpdaterControllerDidChangeCont
@property (nonatomic, readonly) NSIndexSet *deletedSectionIndexes;
@property (nonatomic, readonly) NSIndexSet *insertedSectionIndexes;
-@property (nonatomic, readonly) NSArray *deletedObjectIndexPaths;
-@property (nonatomic, readonly) NSArray *insertedObjectIndexPaths;
-@property (nonatomic, readonly) NSArray *updatedObjectIndexPaths;
-@property (nonatomic, readonly) NSArray *movedObjectIndexPaths; // only set if reportMovesAsInsertionsAndDeletions is NO
+@property (nonatomic, readonly) NSArray *deletedObjectIndexPaths;
+@property (nonatomic, readonly) NSArray *insertedObjectIndexPaths;
+@property (nonatomic, readonly) NSArray *updatedObjectIndexPaths;
+@property (nonatomic, readonly) NSArray *movedObjectIndexPaths; // only set if reportMovesAsInsertionsAndDeletions is NO
- (void)reset;
- (void)resetSectionChanges;
@@ -68,3 +72,5 @@ extern NSString *const PSCFetchedResultsControllerUpdaterControllerDidChangeCont
@property (nonatomic, strong) NSIndexPath *toIndexPath;
@end
+
+NS_ASSUME_NONNULL_END
diff --git a/PSCCoreDataStack/PSCFetchedResultsControllerUpdater.m b/PSCCoreDataStack/PSCFetchedResultsControllerUpdater.m
index b47449f..36e4303 100644
--- a/PSCCoreDataStack/PSCFetchedResultsControllerUpdater.m
+++ b/PSCCoreDataStack/PSCFetchedResultsControllerUpdater.m
@@ -7,6 +7,7 @@
//
#import "PSCFetchedResultsControllerUpdater.h"
+#import
NSString *const PSCFetchedResultsControllerUpdaterControllerDidChangeContentNotification = @"PSCFetchedResultsControllerUpdaterControllerDidChangeContentNotification";
diff --git a/PSCCoreDataStack/PSCPersistenceOperation.h b/PSCCoreDataStack/PSCPersistenceOperation.h
index 8e9fdca..81b72e6 100644
--- a/PSCCoreDataStack/PSCPersistenceOperation.h
+++ b/PSCCoreDataStack/PSCPersistenceOperation.h
@@ -7,13 +7,12 @@
//
#import
+#import
+NS_ASSUME_NONNULL_BEGIN
typedef BOOL(^psc_persistence_block)(NSManagedObjectContext *localContext);
-// the queue used in persistDataInBackgroundWithParentContext:block:completion:
-dispatch_queue_t psc_persistence_queue(void);
-
@interface PSCPersistenceOperation : NSOperation
@@ -23,14 +22,14 @@ dispatch_queue_t psc_persistence_queue(void);
*/
+ (void)persistDataInBackgroundWithParentContext:(NSManagedObjectContext *)parentContext
block:(psc_persistence_block)block
- completion:(dispatch_block_t)completion;
+ completion:(nullable dispatch_block_t)completion;
/**
Creates an NSOperation subclass that can be used to persist data to a local context
*/
+ (instancetype)operationWithParentContext:(NSManagedObjectContext *)parentContext
block:(psc_persistence_block)block
- completion:(dispatch_block_t)completion;
+ completion:(nullable dispatch_block_t)completion;
/** Subclasses can override to perform a persistence action */
- (BOOL)persistWithContext:(NSManagedObjectContext *)localContext;
@@ -40,3 +39,5 @@ dispatch_queue_t psc_persistence_queue(void);
- (void)didNotSaveContext:(NSManagedObjectContext *)localContext;
@end
+
+NS_ASSUME_NONNULL_END
diff --git a/PSCCoreDataStack/PSCPersistenceOperation.m b/PSCCoreDataStack/PSCPersistenceOperation.m
index 43fe996..7c04f97 100644
--- a/PSCCoreDataStack/PSCPersistenceOperation.m
+++ b/PSCCoreDataStack/PSCPersistenceOperation.m
@@ -3,7 +3,7 @@
#import "NSManagedObjectContext+PSCCoreDataHelper.h"
#import "PSCLogging.h"
-
+// the queue used in persistDataInBackgroundWithParentContext:block:completion:
static dispatch_queue_t _psc_persistence_queue = NULL;
@@ -44,19 +44,21 @@ + (void)persistDataInBackgroundWithParentContext:(NSManagedObjectContext *)paren
dispatch_async(psc_persistence_queue(), ^{
NSManagedObjectContext *localContext = [parentContext newChildContextWithConcurrencyType:NSPrivateQueueConcurrencyType];
- NSError *error = nil;
- if (block != nil) {
- block(localContext);
- }
+ [localContext performBlock:^{
+ if (block != nil) {
+ block(localContext);
+ }
- if (![localContext save:&error]) {
- PSCCDLog(@"Error persisting local context in PSCPersistenceAction: %@", error);
- }
+ NSError *error = nil;
+ if (![localContext save:&error]) {
+ PSCCDLog(@"Error persisting local context in PSCPersistenceAction: %@", error);
+ }
- if (completion != nil) {
- dispatch_async(dispatch_get_main_queue(), completion);
- }
+ if (completion != nil) {
+ dispatch_async(dispatch_get_main_queue(), completion);
+ }
+ }];
});
}
@@ -91,28 +93,30 @@ - (void)didNotSaveContext:(NSManagedObjectContext *)localContext {
- (void)main {
NSManagedObjectContext *localContext = [self.parentContext newChildContextWithConcurrencyType:NSPrivateQueueConcurrencyType];
- BOOL save = NO;
-
- // either persist via block (if set), or call method in subclass
- if (self.persistenceBlock != nil) {
- save = self.persistenceBlock(localContext);
- } else {
- save = [self persistWithContext:localContext];
- }
-
- if (save && localContext.hasChanges) {
- NSError *error = nil;
-
- [self willSaveContext:localContext];
-
- if (![localContext save:&error]) {
- [self didFailToSaveContext:localContext error:error];
+ [localContext performBlock:^{
+ BOOL save = NO;
+
+ // either persist via block (if set), or call method in subclass
+ if (self.persistenceBlock != nil) {
+ save = self.persistenceBlock(localContext);
+ } else {
+ save = [self persistWithContext:localContext];
+ }
+
+ if (save && localContext.hasChanges) {
+ NSError *error = nil;
+
+ [self willSaveContext:localContext];
+
+ if (![localContext save:&error]) {
+ [self didFailToSaveContext:localContext error:error];
+ } else {
+ [self didSaveContext:localContext];
+ }
} else {
- [self didSaveContext:localContext];
+ [self didNotSaveContext:localContext];
}
- } else {
- [self didNotSaveContext:localContext];
- }
+ }];
}
////////////////////////////////////////////////////////////////////////
diff --git a/PSCCoreDataStackTests/PSCCoreDataStackTests.h b/PSCCoreDataStackTests/PSCCoreDataStackTests.h
index 3ad88c6..64870c7 100644
--- a/PSCCoreDataStackTests/PSCCoreDataStackTests.h
+++ b/PSCCoreDataStackTests/PSCCoreDataStackTests.h
@@ -6,8 +6,8 @@
// Copyright (c) 2013 PocketScience. All rights reserved.
//
-#import
+#import
-@interface PSCCoreDataStackTests : SenTestCase
+@interface PSCCoreDataStackTests : XCTestCase
@end