├── .gitignore ├── .ruby-version ├── .slather.yml ├── .swiftlint.yml ├── .travis.yml ├── CHANGELOG.md ├── DataManager.podspec ├── DataManager.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ ├── DataManager OSX.xcscheme │ ├── DataManager iOS.xcscheme │ ├── DataManager tvOS.xcscheme │ └── DataManager watchOS.xcscheme ├── DataManager.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ ├── DataManager.xcscmblueprint │ └── IDEWorkspaceChecks.plist ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── Package.swift ├── Podfile ├── Podfile.lock ├── README.md ├── Sources ├── DataManager.h ├── DataManager.swift ├── Info-tvOS.plist └── Info.plist ├── Tests ├── DataManagerTests.swift ├── Group+CoreDataProperties.swift ├── Group.swift ├── Info-tvOS.plist ├── Info.plist ├── MethodSwizzling.swift ├── NSManagedObjectContext+TestSwizzle.swift ├── PersistentStoreTypeTests.swift ├── Person+CoreDataProperties.swift ├── Person.swift ├── TestModel.xcdatamodeld │ └── TestModel.xcdatamodel │ │ └── contents └── XCTestCase+MockLogger.swift └── header_logo.png /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # CocoaPods 5 | Pods/ 6 | 7 | # Xcode 8 | build/ 9 | xcuserdata/ 10 | *.xccheckout 11 | *.pbxuser 12 | *.mode1v3 13 | *.mode2v3 14 | *.perspectivev3 15 | !default.pbxuser 16 | !default.mode1v3 17 | !default.mode2v3 18 | !default.perspectivev3 19 | *.xcscmblueprint 20 | 21 | # SPM 22 | .build/ 23 | 24 | # Slather 25 | bin/ 26 | html/ 27 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 2.5.1 2 | -------------------------------------------------------------------------------- /.slather.yml: -------------------------------------------------------------------------------- 1 | coverage_service: coveralls 2 | xcodeproj: DataManager.xcodeproj 3 | scheme: DataManager\ iOS 4 | ignore: 5 | # No ignores for now -------------------------------------------------------------------------------- /.swiftlint.yml: -------------------------------------------------------------------------------- 1 | disabled_rules: # rule identifiers to exclude from running 2 | - todo # This rule is handled by a separate build phase step. 3 | - line_length 4 | - trailing_whitespace 5 | - statement_position 6 | - opening_brace 7 | - file_length # This rule counts white space and comments. Re-enabled when we've fixed it to not do that. 8 | - nesting 9 | - type_name # This rule is now incorrect for Swift 3 lowercase enums. This can be re-enabled after the rule gets updated. 10 | opt_in_rules: # some rules are only opt-in 11 | - empty_count 12 | - force_unwrapping 13 | 14 | excluded: # paths to ignore during linting. Takes precedence over `included`. 15 | - Pods 16 | - Vendor 17 | - build 18 | 19 | # configurable rules can be customized from this configuration file 20 | # binary rules can set their severity level 21 | force_cast: error 22 | force_try: error 23 | force_unwrapping: error 24 | identifier_name: 25 | max_length: 26 | warning: 55 27 | error: 60 28 | min_length: 29 | error: 4 30 | excluded: 31 | - row 32 | - key 33 | - id 34 | - url 35 | - uri 36 | - db 37 | - bar 38 | - red 39 | - lhs 40 | - rhs 41 | - tag 42 | - rs 43 | - URI 44 | - URL 45 | trailing_newline: error 46 | comma: error 47 | colon: error 48 | empty_count: error 49 | legacy_constructor: error 50 | legacy_constant: error 51 | trailing_semicolon: error 52 | 53 | reporter: "xcode" # reporter type (xcode, json, csv, checkstyle) 54 | 55 | custom_rules: 56 | comments_space: 57 | name: "Space After Comment" 58 | regex: '(^ *//\w+)' 59 | message: "There should be a space after //" 60 | severity: error 61 | empty_first_line: 62 | name: "Empty First Line" 63 | regex: '(^[ a-zA-Z ]*(?:protocol|extension|class|struct) (?!(?:var|let))[ a-zA-Z:]*\{\n *\S+)' 64 | message: "There should be an empty line after a declaration" 65 | severity: error 66 | empty_line_after_guard: 67 | name: "Empty Line After Guard" 68 | regex: '(^ *guard[ a-zA-Z0-9=?.\(\),> "logan.gauthier@metova.com" } 12 | 13 | s.ios.deployment_target = "12.0" 14 | s.osx.deployment_target = "10.13" 15 | s.watchos.deployment_target = "10.0" 16 | s.tvos.deployment_target = "17.0" 17 | 18 | s.platform = :ios, '12.0' 19 | s.swift_version = '5.0' 20 | 21 | s.source = { :git => "https://github.com/metova/DataManager.git", :tag => s.version.to_s } 22 | s.source_files = "Sources/*.swift" 23 | 24 | s.framework = "CoreData" 25 | 26 | end 27 | -------------------------------------------------------------------------------- /DataManager.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 11F98474B2A3CC0640D167B7 /* libPods-DataManager-DataManager iOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 830E706018E7B0CA534B3482 /* libPods-DataManager-DataManager iOS.a */; }; 11 | 37DC73F8B905468A44856B38 /* libPods-DataManager-DataManager tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6756E1E6F9EC604FE639A652 /* libPods-DataManager-DataManager tvOS.a */; }; 12 | 6E026F271D8AF95D0027E37E /* Gemfile.lock in Resources */ = {isa = PBXBuildFile; fileRef = 6E026F251D8AF95D0027E37E /* Gemfile.lock */; }; 13 | 6E08D1FF1CCFF2B900426439 /* PersistentStoreTypeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E08D1FE1CCFF2B900426439 /* PersistentStoreTypeTests.swift */; }; 14 | 6E08D2001CCFF2B900426439 /* PersistentStoreTypeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E08D1FE1CCFF2B900426439 /* PersistentStoreTypeTests.swift */; }; 15 | 6E08D2011CCFF2B900426439 /* PersistentStoreTypeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E08D1FE1CCFF2B900426439 /* PersistentStoreTypeTests.swift */; }; 16 | 6E08D2041CCFF75200426439 /* NSManagedObjectContext+TestSwizzle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E08D2031CCFF75200426439 /* NSManagedObjectContext+TestSwizzle.swift */; }; 17 | 6E08D2051CCFF75200426439 /* NSManagedObjectContext+TestSwizzle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E08D2031CCFF75200426439 /* NSManagedObjectContext+TestSwizzle.swift */; }; 18 | 6E08D2061CCFF75200426439 /* NSManagedObjectContext+TestSwizzle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E08D2031CCFF75200426439 /* NSManagedObjectContext+TestSwizzle.swift */; }; 19 | 6E08D2091CCFFDF300426439 /* Group+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E08D2071CCFFDF300426439 /* Group+CoreDataProperties.swift */; }; 20 | 6E08D20A1CCFFDF300426439 /* Group+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E08D2071CCFFDF300426439 /* Group+CoreDataProperties.swift */; }; 21 | 6E08D20B1CCFFDF300426439 /* Group+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E08D2071CCFFDF300426439 /* Group+CoreDataProperties.swift */; }; 22 | 6E08D20C1CCFFDF300426439 /* Group.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E08D2081CCFFDF300426439 /* Group.swift */; }; 23 | 6E08D20D1CCFFDF300426439 /* Group.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E08D2081CCFFDF300426439 /* Group.swift */; }; 24 | 6E08D20E1CCFFDF300426439 /* Group.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E08D2081CCFFDF300426439 /* Group.swift */; }; 25 | 6E478FEC1CAD8D81003F2AE1 /* DataManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E478FEB1CAD8D81003F2AE1 /* DataManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; 26 | 6E478FF31CAD8D81003F2AE1 /* DataManager.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E478FE81CAD8D81003F2AE1 /* DataManager.framework */; }; 27 | 6E478FF81CAD8D81003F2AE1 /* DataManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E478FF71CAD8D81003F2AE1 /* DataManagerTests.swift */; }; 28 | 6E4790031CAD8DBF003F2AE1 /* DataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E4790021CAD8DBF003F2AE1 /* DataManager.swift */; }; 29 | 6E6DD2D61CB844FA00DD3FB5 /* DataManager.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E6DD2CC1CB844FA00DD3FB5 /* DataManager.framework */; }; 30 | 6E6DD2FF1CB846C800DD3FB5 /* DataManager.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E6DD2F51CB846C700DD3FB5 /* DataManager.framework */; }; 31 | 6E6DD30E1CB85E0F00DD3FB5 /* DataManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E478FF71CAD8D81003F2AE1 /* DataManagerTests.swift */; }; 32 | 6E6DD30F1CB85E1100DD3FB5 /* DataManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E478FF71CAD8D81003F2AE1 /* DataManagerTests.swift */; }; 33 | 6EA68ADF1CD7D1EC00D113FA /* MethodSwizzling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EA68ADE1CD7D1EC00D113FA /* MethodSwizzling.swift */; }; 34 | 6EA68AE01CD7D1EC00D113FA /* MethodSwizzling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EA68ADE1CD7D1EC00D113FA /* MethodSwizzling.swift */; }; 35 | 6EA68AE11CD7D1EC00D113FA /* MethodSwizzling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EA68ADE1CD7D1EC00D113FA /* MethodSwizzling.swift */; }; 36 | 6EA68AE31CD7D3DC00D113FA /* XCTestCase+MockLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EA68AE21CD7D3DC00D113FA /* XCTestCase+MockLogger.swift */; }; 37 | 6EA68AE41CD7D3DC00D113FA /* XCTestCase+MockLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EA68AE21CD7D3DC00D113FA /* XCTestCase+MockLogger.swift */; }; 38 | 6EA68AE51CD7D3DC00D113FA /* XCTestCase+MockLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EA68AE21CD7D3DC00D113FA /* XCTestCase+MockLogger.swift */; }; 39 | 6EFD334C1CC931E4009AD145 /* DataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E4790021CAD8DBF003F2AE1 /* DataManager.swift */; }; 40 | 6EFD334D1CC931E5009AD145 /* DataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E4790021CAD8DBF003F2AE1 /* DataManager.swift */; }; 41 | 6EFD334E1CC931E7009AD145 /* DataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E4790021CAD8DBF003F2AE1 /* DataManager.swift */; }; 42 | 6EFD33561CC93622009AD145 /* TestModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 6EFD33501CC935DA009AD145 /* TestModel.xcdatamodeld */; }; 43 | 6EFD33571CC93624009AD145 /* TestModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 6EFD33501CC935DA009AD145 /* TestModel.xcdatamodeld */; }; 44 | 6EFD33581CC93625009AD145 /* TestModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 6EFD33501CC935DA009AD145 /* TestModel.xcdatamodeld */; }; 45 | 6EFD335D1CC93770009AD145 /* Person+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EFD33591CC93770009AD145 /* Person+CoreDataProperties.swift */; }; 46 | 6EFD335E1CC93770009AD145 /* Person+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EFD33591CC93770009AD145 /* Person+CoreDataProperties.swift */; }; 47 | 6EFD335F1CC93770009AD145 /* Person+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EFD33591CC93770009AD145 /* Person+CoreDataProperties.swift */; }; 48 | 6EFD33601CC93770009AD145 /* Person.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EFD335A1CC93770009AD145 /* Person.swift */; }; 49 | 6EFD33611CC93770009AD145 /* Person.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EFD335A1CC93770009AD145 /* Person.swift */; }; 50 | 6EFD33621CC93770009AD145 /* Person.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EFD335A1CC93770009AD145 /* Person.swift */; }; 51 | 7962A89994FE50240FBA2185 /* libPods-DataManager iOS Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4382E68B031086E14FED15B7 /* libPods-DataManager iOS Tests.a */; }; 52 | 8B087BC0130AB4EC2A1ADA32 /* libPods-DataManager-DataManager OSX.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 180F6C1B6FD8196B8069E680 /* libPods-DataManager-DataManager OSX.a */; }; 53 | 94B82F055C59003363E84FCB /* libPods-DataManager-DataManager watchOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3CBA1DA2EBEDB92F58A3FD64 /* libPods-DataManager-DataManager watchOS.a */; }; 54 | A14CC9F989BAC65AE32D2134 /* libPods-DataManager OSX Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CBC4BAB8D049BC8FC2957508 /* libPods-DataManager OSX Tests.a */; }; 55 | D48B2EB7C9720D42D628012C /* libPods-DataManager tvOS Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 67DA8CD8C9D5043ECCCD64AA /* libPods-DataManager tvOS Tests.a */; }; 56 | /* End PBXBuildFile section */ 57 | 58 | /* Begin PBXContainerItemProxy section */ 59 | 6E478FF41CAD8D81003F2AE1 /* PBXContainerItemProxy */ = { 60 | isa = PBXContainerItemProxy; 61 | containerPortal = 6E478FDF1CAD8D81003F2AE1 /* Project object */; 62 | proxyType = 1; 63 | remoteGlobalIDString = 6E478FE71CAD8D81003F2AE1; 64 | remoteInfo = DataManager; 65 | }; 66 | 6E6DD2D71CB844FA00DD3FB5 /* PBXContainerItemProxy */ = { 67 | isa = PBXContainerItemProxy; 68 | containerPortal = 6E478FDF1CAD8D81003F2AE1 /* Project object */; 69 | proxyType = 1; 70 | remoteGlobalIDString = 6E6DD2CB1CB844FA00DD3FB5; 71 | remoteInfo = "DataManager OSX"; 72 | }; 73 | 6E6DD3001CB846C800DD3FB5 /* PBXContainerItemProxy */ = { 74 | isa = PBXContainerItemProxy; 75 | containerPortal = 6E478FDF1CAD8D81003F2AE1 /* Project object */; 76 | proxyType = 1; 77 | remoteGlobalIDString = 6E6DD2F41CB846C700DD3FB5; 78 | remoteInfo = "DataManager tvOS"; 79 | }; 80 | /* End PBXContainerItemProxy section */ 81 | 82 | /* Begin PBXFileReference section */ 83 | 180F6C1B6FD8196B8069E680 /* libPods-DataManager-DataManager OSX.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-DataManager-DataManager OSX.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 84 | 1A8B7BC1DE13F3E24B80ABF5 /* Pods-DataManager-DataManager tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DataManager-DataManager tvOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-DataManager-DataManager tvOS/Pods-DataManager-DataManager tvOS.debug.xcconfig"; sourceTree = ""; }; 85 | 2AA9186FF28DC8960F0DFA90 /* Pods-DataManager tvOS Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DataManager tvOS Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-DataManager tvOS Tests/Pods-DataManager tvOS Tests.release.xcconfig"; sourceTree = ""; }; 86 | 3C1E6F8A601AABCD650F2B34 /* Pods-DataManager-DataManager iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DataManager-DataManager iOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-DataManager-DataManager iOS/Pods-DataManager-DataManager iOS.debug.xcconfig"; sourceTree = ""; }; 87 | 3CBA1DA2EBEDB92F58A3FD64 /* libPods-DataManager-DataManager watchOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-DataManager-DataManager watchOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 88 | 4382E68B031086E14FED15B7 /* libPods-DataManager iOS Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-DataManager iOS Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 89 | 6756E1E6F9EC604FE639A652 /* libPods-DataManager-DataManager tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-DataManager-DataManager tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 90 | 67DA8CD8C9D5043ECCCD64AA /* libPods-DataManager tvOS Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-DataManager tvOS Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 91 | 6E026F241D8AF95D0027E37E /* Gemfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; fileEncoding = 4; indentWidth = 2; path = Gemfile; sourceTree = ""; tabWidth = 2; }; 92 | 6E026F251D8AF95D0027E37E /* Gemfile.lock */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Gemfile.lock; sourceTree = ""; }; 93 | 6E08D1FC1CCEC86600426439 /* .travis.yml */ = {isa = PBXFileReference; lastKnownFileType = text; path = .travis.yml; sourceTree = ""; }; 94 | 6E08D1FE1CCFF2B900426439 /* PersistentStoreTypeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PersistentStoreTypeTests.swift; sourceTree = ""; }; 95 | 6E08D2031CCFF75200426439 /* NSManagedObjectContext+TestSwizzle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObjectContext+TestSwizzle.swift"; sourceTree = ""; }; 96 | 6E08D2071CCFFDF300426439 /* Group+CoreDataProperties.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Group+CoreDataProperties.swift"; sourceTree = ""; }; 97 | 6E08D2081CCFFDF300426439 /* Group.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Group.swift; sourceTree = ""; }; 98 | 6E40A6CA1F9A443B0023FC14 /* .ruby-version */ = {isa = PBXFileReference; lastKnownFileType = text; path = ".ruby-version"; sourceTree = ""; }; 99 | 6E478FE81CAD8D81003F2AE1 /* DataManager.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DataManager.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 100 | 6E478FEB1CAD8D81003F2AE1 /* DataManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DataManager.h; sourceTree = ""; }; 101 | 6E478FED1CAD8D81003F2AE1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 102 | 6E478FF21CAD8D81003F2AE1 /* DataManager iOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "DataManager iOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 103 | 6E478FF71CAD8D81003F2AE1 /* DataManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataManagerTests.swift; sourceTree = ""; }; 104 | 6E478FF91CAD8D81003F2AE1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 105 | 6E4790021CAD8DBF003F2AE1 /* DataManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataManager.swift; sourceTree = ""; }; 106 | 6E4C18A31CDBA6D900FA65EC /* header_logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = header_logo.png; sourceTree = ""; }; 107 | 6E6DD2CC1CB844FA00DD3FB5 /* DataManager.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DataManager.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 108 | 6E6DD2D51CB844FA00DD3FB5 /* DataManager OSX Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "DataManager OSX Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 109 | 6E6DD2E81CB845E900DD3FB5 /* DataManager.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DataManager.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 110 | 6E6DD2F51CB846C700DD3FB5 /* DataManager.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DataManager.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 111 | 6E6DD2F91CB846C700DD3FB5 /* Info-tvOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-tvOS.plist"; sourceTree = ""; }; 112 | 6E6DD2FE1CB846C800DD3FB5 /* DataManager tvOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "DataManager tvOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 113 | 6E6DD3051CB846C800DD3FB5 /* Info-tvOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-tvOS.plist"; sourceTree = ""; }; 114 | 6EA68ADE1CD7D1EC00D113FA /* MethodSwizzling.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MethodSwizzling.swift; sourceTree = ""; }; 115 | 6EA68AE21CD7D3DC00D113FA /* XCTestCase+MockLogger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "XCTestCase+MockLogger.swift"; sourceTree = ""; }; 116 | 6EE428854890BAA30504A4E2 /* Pods-DataManager-DataManager OSX.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DataManager-DataManager OSX.debug.xcconfig"; path = "Pods/Target Support Files/Pods-DataManager-DataManager OSX/Pods-DataManager-DataManager OSX.debug.xcconfig"; sourceTree = ""; }; 117 | 6EF99F432081303000077E1B /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; indentWidth = 2; path = Podfile; sourceTree = ""; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 118 | 6EF99F442081303A00077E1B /* Podfile.lock */ = {isa = PBXFileReference; lastKnownFileType = text; path = Podfile.lock; sourceTree = ""; }; 119 | 6EFD33511CC935DA009AD145 /* TestModel.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = TestModel.xcdatamodel; sourceTree = ""; }; 120 | 6EFD33591CC93770009AD145 /* Person+CoreDataProperties.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Person+CoreDataProperties.swift"; sourceTree = ""; }; 121 | 6EFD335A1CC93770009AD145 /* Person.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Person.swift; sourceTree = ""; }; 122 | 6EFD336B1CCE6E27009AD145 /* CHANGELOG.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CHANGELOG.md; sourceTree = ""; }; 123 | 6EFD336C1CCE6E27009AD145 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 124 | 6EFD336D1CCE6E27009AD145 /* DataManager.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = DataManager.podspec; sourceTree = ""; }; 125 | 6EFD336E1CCE6E27009AD145 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; 126 | 6EFD336F1CCE6E27009AD145 /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; }; 127 | 6EFD33711CCE6E34009AD145 /* .swiftlint.yml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = .swiftlint.yml; sourceTree = ""; }; 128 | 6EFD33751CCE6E4D009AD145 /* .gitignore */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitignore; sourceTree = ""; }; 129 | 792C09A15000FA08C98B8822 /* Pods-DataManager-DataManager watchOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DataManager-DataManager watchOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-DataManager-DataManager watchOS/Pods-DataManager-DataManager watchOS.release.xcconfig"; sourceTree = ""; }; 130 | 7F2FA690E5B0FFA6C7A32E27 /* Pods-DataManager iOS Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DataManager iOS Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-DataManager iOS Tests/Pods-DataManager iOS Tests.debug.xcconfig"; sourceTree = ""; }; 131 | 830E706018E7B0CA534B3482 /* libPods-DataManager-DataManager iOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-DataManager-DataManager iOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 132 | 9566E6DE55150E411C02F511 /* Pods-DataManager iOS Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DataManager iOS Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-DataManager iOS Tests/Pods-DataManager iOS Tests.release.xcconfig"; sourceTree = ""; }; 133 | A070671BFDC1D25EB9BC3E82 /* Pods-DataManager OSX Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DataManager OSX Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-DataManager OSX Tests/Pods-DataManager OSX Tests.debug.xcconfig"; sourceTree = ""; }; 134 | A3A35B0F67E7F41321164F40 /* Pods-DataManager-DataManager tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DataManager-DataManager tvOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-DataManager-DataManager tvOS/Pods-DataManager-DataManager tvOS.release.xcconfig"; sourceTree = ""; }; 135 | BAA610AC8A20A7B640D2982E /* Pods-DataManager OSX Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DataManager OSX Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-DataManager OSX Tests/Pods-DataManager OSX Tests.release.xcconfig"; sourceTree = ""; }; 136 | C61ACF25ED8BFA8A66F2243E /* Pods-DataManager-DataManager iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DataManager-DataManager iOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-DataManager-DataManager iOS/Pods-DataManager-DataManager iOS.release.xcconfig"; sourceTree = ""; }; 137 | C70D82758C706960F88D2FC9 /* Pods-DataManager-DataManager watchOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DataManager-DataManager watchOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-DataManager-DataManager watchOS/Pods-DataManager-DataManager watchOS.debug.xcconfig"; sourceTree = ""; }; 138 | CBC4BAB8D049BC8FC2957508 /* libPods-DataManager OSX Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-DataManager OSX Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 139 | CDD25EB366977CFCC9D5D917 /* Pods-DataManager tvOS Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DataManager tvOS Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-DataManager tvOS Tests/Pods-DataManager tvOS Tests.debug.xcconfig"; sourceTree = ""; }; 140 | F43DA1B74A5DAEB807D358F3 /* Pods-DataManager-DataManager OSX.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DataManager-DataManager OSX.release.xcconfig"; path = "Pods/Target Support Files/Pods-DataManager-DataManager OSX/Pods-DataManager-DataManager OSX.release.xcconfig"; sourceTree = ""; }; 141 | /* End PBXFileReference section */ 142 | 143 | /* Begin PBXFrameworksBuildPhase section */ 144 | 6E478FE41CAD8D81003F2AE1 /* Frameworks */ = { 145 | isa = PBXFrameworksBuildPhase; 146 | buildActionMask = 2147483647; 147 | files = ( 148 | 11F98474B2A3CC0640D167B7 /* libPods-DataManager-DataManager iOS.a in Frameworks */, 149 | ); 150 | runOnlyForDeploymentPostprocessing = 0; 151 | }; 152 | 6E478FEF1CAD8D81003F2AE1 /* Frameworks */ = { 153 | isa = PBXFrameworksBuildPhase; 154 | buildActionMask = 2147483647; 155 | files = ( 156 | 6E478FF31CAD8D81003F2AE1 /* DataManager.framework in Frameworks */, 157 | 7962A89994FE50240FBA2185 /* libPods-DataManager iOS Tests.a in Frameworks */, 158 | ); 159 | runOnlyForDeploymentPostprocessing = 0; 160 | }; 161 | 6E6DD2C81CB844FA00DD3FB5 /* Frameworks */ = { 162 | isa = PBXFrameworksBuildPhase; 163 | buildActionMask = 2147483647; 164 | files = ( 165 | 8B087BC0130AB4EC2A1ADA32 /* libPods-DataManager-DataManager OSX.a in Frameworks */, 166 | ); 167 | runOnlyForDeploymentPostprocessing = 0; 168 | }; 169 | 6E6DD2D21CB844FA00DD3FB5 /* Frameworks */ = { 170 | isa = PBXFrameworksBuildPhase; 171 | buildActionMask = 2147483647; 172 | files = ( 173 | 6E6DD2D61CB844FA00DD3FB5 /* DataManager.framework in Frameworks */, 174 | A14CC9F989BAC65AE32D2134 /* libPods-DataManager OSX Tests.a in Frameworks */, 175 | ); 176 | runOnlyForDeploymentPostprocessing = 0; 177 | }; 178 | 6E6DD2E41CB845E900DD3FB5 /* Frameworks */ = { 179 | isa = PBXFrameworksBuildPhase; 180 | buildActionMask = 2147483647; 181 | files = ( 182 | 94B82F055C59003363E84FCB /* libPods-DataManager-DataManager watchOS.a in Frameworks */, 183 | ); 184 | runOnlyForDeploymentPostprocessing = 0; 185 | }; 186 | 6E6DD2F11CB846C700DD3FB5 /* Frameworks */ = { 187 | isa = PBXFrameworksBuildPhase; 188 | buildActionMask = 2147483647; 189 | files = ( 190 | 37DC73F8B905468A44856B38 /* libPods-DataManager-DataManager tvOS.a in Frameworks */, 191 | ); 192 | runOnlyForDeploymentPostprocessing = 0; 193 | }; 194 | 6E6DD2FB1CB846C800DD3FB5 /* Frameworks */ = { 195 | isa = PBXFrameworksBuildPhase; 196 | buildActionMask = 2147483647; 197 | files = ( 198 | 6E6DD2FF1CB846C800DD3FB5 /* DataManager.framework in Frameworks */, 199 | D48B2EB7C9720D42D628012C /* libPods-DataManager tvOS Tests.a in Frameworks */, 200 | ); 201 | runOnlyForDeploymentPostprocessing = 0; 202 | }; 203 | /* End PBXFrameworksBuildPhase section */ 204 | 205 | /* Begin PBXGroup section */ 206 | 6E08D2021CCFF70B00426439 /* Utility */ = { 207 | isa = PBXGroup; 208 | children = ( 209 | 6E08D2031CCFF75200426439 /* NSManagedObjectContext+TestSwizzle.swift */, 210 | 6EA68ADE1CD7D1EC00D113FA /* MethodSwizzling.swift */, 211 | 6EA68AE21CD7D3DC00D113FA /* XCTestCase+MockLogger.swift */, 212 | ); 213 | name = Utility; 214 | sourceTree = ""; 215 | }; 216 | 6E478FDE1CAD8D81003F2AE1 = { 217 | isa = PBXGroup; 218 | children = ( 219 | 6E478FEA1CAD8D81003F2AE1 /* Sources */, 220 | 6E478FF61CAD8D81003F2AE1 /* Tests */, 221 | 6EFD33701CCE6E27009AD145 /* Related Files */, 222 | 6E478FE91CAD8D81003F2AE1 /* Products */, 223 | 9CE1D5AF51F297287AC13C78 /* Pods */, 224 | FEDE350F5B8391546793E9E7 /* Frameworks */, 225 | ); 226 | sourceTree = ""; 227 | }; 228 | 6E478FE91CAD8D81003F2AE1 /* Products */ = { 229 | isa = PBXGroup; 230 | children = ( 231 | 6E478FE81CAD8D81003F2AE1 /* DataManager.framework */, 232 | 6E478FF21CAD8D81003F2AE1 /* DataManager iOS Tests.xctest */, 233 | 6E6DD2CC1CB844FA00DD3FB5 /* DataManager.framework */, 234 | 6E6DD2D51CB844FA00DD3FB5 /* DataManager OSX Tests.xctest */, 235 | 6E6DD2E81CB845E900DD3FB5 /* DataManager.framework */, 236 | 6E6DD2F51CB846C700DD3FB5 /* DataManager.framework */, 237 | 6E6DD2FE1CB846C800DD3FB5 /* DataManager tvOS Tests.xctest */, 238 | ); 239 | name = Products; 240 | sourceTree = ""; 241 | }; 242 | 6E478FEA1CAD8D81003F2AE1 /* Sources */ = { 243 | isa = PBXGroup; 244 | children = ( 245 | 6E6DD2C41CB842CA00DD3FB5 /* Core */, 246 | 6E6DD2C51CB842D000DD3FB5 /* Supporting Files */, 247 | ); 248 | path = Sources; 249 | sourceTree = ""; 250 | }; 251 | 6E478FF61CAD8D81003F2AE1 /* Tests */ = { 252 | isa = PBXGroup; 253 | children = ( 254 | 6E08D2021CCFF70B00426439 /* Utility */, 255 | 6E6DD30D1CB85CDF00DD3FB5 /* Test Data Model */, 256 | 6E6DD30C1CB85AF400DD3FB5 /* Supporting Files */, 257 | 6E478FF71CAD8D81003F2AE1 /* DataManagerTests.swift */, 258 | 6E08D1FE1CCFF2B900426439 /* PersistentStoreTypeTests.swift */, 259 | ); 260 | path = Tests; 261 | sourceTree = ""; 262 | }; 263 | 6E6DD2C41CB842CA00DD3FB5 /* Core */ = { 264 | isa = PBXGroup; 265 | children = ( 266 | 6E4790021CAD8DBF003F2AE1 /* DataManager.swift */, 267 | ); 268 | name = Core; 269 | sourceTree = ""; 270 | }; 271 | 6E6DD2C51CB842D000DD3FB5 /* Supporting Files */ = { 272 | isa = PBXGroup; 273 | children = ( 274 | 6E478FEB1CAD8D81003F2AE1 /* DataManager.h */, 275 | 6E6DD2F91CB846C700DD3FB5 /* Info-tvOS.plist */, 276 | 6E478FED1CAD8D81003F2AE1 /* Info.plist */, 277 | ); 278 | name = "Supporting Files"; 279 | sourceTree = ""; 280 | }; 281 | 6E6DD30C1CB85AF400DD3FB5 /* Supporting Files */ = { 282 | isa = PBXGroup; 283 | children = ( 284 | 6E6DD3051CB846C800DD3FB5 /* Info-tvOS.plist */, 285 | 6E478FF91CAD8D81003F2AE1 /* Info.plist */, 286 | ); 287 | name = "Supporting Files"; 288 | sourceTree = ""; 289 | }; 290 | 6E6DD30D1CB85CDF00DD3FB5 /* Test Data Model */ = { 291 | isa = PBXGroup; 292 | children = ( 293 | 6E08D2071CCFFDF300426439 /* Group+CoreDataProperties.swift */, 294 | 6E08D2081CCFFDF300426439 /* Group.swift */, 295 | 6EFD33591CC93770009AD145 /* Person+CoreDataProperties.swift */, 296 | 6EFD335A1CC93770009AD145 /* Person.swift */, 297 | 6EFD33501CC935DA009AD145 /* TestModel.xcdatamodeld */, 298 | ); 299 | name = "Test Data Model"; 300 | sourceTree = ""; 301 | }; 302 | 6EFD33701CCE6E27009AD145 /* Related Files */ = { 303 | isa = PBXGroup; 304 | children = ( 305 | 6EF99F432081303000077E1B /* Podfile */, 306 | 6EF99F442081303A00077E1B /* Podfile.lock */, 307 | 6E026F241D8AF95D0027E37E /* Gemfile */, 308 | 6E026F251D8AF95D0027E37E /* Gemfile.lock */, 309 | 6EFD33751CCE6E4D009AD145 /* .gitignore */, 310 | 6EFD33711CCE6E34009AD145 /* .swiftlint.yml */, 311 | 6EFD336B1CCE6E27009AD145 /* CHANGELOG.md */, 312 | 6EFD336C1CCE6E27009AD145 /* README.md */, 313 | 6EFD336D1CCE6E27009AD145 /* DataManager.podspec */, 314 | 6EFD336E1CCE6E27009AD145 /* LICENSE */, 315 | 6E4C18A31CDBA6D900FA65EC /* header_logo.png */, 316 | 6EFD336F1CCE6E27009AD145 /* Package.swift */, 317 | 6E08D1FC1CCEC86600426439 /* .travis.yml */, 318 | 6E40A6CA1F9A443B0023FC14 /* .ruby-version */, 319 | ); 320 | name = "Related Files"; 321 | sourceTree = ""; 322 | }; 323 | 9CE1D5AF51F297287AC13C78 /* Pods */ = { 324 | isa = PBXGroup; 325 | children = ( 326 | A070671BFDC1D25EB9BC3E82 /* Pods-DataManager OSX Tests.debug.xcconfig */, 327 | BAA610AC8A20A7B640D2982E /* Pods-DataManager OSX Tests.release.xcconfig */, 328 | 7F2FA690E5B0FFA6C7A32E27 /* Pods-DataManager iOS Tests.debug.xcconfig */, 329 | 9566E6DE55150E411C02F511 /* Pods-DataManager iOS Tests.release.xcconfig */, 330 | CDD25EB366977CFCC9D5D917 /* Pods-DataManager tvOS Tests.debug.xcconfig */, 331 | 2AA9186FF28DC8960F0DFA90 /* Pods-DataManager tvOS Tests.release.xcconfig */, 332 | 6EE428854890BAA30504A4E2 /* Pods-DataManager-DataManager OSX.debug.xcconfig */, 333 | F43DA1B74A5DAEB807D358F3 /* Pods-DataManager-DataManager OSX.release.xcconfig */, 334 | 3C1E6F8A601AABCD650F2B34 /* Pods-DataManager-DataManager iOS.debug.xcconfig */, 335 | C61ACF25ED8BFA8A66F2243E /* Pods-DataManager-DataManager iOS.release.xcconfig */, 336 | 1A8B7BC1DE13F3E24B80ABF5 /* Pods-DataManager-DataManager tvOS.debug.xcconfig */, 337 | A3A35B0F67E7F41321164F40 /* Pods-DataManager-DataManager tvOS.release.xcconfig */, 338 | C70D82758C706960F88D2FC9 /* Pods-DataManager-DataManager watchOS.debug.xcconfig */, 339 | 792C09A15000FA08C98B8822 /* Pods-DataManager-DataManager watchOS.release.xcconfig */, 340 | ); 341 | name = Pods; 342 | sourceTree = ""; 343 | }; 344 | FEDE350F5B8391546793E9E7 /* Frameworks */ = { 345 | isa = PBXGroup; 346 | children = ( 347 | CBC4BAB8D049BC8FC2957508 /* libPods-DataManager OSX Tests.a */, 348 | 4382E68B031086E14FED15B7 /* libPods-DataManager iOS Tests.a */, 349 | 67DA8CD8C9D5043ECCCD64AA /* libPods-DataManager tvOS Tests.a */, 350 | 180F6C1B6FD8196B8069E680 /* libPods-DataManager-DataManager OSX.a */, 351 | 830E706018E7B0CA534B3482 /* libPods-DataManager-DataManager iOS.a */, 352 | 6756E1E6F9EC604FE639A652 /* libPods-DataManager-DataManager tvOS.a */, 353 | 3CBA1DA2EBEDB92F58A3FD64 /* libPods-DataManager-DataManager watchOS.a */, 354 | ); 355 | name = Frameworks; 356 | sourceTree = ""; 357 | }; 358 | /* End PBXGroup section */ 359 | 360 | /* Begin PBXHeadersBuildPhase section */ 361 | 6E478FE51CAD8D81003F2AE1 /* Headers */ = { 362 | isa = PBXHeadersBuildPhase; 363 | buildActionMask = 2147483647; 364 | files = ( 365 | 6E478FEC1CAD8D81003F2AE1 /* DataManager.h in Headers */, 366 | ); 367 | runOnlyForDeploymentPostprocessing = 0; 368 | }; 369 | 6E6DD2C91CB844FA00DD3FB5 /* Headers */ = { 370 | isa = PBXHeadersBuildPhase; 371 | buildActionMask = 2147483647; 372 | files = ( 373 | ); 374 | runOnlyForDeploymentPostprocessing = 0; 375 | }; 376 | 6E6DD2E51CB845E900DD3FB5 /* Headers */ = { 377 | isa = PBXHeadersBuildPhase; 378 | buildActionMask = 2147483647; 379 | files = ( 380 | ); 381 | runOnlyForDeploymentPostprocessing = 0; 382 | }; 383 | 6E6DD2F21CB846C700DD3FB5 /* Headers */ = { 384 | isa = PBXHeadersBuildPhase; 385 | buildActionMask = 2147483647; 386 | files = ( 387 | ); 388 | runOnlyForDeploymentPostprocessing = 0; 389 | }; 390 | /* End PBXHeadersBuildPhase section */ 391 | 392 | /* Begin PBXNativeTarget section */ 393 | 6E478FE71CAD8D81003F2AE1 /* DataManager iOS */ = { 394 | isa = PBXNativeTarget; 395 | buildConfigurationList = 6E478FFC1CAD8D81003F2AE1 /* Build configuration list for PBXNativeTarget "DataManager iOS" */; 396 | buildPhases = ( 397 | CF37EC56ACE9BD3C31E80914 /* [CP] Check Pods Manifest.lock */, 398 | 6EFD33761CCE6EE7009AD145 /* SwiftLint */, 399 | 6E478FE31CAD8D81003F2AE1 /* Sources */, 400 | 6E478FE41CAD8D81003F2AE1 /* Frameworks */, 401 | 6E478FE51CAD8D81003F2AE1 /* Headers */, 402 | 6E478FE61CAD8D81003F2AE1 /* Resources */, 403 | ); 404 | buildRules = ( 405 | ); 406 | dependencies = ( 407 | ); 408 | name = "DataManager iOS"; 409 | productName = DataManager; 410 | productReference = 6E478FE81CAD8D81003F2AE1 /* DataManager.framework */; 411 | productType = "com.apple.product-type.framework"; 412 | }; 413 | 6E478FF11CAD8D81003F2AE1 /* DataManager iOS Tests */ = { 414 | isa = PBXNativeTarget; 415 | buildConfigurationList = 6E478FFF1CAD8D81003F2AE1 /* Build configuration list for PBXNativeTarget "DataManager iOS Tests" */; 416 | buildPhases = ( 417 | 14D2D6269075BCC4FB2E5ED7 /* [CP] Check Pods Manifest.lock */, 418 | 6E478FEE1CAD8D81003F2AE1 /* Sources */, 419 | 6E478FEF1CAD8D81003F2AE1 /* Frameworks */, 420 | 6E478FF01CAD8D81003F2AE1 /* Resources */, 421 | ); 422 | buildRules = ( 423 | ); 424 | dependencies = ( 425 | 6E478FF51CAD8D81003F2AE1 /* PBXTargetDependency */, 426 | ); 427 | name = "DataManager iOS Tests"; 428 | productName = DataManagerTests; 429 | productReference = 6E478FF21CAD8D81003F2AE1 /* DataManager iOS Tests.xctest */; 430 | productType = "com.apple.product-type.bundle.unit-test"; 431 | }; 432 | 6E6DD2CB1CB844FA00DD3FB5 /* DataManager OSX */ = { 433 | isa = PBXNativeTarget; 434 | buildConfigurationList = 6E6DD2DD1CB844FA00DD3FB5 /* Build configuration list for PBXNativeTarget "DataManager OSX" */; 435 | buildPhases = ( 436 | 2E2E8BAC1E4069C8BC1A9EE3 /* [CP] Check Pods Manifest.lock */, 437 | 6EFD33771CCE6F07009AD145 /* SwiftLint */, 438 | 6E6DD2C71CB844FA00DD3FB5 /* Sources */, 439 | 6E6DD2C81CB844FA00DD3FB5 /* Frameworks */, 440 | 6E6DD2C91CB844FA00DD3FB5 /* Headers */, 441 | 6E6DD2CA1CB844FA00DD3FB5 /* Resources */, 442 | ); 443 | buildRules = ( 444 | ); 445 | dependencies = ( 446 | ); 447 | name = "DataManager OSX"; 448 | productName = "DataManager OSX"; 449 | productReference = 6E6DD2CC1CB844FA00DD3FB5 /* DataManager.framework */; 450 | productType = "com.apple.product-type.framework"; 451 | }; 452 | 6E6DD2D41CB844FA00DD3FB5 /* DataManager OSX Tests */ = { 453 | isa = PBXNativeTarget; 454 | buildConfigurationList = 6E6DD2E01CB844FA00DD3FB5 /* Build configuration list for PBXNativeTarget "DataManager OSX Tests" */; 455 | buildPhases = ( 456 | 840ECBF339A5567ECED54102 /* [CP] Check Pods Manifest.lock */, 457 | 6E6DD2D11CB844FA00DD3FB5 /* Sources */, 458 | 6E6DD2D21CB844FA00DD3FB5 /* Frameworks */, 459 | 6E6DD2D31CB844FA00DD3FB5 /* Resources */, 460 | ); 461 | buildRules = ( 462 | ); 463 | dependencies = ( 464 | 6E6DD2D81CB844FA00DD3FB5 /* PBXTargetDependency */, 465 | ); 466 | name = "DataManager OSX Tests"; 467 | productName = "DataManager OSXTests"; 468 | productReference = 6E6DD2D51CB844FA00DD3FB5 /* DataManager OSX Tests.xctest */; 469 | productType = "com.apple.product-type.bundle.unit-test"; 470 | }; 471 | 6E6DD2E71CB845E900DD3FB5 /* DataManager watchOS */ = { 472 | isa = PBXNativeTarget; 473 | buildConfigurationList = 6E6DD2ED1CB845E900DD3FB5 /* Build configuration list for PBXNativeTarget "DataManager watchOS" */; 474 | buildPhases = ( 475 | 24A12C9CE24E7FACD478EE90 /* [CP] Check Pods Manifest.lock */, 476 | 6EFD33791CCE6F35009AD145 /* SwiftLint */, 477 | 6E6DD2E31CB845E900DD3FB5 /* Sources */, 478 | 6E6DD2E41CB845E900DD3FB5 /* Frameworks */, 479 | 6E6DD2E51CB845E900DD3FB5 /* Headers */, 480 | 6E6DD2E61CB845E900DD3FB5 /* Resources */, 481 | ); 482 | buildRules = ( 483 | ); 484 | dependencies = ( 485 | ); 486 | name = "DataManager watchOS"; 487 | productName = "DataManager watchOS"; 488 | productReference = 6E6DD2E81CB845E900DD3FB5 /* DataManager.framework */; 489 | productType = "com.apple.product-type.framework"; 490 | }; 491 | 6E6DD2F41CB846C700DD3FB5 /* DataManager tvOS */ = { 492 | isa = PBXNativeTarget; 493 | buildConfigurationList = 6E6DD3061CB846C800DD3FB5 /* Build configuration list for PBXNativeTarget "DataManager tvOS" */; 494 | buildPhases = ( 495 | 05DF49D7D7FF63B461DEE1D1 /* [CP] Check Pods Manifest.lock */, 496 | 6EFD33781CCE6F22009AD145 /* SwiftLint */, 497 | 6E6DD2F01CB846C700DD3FB5 /* Sources */, 498 | 6E6DD2F11CB846C700DD3FB5 /* Frameworks */, 499 | 6E6DD2F21CB846C700DD3FB5 /* Headers */, 500 | 6E6DD2F31CB846C700DD3FB5 /* Resources */, 501 | ); 502 | buildRules = ( 503 | ); 504 | dependencies = ( 505 | ); 506 | name = "DataManager tvOS"; 507 | productName = "DataManager tvOS"; 508 | productReference = 6E6DD2F51CB846C700DD3FB5 /* DataManager.framework */; 509 | productType = "com.apple.product-type.framework"; 510 | }; 511 | 6E6DD2FD1CB846C800DD3FB5 /* DataManager tvOS Tests */ = { 512 | isa = PBXNativeTarget; 513 | buildConfigurationList = 6E6DD3091CB846C800DD3FB5 /* Build configuration list for PBXNativeTarget "DataManager tvOS Tests" */; 514 | buildPhases = ( 515 | 057112D757C9952224C16EF0 /* [CP] Check Pods Manifest.lock */, 516 | 6E6DD2FA1CB846C800DD3FB5 /* Sources */, 517 | 6E6DD2FB1CB846C800DD3FB5 /* Frameworks */, 518 | 6E6DD2FC1CB846C800DD3FB5 /* Resources */, 519 | ); 520 | buildRules = ( 521 | ); 522 | dependencies = ( 523 | 6E6DD3011CB846C800DD3FB5 /* PBXTargetDependency */, 524 | ); 525 | name = "DataManager tvOS Tests"; 526 | productName = "DataManager tvOSTests"; 527 | productReference = 6E6DD2FE1CB846C800DD3FB5 /* DataManager tvOS Tests.xctest */; 528 | productType = "com.apple.product-type.bundle.unit-test"; 529 | }; 530 | /* End PBXNativeTarget section */ 531 | 532 | /* Begin PBXProject section */ 533 | 6E478FDF1CAD8D81003F2AE1 /* Project object */ = { 534 | isa = PBXProject; 535 | attributes = { 536 | LastSwiftUpdateCheck = 0730; 537 | LastUpgradeCheck = 1230; 538 | ORGANIZATIONNAME = Metova; 539 | TargetAttributes = { 540 | 6E478FE71CAD8D81003F2AE1 = { 541 | CreatedOnToolsVersion = 7.3; 542 | LastSwiftMigration = 1230; 543 | }; 544 | 6E478FF11CAD8D81003F2AE1 = { 545 | CreatedOnToolsVersion = 7.3; 546 | LastSwiftMigration = 1230; 547 | }; 548 | 6E6DD2CB1CB844FA00DD3FB5 = { 549 | CreatedOnToolsVersion = 7.3; 550 | LastSwiftMigration = 0900; 551 | }; 552 | 6E6DD2D41CB844FA00DD3FB5 = { 553 | CreatedOnToolsVersion = 7.3; 554 | LastSwiftMigration = 0900; 555 | }; 556 | 6E6DD2E71CB845E900DD3FB5 = { 557 | CreatedOnToolsVersion = 7.3; 558 | LastSwiftMigration = 0900; 559 | }; 560 | 6E6DD2F41CB846C700DD3FB5 = { 561 | CreatedOnToolsVersion = 7.3; 562 | LastSwiftMigration = 0900; 563 | }; 564 | 6E6DD2FD1CB846C800DD3FB5 = { 565 | CreatedOnToolsVersion = 7.3; 566 | LastSwiftMigration = 0900; 567 | }; 568 | }; 569 | }; 570 | buildConfigurationList = 6E478FE21CAD8D81003F2AE1 /* Build configuration list for PBXProject "DataManager" */; 571 | compatibilityVersion = "Xcode 3.2"; 572 | developmentRegion = English; 573 | hasScannedForEncodings = 0; 574 | knownRegions = ( 575 | English, 576 | en, 577 | ); 578 | mainGroup = 6E478FDE1CAD8D81003F2AE1; 579 | productRefGroup = 6E478FE91CAD8D81003F2AE1 /* Products */; 580 | projectDirPath = ""; 581 | projectRoot = ""; 582 | targets = ( 583 | 6E478FE71CAD8D81003F2AE1 /* DataManager iOS */, 584 | 6E478FF11CAD8D81003F2AE1 /* DataManager iOS Tests */, 585 | 6E6DD2CB1CB844FA00DD3FB5 /* DataManager OSX */, 586 | 6E6DD2D41CB844FA00DD3FB5 /* DataManager OSX Tests */, 587 | 6E6DD2F41CB846C700DD3FB5 /* DataManager tvOS */, 588 | 6E6DD2FD1CB846C800DD3FB5 /* DataManager tvOS Tests */, 589 | 6E6DD2E71CB845E900DD3FB5 /* DataManager watchOS */, 590 | ); 591 | }; 592 | /* End PBXProject section */ 593 | 594 | /* Begin PBXResourcesBuildPhase section */ 595 | 6E478FE61CAD8D81003F2AE1 /* Resources */ = { 596 | isa = PBXResourcesBuildPhase; 597 | buildActionMask = 2147483647; 598 | files = ( 599 | 6E026F271D8AF95D0027E37E /* Gemfile.lock in Resources */, 600 | ); 601 | runOnlyForDeploymentPostprocessing = 0; 602 | }; 603 | 6E478FF01CAD8D81003F2AE1 /* Resources */ = { 604 | isa = PBXResourcesBuildPhase; 605 | buildActionMask = 2147483647; 606 | files = ( 607 | ); 608 | runOnlyForDeploymentPostprocessing = 0; 609 | }; 610 | 6E6DD2CA1CB844FA00DD3FB5 /* Resources */ = { 611 | isa = PBXResourcesBuildPhase; 612 | buildActionMask = 2147483647; 613 | files = ( 614 | ); 615 | runOnlyForDeploymentPostprocessing = 0; 616 | }; 617 | 6E6DD2D31CB844FA00DD3FB5 /* Resources */ = { 618 | isa = PBXResourcesBuildPhase; 619 | buildActionMask = 2147483647; 620 | files = ( 621 | ); 622 | runOnlyForDeploymentPostprocessing = 0; 623 | }; 624 | 6E6DD2E61CB845E900DD3FB5 /* Resources */ = { 625 | isa = PBXResourcesBuildPhase; 626 | buildActionMask = 2147483647; 627 | files = ( 628 | ); 629 | runOnlyForDeploymentPostprocessing = 0; 630 | }; 631 | 6E6DD2F31CB846C700DD3FB5 /* Resources */ = { 632 | isa = PBXResourcesBuildPhase; 633 | buildActionMask = 2147483647; 634 | files = ( 635 | ); 636 | runOnlyForDeploymentPostprocessing = 0; 637 | }; 638 | 6E6DD2FC1CB846C800DD3FB5 /* Resources */ = { 639 | isa = PBXResourcesBuildPhase; 640 | buildActionMask = 2147483647; 641 | files = ( 642 | ); 643 | runOnlyForDeploymentPostprocessing = 0; 644 | }; 645 | /* End PBXResourcesBuildPhase section */ 646 | 647 | /* Begin PBXShellScriptBuildPhase section */ 648 | 057112D757C9952224C16EF0 /* [CP] Check Pods Manifest.lock */ = { 649 | isa = PBXShellScriptBuildPhase; 650 | buildActionMask = 2147483647; 651 | files = ( 652 | ); 653 | inputPaths = ( 654 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 655 | "${PODS_ROOT}/Manifest.lock", 656 | ); 657 | name = "[CP] Check Pods Manifest.lock"; 658 | outputPaths = ( 659 | "$(DERIVED_FILE_DIR)/Pods-DataManager tvOS Tests-checkManifestLockResult.txt", 660 | ); 661 | runOnlyForDeploymentPostprocessing = 0; 662 | shellPath = /bin/sh; 663 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 664 | showEnvVarsInLog = 0; 665 | }; 666 | 05DF49D7D7FF63B461DEE1D1 /* [CP] Check Pods Manifest.lock */ = { 667 | isa = PBXShellScriptBuildPhase; 668 | buildActionMask = 2147483647; 669 | files = ( 670 | ); 671 | inputPaths = ( 672 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 673 | "${PODS_ROOT}/Manifest.lock", 674 | ); 675 | name = "[CP] Check Pods Manifest.lock"; 676 | outputPaths = ( 677 | "$(DERIVED_FILE_DIR)/Pods-DataManager-DataManager tvOS-checkManifestLockResult.txt", 678 | ); 679 | runOnlyForDeploymentPostprocessing = 0; 680 | shellPath = /bin/sh; 681 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 682 | showEnvVarsInLog = 0; 683 | }; 684 | 14D2D6269075BCC4FB2E5ED7 /* [CP] Check Pods Manifest.lock */ = { 685 | isa = PBXShellScriptBuildPhase; 686 | buildActionMask = 2147483647; 687 | files = ( 688 | ); 689 | inputPaths = ( 690 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 691 | "${PODS_ROOT}/Manifest.lock", 692 | ); 693 | name = "[CP] Check Pods Manifest.lock"; 694 | outputPaths = ( 695 | "$(DERIVED_FILE_DIR)/Pods-DataManager iOS Tests-checkManifestLockResult.txt", 696 | ); 697 | runOnlyForDeploymentPostprocessing = 0; 698 | shellPath = /bin/sh; 699 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 700 | showEnvVarsInLog = 0; 701 | }; 702 | 24A12C9CE24E7FACD478EE90 /* [CP] Check Pods Manifest.lock */ = { 703 | isa = PBXShellScriptBuildPhase; 704 | buildActionMask = 2147483647; 705 | files = ( 706 | ); 707 | inputPaths = ( 708 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 709 | "${PODS_ROOT}/Manifest.lock", 710 | ); 711 | name = "[CP] Check Pods Manifest.lock"; 712 | outputPaths = ( 713 | "$(DERIVED_FILE_DIR)/Pods-DataManager-DataManager watchOS-checkManifestLockResult.txt", 714 | ); 715 | runOnlyForDeploymentPostprocessing = 0; 716 | shellPath = /bin/sh; 717 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 718 | showEnvVarsInLog = 0; 719 | }; 720 | 2E2E8BAC1E4069C8BC1A9EE3 /* [CP] Check Pods Manifest.lock */ = { 721 | isa = PBXShellScriptBuildPhase; 722 | buildActionMask = 2147483647; 723 | files = ( 724 | ); 725 | inputPaths = ( 726 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 727 | "${PODS_ROOT}/Manifest.lock", 728 | ); 729 | name = "[CP] Check Pods Manifest.lock"; 730 | outputPaths = ( 731 | "$(DERIVED_FILE_DIR)/Pods-DataManager-DataManager OSX-checkManifestLockResult.txt", 732 | ); 733 | runOnlyForDeploymentPostprocessing = 0; 734 | shellPath = /bin/sh; 735 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 736 | showEnvVarsInLog = 0; 737 | }; 738 | 6EFD33761CCE6EE7009AD145 /* SwiftLint */ = { 739 | isa = PBXShellScriptBuildPhase; 740 | buildActionMask = 2147483647; 741 | files = ( 742 | ); 743 | inputPaths = ( 744 | ); 745 | name = SwiftLint; 746 | outputPaths = ( 747 | ); 748 | runOnlyForDeploymentPostprocessing = 0; 749 | shellPath = /bin/sh; 750 | shellScript = "${PODS_ROOT}/SwiftLint/swiftlint autocorrect && ${PODS_ROOT}/SwiftLint/swiftlint"; 751 | }; 752 | 6EFD33771CCE6F07009AD145 /* SwiftLint */ = { 753 | isa = PBXShellScriptBuildPhase; 754 | buildActionMask = 2147483647; 755 | files = ( 756 | ); 757 | inputPaths = ( 758 | ); 759 | name = SwiftLint; 760 | outputPaths = ( 761 | ); 762 | runOnlyForDeploymentPostprocessing = 0; 763 | shellPath = /bin/sh; 764 | shellScript = "${PODS_ROOT}/SwiftLint/swiftlint autocorrect && ${PODS_ROOT}/SwiftLint/swiftlint"; 765 | }; 766 | 6EFD33781CCE6F22009AD145 /* SwiftLint */ = { 767 | isa = PBXShellScriptBuildPhase; 768 | buildActionMask = 2147483647; 769 | files = ( 770 | ); 771 | inputPaths = ( 772 | ); 773 | name = SwiftLint; 774 | outputPaths = ( 775 | ); 776 | runOnlyForDeploymentPostprocessing = 0; 777 | shellPath = /bin/sh; 778 | shellScript = "${PODS_ROOT}/SwiftLint/swiftlint autocorrect && ${PODS_ROOT}/SwiftLint/swiftlint"; 779 | }; 780 | 6EFD33791CCE6F35009AD145 /* SwiftLint */ = { 781 | isa = PBXShellScriptBuildPhase; 782 | buildActionMask = 2147483647; 783 | files = ( 784 | ); 785 | inputPaths = ( 786 | ); 787 | name = SwiftLint; 788 | outputPaths = ( 789 | ); 790 | runOnlyForDeploymentPostprocessing = 0; 791 | shellPath = /bin/sh; 792 | shellScript = "${PODS_ROOT}/SwiftLint/swiftlint autocorrect && ${PODS_ROOT}/SwiftLint/swiftlint"; 793 | }; 794 | 840ECBF339A5567ECED54102 /* [CP] Check Pods Manifest.lock */ = { 795 | isa = PBXShellScriptBuildPhase; 796 | buildActionMask = 2147483647; 797 | files = ( 798 | ); 799 | inputPaths = ( 800 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 801 | "${PODS_ROOT}/Manifest.lock", 802 | ); 803 | name = "[CP] Check Pods Manifest.lock"; 804 | outputPaths = ( 805 | "$(DERIVED_FILE_DIR)/Pods-DataManager OSX Tests-checkManifestLockResult.txt", 806 | ); 807 | runOnlyForDeploymentPostprocessing = 0; 808 | shellPath = /bin/sh; 809 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 810 | showEnvVarsInLog = 0; 811 | }; 812 | CF37EC56ACE9BD3C31E80914 /* [CP] Check Pods Manifest.lock */ = { 813 | isa = PBXShellScriptBuildPhase; 814 | buildActionMask = 2147483647; 815 | files = ( 816 | ); 817 | inputPaths = ( 818 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 819 | "${PODS_ROOT}/Manifest.lock", 820 | ); 821 | name = "[CP] Check Pods Manifest.lock"; 822 | outputPaths = ( 823 | "$(DERIVED_FILE_DIR)/Pods-DataManager-DataManager iOS-checkManifestLockResult.txt", 824 | ); 825 | runOnlyForDeploymentPostprocessing = 0; 826 | shellPath = /bin/sh; 827 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 828 | showEnvVarsInLog = 0; 829 | }; 830 | /* End PBXShellScriptBuildPhase section */ 831 | 832 | /* Begin PBXSourcesBuildPhase section */ 833 | 6E478FE31CAD8D81003F2AE1 /* Sources */ = { 834 | isa = PBXSourcesBuildPhase; 835 | buildActionMask = 2147483647; 836 | files = ( 837 | 6E4790031CAD8DBF003F2AE1 /* DataManager.swift in Sources */, 838 | ); 839 | runOnlyForDeploymentPostprocessing = 0; 840 | }; 841 | 6E478FEE1CAD8D81003F2AE1 /* Sources */ = { 842 | isa = PBXSourcesBuildPhase; 843 | buildActionMask = 2147483647; 844 | files = ( 845 | 6E08D1FF1CCFF2B900426439 /* PersistentStoreTypeTests.swift in Sources */, 846 | 6EA68ADF1CD7D1EC00D113FA /* MethodSwizzling.swift in Sources */, 847 | 6E478FF81CAD8D81003F2AE1 /* DataManagerTests.swift in Sources */, 848 | 6EFD33561CC93622009AD145 /* TestModel.xcdatamodeld in Sources */, 849 | 6E08D20C1CCFFDF300426439 /* Group.swift in Sources */, 850 | 6EFD33601CC93770009AD145 /* Person.swift in Sources */, 851 | 6E08D2041CCFF75200426439 /* NSManagedObjectContext+TestSwizzle.swift in Sources */, 852 | 6EA68AE31CD7D3DC00D113FA /* XCTestCase+MockLogger.swift in Sources */, 853 | 6EFD335D1CC93770009AD145 /* Person+CoreDataProperties.swift in Sources */, 854 | 6E08D2091CCFFDF300426439 /* Group+CoreDataProperties.swift in Sources */, 855 | ); 856 | runOnlyForDeploymentPostprocessing = 0; 857 | }; 858 | 6E6DD2C71CB844FA00DD3FB5 /* Sources */ = { 859 | isa = PBXSourcesBuildPhase; 860 | buildActionMask = 2147483647; 861 | files = ( 862 | 6EFD334C1CC931E4009AD145 /* DataManager.swift in Sources */, 863 | ); 864 | runOnlyForDeploymentPostprocessing = 0; 865 | }; 866 | 6E6DD2D11CB844FA00DD3FB5 /* Sources */ = { 867 | isa = PBXSourcesBuildPhase; 868 | buildActionMask = 2147483647; 869 | files = ( 870 | 6E08D2001CCFF2B900426439 /* PersistentStoreTypeTests.swift in Sources */, 871 | 6EA68AE01CD7D1EC00D113FA /* MethodSwizzling.swift in Sources */, 872 | 6E6DD30E1CB85E0F00DD3FB5 /* DataManagerTests.swift in Sources */, 873 | 6EFD33571CC93624009AD145 /* TestModel.xcdatamodeld in Sources */, 874 | 6E08D20D1CCFFDF300426439 /* Group.swift in Sources */, 875 | 6EFD33611CC93770009AD145 /* Person.swift in Sources */, 876 | 6E08D2051CCFF75200426439 /* NSManagedObjectContext+TestSwizzle.swift in Sources */, 877 | 6EA68AE41CD7D3DC00D113FA /* XCTestCase+MockLogger.swift in Sources */, 878 | 6EFD335E1CC93770009AD145 /* Person+CoreDataProperties.swift in Sources */, 879 | 6E08D20A1CCFFDF300426439 /* Group+CoreDataProperties.swift in Sources */, 880 | ); 881 | runOnlyForDeploymentPostprocessing = 0; 882 | }; 883 | 6E6DD2E31CB845E900DD3FB5 /* Sources */ = { 884 | isa = PBXSourcesBuildPhase; 885 | buildActionMask = 2147483647; 886 | files = ( 887 | 6EFD334E1CC931E7009AD145 /* DataManager.swift in Sources */, 888 | ); 889 | runOnlyForDeploymentPostprocessing = 0; 890 | }; 891 | 6E6DD2F01CB846C700DD3FB5 /* Sources */ = { 892 | isa = PBXSourcesBuildPhase; 893 | buildActionMask = 2147483647; 894 | files = ( 895 | 6EFD334D1CC931E5009AD145 /* DataManager.swift in Sources */, 896 | ); 897 | runOnlyForDeploymentPostprocessing = 0; 898 | }; 899 | 6E6DD2FA1CB846C800DD3FB5 /* Sources */ = { 900 | isa = PBXSourcesBuildPhase; 901 | buildActionMask = 2147483647; 902 | files = ( 903 | 6E08D2011CCFF2B900426439 /* PersistentStoreTypeTests.swift in Sources */, 904 | 6EA68AE11CD7D1EC00D113FA /* MethodSwizzling.swift in Sources */, 905 | 6E6DD30F1CB85E1100DD3FB5 /* DataManagerTests.swift in Sources */, 906 | 6EFD33581CC93625009AD145 /* TestModel.xcdatamodeld in Sources */, 907 | 6E08D20E1CCFFDF300426439 /* Group.swift in Sources */, 908 | 6EFD33621CC93770009AD145 /* Person.swift in Sources */, 909 | 6E08D2061CCFF75200426439 /* NSManagedObjectContext+TestSwizzle.swift in Sources */, 910 | 6EA68AE51CD7D3DC00D113FA /* XCTestCase+MockLogger.swift in Sources */, 911 | 6EFD335F1CC93770009AD145 /* Person+CoreDataProperties.swift in Sources */, 912 | 6E08D20B1CCFFDF300426439 /* Group+CoreDataProperties.swift in Sources */, 913 | ); 914 | runOnlyForDeploymentPostprocessing = 0; 915 | }; 916 | /* End PBXSourcesBuildPhase section */ 917 | 918 | /* Begin PBXTargetDependency section */ 919 | 6E478FF51CAD8D81003F2AE1 /* PBXTargetDependency */ = { 920 | isa = PBXTargetDependency; 921 | target = 6E478FE71CAD8D81003F2AE1 /* DataManager iOS */; 922 | targetProxy = 6E478FF41CAD8D81003F2AE1 /* PBXContainerItemProxy */; 923 | }; 924 | 6E6DD2D81CB844FA00DD3FB5 /* PBXTargetDependency */ = { 925 | isa = PBXTargetDependency; 926 | target = 6E6DD2CB1CB844FA00DD3FB5 /* DataManager OSX */; 927 | targetProxy = 6E6DD2D71CB844FA00DD3FB5 /* PBXContainerItemProxy */; 928 | }; 929 | 6E6DD3011CB846C800DD3FB5 /* PBXTargetDependency */ = { 930 | isa = PBXTargetDependency; 931 | target = 6E6DD2F41CB846C700DD3FB5 /* DataManager tvOS */; 932 | targetProxy = 6E6DD3001CB846C800DD3FB5 /* PBXContainerItemProxy */; 933 | }; 934 | /* End PBXTargetDependency section */ 935 | 936 | /* Begin XCBuildConfiguration section */ 937 | 6E478FFA1CAD8D81003F2AE1 /* Debug */ = { 938 | isa = XCBuildConfiguration; 939 | buildSettings = { 940 | ALWAYS_SEARCH_USER_PATHS = NO; 941 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 942 | CLANG_ANALYZER_NONNULL = YES; 943 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 944 | CLANG_CXX_LIBRARY = "libc++"; 945 | CLANG_ENABLE_MODULES = YES; 946 | CLANG_ENABLE_OBJC_ARC = YES; 947 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 948 | CLANG_WARN_BOOL_CONVERSION = YES; 949 | CLANG_WARN_COMMA = YES; 950 | CLANG_WARN_CONSTANT_CONVERSION = YES; 951 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 952 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 953 | CLANG_WARN_EMPTY_BODY = YES; 954 | CLANG_WARN_ENUM_CONVERSION = YES; 955 | CLANG_WARN_INFINITE_RECURSION = YES; 956 | CLANG_WARN_INT_CONVERSION = YES; 957 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 958 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 959 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 960 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 961 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 962 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 963 | CLANG_WARN_STRICT_PROTOTYPES = YES; 964 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 965 | CLANG_WARN_UNREACHABLE_CODE = YES; 966 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 967 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 968 | COPY_PHASE_STRIP = NO; 969 | CURRENT_PROJECT_VERSION = 1; 970 | DEBUG_INFORMATION_FORMAT = dwarf; 971 | ENABLE_STRICT_OBJC_MSGSEND = YES; 972 | ENABLE_TESTABILITY = YES; 973 | GCC_C_LANGUAGE_STANDARD = gnu99; 974 | GCC_DYNAMIC_NO_PIC = NO; 975 | GCC_NO_COMMON_BLOCKS = YES; 976 | GCC_OPTIMIZATION_LEVEL = 0; 977 | GCC_PREPROCESSOR_DEFINITIONS = ( 978 | "DEBUG=1", 979 | "$(inherited)", 980 | ); 981 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 982 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 983 | GCC_WARN_UNDECLARED_SELECTOR = YES; 984 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 985 | GCC_WARN_UNUSED_FUNCTION = YES; 986 | GCC_WARN_UNUSED_VARIABLE = YES; 987 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 988 | MACOSX_DEPLOYMENT_TARGET = 10.13; 989 | MTL_ENABLE_DEBUG_INFO = YES; 990 | ONLY_ACTIVE_ARCH = YES; 991 | SDKROOT = iphoneos; 992 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 993 | SWIFT_VERSION = 5.0; 994 | TARGETED_DEVICE_FAMILY = "1,2"; 995 | VERSIONING_SYSTEM = "apple-generic"; 996 | VERSION_INFO_PREFIX = ""; 997 | }; 998 | name = Debug; 999 | }; 1000 | 6E478FFB1CAD8D81003F2AE1 /* Release */ = { 1001 | isa = XCBuildConfiguration; 1002 | buildSettings = { 1003 | ALWAYS_SEARCH_USER_PATHS = NO; 1004 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 1005 | CLANG_ANALYZER_NONNULL = YES; 1006 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 1007 | CLANG_CXX_LIBRARY = "libc++"; 1008 | CLANG_ENABLE_MODULES = YES; 1009 | CLANG_ENABLE_OBJC_ARC = YES; 1010 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 1011 | CLANG_WARN_BOOL_CONVERSION = YES; 1012 | CLANG_WARN_COMMA = YES; 1013 | CLANG_WARN_CONSTANT_CONVERSION = YES; 1014 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 1015 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 1016 | CLANG_WARN_EMPTY_BODY = YES; 1017 | CLANG_WARN_ENUM_CONVERSION = YES; 1018 | CLANG_WARN_INFINITE_RECURSION = YES; 1019 | CLANG_WARN_INT_CONVERSION = YES; 1020 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 1021 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 1022 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 1023 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 1024 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 1025 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 1026 | CLANG_WARN_STRICT_PROTOTYPES = YES; 1027 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 1028 | CLANG_WARN_UNREACHABLE_CODE = YES; 1029 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 1030 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 1031 | COPY_PHASE_STRIP = NO; 1032 | CURRENT_PROJECT_VERSION = 1; 1033 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 1034 | ENABLE_NS_ASSERTIONS = NO; 1035 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1036 | GCC_C_LANGUAGE_STANDARD = gnu99; 1037 | GCC_NO_COMMON_BLOCKS = YES; 1038 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1039 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 1040 | GCC_WARN_UNDECLARED_SELECTOR = YES; 1041 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1042 | GCC_WARN_UNUSED_FUNCTION = YES; 1043 | GCC_WARN_UNUSED_VARIABLE = YES; 1044 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 1045 | MACOSX_DEPLOYMENT_TARGET = 10.13; 1046 | MTL_ENABLE_DEBUG_INFO = NO; 1047 | SDKROOT = iphoneos; 1048 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 1049 | SWIFT_VERSION = 5.0; 1050 | TARGETED_DEVICE_FAMILY = "1,2"; 1051 | VALIDATE_PRODUCT = YES; 1052 | VERSIONING_SYSTEM = "apple-generic"; 1053 | VERSION_INFO_PREFIX = ""; 1054 | }; 1055 | name = Release; 1056 | }; 1057 | 6E478FFD1CAD8D81003F2AE1 /* Debug */ = { 1058 | isa = XCBuildConfiguration; 1059 | baseConfigurationReference = 3C1E6F8A601AABCD650F2B34 /* Pods-DataManager-DataManager iOS.debug.xcconfig */; 1060 | buildSettings = { 1061 | APPLICATION_EXTENSION_API_ONLY = YES; 1062 | CLANG_ENABLE_MODULES = YES; 1063 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 1064 | DEFINES_MODULE = YES; 1065 | DYLIB_COMPATIBILITY_VERSION = 1; 1066 | DYLIB_CURRENT_VERSION = 1; 1067 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 1068 | INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; 1069 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 1070 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 1071 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1072 | PRODUCT_BUNDLE_IDENTIFIER = com.metova.DataManager; 1073 | PRODUCT_NAME = DataManager; 1074 | SKIP_INSTALL = YES; 1075 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 1076 | SWIFT_VERSION = 5.0; 1077 | }; 1078 | name = Debug; 1079 | }; 1080 | 6E478FFE1CAD8D81003F2AE1 /* Release */ = { 1081 | isa = XCBuildConfiguration; 1082 | baseConfigurationReference = C61ACF25ED8BFA8A66F2243E /* Pods-DataManager-DataManager iOS.release.xcconfig */; 1083 | buildSettings = { 1084 | APPLICATION_EXTENSION_API_ONLY = YES; 1085 | CLANG_ENABLE_MODULES = YES; 1086 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 1087 | DEFINES_MODULE = YES; 1088 | DYLIB_COMPATIBILITY_VERSION = 1; 1089 | DYLIB_CURRENT_VERSION = 1; 1090 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 1091 | INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; 1092 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 1093 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 1094 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1095 | PRODUCT_BUNDLE_IDENTIFIER = com.metova.DataManager; 1096 | PRODUCT_NAME = DataManager; 1097 | SKIP_INSTALL = YES; 1098 | SWIFT_VERSION = 5.0; 1099 | }; 1100 | name = Release; 1101 | }; 1102 | 6E4790001CAD8D81003F2AE1 /* Debug */ = { 1103 | isa = XCBuildConfiguration; 1104 | baseConfigurationReference = 7F2FA690E5B0FFA6C7A32E27 /* Pods-DataManager iOS Tests.debug.xcconfig */; 1105 | buildSettings = { 1106 | INFOPLIST_FILE = Tests/Info.plist; 1107 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1108 | PRODUCT_BUNDLE_IDENTIFIER = com.metova.DataManagerTests; 1109 | PRODUCT_NAME = "$(TARGET_NAME)"; 1110 | SWIFT_VERSION = 5.0; 1111 | }; 1112 | name = Debug; 1113 | }; 1114 | 6E4790011CAD8D81003F2AE1 /* Release */ = { 1115 | isa = XCBuildConfiguration; 1116 | baseConfigurationReference = 9566E6DE55150E411C02F511 /* Pods-DataManager iOS Tests.release.xcconfig */; 1117 | buildSettings = { 1118 | INFOPLIST_FILE = Tests/Info.plist; 1119 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1120 | PRODUCT_BUNDLE_IDENTIFIER = com.metova.DataManagerTests; 1121 | PRODUCT_NAME = "$(TARGET_NAME)"; 1122 | SWIFT_VERSION = 5.0; 1123 | }; 1124 | name = Release; 1125 | }; 1126 | 6E6DD2DE1CB844FA00DD3FB5 /* Debug */ = { 1127 | isa = XCBuildConfiguration; 1128 | baseConfigurationReference = 6EE428854890BAA30504A4E2 /* Pods-DataManager-DataManager OSX.debug.xcconfig */; 1129 | buildSettings = { 1130 | APPLICATION_EXTENSION_API_ONLY = YES; 1131 | CODE_SIGN_IDENTITY = ""; 1132 | COMBINE_HIDPI_IMAGES = YES; 1133 | DEFINES_MODULE = YES; 1134 | DYLIB_COMPATIBILITY_VERSION = 1; 1135 | DYLIB_CURRENT_VERSION = 1; 1136 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 1137 | FRAMEWORK_VERSION = A; 1138 | INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; 1139 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 1140 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 1141 | MACOSX_DEPLOYMENT_TARGET = 10.9; 1142 | PRODUCT_BUNDLE_IDENTIFIER = com.metova.DataManager; 1143 | PRODUCT_NAME = DataManager; 1144 | SDKROOT = macosx; 1145 | SKIP_INSTALL = YES; 1146 | SWIFT_VERSION = 4.0; 1147 | }; 1148 | name = Debug; 1149 | }; 1150 | 6E6DD2DF1CB844FA00DD3FB5 /* Release */ = { 1151 | isa = XCBuildConfiguration; 1152 | baseConfigurationReference = F43DA1B74A5DAEB807D358F3 /* Pods-DataManager-DataManager OSX.release.xcconfig */; 1153 | buildSettings = { 1154 | APPLICATION_EXTENSION_API_ONLY = YES; 1155 | CODE_SIGN_IDENTITY = ""; 1156 | COMBINE_HIDPI_IMAGES = YES; 1157 | DEFINES_MODULE = YES; 1158 | DYLIB_COMPATIBILITY_VERSION = 1; 1159 | DYLIB_CURRENT_VERSION = 1; 1160 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 1161 | FRAMEWORK_VERSION = A; 1162 | INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; 1163 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 1164 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 1165 | MACOSX_DEPLOYMENT_TARGET = 10.9; 1166 | PRODUCT_BUNDLE_IDENTIFIER = com.metova.DataManager; 1167 | PRODUCT_NAME = DataManager; 1168 | SDKROOT = macosx; 1169 | SKIP_INSTALL = YES; 1170 | SWIFT_VERSION = 4.0; 1171 | }; 1172 | name = Release; 1173 | }; 1174 | 6E6DD2E11CB844FA00DD3FB5 /* Debug */ = { 1175 | isa = XCBuildConfiguration; 1176 | baseConfigurationReference = A070671BFDC1D25EB9BC3E82 /* Pods-DataManager OSX Tests.debug.xcconfig */; 1177 | buildSettings = { 1178 | CODE_SIGN_IDENTITY = "-"; 1179 | COMBINE_HIDPI_IMAGES = YES; 1180 | INFOPLIST_FILE = Tests/Info.plist; 1181 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 1182 | MACOSX_DEPLOYMENT_TARGET = 10.11; 1183 | PRODUCT_BUNDLE_IDENTIFIER = "com.metova.DataManager-OSXTests"; 1184 | PRODUCT_NAME = "$(TARGET_NAME)"; 1185 | SDKROOT = macosx; 1186 | SWIFT_VERSION = 4.0; 1187 | }; 1188 | name = Debug; 1189 | }; 1190 | 6E6DD2E21CB844FA00DD3FB5 /* Release */ = { 1191 | isa = XCBuildConfiguration; 1192 | baseConfigurationReference = BAA610AC8A20A7B640D2982E /* Pods-DataManager OSX Tests.release.xcconfig */; 1193 | buildSettings = { 1194 | CODE_SIGN_IDENTITY = "-"; 1195 | COMBINE_HIDPI_IMAGES = YES; 1196 | INFOPLIST_FILE = Tests/Info.plist; 1197 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 1198 | MACOSX_DEPLOYMENT_TARGET = 10.11; 1199 | PRODUCT_BUNDLE_IDENTIFIER = "com.metova.DataManager-OSXTests"; 1200 | PRODUCT_NAME = "$(TARGET_NAME)"; 1201 | SDKROOT = macosx; 1202 | SWIFT_VERSION = 4.0; 1203 | }; 1204 | name = Release; 1205 | }; 1206 | 6E6DD2EE1CB845E900DD3FB5 /* Debug */ = { 1207 | isa = XCBuildConfiguration; 1208 | baseConfigurationReference = C70D82758C706960F88D2FC9 /* Pods-DataManager-DataManager watchOS.debug.xcconfig */; 1209 | buildSettings = { 1210 | APPLICATION_EXTENSION_API_ONLY = YES; 1211 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 1212 | DEFINES_MODULE = YES; 1213 | DYLIB_COMPATIBILITY_VERSION = 1; 1214 | DYLIB_CURRENT_VERSION = 1; 1215 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 1216 | INFOPLIST_FILE = Sources/Info.plist; 1217 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 1218 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1219 | PRODUCT_BUNDLE_IDENTIFIER = com.metova.DataManager; 1220 | PRODUCT_NAME = DataManager; 1221 | SDKROOT = watchos; 1222 | SKIP_INSTALL = YES; 1223 | SWIFT_VERSION = 4.0; 1224 | TARGETED_DEVICE_FAMILY = 4; 1225 | WATCHOS_DEPLOYMENT_TARGET = 2.2; 1226 | }; 1227 | name = Debug; 1228 | }; 1229 | 6E6DD2EF1CB845E900DD3FB5 /* Release */ = { 1230 | isa = XCBuildConfiguration; 1231 | baseConfigurationReference = 792C09A15000FA08C98B8822 /* Pods-DataManager-DataManager watchOS.release.xcconfig */; 1232 | buildSettings = { 1233 | APPLICATION_EXTENSION_API_ONLY = YES; 1234 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 1235 | DEFINES_MODULE = YES; 1236 | DYLIB_COMPATIBILITY_VERSION = 1; 1237 | DYLIB_CURRENT_VERSION = 1; 1238 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 1239 | INFOPLIST_FILE = Sources/Info.plist; 1240 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 1241 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1242 | PRODUCT_BUNDLE_IDENTIFIER = com.metova.DataManager; 1243 | PRODUCT_NAME = DataManager; 1244 | SDKROOT = watchos; 1245 | SKIP_INSTALL = YES; 1246 | SWIFT_VERSION = 4.0; 1247 | TARGETED_DEVICE_FAMILY = 4; 1248 | WATCHOS_DEPLOYMENT_TARGET = 2.2; 1249 | }; 1250 | name = Release; 1251 | }; 1252 | 6E6DD3071CB846C800DD3FB5 /* Debug */ = { 1253 | isa = XCBuildConfiguration; 1254 | baseConfigurationReference = 1A8B7BC1DE13F3E24B80ABF5 /* Pods-DataManager-DataManager tvOS.debug.xcconfig */; 1255 | buildSettings = { 1256 | APPLICATION_EXTENSION_API_ONLY = YES; 1257 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 1258 | DEFINES_MODULE = YES; 1259 | DYLIB_COMPATIBILITY_VERSION = 1; 1260 | DYLIB_CURRENT_VERSION = 1; 1261 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 1262 | INFOPLIST_FILE = "$(SRCROOT)/Sources/Info-tvOS.plist"; 1263 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 1264 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1265 | PRODUCT_BUNDLE_IDENTIFIER = com.metova.DataManager; 1266 | PRODUCT_NAME = DataManager; 1267 | SDKROOT = appletvos; 1268 | SKIP_INSTALL = YES; 1269 | SWIFT_VERSION = 4.0; 1270 | TARGETED_DEVICE_FAMILY = 3; 1271 | TVOS_DEPLOYMENT_TARGET = 12.0; 1272 | }; 1273 | name = Debug; 1274 | }; 1275 | 6E6DD3081CB846C800DD3FB5 /* Release */ = { 1276 | isa = XCBuildConfiguration; 1277 | baseConfigurationReference = A3A35B0F67E7F41321164F40 /* Pods-DataManager-DataManager tvOS.release.xcconfig */; 1278 | buildSettings = { 1279 | APPLICATION_EXTENSION_API_ONLY = YES; 1280 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 1281 | DEFINES_MODULE = YES; 1282 | DYLIB_COMPATIBILITY_VERSION = 1; 1283 | DYLIB_CURRENT_VERSION = 1; 1284 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 1285 | INFOPLIST_FILE = "$(SRCROOT)/Sources/Info-tvOS.plist"; 1286 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 1287 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1288 | PRODUCT_BUNDLE_IDENTIFIER = com.metova.DataManager; 1289 | PRODUCT_NAME = DataManager; 1290 | SDKROOT = appletvos; 1291 | SKIP_INSTALL = YES; 1292 | SWIFT_VERSION = 4.0; 1293 | TARGETED_DEVICE_FAMILY = 3; 1294 | TVOS_DEPLOYMENT_TARGET = 12.0; 1295 | }; 1296 | name = Release; 1297 | }; 1298 | 6E6DD30A1CB846C800DD3FB5 /* Debug */ = { 1299 | isa = XCBuildConfiguration; 1300 | baseConfigurationReference = CDD25EB366977CFCC9D5D917 /* Pods-DataManager tvOS Tests.debug.xcconfig */; 1301 | buildSettings = { 1302 | INFOPLIST_FILE = "Tests/Info-tvOS.plist"; 1303 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1304 | PRODUCT_BUNDLE_IDENTIFIER = "com.metova.DataManager-tvOSTests"; 1305 | PRODUCT_NAME = "$(TARGET_NAME)"; 1306 | SDKROOT = appletvos; 1307 | SWIFT_VERSION = 4.0; 1308 | TVOS_DEPLOYMENT_TARGET = 12.0; 1309 | }; 1310 | name = Debug; 1311 | }; 1312 | 6E6DD30B1CB846C800DD3FB5 /* Release */ = { 1313 | isa = XCBuildConfiguration; 1314 | baseConfigurationReference = 2AA9186FF28DC8960F0DFA90 /* Pods-DataManager tvOS Tests.release.xcconfig */; 1315 | buildSettings = { 1316 | INFOPLIST_FILE = "Tests/Info-tvOS.plist"; 1317 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1318 | PRODUCT_BUNDLE_IDENTIFIER = "com.metova.DataManager-tvOSTests"; 1319 | PRODUCT_NAME = "$(TARGET_NAME)"; 1320 | SDKROOT = appletvos; 1321 | SWIFT_VERSION = 4.0; 1322 | TVOS_DEPLOYMENT_TARGET = 12.0; 1323 | }; 1324 | name = Release; 1325 | }; 1326 | /* End XCBuildConfiguration section */ 1327 | 1328 | /* Begin XCConfigurationList section */ 1329 | 6E478FE21CAD8D81003F2AE1 /* Build configuration list for PBXProject "DataManager" */ = { 1330 | isa = XCConfigurationList; 1331 | buildConfigurations = ( 1332 | 6E478FFA1CAD8D81003F2AE1 /* Debug */, 1333 | 6E478FFB1CAD8D81003F2AE1 /* Release */, 1334 | ); 1335 | defaultConfigurationIsVisible = 0; 1336 | defaultConfigurationName = Release; 1337 | }; 1338 | 6E478FFC1CAD8D81003F2AE1 /* Build configuration list for PBXNativeTarget "DataManager iOS" */ = { 1339 | isa = XCConfigurationList; 1340 | buildConfigurations = ( 1341 | 6E478FFD1CAD8D81003F2AE1 /* Debug */, 1342 | 6E478FFE1CAD8D81003F2AE1 /* Release */, 1343 | ); 1344 | defaultConfigurationIsVisible = 0; 1345 | defaultConfigurationName = Release; 1346 | }; 1347 | 6E478FFF1CAD8D81003F2AE1 /* Build configuration list for PBXNativeTarget "DataManager iOS Tests" */ = { 1348 | isa = XCConfigurationList; 1349 | buildConfigurations = ( 1350 | 6E4790001CAD8D81003F2AE1 /* Debug */, 1351 | 6E4790011CAD8D81003F2AE1 /* Release */, 1352 | ); 1353 | defaultConfigurationIsVisible = 0; 1354 | defaultConfigurationName = Release; 1355 | }; 1356 | 6E6DD2DD1CB844FA00DD3FB5 /* Build configuration list for PBXNativeTarget "DataManager OSX" */ = { 1357 | isa = XCConfigurationList; 1358 | buildConfigurations = ( 1359 | 6E6DD2DE1CB844FA00DD3FB5 /* Debug */, 1360 | 6E6DD2DF1CB844FA00DD3FB5 /* Release */, 1361 | ); 1362 | defaultConfigurationIsVisible = 0; 1363 | defaultConfigurationName = Release; 1364 | }; 1365 | 6E6DD2E01CB844FA00DD3FB5 /* Build configuration list for PBXNativeTarget "DataManager OSX Tests" */ = { 1366 | isa = XCConfigurationList; 1367 | buildConfigurations = ( 1368 | 6E6DD2E11CB844FA00DD3FB5 /* Debug */, 1369 | 6E6DD2E21CB844FA00DD3FB5 /* Release */, 1370 | ); 1371 | defaultConfigurationIsVisible = 0; 1372 | defaultConfigurationName = Release; 1373 | }; 1374 | 6E6DD2ED1CB845E900DD3FB5 /* Build configuration list for PBXNativeTarget "DataManager watchOS" */ = { 1375 | isa = XCConfigurationList; 1376 | buildConfigurations = ( 1377 | 6E6DD2EE1CB845E900DD3FB5 /* Debug */, 1378 | 6E6DD2EF1CB845E900DD3FB5 /* Release */, 1379 | ); 1380 | defaultConfigurationIsVisible = 0; 1381 | defaultConfigurationName = Release; 1382 | }; 1383 | 6E6DD3061CB846C800DD3FB5 /* Build configuration list for PBXNativeTarget "DataManager tvOS" */ = { 1384 | isa = XCConfigurationList; 1385 | buildConfigurations = ( 1386 | 6E6DD3071CB846C800DD3FB5 /* Debug */, 1387 | 6E6DD3081CB846C800DD3FB5 /* Release */, 1388 | ); 1389 | defaultConfigurationIsVisible = 0; 1390 | defaultConfigurationName = Release; 1391 | }; 1392 | 6E6DD3091CB846C800DD3FB5 /* Build configuration list for PBXNativeTarget "DataManager tvOS Tests" */ = { 1393 | isa = XCConfigurationList; 1394 | buildConfigurations = ( 1395 | 6E6DD30A1CB846C800DD3FB5 /* Debug */, 1396 | 6E6DD30B1CB846C800DD3FB5 /* Release */, 1397 | ); 1398 | defaultConfigurationIsVisible = 0; 1399 | defaultConfigurationName = Release; 1400 | }; 1401 | /* End XCConfigurationList section */ 1402 | 1403 | /* Begin XCVersionGroup section */ 1404 | 6EFD33501CC935DA009AD145 /* TestModel.xcdatamodeld */ = { 1405 | isa = XCVersionGroup; 1406 | children = ( 1407 | 6EFD33511CC935DA009AD145 /* TestModel.xcdatamodel */, 1408 | ); 1409 | currentVersion = 6EFD33511CC935DA009AD145 /* TestModel.xcdatamodel */; 1410 | path = TestModel.xcdatamodeld; 1411 | sourceTree = ""; 1412 | versionGroupType = wrapper.xcdatamodel; 1413 | }; 1414 | /* End XCVersionGroup section */ 1415 | }; 1416 | rootObject = 6E478FDF1CAD8D81003F2AE1 /* Project object */; 1417 | } 1418 | -------------------------------------------------------------------------------- /DataManager.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /DataManager.xcodeproj/xcshareddata/xcschemes/DataManager OSX.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 38 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 63 | 64 | 70 | 71 | 72 | 73 | 79 | 80 | 86 | 87 | 88 | 89 | 91 | 92 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /DataManager.xcodeproj/xcshareddata/xcschemes/DataManager iOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 38 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 63 | 64 | 70 | 71 | 72 | 73 | 79 | 80 | 86 | 87 | 88 | 89 | 91 | 92 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /DataManager.xcodeproj/xcshareddata/xcschemes/DataManager tvOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 38 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 63 | 64 | 70 | 71 | 72 | 73 | 79 | 80 | 86 | 87 | 88 | 89 | 91 | 92 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /DataManager.xcodeproj/xcshareddata/xcschemes/DataManager watchOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 44 | 45 | 51 | 52 | 53 | 54 | 60 | 61 | 67 | 68 | 69 | 70 | 72 | 73 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /DataManager.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /DataManager.xcworkspace/xcshareddata/DataManager.xcscmblueprint: -------------------------------------------------------------------------------- 1 | { 2 | "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "BC50F10C09131FA7C1968BC4121809B370907B20", 3 | "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { 4 | 5 | }, 6 | "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { 7 | "CD22FC54F4745ABAEE53320B6E5709DBAC241BD3" : 0, 8 | "BC50F10C09131FA7C1968BC4121809B370907B20" : 0 9 | }, 10 | "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "C8E10F7B-8915-49F0-B815-00C575F0EB48", 11 | "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { 12 | "CD22FC54F4745ABAEE53320B6E5709DBAC241BD3" : "", 13 | "BC50F10C09131FA7C1968BC4121809B370907B20" : "DataManager\/" 14 | }, 15 | "DVTSourceControlWorkspaceBlueprintNameKey" : "DataManager", 16 | "DVTSourceControlWorkspaceBlueprintVersion" : 204, 17 | "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "DataManager.xcworkspace", 18 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ 19 | { 20 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/metova\/DataManager.git", 21 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 22 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "BC50F10C09131FA7C1968BC4121809B370907B20" 23 | }, 24 | { 25 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/bitbucket.org\/metova\/bookgrabbr-web.git", 26 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 27 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "CD22FC54F4745ABAEE53320B6E5709DBAC241BD3" 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /DataManager.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | gem 'slather' 3 | gem 'cocoapods' 4 | gem 'xcpretty' 5 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.6) 5 | rexml 6 | activesupport (5.2.8.1) 7 | concurrent-ruby (~> 1.0, >= 1.0.2) 8 | i18n (>= 0.7, < 2) 9 | minitest (~> 5.1) 10 | tzinfo (~> 1.1) 11 | addressable (2.8.5) 12 | public_suffix (>= 2.0.2, < 6.0) 13 | algoliasearch (1.27.5) 14 | httpclient (~> 2.8, >= 2.8.3) 15 | json (>= 1.5.1) 16 | atomos (0.1.3) 17 | claide (1.1.0) 18 | clamp (1.3.2) 19 | cocoapods (1.14.3) 20 | addressable (~> 2.8) 21 | claide (>= 1.0.2, < 2.0) 22 | cocoapods-core (= 1.14.3) 23 | cocoapods-deintegrate (>= 1.0.3, < 2.0) 24 | cocoapods-downloader (>= 2.1, < 3.0) 25 | cocoapods-plugins (>= 1.0.0, < 2.0) 26 | cocoapods-search (>= 1.0.0, < 2.0) 27 | cocoapods-trunk (>= 1.6.0, < 2.0) 28 | cocoapods-try (>= 1.1.0, < 2.0) 29 | colored2 (~> 3.1) 30 | escape (~> 0.0.4) 31 | fourflusher (>= 2.3.0, < 3.0) 32 | gh_inspector (~> 1.0) 33 | molinillo (~> 0.8.0) 34 | nap (~> 1.0) 35 | ruby-macho (>= 2.3.0, < 3.0) 36 | xcodeproj (>= 1.23.0, < 2.0) 37 | cocoapods-core (1.14.3) 38 | activesupport (>= 5.0, < 8) 39 | addressable (~> 2.8) 40 | algoliasearch (~> 1.0) 41 | concurrent-ruby (~> 1.1) 42 | fuzzy_match (~> 2.0.4) 43 | nap (~> 1.0) 44 | netrc (~> 0.11) 45 | public_suffix (~> 4.0) 46 | typhoeus (~> 1.0) 47 | cocoapods-deintegrate (1.0.5) 48 | cocoapods-downloader (2.1) 49 | cocoapods-plugins (1.0.0) 50 | nap 51 | cocoapods-search (1.0.1) 52 | cocoapods-trunk (1.6.0) 53 | nap (>= 0.8, < 2.0) 54 | netrc (~> 0.11) 55 | cocoapods-try (1.2.0) 56 | colored2 (3.1.2) 57 | concurrent-ruby (1.2.2) 58 | escape (0.0.4) 59 | ethon (0.16.0) 60 | ffi (>= 1.15.0) 61 | ffi (1.16.3) 62 | fourflusher (2.3.1) 63 | fuzzy_match (2.0.4) 64 | gh_inspector (1.1.3) 65 | httpclient (2.8.3) 66 | i18n (1.14.1) 67 | concurrent-ruby (~> 1.0) 68 | json (2.6.3) 69 | mini_portile2 (2.5.0) 70 | minitest (5.15.0) 71 | molinillo (0.8.0) 72 | nanaimo (0.3.0) 73 | nap (1.1.0) 74 | netrc (0.11.0) 75 | nokogiri (1.11.1) 76 | mini_portile2 (~> 2.5.0) 77 | racc (~> 1.4) 78 | public_suffix (4.0.7) 79 | racc (1.5.2) 80 | rexml (3.2.6) 81 | rouge (2.0.7) 82 | ruby-macho (2.5.1) 83 | slather (2.6.1) 84 | CFPropertyList (>= 2.2, < 4) 85 | activesupport 86 | clamp (~> 1.3) 87 | nokogiri (~> 1.11) 88 | xcodeproj (~> 1.7) 89 | thread_safe (0.3.6) 90 | typhoeus (1.4.1) 91 | ethon (>= 0.9.0) 92 | tzinfo (1.2.11) 93 | thread_safe (~> 0.1) 94 | xcodeproj (1.23.0) 95 | CFPropertyList (>= 2.3.3, < 4.0) 96 | atomos (~> 0.1.3) 97 | claide (>= 1.0.2, < 2.0) 98 | colored2 (~> 3.1) 99 | nanaimo (~> 0.3.0) 100 | rexml (~> 3.2.4) 101 | xcpretty (0.3.0) 102 | rouge (~> 2.0.7) 103 | 104 | PLATFORMS 105 | ruby 106 | 107 | DEPENDENCIES 108 | cocoapods (~> 1.14.2) 109 | slather 110 | xcpretty 111 | 112 | BUNDLED WITH 113 | 2.2.27 114 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Metova Inc. 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Package.swift 3 | // DataManager 4 | // 5 | // Copyright (c) 2016 Metova Inc. 6 | // 7 | // MIT License 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining 10 | // a copy of this software and associated documentation files (the 11 | // "Software"), to deal in the Software without restriction, including 12 | // without limitation the rights to use, copy, modify, merge, publish, 13 | // distribute, sublicense, and/or sell copies of the Software, and to 14 | // permit persons to whom the Software is furnished to do so, subject to 15 | // the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be 18 | // included in all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 24 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 25 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 26 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | // 28 | // swift-tools-version:5.3 29 | 30 | import PackageDescription 31 | 32 | let package = Package( 33 | name: "DataManager" 34 | ) 35 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '12.0' 2 | 3 | abstract_target 'DataManager' do 4 | 5 | pod 'SwiftLint' 6 | 7 | target 'DataManager iOS' do 8 | target 'DataManager iOS Tests' do 9 | inherit! :search_paths 10 | end 11 | end 12 | 13 | target 'DataManager OSX' do 14 | target 'DataManager OSX Tests' do 15 | inherit! :search_paths 16 | end 17 | end 18 | 19 | target 'DataManager tvOS' do 20 | target 'DataManager tvOS Tests' do 21 | inherit! :search_paths 22 | end 23 | end 24 | 25 | target 'DataManager watchOS' do 26 | end 27 | end 28 | 29 | post_install do |installer| 30 | installer.generated_projects.each do |project| 31 | project.targets.each do |target| 32 | target.build_configurations.each do |config| 33 | config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0' 34 | end 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - SwiftLint (0.42.0) 3 | 4 | DEPENDENCIES: 5 | - SwiftLint 6 | 7 | SPEC REPOS: 8 | trunk: 9 | - SwiftLint 10 | 11 | SPEC CHECKSUMS: 12 | SwiftLint: 4fa9579c63416865179bc416f0a92d55f009600d 13 | 14 | PODFILE CHECKSUM: 741bf09c15b4ff9df0e64dda3cf52a164db0051b 15 | 16 | COCOAPODS: 1.14.3 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![DataManager](header_logo.png) 2 | 3 | [![Build Status](https://travis-ci.org/metova/DataManager.svg)](https://travis-ci.org/metova/DataManager?branch=master) 4 | [![CocoaPods Compatible](https://img.shields.io/cocoapods/v/DataManager.svg)](https://img.shields.io/cocoapods/v/DataManager.svg) 5 | [![Documentation](https://img.shields.io/cocoapods/metrics/doc-percent/DataManager.svg)](http://cocoadocs.org/docsets/DataManager/) 6 | [![Coverage Status](https://coveralls.io/repos/github/metova/DataManager/badge.svg?branch=master)](https://coveralls.io/github/metova/DataManager?branch=master) 7 | [![Platform](https://img.shields.io/cocoapods/p/DataManager.svg?style=flat)](http://cocoadocs.org/docsets/DataManager) 8 | [![Twitter](https://img.shields.io/badge/twitter-@Metova-3CAC84.svg)](http://twitter.com/metova) 9 | 10 | DataManager is a lightweight Core Data utility. It is not a replacement/wrapper for Core Data. Here are some of the highlights: 11 | 12 | - Encapsulates the boilerplate associated with setting up the Core Data stack. 13 | - Sets up the stack with a private `NSPrivateQueueConcurrencyType` context as the root context with a public `NSMainQueueConcurrencyType` child context. This setup allows for asynchronous saves to disk. 14 | - Provides Swift-friendly convenience fetching methods that make use of generics to prevent you from having to handle downcasting from `NSManagedObject` to the entity's class every time you perform a fetch. 15 | 16 | ## Requirements 17 | 18 | - iOS 12.0 19 | - Swift 5.0 20 | 21 | ## Installation 22 | 23 | DataManager is available through [CocoaPods](http://cocoapods.org). To install it, simply add the following line to your Podfile: 24 | 25 | ```ruby 26 | pod 'DataManager' 27 | ``` 28 | 29 | If you would like to test a beta version of DataManager, you can install the latest from develop: 30 | 31 | ```ruby 32 | pod 'DataManager', :git => 'https://github.com/metova/DataManager.git', :branch => 'develop' 33 | ``` 34 | 35 | ## Usage 36 | 37 | #### Setup 38 | 39 | When your app is launched, set up `DataManager` with the data model name and a name for the persistent store file: 40 | ```swift 41 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 42 | 43 | DataManager.setUp(withDataModelName: "MyApp", bundle: .main, persistentStoreName: "MyApp") 44 | 45 | /* ... */ 46 | 47 | return true 48 | } 49 | ``` 50 | 51 | This won't set up the Core Data stack right away. The stack is lazy loaded when `DataManager.mainContext` is first used. 52 | 53 | #### Fetching 54 | 55 | DataManager uses generics so you don't have to worry about casting the `NSManagedObject` results to the entity's class every time you perform a fetch. For example, the type of `olderUsers` below is `[User]`. 56 | 57 | ```swift 58 | let predicate = NSPredicate(format: "\(#keyPath(Person.birthDate)) < %@", someDate) 59 | let olderUsers = DataManager.fetchObjects(entity: User.self, predicate: predicate, context: DataManager.mainContext) 60 | ``` 61 | 62 | #### Deleting 63 | 64 | ```swift 65 | DataManager.delete([user1, user2], in: DataManager.mainContext) 66 | ``` 67 | 68 | #### Saving 69 | 70 | ```swift 71 | DataManager.persist(synchronously: false) 72 | ``` 73 | 74 | #### Child Contexts 75 | 76 | ```swift 77 | let backgroundContext = DataManager.createChildContext(withParent: DataManager.mainContext) 78 | 79 | backgroundContext.perform { 80 | /* Do heavy lifting in the background */ 81 | } 82 | ``` 83 | 84 | ## Credits 85 | 86 | DataManager is owned and maintained by [Metova Inc.](https://metova.com) 87 | 88 | [Contributors](https://github.com/Metova/DataManager/graphs/contributors) 89 | 90 | ## License 91 | 92 | DataManager is available under the MIT license. See the [LICENSE](LICENSE) file for more info. 93 | 94 | ## Alternatives 95 | 96 | - [CoreDataMate](https://github.com/groomsy/coredatamate) by [Todd Grooms](https://github.com/groomsy) is essentially the original Objective-C version that DataManager evolved from. 97 | -------------------------------------------------------------------------------- /Sources/DataManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // DataManager.h 3 | // DataManager 4 | // 5 | // Copyright (c) 2016 Metova Inc. 6 | // 7 | // MIT License 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining 10 | // a copy of this software and associated documentation files (the 11 | // "Software"), to deal in the Software without restriction, including 12 | // without limitation the rights to use, copy, modify, merge, publish, 13 | // distribute, sublicense, and/or sell copies of the Software, and to 14 | // permit persons to whom the Software is furnished to do so, subject to 15 | // the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be 18 | // included in all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 24 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 25 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 26 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | // 28 | 29 | @import Foundation; 30 | 31 | FOUNDATION_EXPORT double DataManagerVersionNumber; 32 | FOUNDATION_EXPORT const unsigned char DataManagerVersionString[]; 33 | -------------------------------------------------------------------------------- /Sources/DataManager.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DataManager.swift 3 | // DataManager 4 | // 5 | // Copyright (c) 2016 Metova Inc. 6 | // 7 | // MIT License 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining 10 | // a copy of this software and associated documentation files (the 11 | // "Software"), to deal in the Software without restriction, including 12 | // without limitation the rights to use, copy, modify, merge, publish, 13 | // distribute, sublicense, and/or sell copies of the Software, and to 14 | // permit persons to whom the Software is furnished to do so, subject to 15 | // the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be 18 | // included in all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 24 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 25 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 26 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | // 28 | 29 | import Foundation 30 | import CoreData 31 | 32 | // MARK: - PersistentStoreType 33 | 34 | /// An enumeration of the three string constants that are used for specifying the persistent store type (NSSQLiteStoreType, NSBinaryStoreType, NSInMemoryStoreType). 35 | public enum PersistentStoreType { 36 | 37 | /// Represents the value for NSSQLiteStoreType. 38 | case sqLite 39 | 40 | /// Represents the value for NSBinaryStoreType. 41 | case binary 42 | 43 | /// Represents the value for NSInMemoryStoreType. 44 | case inMemory 45 | 46 | /// Value of the Core Data string constants corresponding to each case. 47 | var stringValue: String { 48 | switch self { 49 | case .sqLite: 50 | return NSSQLiteStoreType 51 | case .binary: 52 | return NSBinaryStoreType 53 | case .inMemory: 54 | return NSInMemoryStoreType 55 | } 56 | } 57 | 58 | @available(iOS 15.0, *) 59 | var storeType: NSPersistentStore.StoreType { 60 | switch self { 61 | case .sqLite: 62 | return .sqlite 63 | case .binary: 64 | return .binary 65 | case .inMemory: 66 | return .inMemory 67 | } 68 | } 69 | } 70 | 71 | // MARK: - Logger 72 | 73 | /** 74 | * Defines requirements for a logger that DataManager can use to log errors. 75 | */ 76 | public protocol DataManagerErrorLogger { 77 | 78 | /** 79 | This method is called when DataManager catches a thrown error internally. Custom loggers may have this method print to the console or write to a file. 80 | 81 | - parameter error: The error that was thrown. 82 | - parameter file: The file from which the error logging method was called from. 83 | - parameter function: The function from which the error logging method was called from. 84 | - parameter line: The line number in the file from which the error logging method was called from. 85 | */ 86 | func log(error: NSError, file: StaticString, function: StaticString, line: UInt) 87 | } 88 | 89 | // MARK: - DefaultLogger 90 | 91 | private class DefaultLogger: DataManagerErrorLogger { 92 | 93 | func log(error: NSError, file: StaticString, function: StaticString, line: UInt) { 94 | 95 | print("[DataManager - \(function) line \(line)] Error: \(error.localizedDescription)") 96 | } 97 | } 98 | 99 | // MARK: - Constants 100 | 101 | private struct Constants { 102 | 103 | static fileprivate let mustCallSetupMethodErrorMessage = "DataManager must be set up using setUp(withDataModelName:bundle:persistentStoreType:) before it can be used." 104 | } 105 | 106 | // MARK: - DataManager 107 | 108 | /** 109 | Responsible for setting up the Core Data stack. Also provides some convenience methods for fetching, deleting, and saving. 110 | */ 111 | public final class DataManager { 112 | 113 | // MARK: Properties 114 | 115 | private static var dataModelName: String? 116 | private static var dataModelBundle: Bundle? 117 | private static var persistentStoreName: String? 118 | private static var persistentStoreType = PersistentStoreType.sqLite 119 | private static var groupIdentifier: String? 120 | 121 | /// The logger to use for logging errors caught internally. A default logger is used if a custom one isn't provided. Assigning nil to this property prevents DataManager from emitting any logs to the console. 122 | public static var errorLogger: DataManagerErrorLogger? = DefaultLogger() 123 | 124 | /// The value to use for `fetchBatchSize` when fetching objects. 125 | public static var defaultFetchBatchSize = 0 126 | 127 | // MARK: Setup 128 | 129 | /** 130 | This method must be called before DataManager can be used. It provides DataManager with the required information for setting up the Core Data stack. Call this in application(_:didFinishLaunchingWithOptions:). 131 | 132 | - parameter dataModelName: The name of the data model schema file. 133 | - parameter bundle: The bundle in which the data model schema file resides. 134 | - parameter persistentStoreName: The name of the persistent store. 135 | - parameter persistentStoreType: The persistent store type. Defaults to SQLite. 136 | - parameter groupIdentifier: The App-Group identifier if exist. Defaults to nil. 137 | */ 138 | public static func setUp(withDataModelName dataModelName: String, bundle: Bundle, persistentStoreName: String, persistentStoreType: PersistentStoreType = .sqLite, groupIdentifier: String? = nil) { 139 | 140 | DataManager.dataModelName = dataModelName 141 | DataManager.dataModelBundle = bundle 142 | DataManager.persistentStoreName = persistentStoreName 143 | DataManager.persistentStoreType = persistentStoreType 144 | DataManager.groupIdentifier = groupIdentifier 145 | } 146 | 147 | // MARK: Core Data Stack 148 | 149 | private static var applicationDocumentsDirectory: URL = { 150 | 151 | // If present, create URL using App-Group identifier 152 | if let groupIdentifier = DataManager.groupIdentifier, 153 | let url = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: groupIdentifier) { 154 | return url 155 | } 156 | 157 | let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) 158 | return urls[urls.count - 1] 159 | }() 160 | 161 | private static var managedObjectModel: NSManagedObjectModel = { 162 | 163 | guard let dataModelName = DataManager.dataModelName else { 164 | fatalError("Attempting to use nil data model name. \(Constants.mustCallSetupMethodErrorMessage)") 165 | } 166 | 167 | guard let modelURL = DataManager.dataModelBundle?.url(forResource: DataManager.dataModelName, withExtension: "momd") else { 168 | fatalError("Failed to locate data model schema file.") 169 | } 170 | 171 | guard let managedObjectModel = NSManagedObjectModel(contentsOf: modelURL) else { 172 | fatalError("Failed to created managed object model") 173 | } 174 | 175 | return managedObjectModel 176 | }() 177 | 178 | private static var persistentStoreCoordinator: NSPersistentStoreCoordinator = { 179 | 180 | guard let persistentStoreName = DataManager.persistentStoreName else { 181 | fatalError("Attempting to use nil persistent store name. \(Constants.mustCallSetupMethodErrorMessage)") 182 | } 183 | 184 | let coordinator = NSPersistentStoreCoordinator(managedObjectModel: DataManager.managedObjectModel) 185 | let url = DataManager.applicationDocumentsDirectory.appendingPathComponent("\(persistentStoreName).sqlite") 186 | 187 | let options = [ 188 | NSMigratePersistentStoresAutomaticallyOption: true, 189 | NSInferMappingModelAutomaticallyOption: true 190 | ] 191 | 192 | do { 193 | if #available(iOS 15.0, *) { 194 | _ = try coordinator.addPersistentStore(type: DataManager.persistentStoreType.storeType, configuration: nil, at: url, options: options) 195 | } else { 196 | try coordinator.addPersistentStore(ofType: DataManager.persistentStoreType.stringValue, configurationName: nil, at: url, options: options) 197 | } 198 | } 199 | catch let error as NSError { 200 | fatalError("Failed to initialize the application's persistent data: \(error.localizedDescription)") 201 | } 202 | catch { 203 | fatalError("Failed to initialize the application's persistent data") 204 | } 205 | 206 | return coordinator 207 | }() 208 | 209 | static var privateContext: NSManagedObjectContext = { 210 | 211 | let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType) 212 | context.persistentStoreCoordinator = DataManager.persistentStoreCoordinator 213 | return context 214 | }() 215 | 216 | /// A MainQueueConcurrencyType context whose parent is a PrivateQueueConcurrencyType context. The PrivateQueueConcurrencyType context is the root context. 217 | public static var mainContext: NSManagedObjectContext = { 218 | 219 | let context = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType) 220 | context.parent = DataManager.privateContext 221 | return context 222 | }() 223 | 224 | // MARK: Child Contexts 225 | 226 | /** 227 | Creates a private queue concurrency type context that is the child of the specified parent context. 228 | 229 | - parameter parentContext: The context to act as the parent of the returned context. 230 | 231 | - returns: A private queue concurrency type context that is the child of the specified parent context. 232 | */ 233 | public static func createChildContext(withParent parent: NSManagedObjectContext) -> NSManagedObjectContext { 234 | 235 | let managedObjectContext = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType) 236 | managedObjectContext.parent = parent 237 | return managedObjectContext 238 | } 239 | 240 | // MARK: Fetching 241 | 242 | /** 243 | This is a convenience method for performing a fetch request. Note: Errors thrown by executeFetchRequest are suppressed and logged in order to make usage less verbose. If detecting thrown errors is needed in your use case, you will need to use Core Data directly. 244 | 245 | - parameter entity: The NSManagedObject subclass to be fetched. 246 | - parameter predicate: A predicate to use for the fetch if needed (defaults to nil). 247 | - parameter sortDescriptors: Sort descriptors to use for the fetch if needed (defaults to nil). 248 | - parameter context: The NSManagedObjectContext to perform the fetch with. 249 | 250 | - returns: A typed array containing the results. If executeFetchRequest throws an error, an empty array is returned. 251 | */ 252 | public static func fetchObjects(entity: T.Type, predicate: NSPredicate? = nil, sortDescriptors: [NSSortDescriptor]? = nil, context: NSManagedObjectContext) -> [T] { 253 | 254 | let request = NSFetchRequest(entityName: String(describing: entity)) 255 | request.predicate = predicate 256 | request.sortDescriptors = sortDescriptors 257 | request.fetchBatchSize = defaultFetchBatchSize 258 | 259 | do { 260 | return try context.fetch(request) 261 | } 262 | catch let error as NSError { 263 | log(error: error) 264 | return [T]() 265 | } 266 | } 267 | 268 | /** 269 | This is a convenience method for performing a fetch request that fetches a single object. Note: Errors thrown by executeFetchRequest are suppressed and logged in order to make usage less verbose. If detecting thrown errors is needed in your use case, you will need to use Core Data directly. 270 | 271 | - parameter entity: The NSManagedObject subclass to be fetched. 272 | - parameter predicate: A predicate to use for the fetch if needed (defaults to nil). 273 | - parameter sortDescriptors: Sort descriptors to use for the fetch if needed (defaults to nil). 274 | - parameter context: The NSManagedObjectContext to perform the fetch with. 275 | 276 | - returns: A typed result if found. If executeFetchRequest throws an error, nil is returned. 277 | */ 278 | public static func fetchObject(entity: T.Type, predicate: NSPredicate? = nil, sortDescriptors: [NSSortDescriptor]? = nil, context: NSManagedObjectContext) -> T? { 279 | 280 | let request = NSFetchRequest(entityName: String(describing: entity)) 281 | 282 | request.predicate = predicate 283 | request.sortDescriptors = sortDescriptors 284 | request.fetchLimit = 1 285 | 286 | do { 287 | return try context.fetch(request).first 288 | } 289 | catch let error as NSError { 290 | log(error: error) 291 | return nil 292 | } 293 | } 294 | 295 | // MARK: Deleting 296 | 297 | /** 298 | Iterates over the objects and deletes them using the supplied context. 299 | 300 | - parameter objects: The objects to delete. 301 | - parameter context: The context to perform the deletion with. 302 | */ 303 | public static func delete(_ objects: [NSManagedObject], in context: NSManagedObjectContext) { 304 | 305 | for object in objects { 306 | context.delete(object) 307 | } 308 | } 309 | 310 | /** 311 | For each entity in the model, fetches all objects into memory, iterates over each object and deletes them using the main context. Note: Errors thrown by executeFetchRequest are suppressed and logged in order to make usage less verbose. If detecting thrown errors is needed in your use case, you will need to use Core Data directly. 312 | */ 313 | public static func deleteAllObjects() { 314 | 315 | for entityName in managedObjectModel.entitiesByName.keys { 316 | 317 | let request = NSFetchRequest(entityName: entityName) 318 | request.includesPropertyValues = false 319 | 320 | do { 321 | for object in try mainContext.fetch(request) { 322 | mainContext.delete(object) 323 | } 324 | } 325 | catch let error as NSError { 326 | log(error: error) 327 | } 328 | } 329 | } 330 | 331 | // MARK: Saving 332 | 333 | /** 334 | Saves changes to the persistent store. 335 | 336 | - parameter synchronously: Whether the main thread should block while writing to the persistent store or not. 337 | - parameter completion: Called after the save on the private context completes. If there is an error, it is called immediately and the error parameter is populated. 338 | */ 339 | public static func persist(synchronously: Bool, completion: ((NSError?) -> Void)? = nil) { 340 | 341 | var mainContextSaveError: NSError? 342 | 343 | if mainContext.hasChanges { 344 | mainContext.performAndWait { 345 | do { 346 | try self.mainContext.save() 347 | } 348 | catch let error as NSError { 349 | mainContextSaveError = error 350 | } 351 | } 352 | } 353 | 354 | guard mainContextSaveError == nil else { 355 | completion?(mainContextSaveError) 356 | return 357 | } 358 | 359 | func savePrivateContext() { 360 | do { 361 | try privateContext.save() 362 | completion?(nil) 363 | } 364 | catch let error as NSError { 365 | completion?(error) 366 | } 367 | } 368 | 369 | if privateContext.hasChanges { 370 | if synchronously { 371 | privateContext.performAndWait(savePrivateContext) 372 | } 373 | else { 374 | privateContext.perform(savePrivateContext) 375 | } 376 | } 377 | } 378 | 379 | // MARK: Logging 380 | 381 | private static func log(error: NSError, file: StaticString = #file, function: StaticString = #function, line: UInt = #line) { 382 | 383 | errorLogger?.log(error: error, file: file, function: function, line: line) 384 | } 385 | } 386 | -------------------------------------------------------------------------------- /Sources/Info-tvOS.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Sources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Tests/DataManagerTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DataManagerTests.swift 3 | // DataManagerTests 4 | // 5 | // Created by Logan Gauthier on 3/31/16. 6 | // Copyright © 2016 Metova. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import CoreData 11 | @testable import DataManager 12 | 13 | class DataManagerTests: XCTestCase { 14 | 15 | // MARK: - Set Up / Tear Down 16 | 17 | override func setUp() { 18 | 19 | super.setUp() 20 | 21 | DataManager.setUp(withDataModelName: "TestModel", bundle: Bundle(for: DataManagerTests.self), persistentStoreName: "Test", persistentStoreType: .inMemory) 22 | } 23 | 24 | override func tearDown() { 25 | 26 | DataManager.deleteAllObjects() 27 | 28 | super.tearDown() 29 | } 30 | 31 | // MARK: Helper 32 | 33 | func createTestPerson(name: String = "Test Person", birthDate: Date = Date(timeIntervalSince1970: 0)) -> Person { 34 | 35 | return Person(context: DataManager.mainContext, name: name, birthDate: birthDate) 36 | } 37 | 38 | func createTestGroup(title: String = "Test Group") -> Group { 39 | 40 | return Group(context: DataManager.mainContext, title: title) 41 | } 42 | 43 | // MARK: - Tests 44 | // MARK: Child Context Creation 45 | 46 | func testCreatingChildContext() { 47 | 48 | let childContext = DataManager.createChildContext(withParent: DataManager.mainContext) 49 | 50 | XCTAssertEqual(childContext.concurrencyType, NSManagedObjectContextConcurrencyType.privateQueueConcurrencyType) 51 | XCTAssertTrue(childContext.parent === DataManager.mainContext) 52 | } 53 | 54 | // MARK: Fetch Single Object 55 | 56 | func testFetchingSingleObjectWithSortDescriptor() { 57 | 58 | let person1 = createTestPerson(birthDate: Date(timeIntervalSince1970: 0)) 59 | let person2 = createTestPerson(birthDate: Date(timeIntervalSince1970: 1)) 60 | 61 | let ascendingSortDescriptor = NSSortDescriptor(key: #keyPath(Person.birthDate), ascending: true) 62 | let descendingSortDescriptor = NSSortDescriptor(key: #keyPath(Person.birthDate), ascending: false) 63 | 64 | let olderPerson = DataManager.fetchObject(entity: Person.self, sortDescriptors: [ascendingSortDescriptor], context: DataManager.mainContext) 65 | 66 | XCTAssertNotNil(olderPerson, "Failed to fetch a single Person.") 67 | XCTAssertTrue(person1 === olderPerson, "Fetched incorrect Person.") 68 | 69 | let youngerPerson = DataManager.fetchObject(entity: Person.self, sortDescriptors: [descendingSortDescriptor], context: DataManager.mainContext) 70 | 71 | XCTAssertNotNil(youngerPerson, "Failed to fetch a single Person.") 72 | XCTAssertTrue(person2 === youngerPerson, "Fetched incorrect Person.") 73 | } 74 | 75 | func testFetchingSingleObjectWithPredicate() { 76 | 77 | let person = createTestPerson(name: "Logan Gauthier") 78 | _ = createTestPerson() 79 | 80 | let predicate = NSPredicate(format: "\(#keyPath(Person.name)) == %@", "Logan Gauthier") 81 | 82 | let fetchedPerson = DataManager.fetchObject(entity: Person.self, predicate: predicate, context: DataManager.mainContext) 83 | 84 | XCTAssertNotNil(fetchedPerson, "Failed to fetch a single Person.") 85 | XCTAssertTrue(person === fetchedPerson, "Fetched incorrect Person.") 86 | } 87 | 88 | func testFetchingSingleObjectsForThrownError() { 89 | 90 | executeTestWithErrorThrowingExecuteFetchRequestMock(contextToSwizzle: DataManager.mainContext) { 91 | 92 | _ = self.createTestPerson() 93 | 94 | let fetchedPerson = DataManager.fetchObject(entity: Person.self, context: DataManager.mainContext) 95 | 96 | XCTAssertNil(fetchedPerson, "When an error is thrown, it should be caught and nil should be returned.") 97 | } 98 | } 99 | 100 | func testErrorsAreLoggedWhenFetchingSingleObject() { 101 | 102 | executeTestWithErrorThrowingExecuteFetchRequestMock(contextToSwizzle: DataManager.mainContext) { 103 | 104 | let didLogError = self.isLogMethodExecutedInClosure { 105 | _ = DataManager.fetchObject(entity: Person.self, context: DataManager.mainContext) 106 | } 107 | 108 | XCTAssertTrue(didLogError, "Errors caught internally should be logged.") 109 | } 110 | } 111 | 112 | // MARK: Fetch Multiple Objects 113 | 114 | func testFetchingMultipleObjects() { 115 | 116 | let person1 = createTestPerson() 117 | let person2 = createTestPerson() 118 | 119 | let fetchedPeople = DataManager.fetchObjects(entity: Person.self, context: DataManager.mainContext) 120 | 121 | XCTAssertEqual(fetchedPeople.count, 2) 122 | XCTAssertTrue(fetchedPeople.contains(person1)) 123 | XCTAssertTrue(fetchedPeople.contains(person2)) 124 | } 125 | 126 | func testFetchingMultipleObjectsWithPredicate() { 127 | 128 | let person1 = createTestPerson() 129 | let person2 = createTestPerson() 130 | _ = createTestPerson(name: "Some Other Name") 131 | 132 | let predicate = NSPredicate(format: "\(#keyPath(Person.name)) == %@", "Test Person") 133 | 134 | let fetchedPeople = DataManager.fetchObjects(entity: Person.self, predicate: predicate, context: DataManager.mainContext) 135 | 136 | XCTAssertEqual(fetchedPeople.count, 2) 137 | XCTAssertTrue(fetchedPeople.contains(person1)) 138 | XCTAssertTrue(fetchedPeople.contains(person2)) 139 | } 140 | 141 | func testFetchingMultipleObjectsWithSortDescriptor() { 142 | 143 | let person1 = createTestPerson(birthDate: Date(timeIntervalSince1970: 0)) 144 | let person2 = createTestPerson(birthDate: Date(timeIntervalSince1970: 1)) 145 | 146 | let ascendingSortDescriptor = NSSortDescriptor(key: #keyPath(Person.birthDate), ascending: true) 147 | let descendingSortDescriptor = NSSortDescriptor(key: #keyPath(Person.birthDate), ascending: false) 148 | 149 | let fetchedPeopleAscending = DataManager.fetchObjects(entity: Person.self, sortDescriptors: [ascendingSortDescriptor], context: DataManager.mainContext) 150 | 151 | XCTAssertEqual(fetchedPeopleAscending.count, 2) 152 | XCTAssertTrue(fetchedPeopleAscending[0] === person1) 153 | XCTAssertTrue(fetchedPeopleAscending[1] === person2) 154 | 155 | let fetchedPeopleDescending = DataManager.fetchObjects(entity: Person.self, sortDescriptors: [descendingSortDescriptor], context: DataManager.mainContext) 156 | 157 | XCTAssertEqual(fetchedPeopleDescending.count, 2) 158 | XCTAssertTrue(fetchedPeopleDescending[0] === person2) 159 | XCTAssertTrue(fetchedPeopleDescending[1] === person1) 160 | } 161 | 162 | func testFetchingMultipleObjectsForThrownError() { 163 | 164 | executeTestWithErrorThrowingExecuteFetchRequestMock(contextToSwizzle: DataManager.mainContext) { 165 | 166 | _ = self.createTestPerson() 167 | _ = self.createTestPerson() 168 | 169 | let fetchedPeople = DataManager.fetchObjects(entity: Person.self, context: DataManager.mainContext) 170 | 171 | XCTAssertEqual(fetchedPeople.count, 0, "When an error is thrown, it should be caught and an empty array should be returned.") 172 | } 173 | } 174 | 175 | func testErrorsAreLoggedWhenFetchingMultipleObjects() { 176 | 177 | executeTestWithErrorThrowingExecuteFetchRequestMock(contextToSwizzle: DataManager.mainContext) { 178 | 179 | let didLogError = self.isLogMethodExecutedInClosure { 180 | _ = DataManager.fetchObjects(entity: Person.self, context: DataManager.mainContext) 181 | } 182 | 183 | XCTAssertTrue(didLogError, "Errors caught internally should be logged.") 184 | } 185 | } 186 | 187 | // MARK: Deleting 188 | 189 | func testDeletingObjects() { 190 | 191 | let person1 = createTestPerson() 192 | let person2 = createTestPerson() 193 | 194 | DataManager.persist(synchronously: true) 195 | DataManager.delete([person1, person2], in: DataManager.mainContext) 196 | 197 | XCTAssertTrue(person1.isDeleted) 198 | XCTAssertTrue(person2.isDeleted) 199 | } 200 | 201 | func testDeletingAllObjects() { 202 | 203 | let person1 = createTestPerson() 204 | let person2 = createTestPerson() 205 | let group1 = createTestGroup() 206 | let group2 = createTestGroup() 207 | 208 | DataManager.persist(synchronously: true) 209 | DataManager.deleteAllObjects() 210 | 211 | XCTAssertTrue(person1.isDeleted) 212 | XCTAssertTrue(person2.isDeleted) 213 | XCTAssertTrue(group1.isDeleted) 214 | XCTAssertTrue(group2.isDeleted) 215 | } 216 | 217 | func testErrorsAreLoggedWhenDeleting() { 218 | 219 | executeTestWithErrorThrowingExecuteFetchRequestMock(contextToSwizzle: DataManager.mainContext) { 220 | 221 | let didLogError = self.isLogMethodExecutedInClosure { 222 | DataManager.deleteAllObjects() 223 | } 224 | 225 | XCTAssertTrue(didLogError, "Errors caught internally should be logged.") 226 | } 227 | } 228 | 229 | // MARK: Persistence 230 | 231 | func testAsynchronousPersistence() { 232 | 233 | let person1 = createTestPerson() 234 | 235 | XCTAssertTrue(person1.managedObjectContext?.hasChanges == true) 236 | 237 | let expectation = self.expectation(description: "Expect private context to save asynchronously.") 238 | 239 | DataManager.persist(synchronously: false) { error in 240 | 241 | defer { expectation.fulfill() } 242 | 243 | guard let privateContext = person1.managedObjectContext?.parent else { 244 | XCTFail("Failed to obtain parent context from person.") 245 | return 246 | } 247 | 248 | XCTAssertFalse(privateContext.hasChanges) 249 | XCTAssertNil(error) 250 | } 251 | 252 | XCTAssertTrue(person1.managedObjectContext?.hasChanges == false) 253 | 254 | waitForExpectations(timeout: 5) { error in 255 | 256 | if let error = error { 257 | XCTFail("Private context failed to save. Expectation error: \(error.localizedDescription)") 258 | } 259 | } 260 | } 261 | 262 | func testSynchronousPersistence() { 263 | 264 | let person1 = createTestPerson() 265 | 266 | XCTAssertTrue(person1.managedObjectContext?.hasChanges == true) 267 | 268 | DataManager.persist(synchronously: true) 269 | 270 | XCTAssertTrue(person1.managedObjectContext?.hasChanges == false) 271 | XCTAssertTrue(person1.managedObjectContext?.parent?.hasChanges == false) 272 | } 273 | 274 | func testSavingForThrownError() { 275 | 276 | func assertErrorIsProvidedInCompletionClosure() { 277 | 278 | _ = createTestPerson() 279 | 280 | DataManager.persist(synchronously: true) { error in 281 | 282 | XCTAssertNotNil(error, "When executeFetchRequest(_:) throws an error, it should be passed in the completion closure.") 283 | } 284 | } 285 | 286 | executeTestWithErrorThrowingSaveMock(contextToSwizzle: DataManager.mainContext, test: assertErrorIsProvidedInCompletionClosure) 287 | executeTestWithErrorThrowingSaveMock(contextToSwizzle: DataManager.privateContext, test: assertErrorIsProvidedInCompletionClosure) 288 | } 289 | } 290 | -------------------------------------------------------------------------------- /Tests/Group+CoreDataProperties.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Group+CoreDataProperties.swift 3 | // DataManager 4 | // 5 | // Created by Logan Gauthier on 4/26/16. 6 | // Copyright © 2016 Metova. All rights reserved. 7 | // 8 | // Choose "Create NSManagedObject Subclass…" from the Core Data editor menu 9 | // to delete and recreate this implementation file for your updated model. 10 | // 11 | 12 | import Foundation 13 | import CoreData 14 | 15 | extension Group { 16 | 17 | @NSManaged var title: String? 18 | 19 | } 20 | -------------------------------------------------------------------------------- /Tests/Group.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Group.swift 3 | // DataManager 4 | // 5 | // Created by Logan Gauthier on 4/26/16. 6 | // Copyright © 2016 Metova. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import CoreData 11 | 12 | class Group: NSManagedObject { 13 | 14 | // MARK: Initialization 15 | 16 | convenience init(context: NSManagedObjectContext, title: String) { 17 | 18 | guard let entity = NSEntityDescription.entity(forEntityName: String(describing: Group.self), in: context) else { 19 | 20 | fatalError("Unable to get entity named \(String(describing: Group.self))") 21 | } 22 | 23 | self.init(entity: entity, insertInto: context) 24 | self.title = title 25 | } 26 | 27 | override init(entity: NSEntityDescription, insertInto context: NSManagedObjectContext?) { 28 | super.init(entity: entity, insertInto: context) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Tests/Info-tvOS.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Tests/MethodSwizzling.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MethodSwizzling.swift 3 | // DataManager 4 | // 5 | // Created by Logan Gauthier on 5/2/16. 6 | // Copyright © 2016 Metova. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | func swizzle(original selector: Selector, with newSelector: Selector, for classType: AnyClass) { 12 | 13 | guard 14 | let originalMethod = class_getInstanceMethod(classType, selector), 15 | let swizzledMethod = class_getInstanceMethod(classType, newSelector) 16 | else { 17 | assertionFailure("Swizzle failure - Failed to get one or both instance methods for \(selector) and \(newSelector) for class type \(String(describing: classType)).") 18 | return 19 | } 20 | 21 | let didAddMethod = class_addMethod(classType, selector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod)) 22 | 23 | if didAddMethod { 24 | class_replaceMethod(classType, newSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)) 25 | } 26 | else { 27 | method_exchangeImplementations(originalMethod, swizzledMethod) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Tests/NSManagedObjectContext+TestSwizzle.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NSManagedObjectContext+TestSwizzle.swift 3 | // DataManager 4 | // 5 | // Created by Logan Gauthier on 4/26/16. 6 | // Copyright © 2016 Metova. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import CoreData 11 | import XCTest 12 | 13 | /** 14 | Represents the behavior an NSManagedObjectContext should use when executing a swizzled method. 15 | 16 | - useOriginalMethod: The context should execute the original method and not use the swizzled version. 17 | - throwError: If the context is the same instance as the associated context, it should execute the swizzled code which throws a fake error. Otherwise, it should execute the original method. 18 | */ 19 | private enum ContextSwizzleBehavior { 20 | 21 | case useOriginalMethod 22 | case throwError(NSManagedObjectContext) 23 | } 24 | 25 | /// The behavior to use when executing the `fetch(_:)` method. 26 | private var executeFetchRequestMethodBehavior = ContextSwizzleBehavior.useOriginalMethod 27 | 28 | /// The behavior to use when executing the `save` method. 29 | private var saveMethodBehavior = ContextSwizzleBehavior.useOriginalMethod 30 | 31 | // MARK: - XCTestCase Extension 32 | 33 | extension XCTestCase { 34 | 35 | /** 36 | When this method is called, `contextToSwizzle` will throw an error whenever `fetch(_:)` is invoked inside the `test` closure. 37 | 38 | - parameter contextToSwizzle: The context that should exhibit the error throwing behavior. 39 | - parameter test: The test code. 40 | */ 41 | func executeTestWithErrorThrowingExecuteFetchRequestMock(contextToSwizzle: NSManagedObjectContext, test: () -> Void) { 42 | 43 | setUpSwizzling() 44 | executeFetchRequestMethodBehavior = .throwError(contextToSwizzle) 45 | test() 46 | executeFetchRequestMethodBehavior = .useOriginalMethod 47 | } 48 | 49 | /** 50 | When this method is called, `contextToSwizzle` will throw an error whenever `save` is invoked inside the `test` closure. 51 | 52 | - parameter contextToSwizzle: The context that should exhibit the error throwing behavior. 53 | - parameter test: The test code. 54 | */ 55 | func executeTestWithErrorThrowingSaveMock(contextToSwizzle: NSManagedObjectContext, test: () -> Void) { 56 | 57 | setUpSwizzling() 58 | saveMethodBehavior = .throwError(contextToSwizzle) 59 | test() 60 | saveMethodBehavior = .useOriginalMethod 61 | } 62 | 63 | /// Swizzle `NSManagedObjectContext`'s `fetch(_:)` and `save` methods in preparation for tests that require custom behavior. 64 | private func setUpSwizzling() { 65 | 66 | DispatchQueue.once(withToken: "NSManagedObjectContextSwizzle") { 67 | swizzle(original: #selector(NSManagedObjectContext.fetch(_:)), with: #selector(NSManagedObjectContext.dataManagerTestExecute(fetchRequest:)), for: NSManagedObjectContext.self) 68 | swizzle(original: #selector(NSManagedObjectContext.save), with: #selector(NSManagedObjectContext.dataManagerTestSave), for: NSManagedObjectContext.self) 69 | } 70 | } 71 | } 72 | 73 | // MARK: - DispatchQueue Extension 74 | 75 | extension DispatchQueue { 76 | 77 | private static var onceTracker = [String]() 78 | 79 | /** 80 | Executes a block of code, associated with a unique token, only once. The code is thread safe and will 81 | only execute the code once even in the presence of multithreaded calls. 82 | 83 | - parameter token: A unique token representing the action to execute once. 84 | - parameter onceAction: Action to execute once. 85 | */ 86 | class func once(withToken token: String, onceAction: () -> Void) { 87 | 88 | objc_sync_enter(self); defer { objc_sync_exit(self) } 89 | 90 | guard !onceTracker.contains(token) else { return } 91 | 92 | onceTracker.append(token) 93 | onceAction() 94 | } 95 | } 96 | 97 | // MARK: - NSManagedObjectContext Extension 98 | 99 | extension NSManagedObjectContext { 100 | 101 | // MARK: Swizzled Methods 102 | 103 | @objc func dataManagerTestExecute(fetchRequest: NSFetchRequest) throws -> [AnyObject] { 104 | 105 | switch executeFetchRequestMethodBehavior { 106 | case .throwError(let context) where context === self: 107 | throw NSError(domain: "DataManagerTests", code: 0, userInfo: nil) 108 | default: 109 | return try dataManagerTestExecute(fetchRequest: fetchRequest) 110 | } 111 | } 112 | 113 | @objc func dataManagerTestSave() throws { 114 | 115 | switch saveMethodBehavior { 116 | case .throwError(let context) where context === self: 117 | throw NSError(domain: "DataManagerTests", code: 0, userInfo: nil) 118 | default: 119 | return try dataManagerTestSave() 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /Tests/PersistentStoreTypeTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PersistentStoreTypeTests.swift 3 | // DataManager 4 | // 5 | // Created by Logan Gauthier on 4/26/16. 6 | // Copyright © 2016 Metova. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import CoreData 11 | 12 | @testable import DataManager 13 | 14 | class PersistentStoreTypeTests: XCTestCase { 15 | 16 | // MARK: Tests 17 | 18 | func testPersistentStoreTypeStringValues() { 19 | 20 | XCTAssertEqual(PersistentStoreType.sqLite.stringValue, NSSQLiteStoreType) 21 | XCTAssertEqual(PersistentStoreType.binary.stringValue, NSBinaryStoreType) 22 | XCTAssertEqual(PersistentStoreType.inMemory.stringValue, NSInMemoryStoreType) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Tests/Person+CoreDataProperties.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Person+CoreDataProperties.swift 3 | // DataManager 4 | // 5 | // Created by Logan Gauthier on 4/21/16. 6 | // Copyright © 2016 Metova. All rights reserved. 7 | // 8 | // Choose "Create NSManagedObject Subclass…" from the Core Data editor menu 9 | // to delete and recreate this implementation file for your updated model. 10 | // 11 | 12 | import Foundation 13 | import CoreData 14 | 15 | extension Person { 16 | 17 | @NSManaged var name: String? 18 | @NSManaged var birthDate: Date? 19 | 20 | } 21 | -------------------------------------------------------------------------------- /Tests/Person.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Person.swift 3 | // DataManager 4 | // 5 | // Created by Logan Gauthier on 4/21/16. 6 | // Copyright © 2016 Metova. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import CoreData 11 | 12 | class Person: NSManagedObject { 13 | 14 | // MARK: Initialization 15 | 16 | convenience init(context: NSManagedObjectContext, name: String, birthDate: Date) { 17 | 18 | guard let entity = NSEntityDescription.entity(forEntityName: String(describing: Person.self), in: context) else { 19 | 20 | fatalError("Unable to get entity named \(String(describing: Person.self))") 21 | } 22 | 23 | self.init(entity: entity, insertInto: context) 24 | self.name = name 25 | self.birthDate = birthDate 26 | } 27 | 28 | override init(entity: NSEntityDescription, insertInto context: NSManagedObjectContext?) { 29 | super.init(entity: entity, insertInto: context) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Tests/TestModel.xcdatamodeld/TestModel.xcdatamodel/contents: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Tests/XCTestCase+MockLogger.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DataManager+LogSwizzle.swift 3 | // DataManager 4 | // 5 | // Created by Logan Gauthier on 5/2/16. 6 | // Copyright © 2016 Metova. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import XCTest 11 | @testable import DataManager 12 | 13 | // MARK: XCTestCase Extension 14 | 15 | extension XCTestCase { 16 | 17 | func isLogMethodExecutedInClosure(_ closure: () -> Void) -> Bool { 18 | 19 | let originalLogger = DataManager.errorLogger 20 | let mockLogger = MockLogger() 21 | DataManager.errorLogger = mockLogger 22 | closure() 23 | DataManager.errorLogger = originalLogger 24 | return mockLogger.didExecuteLogMethod 25 | } 26 | } 27 | 28 | // MARK: MockLogger 29 | 30 | class MockLogger: DataManagerErrorLogger { 31 | 32 | var didExecuteLogMethod = false 33 | 34 | func log(error: NSError, file: StaticString, function: StaticString, line: UInt) { 35 | 36 | didExecuteLogMethod = true 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /header_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metova/DataManager/7ed06e54c78db6f75a2bdd3e5800dcb3f70e7cd4/header_logo.png --------------------------------------------------------------------------------