diff --git a/Demo.xcodeproj/project.pbxproj b/Demo.xcodeproj/project.pbxproj index 8f061aa5..2fe29f11 100644 --- a/Demo.xcodeproj/project.pbxproj +++ b/Demo.xcodeproj/project.pbxproj @@ -58,13 +58,14 @@ 141894641BDD62F600EE52CE /* Unique.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 1418943B1BDD62F600EE52CE /* Unique.xcdatamodeld */; }; 141D9E721CE9A4830041A7FC /* 157-locations.json in Resources */ = {isa = PBXBuildFile; fileRef = 141D9E711CE9A4830041A7FC /* 157-locations.json */; }; 141D9E751CE9A4970041A7FC /* Bug157.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 141D9E731CE9A4970041A7FC /* Bug157.xcdatamodeld */; }; - 1425D5A01CC65BEB00EC49D4 /* NSArray+Sync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1425D59B1CC65BEB00EC49D4 /* NSArray+Sync.swift */; }; - 1425D5A11CC65BEB00EC49D4 /* NSEntityDescription+Sync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1425D59C1CC65BEB00EC49D4 /* NSEntityDescription+Sync.swift */; }; - 1425D5A21CC65BEB00EC49D4 /* NSManagedObject+Sync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1425D59D1CC65BEB00EC49D4 /* NSManagedObject+Sync.swift */; }; - 1425D5A31CC65BEB00EC49D4 /* NSManagedObjectContext+Sync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1425D59E1CC65BEB00EC49D4 /* NSManagedObjectContext+Sync.swift */; }; - 1425D5A41CC65BEB00EC49D4 /* Sync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1425D59F1CC65BEB00EC49D4 /* Sync.swift */; }; 143753B31D6BAAAE00577EB1 /* Bug257.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 143753B11D6BAAAE00577EB1 /* Bug257.xcdatamodeld */; }; 143753B51D6BAB4800577EB1 /* bug-257.json in Resources */ = {isa = PBXBuildFile; fileRef = 143753B41D6BAB4800577EB1 /* bug-257.json */; }; + 143ADAB71DAAD01F004B98A2 /* DATAFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 143ADAB01DAAD01F004B98A2 /* DATAFilter.swift */; }; + 143ADAB81DAAD01F004B98A2 /* NSArray+Sync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 143ADAB21DAAD01F004B98A2 /* NSArray+Sync.swift */; }; + 143ADAB91DAAD01F004B98A2 /* NSEntityDescription+Sync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 143ADAB31DAAD01F004B98A2 /* NSEntityDescription+Sync.swift */; }; + 143ADABA1DAAD01F004B98A2 /* NSManagedObject+Sync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 143ADAB41DAAD01F004B98A2 /* NSManagedObject+Sync.swift */; }; + 143ADABB1DAAD01F004B98A2 /* NSManagedObjectContext+Sync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 143ADAB51DAAD01F004B98A2 /* NSManagedObjectContext+Sync.swift */; }; + 143ADABC1DAAD01F004B98A2 /* Sync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 143ADAB61DAAD01F004B98A2 /* Sync.swift */; }; 144D87FD1D6ED2C7000F9B3F /* ToOne.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 144D87FB1D6ED2C7000F9B3F /* ToOne.xcdatamodeld */; }; 144EFF4A1D6CF3DA003EA935 /* Bug254.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 144EFF481D6CF3DA003EA935 /* Bug254.xcdatamodeld */; }; 144EFF4C1D6CF3EC003EA935 /* bug-254.json in Resources */ = {isa = PBXBuildFile; fileRef = 144EFF4B1D6CF3EC003EA935 /* bug-254.json */; }; @@ -76,6 +77,7 @@ 146F2EB51CE1F2C500543F83 /* id.json in Resources */ = {isa = PBXBuildFile; fileRef = 146F2EB41CE1F2C500543F83 /* id.json */; }; 147A3A0F1D704D860049C22A /* 225-a-empty.json in Resources */ = {isa = PBXBuildFile; fileRef = 147A3A0D1D704D860049C22A /* 225-a-empty.json */; }; 147A3A101D704D860049C22A /* 225-a-null.json in Resources */ = {isa = PBXBuildFile; fileRef = 147A3A0E1D704D860049C22A /* 225-a-null.json */; }; + 1487F2F41DAAD0A7008A3041 /* DATAObjectIDs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1487F2F31DAAD0A7008A3041 /* DATAObjectIDs.swift */; }; 1491123C1D70272D00167D26 /* 225-a.json in Resources */ = {isa = PBXBuildFile; fileRef = 149112351D70272D00167D26 /* 225-a.json */; }; 1491123D1D70272D00167D26 /* 225-a-replaced.json in Resources */ = {isa = PBXBuildFile; fileRef = 149112361D70272D00167D26 /* 225-a-replaced.json */; }; 149112451D70279200167D26 /* 225.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 149112431D70279200167D26 /* 225.xcdatamodeld */; }; @@ -90,6 +92,7 @@ 14D4CA801C48176F00CAB8A0 /* NSManagedObject+SyncTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14D4CA7F1C48176F00CAB8A0 /* NSManagedObject+SyncTests.swift */; }; 14D5E3001C4FF3300000CC5F /* NSManagedObjectContext+SyncTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14D5E2FF1C4FF3300000CC5F /* NSManagedObjectContext+SyncTests.swift */; }; 14D5E3021C4FF3750000CC5F /* NSEntityDescription+SyncTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14D5E3011C4FF3750000CC5F /* NSEntityDescription+SyncTests.swift */; }; + 14D604241DAAD330008AF4ED /* TestCheck.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14D604231DAAD330008AF4ED /* TestCheck.swift */; }; 14D7321F1CE9A6C400C28D40 /* 157-cities.json in Resources */ = {isa = PBXBuildFile; fileRef = 14D7321E1CE9A6C400C28D40 /* 157-cities.json */; }; 14D943591C51844C00F90DC2 /* NSArray+SyncTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14D943581C51844C00F90DC2 /* NSArray+SyncTests.swift */; }; 14E298431C563EE500B68B72 /* OrderedSocial.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 14E298411C563EE500B68B72 /* OrderedSocial.xcdatamodeld */; }; @@ -160,13 +163,14 @@ 1418943C1BDD62F600EE52CE /* Unique.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Unique.xcdatamodel; sourceTree = ""; }; 141D9E711CE9A4830041A7FC /* 157-locations.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "157-locations.json"; sourceTree = ""; }; 141D9E741CE9A4970041A7FC /* Demo.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Demo.xcdatamodel; sourceTree = ""; }; - 1425D59B1CC65BEB00EC49D4 /* NSArray+Sync.swift */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = "NSArray+Sync.swift"; sourceTree = ""; tabWidth = 4; }; - 1425D59C1CC65BEB00EC49D4 /* NSEntityDescription+Sync.swift */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = "NSEntityDescription+Sync.swift"; sourceTree = ""; tabWidth = 4; }; - 1425D59D1CC65BEB00EC49D4 /* NSManagedObject+Sync.swift */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObject+Sync.swift"; sourceTree = ""; tabWidth = 4; }; - 1425D59E1CC65BEB00EC49D4 /* NSManagedObjectContext+Sync.swift */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObjectContext+Sync.swift"; sourceTree = ""; tabWidth = 4; }; - 1425D59F1CC65BEB00EC49D4 /* Sync.swift */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = Sync.swift; sourceTree = ""; tabWidth = 4; }; 143753B21D6BAAAE00577EB1 /* Bug179.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Bug179.xcdatamodel; sourceTree = ""; }; 143753B41D6BAB4800577EB1 /* bug-257.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "bug-257.json"; sourceTree = ""; }; + 143ADAB01DAAD01F004B98A2 /* DATAFilter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DATAFilter.swift; sourceTree = ""; }; + 143ADAB21DAAD01F004B98A2 /* NSArray+Sync.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSArray+Sync.swift"; sourceTree = ""; }; + 143ADAB31DAAD01F004B98A2 /* NSEntityDescription+Sync.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSEntityDescription+Sync.swift"; sourceTree = ""; }; + 143ADAB41DAAD01F004B98A2 /* NSManagedObject+Sync.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObject+Sync.swift"; sourceTree = ""; }; + 143ADAB51DAAD01F004B98A2 /* NSManagedObjectContext+Sync.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObjectContext+Sync.swift"; sourceTree = ""; }; + 143ADAB61DAAD01F004B98A2 /* Sync.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Sync.swift; sourceTree = ""; }; 144D87FC1D6ED2C7000F9B3F /* Demo.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Demo.xcdatamodel; sourceTree = ""; }; 144EFF491D6CF3DA003EA935 /* Bug179.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Bug179.xcdatamodel; sourceTree = ""; }; 144EFF4B1D6CF3EC003EA935 /* bug-254.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "bug-254.json"; sourceTree = ""; }; @@ -180,6 +184,7 @@ 146F2EB41CE1F2C500543F83 /* id.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = id.json; sourceTree = ""; }; 147A3A0D1D704D860049C22A /* 225-a-empty.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "225-a-empty.json"; sourceTree = ""; }; 147A3A0E1D704D860049C22A /* 225-a-null.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "225-a-null.json"; sourceTree = ""; }; + 1487F2F31DAAD0A7008A3041 /* DATAObjectIDs.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DATAObjectIDs.swift; sourceTree = ""; }; 149112351D70272D00167D26 /* 225-a.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "225-a.json"; sourceTree = ""; }; 149112361D70272D00167D26 /* 225-a-replaced.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "225-a-replaced.json"; sourceTree = ""; }; 149112441D70279200167D26 /* 151-many-to-many.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "151-many-to-many.xcdatamodel"; sourceTree = ""; }; @@ -199,6 +204,7 @@ 14D4CA7F1C48176F00CAB8A0 /* NSManagedObject+SyncTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObject+SyncTests.swift"; sourceTree = ""; tabWidth = 4; }; 14D5E2FF1C4FF3300000CC5F /* NSManagedObjectContext+SyncTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObjectContext+SyncTests.swift"; sourceTree = ""; tabWidth = 4; }; 14D5E3011C4FF3750000CC5F /* NSEntityDescription+SyncTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = "NSEntityDescription+SyncTests.swift"; sourceTree = ""; tabWidth = 4; }; + 14D604231DAAD330008AF4ED /* TestCheck.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestCheck.swift; sourceTree = ""; }; 14D7321E1CE9A6C400C28D40 /* 157-cities.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "157-cities.json"; sourceTree = ""; }; 14D943581C51844C00F90DC2 /* NSArray+SyncTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = "NSArray+SyncTests.swift"; sourceTree = ""; tabWidth = 4; }; 14E298421C563EE500B68B72 /* Demo.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Demo.xcdatamodel; sourceTree = ""; }; @@ -341,15 +347,34 @@ 1425D59A1CC65BEB00EC49D4 /* Source */ = { isa = PBXGroup; children = ( - 1425D59F1CC65BEB00EC49D4 /* Sync.swift */, - 1425D59D1CC65BEB00EC49D4 /* NSManagedObject+Sync.swift */, - 1425D59C1CC65BEB00EC49D4 /* NSEntityDescription+Sync.swift */, - 1425D59E1CC65BEB00EC49D4 /* NSManagedObjectContext+Sync.swift */, - 1425D59B1CC65BEB00EC49D4 /* NSArray+Sync.swift */, + 14D604221DAAD330008AF4ED /* TestCheck */, + 1487F2F21DAAD0A7008A3041 /* DATAObjectIDs */, + 143ADAAE1DAAD01F004B98A2 /* DATAFilter */, + 143ADAB11DAAD01F004B98A2 /* Sync */, ); path = Source; sourceTree = ""; }; + 143ADAAE1DAAD01F004B98A2 /* DATAFilter */ = { + isa = PBXGroup; + children = ( + 143ADAB01DAAD01F004B98A2 /* DATAFilter.swift */, + ); + path = DATAFilter; + sourceTree = ""; + }; + 143ADAB11DAAD01F004B98A2 /* Sync */ = { + isa = PBXGroup; + children = ( + 143ADAB21DAAD01F004B98A2 /* NSArray+Sync.swift */, + 143ADAB31DAAD01F004B98A2 /* NSEntityDescription+Sync.swift */, + 143ADAB41DAAD01F004B98A2 /* NSManagedObject+Sync.swift */, + 143ADAB51DAAD01F004B98A2 /* NSManagedObjectContext+Sync.swift */, + 143ADAB61DAAD01F004B98A2 /* Sync.swift */, + ); + path = Sync; + sourceTree = ""; + }; 146D728A1AB782920058798C = { isa = PBXGroup; children = ( @@ -396,6 +421,14 @@ name = "Supporting Files"; sourceTree = ""; }; + 1487F2F21DAAD0A7008A3041 /* DATAObjectIDs */ = { + isa = PBXGroup; + children = ( + 1487F2F31DAAD0A7008A3041 /* DATAObjectIDs.swift */, + ); + path = DATAObjectIDs; + sourceTree = ""; + }; 14C136501AB7849300B7B07A /* Metadata */ = { isa = PBXGroup; children = ( @@ -408,6 +441,14 @@ name = Metadata; sourceTree = ""; }; + 14D604221DAAD330008AF4ED /* TestCheck */ = { + isa = PBXGroup; + children = ( + 14D604231DAAD330008AF4ED /* TestCheck.swift */, + ); + path = TestCheck; + sourceTree = ""; + }; 515545DD1958EE5C50CA007A /* Frameworks */ = { isa = PBXGroup; children = ( @@ -604,19 +645,20 @@ files = ( 14D16B3A1D6EE27000F63AB2 /* Bug239.xcdatamodeld in Sources */, 14D4CA801C48176F00CAB8A0 /* NSManagedObject+SyncTests.swift in Sources */, + 143ADAB91DAAD01F004B98A2 /* NSEntityDescription+Sync.swift in Sources */, 140FBF1C1CB91A5D0026484E /* Camelcase.xcdatamodeld in Sources */, - 1425D5A21CC65BEB00EC49D4 /* NSManagedObject+Sync.swift in Sources */, 14D943591C51844C00F90DC2 /* NSArray+SyncTests.swift in Sources */, 146F2EB31CE1F27200543F83 /* id.xcdatamodeld in Sources */, 14FDB4D11C511A5B0061D9FA /* SyncTests.swift in Sources */, 141894611BDD62F600EE52CE /* Patients.xcdatamodeld in Sources */, - 1425D5A41CC65BEB00EC49D4 /* Sync.swift in Sources */, 1418945B1BDD62F600EE52CE /* Bug125.xcdatamodeld in Sources */, 1418945C1BDD62F600EE52CE /* Bug84.xcdatamodeld in Sources */, B0B637141C6E4F2D00229B03 /* Bug179.xcdatamodeld in Sources */, 44FE8EBA1D9989080057BBA8 /* 280.xcdatamodeld in Sources */, 44D7C6661D99D12500F659C0 /* 283.xcdatamodeld in Sources */, 1418945F1BDD62F600EE52CE /* Notes.xcdatamodeld in Sources */, + 143ADABB1DAAD01F004B98A2 /* NSManagedObjectContext+Sync.swift in Sources */, + 14D604241DAAD330008AF4ED /* TestCheck.swift in Sources */, 141894641BDD62F600EE52CE /* Unique.xcdatamodeld in Sources */, 141D9E751CE9A4970041A7FC /* Bug157.xcdatamodeld in Sources */, 141894621BDD62F600EE52CE /* Recursive.xcdatamodeld in Sources */, @@ -624,20 +666,22 @@ 149112451D70279200167D26 /* 225.xcdatamodeld in Sources */, 44D7C6681D99D12500F659C0 /* InsertObjectsInParent.xcdatamodeld in Sources */, 14A644111CD77A4C00F51E23 /* Bug202.xcdatamodeld in Sources */, - 1425D5A31CC65BEB00EC49D4 /* NSManagedObjectContext+Sync.swift in Sources */, 141894591BDD62F600EE52CE /* Bug113.xcdatamodeld in Sources */, 14D5E3021C4FF3750000CC5F /* NSEntityDescription+SyncTests.swift in Sources */, 14D5E3001C4FF3300000CC5F /* NSManagedObjectContext+SyncTests.swift in Sources */, - 1425D5A01CC65BEB00EC49D4 /* NSArray+Sync.swift in Sources */, 144EFF4A1D6CF3DA003EA935 /* Bug254.xcdatamodeld in Sources */, 44D7C6671D99D12500F659C0 /* CustomRelationshipKey.xcdatamodeld in Sources */, 14FDB4D31C511A6F0061D9FA /* Helper.swift in Sources */, 1469B7F91C68D7820080FD71 /* NotesB.xcdatamodeld in Sources */, 141894631BDD62F600EE52CE /* Social.xcdatamodeld in Sources */, - 1425D5A11CC65BEB00EC49D4 /* NSEntityDescription+Sync.swift in Sources */, + 143ADABC1DAAD01F004B98A2 /* Sync.swift in Sources */, + 143ADAB71DAAD01F004B98A2 /* DATAFilter.swift in Sources */, + 143ADABA1DAAD01F004B98A2 /* NSManagedObject+Sync.swift in Sources */, 14096A431CEAF483002690D6 /* 151-ordered-to-many.xcdatamodeld in Sources */, 14096A421CEAF483002690D6 /* 151-ordered-many-to-many.xcdatamodeld in Sources */, + 1487F2F41DAAD0A7008A3041 /* DATAObjectIDs.swift in Sources */, 14096A3C1CEAF40E002690D6 /* 151-many-to-many.xcdatamodeld in Sources */, + 143ADAB81DAAD01F004B98A2 /* NSArray+Sync.swift in Sources */, 143753B31D6BAAAE00577EB1 /* Bug257.xcdatamodeld in Sources */, 144D87FD1D6ED2C7000F9B3F /* ToOne.xcdatamodeld in Sources */, 141894601BDD62F600EE52CE /* Organizations.xcdatamodeld in Sources */, diff --git a/Podfile.lock b/Podfile.lock index 5a56d02c..23126ecd 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,25 +1,11 @@ PODS: - - DATAFilter (0.11.2): - - DATAObjectIDs (~> 0.6.0) - - DATAObjectIDs (0.6.1) - DATASource (5.10.0) - DATAStack (5.4.2) - - DateParser (0.1.1) - JSON (4.0.2) - - NSDictionary-ANDYSafeValue (0.3.1) - - NSEntityDescription-SYNCPrimaryKey (1.2.8): - - NSString-HYPNetworking (~> 1.0.6) - - NSManagedObject-HYPPropertyMapper (4.1.3): - - DateParser (~> 0.1.1) - - NSEntityDescription-SYNCPrimaryKey (~> 1.2.8) - - NSString-HYPNetworking (1.0.6) - - Sync (1.14.4): - - DATAFilter (~> 0.11.2) - - DATAStack (~> 5.4.1) - - NSDictionary-ANDYSafeValue (~> 0.3.1) - - NSManagedObject-HYPPropertyMapper (~> 4.1.1) - - TestCheck (~> 0.3.1) - - TestCheck (0.3.1) + - NSManagedObject-HYPPropertyMapper (4.1.4) + - Sync (1.15.0): + - DATAStack (~> 5.4.2) + - NSManagedObject-HYPPropertyMapper (~> 4.1.4) DEPENDENCIES: - DATASource (~> 5) @@ -31,18 +17,11 @@ EXTERNAL SOURCES: :path: "." SPEC CHECKSUMS: - DATAFilter: 1d339e27caf0a72d895a1ae664e044fff368a520 - DATAObjectIDs: add3013859faf600b073051453bb7f902b479334 DATASource: 444542bc20734886c3fa46f53ec4b1dbee750950 DATAStack: 931ef9a21c6badd0ff5de494a5d49109ba7e8115 - DateParser: 17a256f651c5dd754b83aca6ef5827d796a5f292 JSON: d08f22c3e523be050d5d5f40bca43ec02d95b2cc - NSDictionary-ANDYSafeValue: 2d7adf339b6e302d71fec5f1d71ae00aacda993e - NSEntityDescription-SYNCPrimaryKey: 6e0ca0958f7e05a15e2ed9317e5afeb75af6c782 - NSManagedObject-HYPPropertyMapper: b054e2b9c8be5bb24a7f6f1729395cdb5903171c - NSString-HYPNetworking: 97eb879c5c43663dde06f89e01e8e1551a3f5bb7 - Sync: a41f5628374be4c3f7b7c7f13cdbc7058dc11bcd - TestCheck: 9a9aad0a356703989f4f2b640b6ed95e53e2214f + NSManagedObject-HYPPropertyMapper: 0502d7a0dcb8c0c8112757b80e6318a1baf9c486 + Sync: 82e4eb203dc5366aeb57fda516e1666838bbed3a PODFILE CHECKSUM: 7a3c7e2d1ff850847d49164a7d6f1dedd5261745 diff --git a/Source/DATAFilter/DATAFilter.swift b/Source/DATAFilter/DATAFilter.swift new file mode 100755 index 00000000..cab97363 --- /dev/null +++ b/Source/DATAFilter/DATAFilter.swift @@ -0,0 +1,87 @@ +import Foundation +import CoreData + +public class DATAFilter: NSObject { + public struct Operation : OptionSetType { + public let rawValue: Int + + public init(rawValue: Int) { + self.rawValue = rawValue + } + + public static let Insert = Operation(rawValue: 1 << 0) + public static let Update = Operation(rawValue: 1 << 1) + public static let Delete = Operation(rawValue: 1 << 2) + public static let All: Operation = [.Insert, .Update, .Delete] + } + + public class func changes(changes: [[String : AnyObject]], + inEntityNamed entityName: String, + localPrimaryKey: String, + remotePrimaryKey: String, + context: NSManagedObjectContext, + inserted: (JSON: [String : AnyObject]) -> Void, + updated: (JSON: [String : AnyObject], updatedObject: NSManagedObject) -> Void){ + self.changes(changes, inEntityNamed: entityName, predicate: nil, operations: .All, localPrimaryKey: localPrimaryKey, remotePrimaryKey: remotePrimaryKey, context: context, inserted: inserted, updated: updated) + } + + public class func changes(changes: [[String : AnyObject]], + inEntityNamed entityName: String, + predicate: NSPredicate?, + operations: Operation, + localPrimaryKey: String, + remotePrimaryKey: String, + context: NSManagedObjectContext, + inserted: (JSON: [String : AnyObject]) -> Void, + updated: (JSON: [String : AnyObject], updatedObject: NSManagedObject) -> Void) { + // `DATAObjectIDs.objectIDsInEntityNamed` also deletes all objects that don't have a primary key or that have the same primary key already found in the context + let primaryKeysAndObjectIDs = DATAObjectIDs.objectIDs(inEntityNamed: entityName, withAttributesNamed: localPrimaryKey, context: context, predicate: predicate) as? [NSObject : NSManagedObjectID] ?? [NSObject : NSManagedObjectID]() + let localPrimaryKeys = Array(primaryKeysAndObjectIDs.keys) + let remotePrimaryKeys = changes.map { $0[remotePrimaryKey] } + let remotePrimaryKeysWithoutNils = (remotePrimaryKeys.filter { (($0 as? NSObject) != NSNull()) && ($0 != nil) } as! [NSObject!]) as! [NSObject] + + var remotePrimaryKeysAndChanges = [NSObject : [String : AnyObject]]() + for (primaryKey, change) in zip(remotePrimaryKeysWithoutNils, changes) { + remotePrimaryKeysAndChanges[primaryKey] = change + } + + var intersection = Set(remotePrimaryKeysWithoutNils) + intersection.intersectInPlace(Set(localPrimaryKeys)) + let updatedObjectIDs = Array(intersection) + + + var deletedObjectIDs = localPrimaryKeys + deletedObjectIDs = deletedObjectIDs.filter { value in + !remotePrimaryKeysWithoutNils.contains { $0.isEqual(value) } + } + + var insertedObjectIDs = remotePrimaryKeysWithoutNils + insertedObjectIDs = insertedObjectIDs.filter { value in + !localPrimaryKeys.contains { $0.isEqual(value) } + } + + if operations.contains(.Delete) { + for fetchedID in deletedObjectIDs { + let objectID = primaryKeysAndObjectIDs[fetchedID]! + let object = context.objectWithID(objectID) + context.deleteObject(object) + } + } + + if operations.contains(.Insert) { + for fetchedID in insertedObjectIDs { + let objectDictionary = remotePrimaryKeysAndChanges[fetchedID]! + inserted(JSON: objectDictionary) + } + } + + if operations.contains(.Update) { + for fetchedID in updatedObjectIDs { + let JSON = remotePrimaryKeysAndChanges[fetchedID]! + let objectID = primaryKeysAndObjectIDs[fetchedID]! + let object = context.objectWithID(objectID) + updated(JSON: JSON, updatedObject: object) + } + } + } +} diff --git a/Source/DATAObjectIDs/DATAObjectIDs.swift b/Source/DATAObjectIDs/DATAObjectIDs.swift new file mode 100755 index 00000000..8a3896d3 --- /dev/null +++ b/Source/DATAObjectIDs/DATAObjectIDs.swift @@ -0,0 +1,90 @@ +import CoreData + +public class DATAObjectIDs: NSObject { + public class func objectIDs(inEntityNamed entityName: String, withAttributesNamed attributeName: String, context: NSManagedObjectContext, predicate: NSPredicate?) -> [NSObject: AnyObject] { + return self.generateObjectIDs(inEntityNamed: entityName, withAttributesNamed: attributeName, context: context, predicate: predicate, sortDescriptors: nil) + } + + class func generateObjectIDs(inEntityNamed entityName: String, withAttributesNamed attributeName: String, context: NSManagedObjectContext, predicate: NSPredicate?, sortDescriptors: [NSSortDescriptor]?) -> [NSObject: AnyObject] { + var result = [NSObject: AnyObject]() + + context.performBlockAndWait { + let expression = NSExpressionDescription() + expression.name = "objectID" + expression.expression = NSExpression.expressionForEvaluatedObject() + expression.expressionResultType = .ObjectIDAttributeType + + let request = NSFetchRequest(entityName: entityName) + request.predicate = predicate + request.resultType = .DictionaryResultType + request.propertiesToFetch = [expression, attributeName] + request.sortDescriptors = sortDescriptors + + do { + let objects = try context.executeFetchRequest(request) + for object in objects { + let fetchedID = object[attributeName] as! NSObject + let objectID = object["objectID"] as! NSManagedObjectID + + if let _ = result[fetchedID] { + context.deleteObject(context.objectWithID(objectID)) + } else { + result[fetchedID] = objectID + } + } + } catch let error as NSError { + print("error: \(error)") + } + } + + return result + } + + class func generateObjectIDs(inEntityNamed entityName: String, context: NSManagedObjectContext, predicate: NSPredicate?, sortDescriptors: [NSSortDescriptor]?) -> [Any] { + var objectIDs = [NSManagedObjectID]() + + context.performBlockAndWait { + let request = NSFetchRequest(entityName: entityName) + request.predicate = predicate; + request.resultType = .ManagedObjectIDResultType + + do { + objectIDs = try context.executeFetchRequest(request) as? [NSManagedObjectID] ?? [NSManagedObjectID]() + } catch let error as NSError { + print("error: \(error)") + } + } + + return objectIDs + } + + class func generateAttributes(inEntityNamed entityName: String, attributeName: String, context: NSManagedObjectContext, predicate: NSPredicate?, sortDescriptors: [NSSortDescriptor]?) -> [Any] { + var attributes = [Any]() + + context.performBlockAndWait { + let expression = NSExpressionDescription() + expression.name = "objectID" + expression.expression = NSExpression.expressionForEvaluatedObject() + expression.expressionResultType = .ObjectIDAttributeType + + let request = NSFetchRequest(entityName: entityName) + request.predicate = predicate + request.resultType = .DictionaryResultType + request.propertiesToFetch = [expression, attributeName] + request.sortDescriptors = sortDescriptors + + do { + let objects = try context.executeFetchRequest(request) + for object in objects { + if let fetchedID = object[attributeName] { + attributes.append(fetchedID) + } + } + } catch let error as NSError { + print("error: \(error)") + } + } + + return attributes + } +} diff --git a/Source/NSArray+Sync.swift b/Source/Sync/NSArray+Sync.swift similarity index 90% rename from Source/NSArray+Sync.swift rename to Source/Sync/NSArray+Sync.swift index 937a3f45..4c752dec 100644 --- a/Source/NSArray+Sync.swift +++ b/Source/Sync/NSArray+Sync.swift @@ -1,7 +1,6 @@ import Foundation import DATAStack import NSManagedObject_HYPPropertyMapper -import DATAFilter public extension NSArray { /** @@ -26,9 +25,8 @@ public extension NSArray { guard let filteredArray = (objectChanges as NSArray).filteredArrayUsingPredicate(predicate) as? [NSManagedObject] else { fatalError("Couldn't cast filteredArray as [NSManagedObject]: \(objectChanges), predicate: \(predicate)") } for filteredObject in filteredArray { - if let change = filteredObject.hyp_dictionaryUsingRelationshipType(.Array) as? [String : AnyObject] { - filteredChanges.append(change) - } + let change = filteredObject.hyp_dictionaryUsingRelationshipType(.Array) + filteredChanges.append(change) } } } diff --git a/Source/NSEntityDescription+Sync.swift b/Source/Sync/NSEntityDescription+Sync.swift similarity index 100% rename from Source/NSEntityDescription+Sync.swift rename to Source/Sync/NSEntityDescription+Sync.swift diff --git a/Source/NSManagedObject+Sync.swift b/Source/Sync/NSManagedObject+Sync.swift similarity index 99% rename from Source/NSManagedObject+Sync.swift rename to Source/Sync/NSManagedObject+Sync.swift index 667be685..7857d1e4 100644 --- a/Source/NSManagedObject+Sync.swift +++ b/Source/Sync/NSManagedObject+Sync.swift @@ -1,8 +1,6 @@ import CoreData -import NSEntityDescription_SYNCPrimaryKey import DATAStack -import NSString_HYPNetworking -import DATAFilter +import NSManagedObject_HYPPropertyMapper public extension NSManagedObject { /** diff --git a/Source/NSManagedObjectContext+Sync.swift b/Source/Sync/NSManagedObjectContext+Sync.swift similarity index 95% rename from Source/NSManagedObjectContext+Sync.swift rename to Source/Sync/NSManagedObjectContext+Sync.swift index 80673b76..784ac495 100644 --- a/Source/NSManagedObjectContext+Sync.swift +++ b/Source/Sync/NSManagedObjectContext+Sync.swift @@ -1,6 +1,4 @@ import CoreData -import NSEntityDescription_SYNCPrimaryKey -import NSString_HYPNetworking public extension NSManagedObjectContext { /** diff --git a/Source/Sync.swift b/Source/Sync/Sync.swift similarity index 99% rename from Source/Sync.swift rename to Source/Sync/Sync.swift index 38681497..79b316ce 100644 --- a/Source/Sync.swift +++ b/Source/Sync/Sync.swift @@ -1,9 +1,6 @@ import CoreData -import NSEntityDescription_SYNCPrimaryKey -import DATAFilter import NSManagedObject_HYPPropertyMapper import DATAStack -import TestCheck @objc public class Sync: NSOperation { var downloadFinished = false diff --git a/Source/TestCheck/TestCheck.swift b/Source/TestCheck/TestCheck.swift new file mode 100755 index 00000000..adc48a53 --- /dev/null +++ b/Source/TestCheck/TestCheck.swift @@ -0,0 +1,28 @@ +import Foundation + +@objc public class TestCheck: NSObject { + /** + Method to check wheter your on testing mode or not. + - returns: A Bool, `true` if you're on testing mode, `false` if you're not. + */ + public static let isTesting: Bool = { + let enviroment = NSProcessInfo.processInfo().environment + let serviceName = enviroment["XPC_SERVICE_NAME"] + let injectBundle = enviroment["XCInjectBundle"] + var isRunning = (enviroment["TRAVIS"] != nil || enviroment["XCTestConfigurationFilePath"] != nil) + + if !isRunning { + if let serviceName = serviceName { + isRunning = (serviceName as NSString).pathExtension == "xctest" + } + } + + if !isRunning { + if let injectBundle = injectBundle { + isRunning = (injectBundle as NSString).pathExtension == "xctest" + } + } + + return isRunning + }() +} diff --git a/Sync.podspec b/Sync.podspec index 10f3c634..fd030e7c 100755 --- a/Sync.podspec +++ b/Sync.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "Sync" -s.version = "1.14.4" +s.version = "1.15.0" s.summary = "Modern Swift JSON synchronization to Core Data" s.description = <<-DESC **Sync** eases your everyday job of parsing a `JSON` response and getting it into Core Data. It uses a convention-over-configuration paradigm to facilitate your workflow. @@ -28,9 +28,6 @@ s.source_files = 'Source/**/*' s.frameworks = 'Foundation', 'CoreData' -s.dependency 'DATAFilter', '~> 0.11.2' -s.dependency 'DATAStack', '~> 5.4.1' -s.dependency 'NSDictionary-ANDYSafeValue', '~> 0.3.1' -s.dependency 'NSManagedObject-HYPPropertyMapper', '~> 4.1.1' -s.dependency 'TestCheck', '~> 0.3.1' +s.dependency 'DATAStack', '~> 5.4.2' +s.dependency 'NSManagedObject-HYPPropertyMapper', '~> 4.1.4' end