diff --git a/Demo.xcodeproj/project.pbxproj b/Demo.xcodeproj/project.pbxproj index d5827e64..2a78f02f 100644 --- a/Demo.xcodeproj/project.pbxproj +++ b/Demo.xcodeproj/project.pbxproj @@ -489,6 +489,14 @@ 14867F861E7AF4D2001D228A /* JSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14867DD21E7AF4D2001D228A /* JSON.swift */; }; 14867F871E7AF4D2001D228A /* JSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14867DD21E7AF4D2001D228A /* JSON.swift */; }; 14867F881E7AF4D2001D228A /* JSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14867DD21E7AF4D2001D228A /* JSON.swift */; }; + 149CC25F1E81DBF2004D1B76 /* NSPropertyDescription+Sync.h in Headers */ = {isa = PBXBuildFile; fileRef = 149CC25D1E81DBF2004D1B76 /* NSPropertyDescription+Sync.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 149CC2601E81DBF2004D1B76 /* NSPropertyDescription+Sync.h in Headers */ = {isa = PBXBuildFile; fileRef = 149CC25D1E81DBF2004D1B76 /* NSPropertyDescription+Sync.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 149CC2611E81DBF2004D1B76 /* NSPropertyDescription+Sync.h in Headers */ = {isa = PBXBuildFile; fileRef = 149CC25D1E81DBF2004D1B76 /* NSPropertyDescription+Sync.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 149CC2621E81DBF2004D1B76 /* NSPropertyDescription+Sync.h in Headers */ = {isa = PBXBuildFile; fileRef = 149CC25D1E81DBF2004D1B76 /* NSPropertyDescription+Sync.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 149CC2631E81DBF2004D1B76 /* NSPropertyDescription+Sync.m in Sources */ = {isa = PBXBuildFile; fileRef = 149CC25E1E81DBF2004D1B76 /* NSPropertyDescription+Sync.m */; }; + 149CC2641E81DBF2004D1B76 /* NSPropertyDescription+Sync.m in Sources */ = {isa = PBXBuildFile; fileRef = 149CC25E1E81DBF2004D1B76 /* NSPropertyDescription+Sync.m */; }; + 149CC2651E81DBF2004D1B76 /* NSPropertyDescription+Sync.m in Sources */ = {isa = PBXBuildFile; fileRef = 149CC25E1E81DBF2004D1B76 /* NSPropertyDescription+Sync.m */; }; + 149CC2661E81DBF2004D1B76 /* NSPropertyDescription+Sync.m in Sources */ = {isa = PBXBuildFile; fileRef = 149CC25E1E81DBF2004D1B76 /* NSPropertyDescription+Sync.m */; }; 149FF9EA1E808C4400617A63 /* 375.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 149FF9E81E808C4400617A63 /* 375.xcdatamodeld */; }; 149FF9EB1E808C4400617A63 /* 375.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 149FF9E81E808C4400617A63 /* 375.xcdatamodeld */; }; 149FF9EC1E808C4400617A63 /* 375.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 149FF9E81E808C4400617A63 /* 375.xcdatamodeld */; }; @@ -553,6 +561,15 @@ 14E2F0A11E7ADE0E00DF1776 /* Sync.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 14241E981DBC39730042ED81 /* Sync.framework */; settings = {ATTRIBUTES = (Required, ); }; }; 14E2F0A21E7ADE1400DF1776 /* Sync.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 14241E8B1DBC39690042ED81 /* Sync.framework */; }; 14E2F0F31E7AE12200DF1776 /* Sync.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 14241E711DBC39520042ED81 /* Sync.framework */; }; + 14E6522A1E809A68000E7CC6 /* hyper_remote_key.json in Resources */ = {isa = PBXBuildFile; fileRef = 14E652291E809A68000E7CC6 /* hyper_remote_key.json */; }; + 14E6522B1E809A68000E7CC6 /* hyper_remote_key.json in Resources */ = {isa = PBXBuildFile; fileRef = 14E652291E809A68000E7CC6 /* hyper_remote_key.json */; }; + 14E6522C1E809A68000E7CC6 /* hyper_remote_key.json in Resources */ = {isa = PBXBuildFile; fileRef = 14E652291E809A68000E7CC6 /* hyper_remote_key.json */; }; + 14E652341E809B75000E7CC6 /* HyperRemoteKey.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 14E652321E809B75000E7CC6 /* HyperRemoteKey.xcdatamodeld */; }; + 14E652351E809B75000E7CC6 /* HyperRemoteKey.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 14E652321E809B75000E7CC6 /* HyperRemoteKey.xcdatamodeld */; }; + 14E652361E809B75000E7CC6 /* HyperRemoteKey.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 14E652321E809B75000E7CC6 /* HyperRemoteKey.xcdatamodeld */; }; + 14E6523D1E809E9C000E7CC6 /* NSPropertyDescription+SyncTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14E6523C1E809E9C000E7CC6 /* NSPropertyDescription+SyncTests.swift */; }; + 14E6523E1E809E9C000E7CC6 /* NSPropertyDescription+SyncTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14E6523C1E809E9C000E7CC6 /* NSPropertyDescription+SyncTests.swift */; }; + 14E6523F1E809E9C000E7CC6 /* NSPropertyDescription+SyncTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14E6523C1E809E9C000E7CC6 /* NSPropertyDescription+SyncTests.swift */; }; 14E93C441DBCCD2800E3304E /* Sync.h in Headers */ = {isa = PBXBuildFile; fileRef = 14E93C431DBCCD2800E3304E /* Sync.h */; settings = {ATTRIBUTES = (Public, ); }; }; 14E93C461DBCCD2800E3304E /* Sync.h in Headers */ = {isa = PBXBuildFile; fileRef = 14E93C431DBCCD2800E3304E /* Sync.h */; settings = {ATTRIBUTES = (Public, ); }; }; 14F6275B1E7AE6B2001C2EA0 /* DataStack.swift in Headers */ = {isa = PBXBuildFile; fileRef = 1467388B1E7ADBA700913C8E /* DataStack.swift */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -835,6 +852,8 @@ 14867DD21E7AF4D2001D228A /* JSON.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSON.swift; sourceTree = ""; }; 14975BE81DBC368B0024901A /* tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = tvOSTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 14975BF41DBC36960024901A /* macOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = macOSTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 149CC25D1E81DBF2004D1B76 /* NSPropertyDescription+Sync.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSPropertyDescription+Sync.h"; sourceTree = ""; }; + 149CC25E1E81DBF2004D1B76 /* NSPropertyDescription+Sync.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSPropertyDescription+Sync.m"; sourceTree = ""; }; 149FF9E91E808C4400617A63 /* 113.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = 113.xcdatamodel; sourceTree = ""; }; 149FF9ED1E808DFB00617A63 /* 375.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = 375.json; sourceTree = ""; }; 14AF6AFA1DFC3D88009E5BC4 /* Result.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Result.swift; sourceTree = ""; }; @@ -852,6 +871,9 @@ 14D93C071E4E65C700DED595 /* SyncPropertyMapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SyncPropertyMapper.m; sourceTree = ""; }; 14D93C091E4E65C700DED595 /* NSString+SyncInflections.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+SyncInflections.h"; sourceTree = ""; }; 14D93C0A1E4E65C700DED595 /* NSString+SyncInflections.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+SyncInflections.m"; sourceTree = ""; }; + 14E652291E809A68000E7CC6 /* hyper_remote_key.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = hyper_remote_key.json; sourceTree = ""; }; + 14E652331E809B75000E7CC6 /* HyperRemoteKey.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = HyperRemoteKey.xcdatamodel; sourceTree = ""; }; + 14E6523C1E809E9C000E7CC6 /* NSPropertyDescription+SyncTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSPropertyDescription+SyncTests.swift"; sourceTree = ""; }; 14E93C431DBCCD2800E3304E /* Sync.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Sync.h; sourceTree = ""; }; 441FA7B71E4F00D300023821 /* User+CoreDataClass.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "User+CoreDataClass.swift"; sourceTree = ""; }; 441FA7B81E4F00D300023821 /* User+CoreDataProperties.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "User+CoreDataProperties.swift"; sourceTree = ""; }; @@ -939,6 +961,7 @@ 1425D59A1CC65BEB00EC49D4 /* Source */ = { isa = PBXGroup; children = ( + 149CC25C1E81DBC4004D1B76 /* NSPropertyDescription-Sync */, 1467388A1E7ADBA700913C8E /* DataStack */, 14D93BFD1E4E65C700DED595 /* DateParser */, 14D93C001E4E65C700DED595 /* NSEntityDescription-SyncPrimaryKey */, @@ -1083,6 +1106,7 @@ 14867DAD1E7AF4D2001D228A /* SyncDelegateTests.swift */, 14867DAE1E7AF4D2001D228A /* SyncTests.swift */, 14867DAF1E7AF4D2001D228A /* UpdateTests.swift */, + 14E6523C1E809E9C000E7CC6 /* NSPropertyDescription+SyncTests.swift */, ); path = Sync; sourceTree = ""; @@ -1140,6 +1164,7 @@ 14867D461E7AF4D2001D228A /* id.json */, 14867D471E7AF4D2001D228A /* images.json */, 14867D481E7AF4D2001D228A /* markets_items.json */, + 14E652291E809A68000E7CC6 /* hyper_remote_key.json */, 14867D491E7AF4D2001D228A /* notes_for_user_a.json */, 14867D4B1E7AF4D2001D228A /* notes_with_user_id_custom.json */, 14867D4A1E7AF4D2001D228A /* notes_with_user_id.json */, @@ -1205,6 +1230,7 @@ 14867DA21E7AF4D2001D228A /* Tests.xcdatamodeld */, 14867DA41E7AF4D2001D228A /* ToOne.xcdatamodeld */, 14867DA61E7AF4D2001D228A /* Unique.xcdatamodeld */, + 14E652321E809B75000E7CC6 /* HyperRemoteKey.xcdatamodeld */, ); path = Models; sourceTree = ""; @@ -1267,6 +1293,15 @@ path = Vendor; sourceTree = ""; }; + 149CC25C1E81DBC4004D1B76 /* NSPropertyDescription-Sync */ = { + isa = PBXGroup; + children = ( + 149CC25D1E81DBF2004D1B76 /* NSPropertyDescription+Sync.h */, + 149CC25E1E81DBF2004D1B76 /* NSPropertyDescription+Sync.m */, + ); + path = "NSPropertyDescription-Sync"; + sourceTree = ""; + }; 14C136501AB7849300B7B07A /* Metadata */ = { isa = PBXGroup; children = ( @@ -1384,6 +1419,7 @@ 14E93C441DBCCD2800E3304E /* Sync.h in Headers */, 14D93C171E4E65C700DED595 /* NSEntityDescription+SyncPrimaryKey.h in Headers */, 14D93C3B1E4E65C700DED595 /* NSString+SyncInflections.h in Headers */, + 149CC25F1E81DBF2004D1B76 /* NSPropertyDescription+Sync.h in Headers */, 14D93C231E4E65C700DED595 /* NSManagedObject+SyncPropertyMapperHelpers.h in Headers */, 14D93C481E4E67A200DED595 /* Sync.swift in Headers */, 14D93C491E4E67A200DED595 /* Sync+DataStack.swift in Headers */, @@ -1407,6 +1443,7 @@ 14F6276D1E7AE6B5001C2EA0 /* NSManagedObject+SyncPropertyMapperHelpers.h in Headers */, 14F6276E1E7AE6B5001C2EA0 /* SyncPropertyMapper.h in Headers */, 14F6276F1E7AE6B5001C2EA0 /* NSString+SyncInflections.h in Headers */, + 149CC2621E81DBF2004D1B76 /* NSPropertyDescription+Sync.h in Headers */, 14F627701E7AE6B5001C2EA0 /* Sync.h in Headers */, 14F627711E7AE6B5001C2EA0 /* Sync.swift in Headers */, 14F627721E7AE6B5001C2EA0 /* Sync+DataStack.swift in Headers */, @@ -1428,6 +1465,7 @@ 14D93C0D1E4E65C700DED595 /* NSDate+SyncPropertyMapper.h in Headers */, 14D93C191E4E65C700DED595 /* NSEntityDescription+SyncPrimaryKey.h in Headers */, 14D93C3D1E4E65C700DED595 /* NSString+SyncInflections.h in Headers */, + 149CC2601E81DBF2004D1B76 /* NSPropertyDescription+Sync.h in Headers */, 14D93C251E4E65C700DED595 /* NSManagedObject+SyncPropertyMapperHelpers.h in Headers */, 14A84E951E4E70B900701B8A /* Sync.swift in Headers */, 14A84E961E4E70B900701B8A /* Sync+DataStack.swift in Headers */, @@ -1451,6 +1489,7 @@ 14F6275E1E7AE6B2001C2EA0 /* NSManagedObject+SyncPropertyMapperHelpers.h in Headers */, 14F6275F1E7AE6B2001C2EA0 /* SyncPropertyMapper.h in Headers */, 14F627601E7AE6B2001C2EA0 /* NSString+SyncInflections.h in Headers */, + 149CC2611E81DBF2004D1B76 /* NSPropertyDescription+Sync.h in Headers */, 14F627611E7AE6B2001C2EA0 /* Sync.h in Headers */, 14F627621E7AE6B2001C2EA0 /* Sync.swift in Headers */, 14F627631E7AE6B2001C2EA0 /* Sync+DataStack.swift in Headers */, @@ -1729,6 +1768,7 @@ 14867E601E7AF4D2001D228A /* bug-179-places.json in Resources */, 14867E691E7AF4D2001D228A /* bug-202-b.json in Resources */, 14867EA81E7AF4D2001D228A /* stories-comments-no-ids.json in Resources */, + 14E6522A1E809A68000E7CC6 /* hyper_remote_key.json in Resources */, 14867EC01E7AF4D2001D228A /* users_c.json in Resources */, 14867E751E7AF4D2001D228A /* bug-number-84.json in Resources */, 14867E421E7AF4D2001D228A /* 277.json in Resources */, @@ -1805,6 +1845,7 @@ 14867E611E7AF4D2001D228A /* bug-179-places.json in Resources */, 14867E6A1E7AF4D2001D228A /* bug-202-b.json in Resources */, 14867EA91E7AF4D2001D228A /* stories-comments-no-ids.json in Resources */, + 14E6522B1E809A68000E7CC6 /* hyper_remote_key.json in Resources */, 14867EC11E7AF4D2001D228A /* users_c.json in Resources */, 14867E761E7AF4D2001D228A /* bug-number-84.json in Resources */, 14867E431E7AF4D2001D228A /* 277.json in Resources */, @@ -1881,6 +1922,7 @@ 14867E621E7AF4D2001D228A /* bug-179-places.json in Resources */, 14867E6B1E7AF4D2001D228A /* bug-202-b.json in Resources */, 14867EAA1E7AF4D2001D228A /* stories-comments-no-ids.json in Resources */, + 14E6522C1E809A68000E7CC6 /* hyper_remote_key.json in Resources */, 14867EC21E7AF4D2001D228A /* users_c.json in Resources */, 14867E771E7AF4D2001D228A /* bug-number-84.json in Resources */, 14867E441E7AF4D2001D228A /* 277.json in Resources */, @@ -1983,6 +2025,7 @@ 14D93C431E4E65C700DED595 /* NSString+SyncInflections.m in Sources */, 14D93C1F1E4E65C700DED595 /* NSEntityDescription+SyncPrimaryKey.m in Sources */, 14D93C371E4E65C700DED595 /* SyncPropertyMapper.m in Sources */, + 149CC2631E81DBF2004D1B76 /* NSPropertyDescription+Sync.m in Sources */, 14D93C131E4E65C700DED595 /* NSDate+SyncPropertyMapper.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -2008,6 +2051,7 @@ 14D93C141E4E65C700DED595 /* NSDate+SyncPropertyMapper.m in Sources */, 14241EAD1DBC3A770042ED81 /* DataFilter.swift in Sources */, 14241EAF1DBC3A770042ED81 /* TestCheck.swift in Sources */, + 149CC2661E81DBF2004D1B76 /* NSPropertyDescription+Sync.m in Sources */, 142CD2A91DEF39AE002FDABE /* Sync+DataStack.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -2033,6 +2077,7 @@ 14D93C151E4E65C700DED595 /* NSDate+SyncPropertyMapper.m in Sources */, 14241EB51DBC3A7F0042ED81 /* DataFilter.swift in Sources */, 14241EB71DBC3A7F0042ED81 /* TestCheck.swift in Sources */, + 149CC2641E81DBF2004D1B76 /* NSPropertyDescription+Sync.m in Sources */, 142CD2AA1DEF39AE002FDABE /* Sync+DataStack.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -2058,6 +2103,7 @@ 14D93C161E4E65C700DED595 /* NSDate+SyncPropertyMapper.m in Sources */, 14241EBD1DBC3A880042ED81 /* DataFilter.swift in Sources */, 14241EBF1DBC3A880042ED81 /* TestCheck.swift in Sources */, + 149CC2651E81DBF2004D1B76 /* NSPropertyDescription+Sync.m in Sources */, 142CD2AB1DEF39AE002FDABE /* Sync+DataStack.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -2078,6 +2124,7 @@ 14867F651E7AF4D2001D228A /* 137.xcdatamodeld in Sources */, 14867F501E7AF4D2001D228A /* DictionaryTests.swift in Sources */, 14867F771E7AF4D2001D228A /* SyncFillWithDictionaryTests.m in Sources */, + 14E6523D1E809E9C000E7CC6 /* NSPropertyDescription+SyncTests.swift in Sources */, 14867F621E7AF4D2001D228A /* 129.xcdatamodeld in Sources */, 14867F321E7AF4D2001D228A /* ToOne.xcdatamodeld in Sources */, 14867F081E7AF4D2001D228A /* Camelcase.xcdatamodeld in Sources */, @@ -2098,6 +2145,7 @@ 14867EFF1E7AF4D2001D228A /* 320.xcdatamodeld in Sources */, 14867F5F1E7AF4D2001D228A /* 123.xcdatamodeld in Sources */, 14867E0F1E7AF4D2001D228A /* InsertOrUpdateTests.swift in Sources */, + 14E652341E809B75000E7CC6 /* HyperRemoteKey.xcdatamodeld in Sources */, 14867E091E7AF4D2001D228A /* FetchTests.swift in Sources */, 14867DD31E7AF4D2001D228A /* DataFilter.xcdatamodeld in Sources */, 14867F021E7AF4D2001D228A /* 3ca82a0.xcdatamodeld in Sources */, @@ -2164,6 +2212,7 @@ 14867F661E7AF4D2001D228A /* 137.xcdatamodeld in Sources */, 14867F511E7AF4D2001D228A /* DictionaryTests.swift in Sources */, 14867F781E7AF4D2001D228A /* SyncFillWithDictionaryTests.m in Sources */, + 14E6523E1E809E9C000E7CC6 /* NSPropertyDescription+SyncTests.swift in Sources */, 14867F631E7AF4D2001D228A /* 129.xcdatamodeld in Sources */, 14867F331E7AF4D2001D228A /* ToOne.xcdatamodeld in Sources */, 14867F091E7AF4D2001D228A /* Camelcase.xcdatamodeld in Sources */, @@ -2184,6 +2233,7 @@ 14867F001E7AF4D2001D228A /* 320.xcdatamodeld in Sources */, 14867F601E7AF4D2001D228A /* 123.xcdatamodeld in Sources */, 14867E101E7AF4D2001D228A /* InsertOrUpdateTests.swift in Sources */, + 14E652351E809B75000E7CC6 /* HyperRemoteKey.xcdatamodeld in Sources */, 14867E0A1E7AF4D2001D228A /* FetchTests.swift in Sources */, 14867DD41E7AF4D2001D228A /* DataFilter.xcdatamodeld in Sources */, 14867F031E7AF4D2001D228A /* 3ca82a0.xcdatamodeld in Sources */, @@ -2250,6 +2300,7 @@ 14867F671E7AF4D2001D228A /* 137.xcdatamodeld in Sources */, 14867F521E7AF4D2001D228A /* DictionaryTests.swift in Sources */, 14867F791E7AF4D2001D228A /* SyncFillWithDictionaryTests.m in Sources */, + 14E6523F1E809E9C000E7CC6 /* NSPropertyDescription+SyncTests.swift in Sources */, 14867F641E7AF4D2001D228A /* 129.xcdatamodeld in Sources */, 14867F341E7AF4D2001D228A /* ToOne.xcdatamodeld in Sources */, 14867F0A1E7AF4D2001D228A /* Camelcase.xcdatamodeld in Sources */, @@ -2270,6 +2321,7 @@ 14867F011E7AF4D2001D228A /* 320.xcdatamodeld in Sources */, 14867F611E7AF4D2001D228A /* 123.xcdatamodeld in Sources */, 14867E111E7AF4D2001D228A /* InsertOrUpdateTests.swift in Sources */, + 14E652361E809B75000E7CC6 /* HyperRemoteKey.xcdatamodeld in Sources */, 14867E0B1E7AF4D2001D228A /* FetchTests.swift in Sources */, 14867DD51E7AF4D2001D228A /* DataFilter.xcdatamodeld in Sources */, 14867F041E7AF4D2001D228A /* 3ca82a0.xcdatamodeld in Sources */, @@ -3420,6 +3472,16 @@ sourceTree = ""; versionGroupType = wrapper.xcdatamodel; }; + 14E652321E809B75000E7CC6 /* HyperRemoteKey.xcdatamodeld */ = { + isa = XCVersionGroup; + children = ( + 14E652331E809B75000E7CC6 /* HyperRemoteKey.xcdatamodel */, + ); + currentVersion = 14E652331E809B75000E7CC6 /* HyperRemoteKey.xcdatamodel */; + path = HyperRemoteKey.xcdatamodeld; + sourceTree = ""; + versionGroupType = wrapper.xcdatamodel; + }; 44B5481C1DCF3E18009215FA /* iOSDemo.xcdatamodeld */ = { isa = XCVersionGroup; children = ( diff --git a/README.md b/README.md index 71b9b7b1..9c927143 100755 --- a/README.md +++ b/README.md @@ -191,7 +191,7 @@ If you add the flag `hyper.isPrimaryKey` to the attribute `contractID` then: - Local primary key will be: `contractID` - Remote primary key will be: `contract_id` -If you want to use `id` for the remote primary key you also have to add the flag `hyper.remoteKey` and write `id` as the value. +If you want to use `id` for the remote primary key you also have to add the flag `sync.remoteKey` and write `id` as the value. - Local primary key will be: `articleBody` - Remote primary key will be: `id` @@ -205,7 +205,7 @@ There are some exception to this rule: * Reserved attributes should be prefixed with the `entityName` (`type` becomes `userType`, `description` becomes `userDescription` and so on). In the JSON they don't need to change, you can keep `type` and `description` for example. A full list of reserved attributes can be found [here](https://github.com/SyncDB/SyncPropertyMapper/blob/master/Sources/NSManagedObject-SyncPropertyMapper/NSManagedObject%2BSyncPropertyMapperHelpers.m#L282-L284) * Attributes with acronyms will be normalized (`id`, `pdf`, `url`, `png`, `jpg`, `uri`, `json`, `xml`). For example `user_id` will be mapped to `userID` and so on. You can find the entire list of supported acronyms [here](https://github.com/SyncDB/SyncPropertyMapper/blob/master/Sources/NSString-SyncInflections/NSString%2BSyncInflections.m#L204-L206). -If you want to map your Core Data attribute with a JSON attribute that has different naming, you can do by adding `hyper.remoteKey` in the user info box with the value you want to map. +If you want to map your Core Data attribute with a JSON attribute that has different naming, you can do by adding `sync.remoteKey` in the user info box with the value you want to map. ![Custom remote key](https://raw.githubusercontent.com/SyncDB/Sync/master/Images/custom-remote-key-v2.png) diff --git a/Source/NSEntityDescription-SyncPrimaryKey/NSEntityDescription+SyncPrimaryKey.h b/Source/NSEntityDescription-SyncPrimaryKey/NSEntityDescription+SyncPrimaryKey.h index 1beaec27..abae9460 100755 --- a/Source/NSEntityDescription-SyncPrimaryKey/NSEntityDescription+SyncPrimaryKey.h +++ b/Source/NSEntityDescription-SyncPrimaryKey/NSEntityDescription+SyncPrimaryKey.h @@ -11,7 +11,8 @@ static NSString * const SyncCustomLocalPrimaryKey = @"hyper.isPrimaryKey"; static NSString * const SyncCustomLocalPrimaryKeyValue = @"YES"; static NSString * const SyncCustomLocalPrimaryKeyAlternativeValue = @"true"; -static NSString * const SyncCustomRemoteKey = @"hyper.remoteKey"; +static NSString * const SyncCustomRemoteKey = @"sync.remoteKey"; +static NSString * const SyncCompatibilityCustomRemoteKey = @"hyper.remoteKey"; @interface NSEntityDescription (SyncPrimaryKey) diff --git a/Source/NSEntityDescription-SyncPrimaryKey/NSEntityDescription+SyncPrimaryKey.m b/Source/NSEntityDescription-SyncPrimaryKey/NSEntityDescription+SyncPrimaryKey.m index 7b965d69..7759253a 100755 --- a/Source/NSEntityDescription-SyncPrimaryKey/NSEntityDescription+SyncPrimaryKey.m +++ b/Source/NSEntityDescription-SyncPrimaryKey/NSEntityDescription+SyncPrimaryKey.m @@ -1,6 +1,7 @@ #import "NSEntityDescription+SyncPrimaryKey.h" #import "NSString+SyncInflections.h" +#import "NSPropertyDescription+Sync.h" @implementation NSEntityDescription (SyncPrimaryKey) @@ -35,7 +36,7 @@ - (nonnull NSString *)sync_localPrimaryKey { - (nonnull NSString *)sync_remotePrimaryKey { NSAttributeDescription *primaryKeyAttribute = [self sync_primaryKeyAttribute]; - NSString *remoteKey = primaryKeyAttribute.userInfo[SyncCustomRemoteKey]; + NSString *remoteKey = primaryKeyAttribute.customKey; if (!remoteKey) { if ([primaryKeyAttribute.name isEqualToString:SyncDefaultLocalPrimaryKey] || [primaryKeyAttribute.name isEqualToString:SyncDefaultLocalCompatiblePrimaryKey]) { diff --git a/Source/NSManagedObject-SyncPropertyMapper/NSManagedObject+SyncPropertyMapperHelpers.h b/Source/NSManagedObject-SyncPropertyMapper/NSManagedObject+SyncPropertyMapperHelpers.h index 6421e31e..34cf60f7 100755 --- a/Source/NSManagedObject-SyncPropertyMapper/NSManagedObject+SyncPropertyMapperHelpers.h +++ b/Source/NSManagedObject-SyncPropertyMapper/NSManagedObject+SyncPropertyMapperHelpers.h @@ -4,7 +4,6 @@ static NSString * const SyncPropertyMapperDestroyKey = @"destroy"; static NSString * const SyncPropertyMapperCustomValueTransformerKey = @"hyper.valueTransformer"; -static NSString * const SyncPropertyMapperCustomRemoteKey = @"hyper.remoteKey"; static NSString * const SyncPropertyMapperNonExportableKey = @"hyper.nonExportable"; /** diff --git a/Source/NSManagedObject-SyncPropertyMapper/NSManagedObject+SyncPropertyMapperHelpers.m b/Source/NSManagedObject-SyncPropertyMapper/NSManagedObject+SyncPropertyMapperHelpers.m index 12a0f949..8d6b83d1 100755 --- a/Source/NSManagedObject-SyncPropertyMapper/NSManagedObject+SyncPropertyMapperHelpers.m +++ b/Source/NSManagedObject-SyncPropertyMapper/NSManagedObject+SyncPropertyMapperHelpers.m @@ -4,6 +4,7 @@ #import "NSString+SyncInflections.h" #import "NSEntityDescription+SyncPrimaryKey.h" #import "NSDate+SyncPropertyMapper.h" +#import "NSPropertyDescription+Sync.h" @implementation NSManagedObject (SyncPropertyMapperHelpers) @@ -43,8 +44,8 @@ - (NSAttributeDescription *)attributeDescriptionForRemoteKey:(NSString *)remoteK if ([propertyDescription isKindOfClass:[NSAttributeDescription class]]) { NSAttributeDescription *attributeDescription = (NSAttributeDescription *)propertyDescription; - NSDictionary *userInfo = [self.entity.propertiesByName[attributeDescription.name] userInfo]; - NSString *customRemoteKey = userInfo[SyncPropertyMapperCustomRemoteKey]; + NSString *customRemoteKey = [self.entity.propertiesByName[attributeDescription.name] customKey]; + BOOL currentAttributeHasTheSameRemoteKey = (customRemoteKey.length > 0 && [customRemoteKey isEqualToString:remoteKey]); if (currentAttributeHasTheSameRemoteKey) { foundAttributeDescription = attributeDescription; @@ -104,8 +105,7 @@ - (NSArray *)attributeDescriptionsForRemoteKeyPath:(NSString *)remoteKey { if ([propertyDescription isKindOfClass:[NSAttributeDescription class]]) { NSAttributeDescription *attributeDescription = (NSAttributeDescription *)propertyDescription; - NSDictionary *userInfo = [self.entity.propertiesByName[attributeDescription.name] userInfo]; - NSString *customRemoteKeyPath = userInfo[SyncPropertyMapperCustomRemoteKey]; + NSString *customRemoteKeyPath = self.entity.propertiesByName[attributeDescription.name].customKey; NSString *customRootRemoteKey = [[customRemoteKeyPath componentsSeparatedByString:@"."] firstObject]; NSString *rootRemoteKey = [[remoteKey componentsSeparatedByString:@"."] firstObject]; BOOL currentAttributeHasTheSameRootRemoteKey = (customRootRemoteKey.length > 0 && [customRootRemoteKey isEqualToString:rootRemoteKey]); @@ -135,11 +135,10 @@ - (NSString *)remoteKeyForAttributeDescription:(NSAttributeDescription *)attribu - (NSString *)remoteKeyForAttributeDescription:(NSAttributeDescription *)attributeDescription usingRelationshipType:(SyncPropertyMapperRelationshipType)relationshipType inflectionType:(SyncPropertyMapperInflectionType)inflectionType { - NSDictionary *userInfo = attributeDescription.userInfo; NSString *localKey = attributeDescription.name; NSString *remoteKey; - NSString *customRemoteKey = userInfo[SyncPropertyMapperCustomRemoteKey]; + NSString *customRemoteKey = attributeDescription.customKey; if (customRemoteKey) { remoteKey = customRemoteKey; } else if ([localKey isEqualToString:SyncDefaultLocalPrimaryKey] || [localKey isEqualToString:SyncDefaultLocalCompatiblePrimaryKey]) { diff --git a/Source/NSPropertyDescription-Sync/NSPropertyDescription+Sync.h b/Source/NSPropertyDescription-Sync/NSPropertyDescription+Sync.h new file mode 100644 index 00000000..ebee378e --- /dev/null +++ b/Source/NSPropertyDescription-Sync/NSPropertyDescription+Sync.h @@ -0,0 +1,7 @@ +@import CoreData; + +@interface NSPropertyDescription (Sync) + +@property (nonatomic, nullable, readonly) NSString *customKey; + +@end diff --git a/Source/NSPropertyDescription-Sync/NSPropertyDescription+Sync.m b/Source/NSPropertyDescription-Sync/NSPropertyDescription+Sync.m new file mode 100644 index 00000000..444ad3ad --- /dev/null +++ b/Source/NSPropertyDescription-Sync/NSPropertyDescription+Sync.m @@ -0,0 +1,16 @@ +#import "NSPropertyDescription+Sync.h" + +#import "NSEntityDescription+SyncPrimaryKey.h" + +@implementation NSPropertyDescription (Sync) + +- (NSString *)customKey { + NSString *keyName = self.userInfo[SyncCustomRemoteKey]; + if (keyName == nil) { + keyName = self.userInfo[SyncCompatibilityCustomRemoteKey]; + } + + return keyName; +} + +@end diff --git a/Source/Sync.h b/Source/Sync.h index ea46df00..c4d864dc 100644 --- a/Source/Sync.h +++ b/Source/Sync.h @@ -8,3 +8,4 @@ FOUNDATION_EXPORT const unsigned char SyncVersionString[]; #import "SyncPropertyMapper.h" #import "NSEntityDescription+SyncPrimaryKey.h" #import "NSManagedObject+SyncPropertyMapperHelpers.h" +#import "NSPropertyDescription+Sync.h" diff --git a/Source/Sync/NSEntityDescription+Sync.swift b/Source/Sync/NSEntityDescription+Sync.swift index 9c2da47f..ea974437 100644 --- a/Source/Sync/NSEntityDescription+Sync.swift +++ b/Source/Sync/NSEntityDescription+Sync.swift @@ -16,6 +16,20 @@ extension NSEntityDescription { return relationships } + /// Finds the attributes for the current entity. + /// + /// - Returns: An array of attributes for the current entity. + func sync_attributes() -> [NSAttributeDescription] { + var attributes = [NSAttributeDescription]() + for propertyDescription in properties { + if let attributeDescription = propertyDescription as? NSAttributeDescription { + attributes.append(attributeDescription) + } + } + + return attributes + } + /** Finds the parent for the current entity, if there are many parents nil will be returned. - returns The parent relationship for the current entity diff --git a/Source/Sync/NSManagedObject+Sync.swift b/Source/Sync/NSManagedObject+Sync.swift index 14121a66..9a956961 100644 --- a/Source/Sync/NSManagedObject+Sync.swift +++ b/Source/Sync/NSManagedObject+Sync.swift @@ -34,7 +34,7 @@ extension NSManagedObject { for relationship in entity.sync_relationships() { let suffix = relationship.isToMany ? "_ids" : "_id" let constructedKeyName = relationship.name.hyp_snakeCase() + suffix - let keyName = relationship.userInfo?[SyncCustomRemoteKey] as? String ?? constructedKeyName + let keyName = relationship.customKey ?? constructedKeyName if relationship.isToMany { if let localPrimaryKey = dictionary[keyName], localPrimaryKey is Array < String> || localPrimaryKey is Array < Int> || localPrimaryKey is NSNull { @@ -169,7 +169,7 @@ extension NSManagedObject { */ func sync_toManyRelationship(_ relationship: NSRelationshipDescription, dictionary: [String: Any], parent: NSManagedObject?, parentRelationship: NSRelationshipDescription?, context: NSManagedObjectContext, operations: Sync.OperationOptions, shouldContinueBlock: (() -> Bool)?, objectJSONBlock: ((_ objectJSON: [String: Any]) -> [String: Any])?) throws { var children: [[String: Any]]? - let childrenIsNull = relationship.userInfo?[SyncCustomRemoteKey] is NSNull || dictionary[relationship.name.hyp_snakeCase()] is NSNull || dictionary[relationship.name] is NSNull + let childrenIsNull = (relationship.customKey as Any?) is NSNull || dictionary[relationship.name.hyp_snakeCase()] is NSNull || dictionary[relationship.name] is NSNull if childrenIsNull { children = [[String: Any]]() @@ -177,7 +177,7 @@ extension NSManagedObject { setValue(nil, forKey: relationship.name) } } else { - if let customRelationshipName = relationship.userInfo?[SyncCustomRemoteKey] as? String { + if let customRelationshipName = relationship.customKey { if customRelationshipName.contains(".") { if let deepMapingRootKey = customRelationshipName.components(separatedBy: ".").first { if let rootObject = dictionary[deepMapingRootKey] as? [String: Any] { @@ -352,7 +352,7 @@ extension NSManagedObject { func sync_toOneRelationship(_ relationship: NSRelationshipDescription, dictionary: [String: Any], context: NSManagedObjectContext, operations: Sync.OperationOptions, shouldContinueBlock: (() -> Bool)?, objectJSONBlock: ((_ objectJSON: [String: Any]) -> [String: Any])?) { var filteredObjectDictionary: [String: Any]? - if let customRelationshipName = relationship.userInfo?[SyncCustomRemoteKey] as? String { + if let customRelationshipName = relationship.customKey { filteredObjectDictionary = dictionary[customRelationshipName] as? [String: Any] } else if let result = dictionary[relationship.name.hyp_snakeCase()] as? [String: Any] { filteredObjectDictionary = result diff --git a/Source/Sync/Sync.swift b/Source/Sync/Sync.swift index c539b82a..eef53295 100644 --- a/Source/Sync/Sync.swift +++ b/Source/Sync/Sync.swift @@ -141,7 +141,7 @@ public protocol SyncDelegate: class { } if remotePrimaryKey.isEmpty { - fatalError("Remote primary key not found for entity: \(entityName), we were looking for id, if your remote ID has a different name consider using hyper.remoteKey to map to the right value") + fatalError("Remote primary key not found for entity: \(entityName), we were looking for id, if your remote ID has a different name consider using sync.remoteKey to map to the right value") } let dataFilterOperations = DataFilter.Operation(rawValue: operations.rawValue) diff --git a/Tests/NSEntityDescription-SyncPrimaryKey/PrimaryKeyTests.m b/Tests/NSEntityDescription-SyncPrimaryKey/PrimaryKeyTests.m index d3be57d9..4e9ae9c1 100755 --- a/Tests/NSEntityDescription-SyncPrimaryKey/PrimaryKeyTests.m +++ b/Tests/NSEntityDescription-SyncPrimaryKey/PrimaryKeyTests.m @@ -56,7 +56,7 @@ - (void)testPrimaryKeyAttribute { XCTAssertEqualObjects(attribute.name, @"alternativeID"); } -- (void)testLocalKey { +- (void)testLocalPrimaryKey { NSEntityDescription *entity = [self entityForName:@"User"]; XCTAssertEqualObjects([entity sync_localPrimaryKey], @"remoteID"); @@ -74,9 +74,12 @@ - (void)testLocalKey { entity = [self entityForName:@"AlternativeID"]; XCTAssertEqualObjects([entity sync_localPrimaryKey], @"alternativeID"); + + entity = [self entityForName:@"Compatibility"]; + XCTAssertEqualObjects([entity sync_localPrimaryKey], @"id"); } -- (void)testRemoteKey { +- (void)testRemotePrimaryKey { NSEntityDescription *entity = [self entityForName:@"User"]; XCTAssertEqualObjects([entity sync_remotePrimaryKey], @"id"); @@ -94,6 +97,9 @@ - (void)testRemoteKey { entity = [self entityForName:@"AlternativeID"]; XCTAssertEqualObjects([entity sync_remotePrimaryKey], @"alternative_id"); + + entity = [self entityForName:@"Compatibility"]; + XCTAssertEqualObjects([entity sync_remotePrimaryKey], @"greeting"); } @end diff --git a/Tests/NSEntityDescription-SyncPrimaryKey/SyncPrimaryKey.xcdatamodeld/SyncPrimaryKey.xcdatamodel/contents b/Tests/NSEntityDescription-SyncPrimaryKey/SyncPrimaryKey.xcdatamodeld/SyncPrimaryKey.xcdatamodel/contents old mode 100755 new mode 100644 index c6c3ccbd..8315d29f --- a/Tests/NSEntityDescription-SyncPrimaryKey/SyncPrimaryKey.xcdatamodeld/SyncPrimaryKey.xcdatamodel/contents +++ b/Tests/NSEntityDescription-SyncPrimaryKey/SyncPrimaryKey.xcdatamodeld/SyncPrimaryKey.xcdatamodel/contents @@ -1,5 +1,5 @@ - + @@ -7,12 +7,19 @@ + + + + + + + - + @@ -27,20 +34,21 @@ - + - + + - + \ No newline at end of file diff --git a/Tests/Sync/JSONs/388.json b/Tests/Sync/JSONs/388.json new file mode 100644 index 00000000..18ad8b7b --- /dev/null +++ b/Tests/Sync/JSONs/388.json @@ -0,0 +1,14 @@ +[ + { + "id": 0, + "name": "Note 0" + }, + { + "id": 1, + "name": "Note 1" + }, + { + "id": 2, + "name": "Note 2" + } +] diff --git a/Tests/Sync/JSONs/hyper_remote_key.json b/Tests/Sync/JSONs/hyper_remote_key.json new file mode 100644 index 00000000..c4498ef6 --- /dev/null +++ b/Tests/Sync/JSONs/hyper_remote_key.json @@ -0,0 +1,7 @@ +[ + { + "id": 1, + "custom_old": "old", + "custom_current": "current" + } +] diff --git a/Tests/Sync/Models/113.xcdatamodeld/113.xcdatamodel/contents b/Tests/Sync/Models/113.xcdatamodeld/113.xcdatamodel/contents index fceec10e..f77489c8 100644 --- a/Tests/Sync/Models/113.xcdatamodeld/113.xcdatamodel/contents +++ b/Tests/Sync/Models/113.xcdatamodeld/113.xcdatamodel/contents @@ -15,7 +15,7 @@ - + diff --git a/Tests/Sync/Models/151-many-to-many.xcdatamodeld/151-many-to-many.xcdatamodel/contents b/Tests/Sync/Models/151-many-to-many.xcdatamodeld/151-many-to-many.xcdatamodel/contents index fee9c750..5a329178 100644 --- a/Tests/Sync/Models/151-many-to-many.xcdatamodeld/151-many-to-many.xcdatamodel/contents +++ b/Tests/Sync/Models/151-many-to-many.xcdatamodeld/151-many-to-many.xcdatamodel/contents @@ -5,7 +5,7 @@ - + @@ -15,7 +15,7 @@ - + diff --git a/Tests/Sync/Models/151-to-many.xcdatamodeld/151-to-many.xcdatamodel/contents b/Tests/Sync/Models/151-to-many.xcdatamodeld/151-to-many.xcdatamodel/contents index 9f79c576..73d9c2aa 100644 --- a/Tests/Sync/Models/151-to-many.xcdatamodeld/151-to-many.xcdatamodel/contents +++ b/Tests/Sync/Models/151-to-many.xcdatamodeld/151-to-many.xcdatamodel/contents @@ -5,7 +5,7 @@ - + @@ -15,7 +15,7 @@ - + diff --git a/Tests/Sync/Models/157.xcdatamodeld/157.xcdatamodel/contents b/Tests/Sync/Models/157.xcdatamodeld/157.xcdatamodel/contents index bcb8e09d..1ea7c154 100644 --- a/Tests/Sync/Models/157.xcdatamodeld/157.xcdatamodel/contents +++ b/Tests/Sync/Models/157.xcdatamodeld/157.xcdatamodel/contents @@ -4,7 +4,7 @@ - + @@ -14,7 +14,7 @@ - + diff --git a/Tests/Sync/Models/179.xcdatamodeld/179.xcdatamodel/contents b/Tests/Sync/Models/179.xcdatamodeld/179.xcdatamodel/contents index efa2f7dd..9aa770a9 100644 --- a/Tests/Sync/Models/179.xcdatamodeld/179.xcdatamodel/contents +++ b/Tests/Sync/Models/179.xcdatamodeld/179.xcdatamodel/contents @@ -17,12 +17,12 @@ - + - + diff --git a/Tests/Sync/Models/257.xcdatamodeld/257.xcdatamodel/contents b/Tests/Sync/Models/257.xcdatamodeld/257.xcdatamodel/contents index dff1b1dc..8689fca1 100644 --- a/Tests/Sync/Models/257.xcdatamodeld/257.xcdatamodel/contents +++ b/Tests/Sync/Models/257.xcdatamodeld/257.xcdatamodel/contents @@ -5,7 +5,7 @@ - + @@ -14,7 +14,7 @@ - + diff --git a/Tests/Sync/Models/280.xcdatamodeld/151-many-to-many.xcdatamodel/contents b/Tests/Sync/Models/280.xcdatamodeld/151-many-to-many.xcdatamodel/contents index 93df3e47..0d3e0660 100644 --- a/Tests/Sync/Models/280.xcdatamodeld/151-many-to-many.xcdatamodel/contents +++ b/Tests/Sync/Models/280.xcdatamodeld/151-many-to-many.xcdatamodel/contents @@ -4,7 +4,7 @@ - + diff --git a/Tests/Sync/Models/375.xcdatamodeld/113.xcdatamodel/contents b/Tests/Sync/Models/375.xcdatamodeld/113.xcdatamodel/contents index c73fb85c..87c89e75 100644 --- a/Tests/Sync/Models/375.xcdatamodeld/113.xcdatamodel/contents +++ b/Tests/Sync/Models/375.xcdatamodeld/113.xcdatamodel/contents @@ -8,7 +8,7 @@ - + diff --git a/Tests/Sync/Models/Camelcase.xcdatamodeld/Demo.xcdatamodel/contents b/Tests/Sync/Models/Camelcase.xcdatamodeld/Demo.xcdatamodel/contents index 4291d66e..586b411a 100644 --- a/Tests/Sync/Models/Camelcase.xcdatamodeld/Demo.xcdatamodel/contents +++ b/Tests/Sync/Models/Camelcase.xcdatamodeld/Demo.xcdatamodel/contents @@ -3,7 +3,7 @@ - + diff --git a/Tests/Sync/Models/Contacts.xcdatamodeld/Demo.xcdatamodel/contents b/Tests/Sync/Models/Contacts.xcdatamodeld/Demo.xcdatamodel/contents index eef25ba8..98c80a9a 100644 --- a/Tests/Sync/Models/Contacts.xcdatamodeld/Demo.xcdatamodel/contents +++ b/Tests/Sync/Models/Contacts.xcdatamodeld/Demo.xcdatamodel/contents @@ -9,7 +9,7 @@ - + diff --git a/Tests/Sync/Models/CustomRelationshipKey.xcdatamodeld/Demo.xcdatamodel/contents b/Tests/Sync/Models/CustomRelationshipKey.xcdatamodeld/Demo.xcdatamodel/contents index 19417a79..c26ac0bc 100644 --- a/Tests/Sync/Models/CustomRelationshipKey.xcdatamodeld/Demo.xcdatamodel/contents +++ b/Tests/Sync/Models/CustomRelationshipKey.xcdatamodeld/Demo.xcdatamodel/contents @@ -8,7 +8,7 @@ - + diff --git a/Tests/Sync/Models/HyperRemoteKey.xcdatamodeld/HyperRemoteKey.xcdatamodel/contents b/Tests/Sync/Models/HyperRemoteKey.xcdatamodeld/HyperRemoteKey.xcdatamodel/contents new file mode 100644 index 00000000..7e81191f --- /dev/null +++ b/Tests/Sync/Models/HyperRemoteKey.xcdatamodeld/HyperRemoteKey.xcdatamodel/contents @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tests/Sync/Models/InsertObjectsInParent.xcdatamodeld/Demo.xcdatamodel/contents b/Tests/Sync/Models/InsertObjectsInParent.xcdatamodeld/Demo.xcdatamodel/contents index 0c7e5e4b..ee919d34 100644 --- a/Tests/Sync/Models/InsertObjectsInParent.xcdatamodeld/Demo.xcdatamodel/contents +++ b/Tests/Sync/Models/InsertObjectsInParent.xcdatamodeld/Demo.xcdatamodel/contents @@ -8,7 +8,7 @@ - + diff --git a/Tests/Sync/Models/Markets.xcdatamodeld/Demo.xcdatamodel/contents b/Tests/Sync/Models/Markets.xcdatamodeld/Demo.xcdatamodel/contents index 038a1ba2..7ba9b4ac 100644 --- a/Tests/Sync/Models/Markets.xcdatamodeld/Demo.xcdatamodel/contents +++ b/Tests/Sync/Models/Markets.xcdatamodeld/Demo.xcdatamodel/contents @@ -5,7 +5,7 @@ - + @@ -15,7 +15,7 @@ - + diff --git a/Tests/Sync/Models/Notes.xcdatamodeld/Demo.xcdatamodel/contents b/Tests/Sync/Models/Notes.xcdatamodeld/Demo.xcdatamodel/contents index 207493dc..c0518b79 100644 --- a/Tests/Sync/Models/Notes.xcdatamodeld/Demo.xcdatamodel/contents +++ b/Tests/Sync/Models/Notes.xcdatamodeld/Demo.xcdatamodel/contents @@ -19,7 +19,7 @@ - + diff --git a/Tests/Sync/Models/NotesB.xcdatamodeld/Demo.xcdatamodel/contents b/Tests/Sync/Models/NotesB.xcdatamodeld/Demo.xcdatamodel/contents index 65903b4a..3fb4b5b4 100644 --- a/Tests/Sync/Models/NotesB.xcdatamodeld/Demo.xcdatamodel/contents +++ b/Tests/Sync/Models/NotesB.xcdatamodeld/Demo.xcdatamodel/contents @@ -5,7 +5,7 @@ - + @@ -17,7 +17,7 @@ - + diff --git a/Tests/Sync/Models/Social.xcdatamodeld/Demo.xcdatamodel/contents b/Tests/Sync/Models/Social.xcdatamodeld/Demo.xcdatamodel/contents index 0c0085a3..8af2f144 100644 --- a/Tests/Sync/Models/Social.xcdatamodeld/Demo.xcdatamodel/contents +++ b/Tests/Sync/Models/Social.xcdatamodeld/Demo.xcdatamodel/contents @@ -15,7 +15,7 @@ - + diff --git a/Tests/Sync/NSPropertyDescription+SyncTests.swift b/Tests/Sync/NSPropertyDescription+SyncTests.swift new file mode 100644 index 00000000..c49bd4a0 --- /dev/null +++ b/Tests/Sync/NSPropertyDescription+SyncTests.swift @@ -0,0 +1,39 @@ +import XCTest +import CoreData +@testable import Sync + +class NSPropertyDescription_SyncTests: XCTestCase { + func testOldCustomKey() { + let dataStack = Helper.dataStackWithModelName("HyperRemoteKey") + + if let entity = NSEntityDescription.entity(forEntityName: "Entity", in: dataStack.mainContext) { + let dayAttribute = entity.sync_attributes().filter { $0.name == "old" }.first + if let dayAttribute = dayAttribute { + XCTAssertEqual(dayAttribute.customKey, "custom_old") + } else { + XCTFail() + } + } else { + XCTFail() + } + + dataStack.drop() + } + + func testCurrentCustomKey() { + let dataStack = Helper.dataStackWithModelName("HyperRemoteKey") + + if let entity = NSEntityDescription.entity(forEntityName: "Entity", in: dataStack.mainContext) { + let dayAttribute = entity.sync_attributes().filter { $0.name == "current" }.first + if let dayAttribute = dayAttribute { + XCTAssertEqual(dayAttribute.customKey, "custom_current") + } else { + XCTFail() + } + } else { + XCTFail() + } + + dataStack.drop() + } +} diff --git a/Tests/Sync/SyncTests.swift b/Tests/Sync/SyncTests.swift index bd207023..3000ab43 100644 --- a/Tests/Sync/SyncTests.swift +++ b/Tests/Sync/SyncTests.swift @@ -1421,4 +1421,19 @@ class SyncTests: XCTestCase { dataStack.drop() } + + // https://github.com/SyncDB/Sync/pull/388 + func testHyperRemoteKeyCompatibility() { + let entititesJSON = Helper.objectsFromJSON("hyper_remote_key.json") as! [[String: Any]] + let dataStack = Helper.dataStackWithModelName("HyperRemoteKey") + dataStack.sync(entititesJSON, inEntityNamed: "Entity", completion: nil) + XCTAssertEqual(Helper.countForEntity("Entity", inContext: dataStack.mainContext), 1) + + let entity = Helper.fetchEntity("Entity", inContext: dataStack.mainContext).first! + XCTAssertEqual(entity.value(forKey: "id") as? Int, 1) + XCTAssertEqual(entity.value(forKey: "old") as? String, "old") + XCTAssertEqual(entity.value(forKey: "current") as? String, "current") + + dataStack.drop() + } } diff --git a/Tests/SyncPropertyMapper/HelperTests.m b/Tests/SyncPropertyMapper/HelperTests.m index 89c5b630..6618edfc 100755 --- a/Tests/SyncPropertyMapper/HelperTests.m +++ b/Tests/SyncPropertyMapper/HelperTests.m @@ -75,6 +75,17 @@ - (void)testAttributeDescriptionForKeyD { XCTAssertEqualObjects(attributeDescription.name, @"camelCaseDepthTwo"); } +- (void)testAttributeDescriptionForKeyCompatibility { + NSManagedObject *keyPath = [self entityNamed:@"Compatibility"]; + NSAttributeDescription *attributeDescription; + + attributeDescription = [keyPath attributeDescriptionForRemoteKey:@"customCurrent"]; + XCTAssertEqualObjects(attributeDescription.name, @"current"); + + attributeDescription = [keyPath attributeDescriptionForRemoteKey:@"customOld"]; + XCTAssertEqualObjects(attributeDescription.name, @"old"); +} + - (void)testRemoteKeyForAttributeDescriptionA { NSManagedObject *company = [self entityNamed:@"Company"]; NSAttributeDescription *attributeDescription; diff --git a/Tests/SyncPropertyMapper/Models/137.xcdatamodeld/hypbug.xcdatamodel/contents b/Tests/SyncPropertyMapper/Models/137.xcdatamodeld/hypbug.xcdatamodel/contents index 2e7a2c99..89cafed6 100755 --- a/Tests/SyncPropertyMapper/Models/137.xcdatamodeld/hypbug.xcdatamodel/contents +++ b/Tests/SyncPropertyMapper/Models/137.xcdatamodeld/hypbug.xcdatamodel/contents @@ -11,7 +11,7 @@ - + diff --git a/Tests/SyncPropertyMapper/Models/140.xcdatamodeld/smartworkout.xcdatamodel/contents b/Tests/SyncPropertyMapper/Models/140.xcdatamodeld/smartworkout.xcdatamodel/contents index 3d8de2dd..da2abe34 100755 --- a/Tests/SyncPropertyMapper/Models/140.xcdatamodeld/smartworkout.xcdatamodel/contents +++ b/Tests/SyncPropertyMapper/Models/140.xcdatamodeld/smartworkout.xcdatamodel/contents @@ -4,14 +4,14 @@ - + - + @@ -21,7 +21,7 @@ - + @@ -32,7 +32,7 @@ - + @@ -45,7 +45,7 @@ - + diff --git a/Tests/SyncPropertyMapper/Models/Model.xcdatamodeld/Model.xcdatamodel/contents b/Tests/SyncPropertyMapper/Models/Model.xcdatamodeld/Model.xcdatamodel/contents index 49e034ca..96f1a2ef 100644 --- a/Tests/SyncPropertyMapper/Models/Model.xcdatamodeld/Model.xcdatamodel/contents +++ b/Tests/SyncPropertyMapper/Models/Model.xcdatamodeld/Model.xcdatamodel/contents @@ -37,25 +37,37 @@ + + + + + + + + + + + + - + - + - + - + @@ -64,7 +76,7 @@ - + @@ -90,7 +102,7 @@ - + @@ -98,7 +110,7 @@ - + @@ -110,7 +122,7 @@ - + @@ -133,5 +145,6 @@ + \ No newline at end of file diff --git a/Tests/SyncPropertyMapper/Models/Ordered.xcdatamodeld/Ordered.xcdatamodel/contents b/Tests/SyncPropertyMapper/Models/Ordered.xcdatamodeld/Ordered.xcdatamodel/contents index 41134017..ceb6aaf2 100644 --- a/Tests/SyncPropertyMapper/Models/Ordered.xcdatamodeld/Ordered.xcdatamodel/contents +++ b/Tests/SyncPropertyMapper/Models/Ordered.xcdatamodeld/Ordered.xcdatamodel/contents @@ -9,7 +9,7 @@ - + @@ -17,7 +17,7 @@ - + @@ -31,7 +31,7 @@ - +