From 21f57518c83321b5ff459f5de44e7cd04730cb6f Mon Sep 17 00:00:00 2001 From: John Estropia Date: Wed, 16 Mar 2016 21:23:41 +0900 Subject: [PATCH] WIP: Objective-C bridge --- CoreStore.xcodeproj/project.pbxproj | 71 +++++++- CoreStoreTests/BridgingTests.h | 30 ++++ CoreStoreTests/BridgingTests.m | 44 +++++ .../CoreStoreTests-Bridging-Header.h | 5 + ...FetchedResultsController+Convenience.swift | 1 + .../NSManagedObject+Convenience.swift | 4 + .../NSProgress+Convenience.swift | 1 + Sources/Migrating/MigrationChain.swift | 126 ++++++++------ Sources/ObjectiveC/CSCoreStore.swift | 63 +++++++ Sources/ObjectiveC/CSDataStack.swift | 155 ++++++++++++++++++ Sources/ObjectiveC/CoreStoreBridge.swift | 74 +++++++++ .../NSManagedObject+Transaction.swift | 1 + 12 files changed, 520 insertions(+), 55 deletions(-) create mode 100644 CoreStoreTests/BridgingTests.h create mode 100644 CoreStoreTests/BridgingTests.m create mode 100644 CoreStoreTests/CoreStoreTests-Bridging-Header.h create mode 100644 Sources/ObjectiveC/CSCoreStore.swift create mode 100644 Sources/ObjectiveC/CSDataStack.swift create mode 100644 Sources/ObjectiveC/CoreStoreBridge.swift diff --git a/CoreStore.xcodeproj/project.pbxproj b/CoreStore.xcodeproj/project.pbxproj index 56ab788..04de4da 100644 --- a/CoreStore.xcodeproj/project.pbxproj +++ b/CoreStore.xcodeproj/project.pbxproj @@ -217,6 +217,10 @@ B59AFF411C6593E400C0ABE2 /* NSPersistentStoreCoordinator+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59AFF401C6593E400C0ABE2 /* NSPersistentStoreCoordinator+Setup.swift */; }; B59D5C221B5BA34B00453479 /* NSFileManager+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59D5C211B5BA34B00453479 /* NSFileManager+Setup.swift */; }; B5A261211B64BFDB006EB6D3 /* MigrationType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A261201B64BFDB006EB6D3 /* MigrationType.swift */; }; + B5AEFAB51C9962AE00AD137F /* CoreStoreBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5AEFAB41C9962AE00AD137F /* CoreStoreBridge.swift */; }; + B5AEFAB61C9962AE00AD137F /* CoreStoreBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5AEFAB41C9962AE00AD137F /* CoreStoreBridge.swift */; }; + B5AEFAB71C9962AE00AD137F /* CoreStoreBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5AEFAB41C9962AE00AD137F /* CoreStoreBridge.swift */; }; + B5AEFAB81C9962AE00AD137F /* CoreStoreBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5AEFAB41C9962AE00AD137F /* CoreStoreBridge.swift */; }; B5C976E31C6C9F6A00B1AF90 /* UnsafeDataTransaction+Observing.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C976E21C6C9F6A00B1AF90 /* UnsafeDataTransaction+Observing.swift */; }; B5C976E41C6C9F9A00B1AF90 /* UnsafeDataTransaction+Observing.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C976E21C6C9F6A00B1AF90 /* UnsafeDataTransaction+Observing.swift */; }; B5C976E51C6C9F9B00B1AF90 /* UnsafeDataTransaction+Observing.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C976E21C6C9F6A00B1AF90 /* UnsafeDataTransaction+Observing.swift */; }; @@ -232,6 +236,17 @@ B5D3F6471C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D3F6441C887C0A00C7492A /* LegacySQLiteStore.swift */; }; B5D3F6481C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D3F6441C887C0A00C7492A /* LegacySQLiteStore.swift */; }; B5D5E0CF1A4D6AAB006468AF /* TestEntity2.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D5E0CE1A4D6AAB006468AF /* TestEntity2.swift */; }; + B5DBE2CD1C9914A900B5CEFA /* CSCoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DBE2CC1C9914A900B5CEFA /* CSCoreStore.swift */; }; + B5DBE2CE1C9914A900B5CEFA /* CSCoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DBE2CC1C9914A900B5CEFA /* CSCoreStore.swift */; }; + B5DBE2CF1C9914A900B5CEFA /* CSCoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DBE2CC1C9914A900B5CEFA /* CSCoreStore.swift */; }; + B5DBE2D01C9914A900B5CEFA /* CSCoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DBE2CC1C9914A900B5CEFA /* CSCoreStore.swift */; }; + B5DBE2D21C991B3E00B5CEFA /* CSDataStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DBE2D11C991B3E00B5CEFA /* CSDataStack.swift */; }; + B5DBE2D31C991B3E00B5CEFA /* CSDataStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DBE2D11C991B3E00B5CEFA /* CSDataStack.swift */; }; + B5DBE2D41C991B3E00B5CEFA /* CSDataStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DBE2D11C991B3E00B5CEFA /* CSDataStack.swift */; }; + B5DBE2D51C991B3E00B5CEFA /* CSDataStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DBE2D11C991B3E00B5CEFA /* CSDataStack.swift */; }; + B5DBE2DF1C9939E100B5CEFA /* BridgingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B5DBE2DE1C9939E100B5CEFA /* BridgingTests.m */; }; + B5DBE2E01C9939E100B5CEFA /* BridgingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B5DBE2DE1C9939E100B5CEFA /* BridgingTests.m */; }; + B5DBE2E11C9939E100B5CEFA /* BridgingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B5DBE2DE1C9939E100B5CEFA /* BridgingTests.m */; }; B5DC47C61C93D22900FA3BF3 /* MigrationChainTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DC47C51C93D22900FA3BF3 /* MigrationChainTests.swift */; }; B5DC47C71C93D22900FA3BF3 /* MigrationChainTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DC47C51C93D22900FA3BF3 /* MigrationChainTests.swift */; }; B5DC47C81C93D22900FA3BF3 /* MigrationChainTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DC47C51C93D22900FA3BF3 /* MigrationChainTests.swift */; }; @@ -360,6 +375,7 @@ B59D5C211B5BA34B00453479 /* NSFileManager+Setup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSFileManager+Setup.swift"; sourceTree = ""; }; B5A261201B64BFDB006EB6D3 /* MigrationType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationType.swift; sourceTree = ""; }; B5AD60CD1C90141E00F2B2E8 /* Package.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = SOURCE_ROOT; }; + B5AEFAB41C9962AE00AD137F /* CoreStoreBridge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreBridge.swift; sourceTree = ""; }; B5BDC91A1C202269008147CD /* Cartfile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Cartfile; path = ../Cartfile; sourceTree = ""; }; B5BDC9271C2024F2008147CD /* .travis.yml */ = {isa = PBXFileReference; lastKnownFileType = text; path = .travis.yml; sourceTree = SOURCE_ROOT; }; B5C976E21C6C9F6A00B1AF90 /* UnsafeDataTransaction+Observing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UnsafeDataTransaction+Observing.swift"; sourceTree = ""; }; @@ -371,6 +387,11 @@ B5D3F6441C887C0A00C7492A /* LegacySQLiteStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LegacySQLiteStore.swift; sourceTree = ""; }; B5D5E0CE1A4D6AAB006468AF /* TestEntity2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestEntity2.swift; sourceTree = ""; }; B5D9C8F61B160ED200E64F0E /* CoreStore.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; path = CoreStore.podspec; sourceTree = SOURCE_ROOT; }; + B5DBE2CC1C9914A900B5CEFA /* CSCoreStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSCoreStore.swift; sourceTree = ""; }; + B5DBE2D11C991B3E00B5CEFA /* CSDataStack.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSDataStack.swift; sourceTree = ""; }; + B5DBE2DA1C9939E100B5CEFA /* CoreStoreTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CoreStoreTests-Bridging-Header.h"; sourceTree = ""; }; + B5DBE2DD1C9939E100B5CEFA /* BridgingTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BridgingTests.h; sourceTree = ""; }; + B5DBE2DE1C9939E100B5CEFA /* BridgingTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BridgingTests.m; sourceTree = ""; }; B5DC47C51C93D22900FA3BF3 /* MigrationChainTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationChainTests.swift; sourceTree = ""; }; B5DC47C91C93D9C800FA3BF3 /* StorageInterfaceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StorageInterfaceTests.swift; sourceTree = ""; }; B5E834B81B76311F001D3D50 /* BaseDataTransaction+Importing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BaseDataTransaction+Importing.swift"; sourceTree = ""; }; @@ -531,6 +552,7 @@ B5E84F191AFF84860064E85B /* Observing */, B56964D11B22FF700075EE4A /* Migrating */, B5E84F261AFF84920064E85B /* Convenience Helpers */, + B5DBE2CB1C99148100B5CEFA /* ObjectiveC */, B5E84F291AFF849C0064E85B /* Internal */, 2F03A53319C5C6DA005002A5 /* Supporting Files */, ); @@ -556,10 +578,13 @@ children = ( 2F03A53F19C5C6DA005002A5 /* CoreStoreTests.swift */, B5DC47C91C93D9C800FA3BF3 /* StorageInterfaceTests.swift */, + B5DBE2DD1C9939E100B5CEFA /* BridgingTests.h */, + B5DBE2DE1C9939E100B5CEFA /* BridgingTests.m */, B5DC47C51C93D22900FA3BF3 /* MigrationChainTests.swift */, B5D372851A39CDDB00F583D9 /* TestEntity1.swift */, B5D5E0CE1A4D6AAB006468AF /* TestEntity2.swift */, 2F03A53D19C5C6DA005002A5 /* Supporting Files */, + B5DBE2DA1C9939E100B5CEFA /* CoreStoreTests-Bridging-Header.h */, ); path = CoreStoreTests; sourceTree = ""; @@ -609,6 +634,16 @@ path = Migrating; sourceTree = ""; }; + B5DBE2CB1C99148100B5CEFA /* ObjectiveC */ = { + isa = PBXGroup; + children = ( + B5DBE2CC1C9914A900B5CEFA /* CSCoreStore.swift */, + B5DBE2D11C991B3E00B5CEFA /* CSDataStack.swift */, + B5AEFAB41C9962AE00AD137F /* CoreStoreBridge.swift */, + ); + path = ObjectiveC; + sourceTree = ""; + }; B5E834B61B7630BD001D3D50 /* Importing Data */ = { isa = PBXGroup; children = ( @@ -918,7 +953,7 @@ 2F03A52719C5C6DA005002A5 /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 0720; + LastSwiftUpdateCheck = 0730; LastUpgradeCheck = 0700; ORGANIZATIONNAME = "John Rommel Estropia"; TargetAttributes = { @@ -1048,6 +1083,7 @@ B56007111B3F6BD500A9A8F9 /* Into.swift in Sources */, B5E84F111AFF847B0064E85B /* Select.swift in Sources */, B5FE4DA21C8481E100FA6A91 /* StorageInterface.swift in Sources */, + B5DBE2D21C991B3E00B5CEFA /* CSDataStack.swift in Sources */, B50392F91C478FF3009900CA /* NSManagedObject+Transaction.swift in Sources */, B5202CFA1C04688100DED140 /* NSFetchedResultsController+Convenience.swift in Sources */, B5E84EE11AFF84500064E85B /* SetupResult.swift in Sources */, @@ -1077,6 +1113,7 @@ B5E84EFC1AFF846E0064E85B /* SynchronousDataTransaction.swift in Sources */, B5E84F281AFF84920064E85B /* NSManagedObject+Convenience.swift in Sources */, B51BE06A1B47FC4B0069F532 /* NSManagedObjectModel+Setup.swift in Sources */, + B5AEFAB51C9962AE00AD137F /* CoreStoreBridge.swift in Sources */, B5E84F391AFF85470064E85B /* NSManagedObjectContext+Querying.swift in Sources */, B5E84EE81AFF84610064E85B /* CoreStoreLogger.swift in Sources */, B5E84F311AFF849C0064E85B /* WeakObject.swift in Sources */, @@ -1089,6 +1126,7 @@ B5E834B91B76311F001D3D50 /* BaseDataTransaction+Importing.swift in Sources */, B5E84EE61AFF84610064E85B /* DefaultLogger.swift in Sources */, B5E84EF41AFF846E0064E85B /* AsynchronousDataTransaction.swift in Sources */, + B5DBE2CD1C9914A900B5CEFA /* CSCoreStore.swift in Sources */, B5E84F151AFF847B0064E85B /* CoreStore+Querying.swift in Sources */, B5E84F241AFF84860064E85B /* ListObserver.swift in Sources */, B5E84F2E1AFF849C0064E85B /* AssociatedObjects.swift in Sources */, @@ -1103,6 +1141,7 @@ B5DC47C61C93D22900FA3BF3 /* MigrationChainTests.swift in Sources */, B5D372861A39CDDB00F583D9 /* TestEntity1.swift in Sources */, B5D372841A39CD6900F583D9 /* Model.xcdatamodeld in Sources */, + B5DBE2DF1C9939E100B5CEFA /* BridgingTests.m in Sources */, B5D5E0CF1A4D6AAB006468AF /* TestEntity2.swift in Sources */, B5DC47CA1C93D9C800FA3BF3 /* StorageInterfaceTests.swift in Sources */, ); @@ -1134,6 +1173,7 @@ 82BA18B11C4BBD3100A0916E /* SaveResult.swift in Sources */, 82BA18DD1C4BBE1400A0916E /* NSFetchedResultsController+Convenience.swift in Sources */, B5FE4DA81C84FB4400FA6A91 /* InMemoryStore.swift in Sources */, + B5DBE2D31C991B3E00B5CEFA /* CSDataStack.swift in Sources */, 82BA18B41C4BBD3900A0916E /* BaseDataTransaction+Importing.swift in Sources */, 82BA18CA1C4BBD5900A0916E /* MigrationResult.swift in Sources */, 82BA18C11C4BBD5300A0916E /* CoreStore+Observing.swift in Sources */, @@ -1163,6 +1203,7 @@ 82BA18C71C4BBD5900A0916E /* CoreStore+Migration.swift in Sources */, 82BA18C41C4BBD5300A0916E /* ListMonitor.swift in Sources */, 82BA18BA1C4BBD4A00A0916E /* Select.swift in Sources */, + B5AEFAB61C9962AE00AD137F /* CoreStoreBridge.swift in Sources */, 82BA18A71C4BBD2900A0916E /* CoreStore+Logging.swift in Sources */, 82BA18D81C4BBD7100A0916E /* WeakObject.swift in Sources */, 82BA18AF1C4BBD3100A0916E /* CoreStore+Transaction.swift in Sources */, @@ -1175,6 +1216,7 @@ 82BA18D61C4BBD7100A0916E /* NSManagedObjectContext+Transaction.swift in Sources */, 82BA18B91C4BBD4A00A0916E /* From.swift in Sources */, 82BA18BE1C4BBD4A00A0916E /* Tweak.swift in Sources */, + B5DBE2CE1C9914A900B5CEFA /* CSCoreStore.swift in Sources */, 82BA18CC1C4BBD6400A0916E /* NSProgress+Convenience.swift in Sources */, 82BA18C01C4BBD5300A0916E /* DataStack+Observing.swift in Sources */, 82BA18A61C4BBD2900A0916E /* DefaultLogger.swift in Sources */, @@ -1188,6 +1230,7 @@ 82BA18DA1C4BBD9700A0916E /* TestEntity1.swift in Sources */, B5DC47C71C93D22900FA3BF3 /* MigrationChainTests.swift in Sources */, 82BA18DB1C4BBD9700A0916E /* TestEntity2.swift in Sources */, + B5DBE2E01C9939E100B5CEFA /* BridgingTests.m in Sources */, 82BA18D91C4BBD9700A0916E /* CoreStoreTests.swift in Sources */, 82BA18DC1C4BBD9C00A0916E /* Model.xcdatamodeld in Sources */, B5DC47CB1C93D9C800FA3BF3 /* StorageInterfaceTests.swift in Sources */, @@ -1198,6 +1241,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + B5DBE2D01C9914A900B5CEFA /* CSCoreStore.swift in Sources */, B52DD1BE1BE1F94300949AFE /* NSProgress+Convenience.swift in Sources */, B52DD1951BE1F92500949AFE /* CoreStoreError.swift in Sources */, B52DD1C21BE1F94600949AFE /* MigrationManager.swift in Sources */, @@ -1251,6 +1295,8 @@ B52DD19B1BE1F92800949AFE /* CoreStoreLogger.swift in Sources */, B52DD1991BE1F92800949AFE /* DefaultLogger.swift in Sources */, B52DD1B91BE1F94000949AFE /* CoreStore+Migration.swift in Sources */, + B5DBE2D51C991B3E00B5CEFA /* CSDataStack.swift in Sources */, + B5AEFAB81C9962AE00AD137F /* CoreStoreBridge.swift in Sources */, B598514B1C90289F00C99590 /* NSPersistentStoreCoordinator+Setup.swift in Sources */, B52DD1AA1BE1F93500949AFE /* ClauseTypes.swift in Sources */, ); @@ -1263,6 +1309,7 @@ B52DD1CD1BE1F94D00949AFE /* TestEntity1.swift in Sources */, B5DC47C81C93D22900FA3BF3 /* MigrationChainTests.swift in Sources */, B52DD1CE1BE1F94D00949AFE /* TestEntity2.swift in Sources */, + B5DBE2E11C9939E100B5CEFA /* BridgingTests.m in Sources */, B52DD1CC1BE1F94D00949AFE /* CoreStoreTests.swift in Sources */, B5598BCC1BE2093D0092EFCE /* Model.xcdatamodeld in Sources */, B5DC47CC1C93D9C800FA3BF3 /* StorageInterfaceTests.swift in Sources */, @@ -1295,6 +1342,7 @@ B56321981BD65216006C9394 /* Where.swift in Sources */, B5202CFD1C046E8400DED140 /* NSFetchedResultsController+Convenience.swift in Sources */, B5FE4DA91C84FB4400FA6A91 /* InMemoryStore.swift in Sources */, + B5DBE2D41C991B3E00B5CEFA /* CSDataStack.swift in Sources */, B56321AF1BD6521C006C9394 /* NSFileManager+Setup.swift in Sources */, B50392FA1C47963F009900CA /* NSManagedObject+Transaction.swift in Sources */, B56321971BD65216006C9394 /* Select.swift in Sources */, @@ -1324,6 +1372,7 @@ B563218E1BD65216006C9394 /* SaveResult.swift in Sources */, B56321A21BD65216006C9394 /* ListObserver.swift in Sources */, B563218A1BD65216006C9394 /* SynchronousDataTransaction.swift in Sources */, + B5AEFAB71C9962AE00AD137F /* CoreStoreBridge.swift in Sources */, B563219F1BD65216006C9394 /* ObjectMonitor.swift in Sources */, B56321B61BD6521C006C9394 /* WeakObject.swift in Sources */, B56321AC1BD6521C006C9394 /* Functions.swift in Sources */, @@ -1336,6 +1385,7 @@ B56321B41BD6521C006C9394 /* NSManagedObjectContext+Transaction.swift in Sources */, B56321861BD65216006C9394 /* CoreStoreLogger.swift in Sources */, B56321841BD65216006C9394 /* DefaultLogger.swift in Sources */, + B5DBE2CF1C9914A900B5CEFA /* CSCoreStore.swift in Sources */, B56321A41BD65216006C9394 /* CoreStore+Migration.swift in Sources */, B56321A01BD65216006C9394 /* ObjectObserver.swift in Sources */, B56321951BD65216006C9394 /* ClauseTypes.swift in Sources */, @@ -1475,6 +1525,7 @@ PRODUCT_NAME = CoreStore; SDKROOT = iphoneos; SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; name = Debug; }; @@ -1508,6 +1559,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.johnestropia.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = CoreStoreTests; SDKROOT = iphoneos; + SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; name = Debug; @@ -1521,12 +1573,14 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.johnestropia.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = CoreStoreTests; SDKROOT = iphoneos; + SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h"; }; name = Release; }; 82BA189A1C4BBCBA00A0916E /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -1538,6 +1592,7 @@ PRODUCT_NAME = CoreStore; SDKROOT = appletvos; SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; TARGETED_DEVICE_FAMILY = 3; }; name = Debug; @@ -1545,6 +1600,7 @@ 82BA189B1C4BBCBA00A0916E /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -1563,12 +1619,15 @@ 82BA189C1C4BBCBA00A0916E /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = CoreStoreTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.johnestropia.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = CoreStoreTests; SDKROOT = appletvos; + SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; TARGETED_DEVICE_FAMILY = 3; }; name = Debug; @@ -1576,6 +1635,7 @@ 82BA189D1C4BBCBA00A0916E /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; COPY_PHASE_STRIP = NO; GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = CoreStoreTests/Info.plist; @@ -1583,6 +1643,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.johnestropia.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = CoreStoreTests; SDKROOT = appletvos; + SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h"; TARGETED_DEVICE_FAMILY = 3; }; name = Release; @@ -1591,6 +1652,7 @@ isa = XCBuildConfiguration; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = "-"; COMBINE_HIDPI_IMAGES = YES; DEBUG_INFORMATION_FORMAT = dwarf; @@ -1606,6 +1668,7 @@ PRODUCT_NAME = CoreStore; SDKROOT = macosx; SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; name = Debug; }; @@ -1613,6 +1676,7 @@ isa = XCBuildConfiguration; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = "-"; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; @@ -1645,6 +1709,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.johnestropia.CoreStore; PRODUCT_NAME = CoreStoreTests; SDKROOT = macosx; + SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; name = Debug; @@ -1663,12 +1728,14 @@ PRODUCT_BUNDLE_IDENTIFIER = com.johnestropia.CoreStore; PRODUCT_NAME = CoreStoreTests; SDKROOT = macosx; + SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h"; }; name = Release; }; B56321751BD65082006C9394 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; @@ -1681,6 +1748,7 @@ PRODUCT_NAME = CoreStore; SDKROOT = watchos; SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; TARGETED_DEVICE_FAMILY = 4; }; name = Debug; @@ -1688,6 +1756,7 @@ B56321761BD65082006C9394 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; diff --git a/CoreStoreTests/BridgingTests.h b/CoreStoreTests/BridgingTests.h new file mode 100644 index 0000000..4785d6d --- /dev/null +++ b/CoreStoreTests/BridgingTests.h @@ -0,0 +1,30 @@ +// +// BridgingTests.h +// CoreStore +// +// Copyright © 2016 John Rommel Estropia +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// + +#import + +@interface BridgingTests : XCTestCase + +@end diff --git a/CoreStoreTests/BridgingTests.m b/CoreStoreTests/BridgingTests.m new file mode 100644 index 0000000..acfb196 --- /dev/null +++ b/CoreStoreTests/BridgingTests.m @@ -0,0 +1,44 @@ +// +// BridgingTests.m +// CoreStore +// +// Copyright © 2016 John Rommel Estropia +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// + +#import "BridgingTests.h" + +@import CoreStore; + +@implementation BridgingTests + +- (void)testDataStack { + + CSDataStack *dataStack = [[CSDataStack alloc] + initWithModelName: @"Model" + bundle: [NSBundle bundleForClass:[self class]] + versionChain: nil]; + XCTAssertNotNil(dataStack); + + [CSCoreStore setDefaultStack:dataStack]; + XCTAssertTrue([dataStack isEqual:[CSCoreStore defaultStack]]); +} + +@end diff --git a/CoreStoreTests/CoreStoreTests-Bridging-Header.h b/CoreStoreTests/CoreStoreTests-Bridging-Header.h new file mode 100644 index 0000000..d5b75f7 --- /dev/null +++ b/CoreStoreTests/CoreStoreTests-Bridging-Header.h @@ -0,0 +1,5 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// + +#import "BridgingTests.h" \ No newline at end of file diff --git a/Sources/Convenience Helpers/NSFetchedResultsController+Convenience.swift b/Sources/Convenience Helpers/NSFetchedResultsController+Convenience.swift index 410b297..deae7e9 100644 --- a/Sources/Convenience Helpers/NSFetchedResultsController+Convenience.swift +++ b/Sources/Convenience Helpers/NSFetchedResultsController+Convenience.swift @@ -34,6 +34,7 @@ public extension NSFetchedResultsController { /** Utility for creating an `NSFetchedResultsController` from a `DataStack`. This is useful to partially support Objective-C classes by passing an `NSFetchedResultsController` instance instead of a `ListMonitor`. */ + @nonobjc public static func createForStack(dataStack: DataStack, fetchRequest: NSFetchRequest, from: From? = nil, sectionBy: SectionBy? = nil, fetchClauses: [FetchClause]) -> NSFetchedResultsController { return CoreStoreFetchedResultsController( diff --git a/Sources/Convenience Helpers/NSManagedObject+Convenience.swift b/Sources/Convenience Helpers/NSManagedObject+Convenience.swift index 17406a1..f1eb1dc 100644 --- a/Sources/Convenience Helpers/NSManagedObject+Convenience.swift +++ b/Sources/Convenience Helpers/NSManagedObject+Convenience.swift @@ -38,6 +38,7 @@ public extension NSManagedObject { - returns: the primitive value for the KVC key */ @warn_unused_result + @nonobjc public func accessValueForKVCKey(KVCKey: KeyPath) -> AnyObject? { self.willAccessValueForKey(KVCKey) @@ -53,6 +54,7 @@ public extension NSManagedObject { - parameter value: the value to set the KVC key with - parameter KVCKey: the KVC key */ + @nonobjc public func setValue(value: AnyObject?, forKVCKey KVCKey: KeyPath) { self.willChangeValueForKey(KVCKey) @@ -63,6 +65,7 @@ public extension NSManagedObject { /** Re-faults the object to use the latest values from the persistent store */ + @nonobjc public func refreshAsFault() { self.managedObjectContext?.refreshObject(self, mergeChanges: false) @@ -71,6 +74,7 @@ public extension NSManagedObject { /** Re-faults the object to use the latest values from the persistent store and merges previously pending changes back */ + @nonobjc public func refreshAndMerge() { self.managedObjectContext?.refreshObject(self, mergeChanges: true) diff --git a/Sources/Convenience Helpers/NSProgress+Convenience.swift b/Sources/Convenience Helpers/NSProgress+Convenience.swift index 23ae408..5448875 100644 --- a/Sources/Convenience Helpers/NSProgress+Convenience.swift +++ b/Sources/Convenience Helpers/NSProgress+Convenience.swift @@ -37,6 +37,7 @@ public extension NSProgress { Sets a closure that the `NSProgress` calls whenever its `fractionCompleted` changes. You can use this instead of setting up KVO. - parameter closure: the closure to execute on progress change */ + @nonobjc public func setProgressHandler(closure: ((progress: NSProgress) -> Void)?) { self.progressObserver.progressHandler = closure diff --git a/Sources/Migrating/MigrationChain.swift b/Sources/Migrating/MigrationChain.swift index eb1a3a0..ce6570a 100644 --- a/Sources/Migrating/MigrationChain.swift +++ b/Sources/Migrating/MigrationChain.swift @@ -62,9 +62,7 @@ import CoreData */ public struct MigrationChain: NilLiteralConvertible, StringLiteralConvertible, DictionaryLiteralConvertible, ArrayLiteralConvertible { - // MARK: NilLiteralConvertible - - public init(nilLiteral: ()) { + public init() { self.versionTree = [:] self.rootVersions = [] @@ -72,10 +70,7 @@ public struct MigrationChain: NilLiteralConvertible, StringLiteralConvertible, D self.valid = true } - - // MARK: StringLiteralConvertible - - public init(stringLiteral value: String) { + public init(_ value: String) { self.versionTree = [:] self.rootVersions = [value] @@ -83,32 +78,30 @@ public struct MigrationChain: NilLiteralConvertible, StringLiteralConvertible, D self.valid = true } - - // MARK: ExtendedGraphemeClusterLiteralConvertible - - public init(extendedGraphemeClusterLiteral value: String) { + public init(_ elements: T) { - self.versionTree = [:] - self.rootVersions = [value] - self.leafVersions = [value] - self.valid = true + CoreStore.assert(Set(elements).count == Array(elements).count, "\(typeName(MigrationChain))'s migration chain could not be created due to duplicate version strings.") + + var lastVersion: String? + var versionTree = [String: String]() + var valid = true + for version in elements { + + if let lastVersion = lastVersion, + let _ = versionTree.updateValue(version, forKey: lastVersion) { + + valid = false + } + lastVersion = version + } + + self.versionTree = versionTree + self.rootVersions = Set([elements.first].flatMap { $0 == nil ? [] : [$0!] }) + self.leafVersions = Set([elements.last].flatMap { $0 == nil ? [] : [$0!] }) + self.valid = valid } - - // MARK: UnicodeScalarLiteralConvertible - - public init(unicodeScalarLiteral value: String) { - - self.versionTree = [:] - self.rootVersions = [value] - self.leafVersions = [value] - self.valid = true - } - - - // MARK: DictionaryLiteralConvertible - - public init(dictionaryLiteral elements: (String, String)...) { + public init(_ elements: [(String, String)]) { var valid = true var versionTree = [String: String]() @@ -124,11 +117,9 @@ public struct MigrationChain: NilLiteralConvertible, StringLiteralConvertible, D valid = false } let leafVersions = Set( - elements.filter { (tuple: (String, String)) -> Bool in - - return versionTree[tuple.1] == nil - - }.map { $1 } + elements + .filter { versionTree[$1] == nil } + .map { $1 } ) let isVersionAmbiguous = { (start: String) -> Bool in @@ -156,30 +147,57 @@ public struct MigrationChain: NilLiteralConvertible, StringLiteralConvertible, D self.valid = valid && Set(versionTree.keys).union(versionTree.values).filter { isVersionAmbiguous($0) }.count <= 0 } + public init(_ dictionary: [String: String]) { + + self.init(dictionary.map { $0 }) + } + + + // MARK: NilLiteralConvertible + + public init(nilLiteral: ()) { + + self.init() + } + + + // MARK: StringLiteralConvertible + + public init(stringLiteral value: String) { + + self.init(value) + } + + + // MARK: ExtendedGraphemeClusterLiteralConvertible + + public init(extendedGraphemeClusterLiteral value: String) { + + self.init(value) + } + + + // MARK: UnicodeScalarLiteralConvertible + + public init(unicodeScalarLiteral value: String) { + + self.init(value) + } + + + // MARK: DictionaryLiteralConvertible + + public init(dictionaryLiteral elements: (String, String)...) { + + self.init(elements) + } + // MARK: ArrayLiteralConvertible public init(arrayLiteral elements: String...) { - CoreStore.assert(Set(elements).count == elements.count, "\(typeName(MigrationChain))'s migration chain could not be created due to duplicate version strings.") - - var lastVersion: String? - var versionTree = [String: String]() - var valid = true - for version in elements { - - if let lastVersion = lastVersion, - let _ = versionTree.updateValue(version, forKey: lastVersion) { - - valid = false - } - lastVersion = version - } - - self.versionTree = versionTree - self.rootVersions = Set([elements.first].flatMap { $0 == nil ? [] : [$0!] }) - self.leafVersions = Set([elements.last].flatMap { $0 == nil ? [] : [$0!] }) - self.valid = valid + self.init(elements) } diff --git a/Sources/ObjectiveC/CSCoreStore.swift b/Sources/ObjectiveC/CSCoreStore.swift new file mode 100644 index 0000000..a38b7a3 --- /dev/null +++ b/Sources/ObjectiveC/CSCoreStore.swift @@ -0,0 +1,63 @@ +// +// CSCoreStore.swift +// CoreStore +// +// Copyright © 2016 John Rommel Estropia +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// + +import Foundation +import CoreData + + +// MARK: - CSCoreStore + +/** + The `CSCoreStore` serves as the Objective-C bridging type for `CoreStore`. + */ +@objc +public final class CSCoreStore: NSObject { + + /** + The default `CSDataStack` instance to be used. If `defaultStack` is not set before the first time accessed, a default-configured `DataStack` will be created. + + Changing the `defaultStack` is thread safe, but it is recommended to setup `DataStacks` on a common queue (e.g. the main queue). + */ + @objc + public class var defaultStack: CSDataStack { + + get { + + return CoreStore.defaultStack.objc + } + set { + + CoreStore.defaultStack = newValue.swift + } + } + + + // MARK: Private + + private override init() { + + fatalError() + } +} diff --git a/Sources/ObjectiveC/CSDataStack.swift b/Sources/ObjectiveC/CSDataStack.swift new file mode 100644 index 0000000..a71dc96 --- /dev/null +++ b/Sources/ObjectiveC/CSDataStack.swift @@ -0,0 +1,155 @@ +// +// CSDataStack.swift +// CoreStore +// +// Copyright © 2016 John Rommel Estropia +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// + +import Foundation +import CoreData + + +// MARK: - DataStack + +extension DataStack: CoreStoreBridgeable { + + // MARK: CoreStoreBridgeable + + public typealias NativeType = CSDataStack +} + + +// MARK: - CSDataStack + +/** + The `CSDataStack` serves as the Objective-C bridging type for `DataStack`. + */ +@objc +public final class CSDataStack: NSObject, CoreStoreBridge { + + /** + Initializes a `CSDataStack` with default settings. CoreStore searches for .xcdatamodeld from the main `NSBundle` and loads an `NSManagedObjectModel` from it. An assertion is raised if the model could not be found. + */ + @objc + public convenience override init() { + + self.init(DataStack()) + } + + /** + Initializes a `CSDataStack` from the model with the specified `modelName` in the specified `bundle`. + + - parameter modelName: the name of the (.xcdatamodeld) model file. If not specified, the application name (CFBundleName) will be used if it exists, or "CoreData" if it the bundle name was not set. + - parameter bundle: an optional bundle to load models from. If not specified, the main bundle will be used. + - parameter versionChain: the version strings that indicate the sequence of model versions to be used as the order for progressive migrations. If not specified, will default to a non-migrating data stack. + */ + @objc + public convenience init(modelName: String = DataStack.applicationName, bundle: NSBundle = NSBundle.mainBundle(), versionChain: [String]? = nil) { + + self.init( + DataStack( + modelName: modelName, + bundle: bundle, + migrationChain: versionChain.flatMap { MigrationChain($0) } ?? nil + ) + ) + } + + /** + Initializes a `CSDataStack` from the model with the specified `modelName` in the specified `bundle`. + + - parameter modelName: the name of the (.xcdatamodeld) model file. If not specified, the application name (CFBundleName) will be used if it exists, or "CoreData" if it the bundle name was not set. + - parameter bundle: an optional bundle to load models from. If not specified, the main bundle will be used. + - parameter versionTree: the version strings that indicate the sequence of model versions to be used as the order for progressive migrations. If not specified, will default to a non-migrating data stack. + */ + @objc + public convenience init(modelName: String = DataStack.applicationName, bundle: NSBundle = NSBundle.mainBundle(), versionTree: [String: String]? = nil) { + + self.init( + DataStack( + modelName: modelName, + bundle: bundle, + migrationChain: versionTree.flatMap { MigrationChain($0) } ?? nil + ) + ) + } + + /** + Initializes a `DataStack` from an `NSManagedObjectModel`. + + - parameter model: the `NSManagedObjectModel` for the stack + - parameter versionChain: the `MigrationChain` that indicates the sequence of model versions to be used as the order for progressive migrations. If not specified, will default to a non-migrating data stack. + */ + @objc + public convenience init(model: NSManagedObjectModel, versionChain: [String]? = nil) { + + self.init( + DataStack( + model: model, + migrationChain: versionChain.flatMap { MigrationChain($0) } ?? nil + ) + ) + } + + /** + Initializes a `DataStack` from an `NSManagedObjectModel`. + + - parameter model: the `NSManagedObjectModel` for the stack + - parameter versionTree: the `MigrationChain` that indicates the sequence of model versions to be used as the order for progressive migrations. If not specified, will default to a non-migrating data stack. + */ + @objc + public convenience init(model: NSManagedObjectModel, versionTree: [String]? = nil) { + + self.init( + DataStack( + model: model, + migrationChain: versionTree.flatMap { MigrationChain($0) } ?? nil + ) + ) + } + + + // MARK: NSObject + + public override var hash: Int { + + return ObjectIdentifier(self.swift).hashValue + } + + public override func isEqual(object: AnyObject?) -> Bool { + + guard let object = object as? CSDataStack else { + + return false + } + return self.swift === object.swift + } + + + // MARK: CoreStoreBridge + + public let swift: DataStack + + public required init(_ swiftObject: DataStack) { + + self.swift = swiftObject + } +} diff --git a/Sources/ObjectiveC/CoreStoreBridge.swift b/Sources/ObjectiveC/CoreStoreBridge.swift new file mode 100644 index 0000000..94bce22 --- /dev/null +++ b/Sources/ObjectiveC/CoreStoreBridge.swift @@ -0,0 +1,74 @@ +// +// CoreStoreBridge.swift +// CoreStore +// +// Copyright © 2016 John Rommel Estropia +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// + +import Foundation + +public protocol CoreStoreBridge: class, AnyObject { + + associatedtype SwiftType + + var swift: SwiftType { get } + + init(_ swiftObject: SwiftType) +} + +public protocol CoreStoreBridgeable: _ObjectiveCBridgeable { + + associatedtype NativeType: CoreStoreBridge +} + +public extension CoreStoreBridgeable where NativeType.SwiftType == Self { + + static func _isBridgedToObjectiveC() -> Bool { + + return true + } + + static func _getObjectiveCType() -> Any.Type { + + return NativeType.self + } + + func _bridgeToObjectiveC() -> NativeType { + + return NativeType(self) + } + + static func _forceBridgeFromObjectiveC(source: NativeType, inout result: Self?) { + + result = source.swift + } + + static func _conditionallyBridgeFromObjectiveC(source: NativeType, inout result: Self?) -> Bool { + + self._forceBridgeFromObjectiveC(source, result: &result) + return true + } + + var objc: NativeType { + + return self._bridgeToObjectiveC() + } +} diff --git a/Sources/Saving and Processing/NSManagedObject+Transaction.swift b/Sources/Saving and Processing/NSManagedObject+Transaction.swift index 6f30eff..600e79a 100644 --- a/Sources/Saving and Processing/NSManagedObject+Transaction.swift +++ b/Sources/Saving and Processing/NSManagedObject+Transaction.swift @@ -38,6 +38,7 @@ public extension NSManagedObject { Note that the internal reference to the transaction is `weak`, and it is still the developer's responsibility to retain a strong reference to the `UnsafeDataTransaction`. */ + @nonobjc public var unsafeDataTransaction: UnsafeDataTransaction? { return self.managedObjectContext?.parentTransaction as? UnsafeDataTransaction