From 9b63002d2a771ee145751ecfabe2c7015d798ec2 Mon Sep 17 00:00:00 2001 From: Lukas Schmidt Date: Mon, 23 Dec 2019 08:59:11 +0100 Subject: [PATCH 01/17] Update README.md --- README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 67b0e76..d2303bd 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,6 @@ [![codecov](https://codecov.io/gh/dbsystel/DBNetworkStack/branch/develop/graph/badge.svg)](https://codecov.io/gh/dbsystel/DBNetworkStack) [![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) [![Swift Package Manager compatible](https://img.shields.io/badge/Swift%20Package%20Manager-compatible-brightgreen.svg)](https://github.com/apple/swift-package-manager) -[![Version](https://img.shields.io/cocoapods/v/DBNetworkStack.svg?style=flat)](http://cocoapods.org/pods/DBNetworkStack) | | Main Features | | --------- | ------------------------------ | @@ -95,6 +94,7 @@ The following table shows all the protocols and their default implementations. | -------------------------------- | ---------------------- | | ```RetryNetworkService``` | Retrys requests after a given delay when an error meets given criteria. | | ```ModifyRequestNetworkService``` | Modify matching requests. Can be used to add auth tokens or API Keys | +| ```NetworkServiceMock``` | Mocks a NetworkService. Can be use during unit tests | ## Requirements @@ -104,6 +104,16 @@ The following table shows all the protocols and their default implementations. ## Installation +### Swift Package Manager + +[SPM](https://swift.org/package-manager/) is integrated with the Swift build system to automate the process of downloading, compiling, and linking dependencies. + +Specify the following in your `Package.swift`: + +```swift +.package(url: "https://github.com/dbsystel/DBNetworkStack", from: "2.0.0"), +``` + ### Carthage [Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. From 846d040b9cacd76e780b783e7dca9e745d865ca2 Mon Sep 17 00:00:00 2001 From: Lukas Schmidt Date: Mon, 12 Apr 2021 17:14:40 +0200 Subject: [PATCH 02/17] expose Error init for stubbing --- Source/NetworkError.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/NetworkError.swift b/Source/NetworkError.swift index 0ba4f09..eb48cb8 100644 --- a/Source/NetworkError.swift +++ b/Source/NetworkError.swift @@ -40,11 +40,11 @@ public enum NetworkError: Error { /// Complete request failed. case requestError(error: Error) - init?(response: HTTPURLResponse?, data: Data?) { + public init?(response: HTTPURLResponse?, data: Data?) { guard let response = response else { return nil } - + switch response.statusCode { case 200..<300: return nil case 401: From 689ddf51e0bf30a873415243b2a305ca14532573 Mon Sep 17 00:00:00 2001 From: Lukas Schmidt Date: Mon, 12 Apr 2021 17:14:54 +0200 Subject: [PATCH 03/17] improves Void handling --- Source/Resource+Void.swift | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 Source/Resource+Void.swift diff --git a/Source/Resource+Void.swift b/Source/Resource+Void.swift new file mode 100644 index 0000000..7237e43 --- /dev/null +++ b/Source/Resource+Void.swift @@ -0,0 +1,19 @@ +// +// File.swift +// +// +// Created by Lukas Schmidt on 12.04.21. +// + +import Foundation + +public extension Resource where Model == Void { + + /// Creates an instace of Resource where the result type is `Void` + /// + /// - Parameters: + /// - request: The request to get the remote data payload + init(request: URLRequest) { + self.init(request: request, parse: { _ in }) + } +} From 7e87dc6e89c23589fb78de61e2423cd620d3ae92 Mon Sep 17 00:00:00 2001 From: Lukas Schmidt Date: Mon, 6 Sep 2021 16:13:00 +0200 Subject: [PATCH 04/17] Removes lots of project files --- DBNetworkStack.xcodeproj/project.pbxproj | 689 ------------------ .../contents.xcworkspacedata | 7 - .../xcshareddata/IDEWorkspaceChecks.plist | 8 - .../xcshareddata/WorkspaceSettings.xcsettings | 5 - .../xcschemes/DBNetworkStack.xcscheme | 100 --- .../xcdebugger/Breakpoints_v2.xcbkptlist | 5 - .../xcschemes/xcschememanagement.plist | 27 - .../contents.xcworkspacedata | 13 - .../xcshareddata/IDEWorkspaceChecks.plist | 8 - .../xcshareddata/WorkspaceSettings.xcsettings | 5 - JSONExample.playground/Contents.swift | 25 - JSONExample.playground/contents.xcplayground | 4 - SimpleDemo.playground/Contents.swift | 21 - SimpleDemo.playground/contents.xcplayground | 4 - Source/DBNetworkStack.h | 34 - Source/Info.plist | 26 - Source/NetworkTask.swift | 2 +- .../ContainerNetworkTaskTest.swift | 0 .../DecodableResoureTest.swift | 0 .../DefaultMocks.swift | 0 Tests/Info.plist | 24 - Tests/LinuxMain.swift | 35 - .../ModifyRequestNetworkService.swift | 0 .../NetworkAccessMock.swift | 0 .../NetworkErrorTest.swift | 0 .../NetworkResponseProcessorTest.swift | 0 .../NetworkServiceMockTest.swift | 0 .../NetworkServiceTest.swift | 0 .../NetworkTaskMockTests.swift | 0 .../ResourceInspectTest.swift | 0 .../ResourceTest.swift | 0 .../RetryNetworkserviceTest.swift | 0 .../TrainModel.swift | 0 .../URL+StaticStringInitTest.swift | 0 .../URLRequestTest.swift | 0 .../URLSession+NetworkAccessTest.swift | 0 .../URLSessionMock.swift | 0 37 files changed, 1 insertion(+), 1041 deletions(-) delete mode 100644 DBNetworkStack.xcodeproj/project.pbxproj delete mode 100644 DBNetworkStack.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 DBNetworkStack.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist delete mode 100644 DBNetworkStack.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings delete mode 100644 DBNetworkStack.xcodeproj/xcshareddata/xcschemes/DBNetworkStack.xcscheme delete mode 100644 DBNetworkStack.xcodeproj/xcuserdata/lukaslaschmidt.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist delete mode 100644 DBNetworkStack.xcodeproj/xcuserdata/lukaslaschmidt.xcuserdatad/xcschemes/xcschememanagement.plist delete mode 100644 DBNetworkStack.xcworkspace/contents.xcworkspacedata delete mode 100644 DBNetworkStack.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist delete mode 100644 DBNetworkStack.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings delete mode 100644 JSONExample.playground/Contents.swift delete mode 100644 JSONExample.playground/contents.xcplayground delete mode 100644 SimpleDemo.playground/Contents.swift delete mode 100644 SimpleDemo.playground/contents.xcplayground delete mode 100644 Source/DBNetworkStack.h delete mode 100644 Source/Info.plist rename Tests/{DBNetworkStackTests => }/ContainerNetworkTaskTest.swift (100%) rename Tests/{DBNetworkStackTests => }/DecodableResoureTest.swift (100%) rename Tests/{DBNetworkStackTests => }/DefaultMocks.swift (100%) delete mode 100644 Tests/Info.plist delete mode 100644 Tests/LinuxMain.swift rename Tests/{DBNetworkStackTests => }/ModifyRequestNetworkService.swift (100%) rename Tests/{DBNetworkStackTests => }/NetworkAccessMock.swift (100%) rename Tests/{DBNetworkStackTests => }/NetworkErrorTest.swift (100%) rename Tests/{DBNetworkStackTests => }/NetworkResponseProcessorTest.swift (100%) rename Tests/{DBNetworkStackTests => }/NetworkServiceMockTest.swift (100%) rename Tests/{DBNetworkStackTests => }/NetworkServiceTest.swift (100%) rename Tests/{DBNetworkStackTests => }/NetworkTaskMockTests.swift (100%) rename Tests/{DBNetworkStackTests => }/ResourceInspectTest.swift (100%) rename Tests/{DBNetworkStackTests => }/ResourceTest.swift (100%) rename Tests/{DBNetworkStackTests => }/RetryNetworkserviceTest.swift (100%) rename Tests/{DBNetworkStackTests => }/TrainModel.swift (100%) rename Tests/{DBNetworkStackTests => }/URL+StaticStringInitTest.swift (100%) rename Tests/{DBNetworkStackTests => }/URLRequestTest.swift (100%) rename Tests/{DBNetworkStackTests => }/URLSession+NetworkAccessTest.swift (100%) rename Tests/{DBNetworkStackTests => }/URLSessionMock.swift (100%) diff --git a/DBNetworkStack.xcodeproj/project.pbxproj b/DBNetworkStack.xcodeproj/project.pbxproj deleted file mode 100644 index 9d44b97..0000000 --- a/DBNetworkStack.xcodeproj/project.pbxproj +++ /dev/null @@ -1,689 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 7C235E0B1DBF6E8500628DC9 /* NetworkError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C235E0A1DBF6E8500628DC9 /* NetworkError.swift */; }; - 7C653BC91E09325500199993 /* NetworkResponseProcessorTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C653BC81E09325500199993 /* NetworkResponseProcessorTest.swift */; }; - C60425081D76F6F400FD3B38 /* NetworkAccess.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60425071D76F6F400FD3B38 /* NetworkAccess.swift */; }; - C604250A1D76F79F00FD3B38 /* BasicNetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60425091D76F79F00FD3B38 /* BasicNetworkService.swift */; }; - C60425131D7803CA00FD3B38 /* ResourceTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60425121D7803CA00FD3B38 /* ResourceTest.swift */; }; - C60BE65F1D6B2BF3006B0364 /* DBNetworkStack.h in Headers */ = {isa = PBXBuildFile; fileRef = C60BE65E1D6B2BF3006B0364 /* DBNetworkStack.h */; settings = {ATTRIBUTES = (Public, ); }; }; - C60BE6661D6B2BF3006B0364 /* DBNetworkStack.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C60BE65B1D6B2BF3006B0364 /* DBNetworkStack.framework */; }; - C60BE68D1D6B2C46006B0364 /* NetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60BE67D1D6B2C46006B0364 /* NetworkService.swift */; }; - C60BE68F1D6B2C46006B0364 /* HTTPMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60BE67F1D6B2C46006B0364 /* HTTPMethod.swift */; }; - C60BE6901D6B2C46006B0364 /* Resource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60BE6801D6B2C46006B0364 /* Resource.swift */; }; - C60BE6A31D6B3807006B0364 /* NetworkServiceTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60BE6A01D6B3807006B0364 /* NetworkServiceTest.swift */; }; - C60BE6AD1D6B3E81006B0364 /* NetworkTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60BE6AC1D6B3E81006B0364 /* NetworkTask.swift */; }; - C60FF0F31E5C94CD00818031 /* URLRequestTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60FF0F11E5C94AC00818031 /* URLRequestTest.swift */; }; - C61E77871E48CAFE00D55BB2 /* NetworkServiceMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6461F0A1E016C7700E0B081 /* NetworkServiceMock.swift */; }; - C61E77891E49A57A00D55BB2 /* NetworkServiceMockTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C61E77881E49A57A00D55BB2 /* NetworkServiceMockTest.swift */; }; - C61E778B1E49B53700D55BB2 /* RetryNetworkserviceTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C61E778A1E49B53700D55BB2 /* RetryNetworkserviceTest.swift */; }; - C61E778C1E49D8A900D55BB2 /* NetworkTaskMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C40B9FD1D9D66A600620563 /* NetworkTaskMock.swift */; }; - C622A7961E5C7F6500BB3D17 /* URLRequest+Init.swift in Sources */ = {isa = PBXBuildFile; fileRef = C622A7951E5C7F6500BB3D17 /* URLRequest+Init.swift */; }; - C62925AE1FC5900000607AEA /* URLRequest+Modifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = C62925AD1FC5900000607AEA /* URLRequest+Modifications.swift */; }; - C6363D8F1F4ED1500052E9BD /* URLSession+NetworkAccessTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6363D8D1F4ED13C0052E9BD /* URLSession+NetworkAccessTest.swift */; }; - C6363D901F4ED1950052E9BD /* URLSessionMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6363D8B1F4ED0840052E9BD /* URLSessionMock.swift */; }; - C6363D911F4ED2030052E9BD /* DefaultMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6C21A3A1F21FD150004A7EB /* DefaultMocks.swift */; }; - C6461F021E01678100E0B081 /* RetryNetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6461F011E01678100E0B081 /* RetryNetworkService.swift */; }; - C6576B6E21DDFD25009AC99C /* NetworkService+Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6576B6D21DDFD25009AC99C /* NetworkService+Result.swift */; }; - C65AA9A221185F68007529BF /* ContainerNetworkTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = C65AA9A121185F68007529BF /* ContainerNetworkTask.swift */; }; - C65AA9A52118723F007529BF /* ContainerNetworkTaskTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C65AA9A321187234007529BF /* ContainerNetworkTaskTest.swift */; }; - C66C7B961FE96CD0009B8C78 /* Resource+Inspect.swift in Sources */ = {isa = PBXBuildFile; fileRef = C66C7B951FE96CD0009B8C78 /* Resource+Inspect.swift */; }; - C66C7B991FE96F26009B8C78 /* ResourceInspectTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C66C7B971FE96EA8009B8C78 /* ResourceInspectTest.swift */; }; - C68FF1F51E1A64CB00A2513F /* Resource+Map.swift in Sources */ = {isa = PBXBuildFile; fileRef = C68FF1F41E1A64CB00A2513F /* Resource+Map.swift */; }; - C69188671EE6865E00BAD320 /* Resource+Decodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C69188661EE6865E00BAD320 /* Resource+Decodable.swift */; }; - C691886A1EE6897900BAD320 /* DecodableResoureTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C69188681EE688F700BAD320 /* DecodableResoureTest.swift */; }; - C699E0771D917501006FE7C6 /* NetworkErrorTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C699E0761D917501006FE7C6 /* NetworkErrorTest.swift */; }; - C6A5DED61D760E5000BC38B1 /* NetworkAccessMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6A5DED51D760E5000BC38B1 /* NetworkAccessMock.swift */; }; - C6A5DEDA1D76A06000BC38B1 /* TrainModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6A5DED91D76A06000BC38B1 /* TrainModel.swift */; }; - C6C21A391F21F90A0004A7EB /* NetworkResponseProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6C21A381F21F90A0004A7EB /* NetworkResponseProcessor.swift */; }; - C6C395941E04212F00413AD2 /* ModifyRequestNetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6C395931E04212F00413AD2 /* ModifyRequestNetworkService.swift */; }; - C6C395961E0422AF00413AD2 /* ModifyRequestNetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6C395951E0422AF00413AD2 /* ModifyRequestNetworkService.swift */; }; - C6E429721F70ECFF004121F1 /* URLSessionDataTask+NetworkTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6E429711F70ECFF004121F1 /* URLSessionDataTask+NetworkTask.swift */; }; - C6F235D51D7DA75000E628D8 /* URLSession+NetworkAccess.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6F235D41D7DA75000E628D8 /* URLSession+NetworkAccess.swift */; }; - C6F3A3FF211D665300BF0086 /* URL+StaticStringInit.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6F3A3FE211D665300BF0086 /* URL+StaticStringInit.swift */; }; - C6F3A402211D732C00BF0086 /* URL+StaticStringInitTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6F3A400211D732500BF0086 /* URL+StaticStringInitTest.swift */; }; - C6F7E3101E49DCBA00FA625F /* NetworkTaskMockTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6F7E30E1E49DC4900FA625F /* NetworkTaskMockTests.swift */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - C60BE6671D6B2BF3006B0364 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = C60BE6521D6B2BF3006B0364 /* Project object */; - proxyType = 1; - remoteGlobalIDString = C60BE65A1D6B2BF3006B0364; - remoteInfo = DBNetworkStack; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - 7C235E0A1DBF6E8500628DC9 /* NetworkError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkError.swift; sourceTree = ""; }; - 7C40B9FD1D9D66A600620563 /* NetworkTaskMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = NetworkTaskMock.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; - 7C653BC81E09325500199993 /* NetworkResponseProcessorTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkResponseProcessorTest.swift; sourceTree = ""; }; - C60425071D76F6F400FD3B38 /* NetworkAccess.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = NetworkAccess.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; - C60425091D76F79F00FD3B38 /* BasicNetworkService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = BasicNetworkService.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; - C60425121D7803CA00FD3B38 /* ResourceTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = ResourceTest.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; - C60BE65B1D6B2BF3006B0364 /* DBNetworkStack.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DBNetworkStack.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - C60BE65E1D6B2BF3006B0364 /* DBNetworkStack.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DBNetworkStack.h; sourceTree = ""; }; - C60BE6601D6B2BF3006B0364 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - C60BE6651D6B2BF3006B0364 /* DBNetworkStackTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DBNetworkStackTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - C60BE66C1D6B2BF3006B0364 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Source/Info.plist; sourceTree = ""; }; - C60BE67D1D6B2C46006B0364 /* NetworkService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = NetworkService.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; - C60BE67F1D6B2C46006B0364 /* HTTPMethod.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTTPMethod.swift; sourceTree = ""; }; - C60BE6801D6B2C46006B0364 /* Resource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = Resource.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; - C60BE6A01D6B3807006B0364 /* NetworkServiceTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = NetworkServiceTest.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; - C60BE6AC1D6B3E81006B0364 /* NetworkTask.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = NetworkTask.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; - C60FF0F11E5C94AC00818031 /* URLRequestTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLRequestTest.swift; sourceTree = ""; }; - C61E77881E49A57A00D55BB2 /* NetworkServiceMockTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkServiceMockTest.swift; sourceTree = ""; }; - C61E778A1E49B53700D55BB2 /* RetryNetworkserviceTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RetryNetworkserviceTest.swift; sourceTree = ""; }; - C622A7951E5C7F6500BB3D17 /* URLRequest+Init.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "URLRequest+Init.swift"; sourceTree = ""; }; - C62925AD1FC5900000607AEA /* URLRequest+Modifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URLRequest+Modifications.swift"; sourceTree = ""; }; - C6363D8B1F4ED0840052E9BD /* URLSessionMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLSessionMock.swift; sourceTree = ""; }; - C6363D8D1F4ED13C0052E9BD /* URLSession+NetworkAccessTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "URLSession+NetworkAccessTest.swift"; sourceTree = ""; }; - C6461F011E01678100E0B081 /* RetryNetworkService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RetryNetworkService.swift; sourceTree = ""; }; - C6461F0A1E016C7700E0B081 /* NetworkServiceMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkServiceMock.swift; sourceTree = ""; }; - C6576B6D21DDFD25009AC99C /* NetworkService+Result.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NetworkService+Result.swift"; sourceTree = ""; }; - C65AA9A121185F68007529BF /* ContainerNetworkTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContainerNetworkTask.swift; sourceTree = ""; }; - C65AA9A321187234007529BF /* ContainerNetworkTaskTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContainerNetworkTaskTest.swift; sourceTree = ""; }; - C66C7B951FE96CD0009B8C78 /* Resource+Inspect.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Resource+Inspect.swift"; sourceTree = ""; }; - C66C7B971FE96EA8009B8C78 /* ResourceInspectTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResourceInspectTest.swift; sourceTree = ""; }; - C68FF1F41E1A64CB00A2513F /* Resource+Map.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Resource+Map.swift"; sourceTree = ""; }; - C69188661EE6865E00BAD320 /* Resource+Decodable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Resource+Decodable.swift"; sourceTree = ""; }; - C69188681EE688F700BAD320 /* DecodableResoureTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DecodableResoureTest.swift; sourceTree = ""; }; - C699E0761D917501006FE7C6 /* NetworkErrorTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkErrorTest.swift; sourceTree = ""; }; - C6A5DED51D760E5000BC38B1 /* NetworkAccessMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = NetworkAccessMock.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; - C6A5DED91D76A06000BC38B1 /* TrainModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TrainModel.swift; sourceTree = ""; }; - C6C21A381F21F90A0004A7EB /* NetworkResponseProcessor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkResponseProcessor.swift; sourceTree = ""; }; - C6C21A3A1F21FD150004A7EB /* DefaultMocks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DefaultMocks.swift; sourceTree = ""; }; - C6C395931E04212F00413AD2 /* ModifyRequestNetworkService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ModifyRequestNetworkService.swift; sourceTree = ""; }; - C6C395951E0422AF00413AD2 /* ModifyRequestNetworkService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ModifyRequestNetworkService.swift; sourceTree = ""; }; - C6E429711F70ECFF004121F1 /* URLSessionDataTask+NetworkTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URLSessionDataTask+NetworkTask.swift"; sourceTree = ""; }; - C6F235D41D7DA75000E628D8 /* URLSession+NetworkAccess.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "URLSession+NetworkAccess.swift"; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; - C6F3A3FE211D665300BF0086 /* URL+StaticStringInit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+StaticStringInit.swift"; sourceTree = ""; }; - C6F3A400211D732500BF0086 /* URL+StaticStringInitTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+StaticStringInitTest.swift"; sourceTree = ""; }; - C6F7E30E1E49DC4900FA625F /* NetworkTaskMockTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkTaskMockTests.swift; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - C60BE6571D6B2BF3006B0364 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - C60BE6621D6B2BF3006B0364 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - C60BE6661D6B2BF3006B0364 /* DBNetworkStack.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - C60BE6511D6B2BF3006B0364 = { - isa = PBXGroup; - children = ( - C60BE65D1D6B2BF3006B0364 /* Source */, - C60BE6691D6B2BF3006B0364 /* Tests */, - C60BE66C1D6B2BF3006B0364 /* Info.plist */, - C60BE65C1D6B2BF3006B0364 /* Products */, - ); - sourceTree = ""; - }; - C60BE65C1D6B2BF3006B0364 /* Products */ = { - isa = PBXGroup; - children = ( - C60BE65B1D6B2BF3006B0364 /* DBNetworkStack.framework */, - C60BE6651D6B2BF3006B0364 /* DBNetworkStackTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - C60BE65D1D6B2BF3006B0364 /* Source */ = { - isa = PBXGroup; - children = ( - C6E5A4D11E2FBD1100F966DB /* NetworkService */, - C6E5A4D41E2FBD7700F966DB /* NetworkAccess */, - C6E5A4D01E2FBCF000F966DB /* Resource */, - C6E5A4D21E2FBD2B00F966DB /* NetworkRequest */, - C6E5A4D31E2FBD5800F966DB /* NetworkTask */, - C60BE67F1D6B2C46006B0364 /* HTTPMethod.swift */, - 7C235E0A1DBF6E8500628DC9 /* NetworkError.swift */, - C60BE65E1D6B2BF3006B0364 /* DBNetworkStack.h */, - C60BE6601D6B2BF3006B0364 /* Info.plist */, - ); - path = Source; - sourceTree = ""; - }; - C60BE6691D6B2BF3006B0364 /* Tests */ = { - isa = PBXGroup; - children = ( - C6A5DED81D76A05300BC38B1 /* Helpers */, - C6A5DED21D760C9E00BC38B1 /* Mocks */, - C6E5A4D51E2FBDDD00F966DB /* NetworkService */, - C6E5A4D61E2FBE0000F966DB /* Ressource */, - C6F7E30E1E49DC4900FA625F /* NetworkTaskMockTests.swift */, - C699E0761D917501006FE7C6 /* NetworkErrorTest.swift */, - 7C653BC81E09325500199993 /* NetworkResponseProcessorTest.swift */, - C60FF0F11E5C94AC00818031 /* URLRequestTest.swift */, - C6363D8D1F4ED13C0052E9BD /* URLSession+NetworkAccessTest.swift */, - C6F3A400211D732500BF0086 /* URL+StaticStringInitTest.swift */, - ); - name = Tests; - path = Tests/DBNetworkStackTests; - sourceTree = ""; - }; - C6A5DED21D760C9E00BC38B1 /* Mocks */ = { - isa = PBXGroup; - children = ( - C6A5DED51D760E5000BC38B1 /* NetworkAccessMock.swift */, - C6C21A3A1F21FD150004A7EB /* DefaultMocks.swift */, - C6363D8B1F4ED0840052E9BD /* URLSessionMock.swift */, - ); - name = Mocks; - sourceTree = ""; - }; - C6A5DED81D76A05300BC38B1 /* Helpers */ = { - isa = PBXGroup; - children = ( - C6A5DED91D76A06000BC38B1 /* TrainModel.swift */, - ); - name = Helpers; - sourceTree = ""; - }; - C6E5A4D01E2FBCF000F966DB /* Resource */ = { - isa = PBXGroup; - children = ( - C60BE6801D6B2C46006B0364 /* Resource.swift */, - C68FF1F41E1A64CB00A2513F /* Resource+Map.swift */, - C69188661EE6865E00BAD320 /* Resource+Decodable.swift */, - C66C7B951FE96CD0009B8C78 /* Resource+Inspect.swift */, - ); - name = Resource; - sourceTree = ""; - }; - C6E5A4D11E2FBD1100F966DB /* NetworkService */ = { - isa = PBXGroup; - children = ( - C60BE67D1D6B2C46006B0364 /* NetworkService.swift */, - C60425091D76F79F00FD3B38 /* BasicNetworkService.swift */, - C6C395931E04212F00413AD2 /* ModifyRequestNetworkService.swift */, - C6461F011E01678100E0B081 /* RetryNetworkService.swift */, - C6461F0A1E016C7700E0B081 /* NetworkServiceMock.swift */, - C6C21A381F21F90A0004A7EB /* NetworkResponseProcessor.swift */, - C6576B6D21DDFD25009AC99C /* NetworkService+Result.swift */, - ); - name = NetworkService; - sourceTree = ""; - }; - C6E5A4D21E2FBD2B00F966DB /* NetworkRequest */ = { - isa = PBXGroup; - children = ( - C622A7951E5C7F6500BB3D17 /* URLRequest+Init.swift */, - C62925AD1FC5900000607AEA /* URLRequest+Modifications.swift */, - C6F3A3FE211D665300BF0086 /* URL+StaticStringInit.swift */, - ); - name = NetworkRequest; - sourceTree = ""; - }; - C6E5A4D31E2FBD5800F966DB /* NetworkTask */ = { - isa = PBXGroup; - children = ( - C6E429711F70ECFF004121F1 /* URLSessionDataTask+NetworkTask.swift */, - 7C40B9FD1D9D66A600620563 /* NetworkTaskMock.swift */, - C60BE6AC1D6B3E81006B0364 /* NetworkTask.swift */, - C65AA9A121185F68007529BF /* ContainerNetworkTask.swift */, - ); - name = NetworkTask; - sourceTree = ""; - }; - C6E5A4D41E2FBD7700F966DB /* NetworkAccess */ = { - isa = PBXGroup; - children = ( - C60425071D76F6F400FD3B38 /* NetworkAccess.swift */, - C6F235D41D7DA75000E628D8 /* URLSession+NetworkAccess.swift */, - ); - name = NetworkAccess; - sourceTree = ""; - }; - C6E5A4D51E2FBDDD00F966DB /* NetworkService */ = { - isa = PBXGroup; - children = ( - C61E77881E49A57A00D55BB2 /* NetworkServiceMockTest.swift */, - C61E778A1E49B53700D55BB2 /* RetryNetworkserviceTest.swift */, - C60BE6A01D6B3807006B0364 /* NetworkServiceTest.swift */, - C6C395951E0422AF00413AD2 /* ModifyRequestNetworkService.swift */, - ); - name = NetworkService; - sourceTree = ""; - }; - C6E5A4D61E2FBE0000F966DB /* Ressource */ = { - isa = PBXGroup; - children = ( - C65AA9A321187234007529BF /* ContainerNetworkTaskTest.swift */, - C69188681EE688F700BAD320 /* DecodableResoureTest.swift */, - C60425121D7803CA00FD3B38 /* ResourceTest.swift */, - C66C7B971FE96EA8009B8C78 /* ResourceInspectTest.swift */, - ); - name = Ressource; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - C60BE6581D6B2BF3006B0364 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - C60BE65F1D6B2BF3006B0364 /* DBNetworkStack.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - C60BE65A1D6B2BF3006B0364 /* DBNetworkStack */ = { - isa = PBXNativeTarget; - buildConfigurationList = C60BE66F1D6B2BF3006B0364 /* Build configuration list for PBXNativeTarget "DBNetworkStack" */; - buildPhases = ( - C60BE6561D6B2BF3006B0364 /* Sources */, - C60BE6571D6B2BF3006B0364 /* Frameworks */, - C60BE6581D6B2BF3006B0364 /* Headers */, - C60BE6591D6B2BF3006B0364 /* Resources */, - C60F0D0D1D9A76B90028C417 /* 🚧 Swift Lint */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = DBNetworkStack; - productName = DBNetworkStack; - productReference = C60BE65B1D6B2BF3006B0364 /* DBNetworkStack.framework */; - productType = "com.apple.product-type.framework"; - }; - C60BE6641D6B2BF3006B0364 /* DBNetworkStackTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = C60BE6721D6B2BF3006B0364 /* Build configuration list for PBXNativeTarget "DBNetworkStackTests" */; - buildPhases = ( - C60BE6611D6B2BF3006B0364 /* Sources */, - C60BE6621D6B2BF3006B0364 /* Frameworks */, - C60BE6631D6B2BF3006B0364 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - C60BE6681D6B2BF3006B0364 /* PBXTargetDependency */, - ); - name = DBNetworkStackTests; - productName = DBNetworkStackTests; - productReference = C60BE6651D6B2BF3006B0364 /* DBNetworkStackTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - C60BE6521D6B2BF3006B0364 /* Project object */ = { - isa = PBXProject; - attributes = { - LastSwiftUpdateCheck = 0730; - LastUpgradeCheck = 0930; - ORGANIZATIONNAME = DBSystel; - TargetAttributes = { - C60BE65A1D6B2BF3006B0364 = { - CreatedOnToolsVersion = 7.3.1; - LastSwiftMigration = 0900; - }; - C60BE6641D6B2BF3006B0364 = { - CreatedOnToolsVersion = 7.3.1; - LastSwiftMigration = 0900; - }; - }; - }; - buildConfigurationList = C60BE6551D6B2BF3006B0364 /* Build configuration list for PBXProject "DBNetworkStack" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - English, - Base, - ); - mainGroup = C60BE6511D6B2BF3006B0364; - productRefGroup = C60BE65C1D6B2BF3006B0364 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - C60BE65A1D6B2BF3006B0364 /* DBNetworkStack */, - C60BE6641D6B2BF3006B0364 /* DBNetworkStackTests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - C60BE6591D6B2BF3006B0364 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - C60BE6631D6B2BF3006B0364 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - C60F0D0D1D9A76B90028C417 /* 🚧 Swift Lint */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "🚧 Swift Lint"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "if [ \\\"${CONFIGURATION}\\\" != \\\"Release\\\" ];\nthen if which swiftlint >/dev/null;\nthen\nswiftlint\nelse\necho \\\"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\\\"\nfi\nfi\n"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - C60BE6561D6B2BF3006B0364 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - C62925AE1FC5900000607AEA /* URLRequest+Modifications.swift in Sources */, - C66C7B961FE96CD0009B8C78 /* Resource+Inspect.swift in Sources */, - C6C395941E04212F00413AD2 /* ModifyRequestNetworkService.swift in Sources */, - C622A7961E5C7F6500BB3D17 /* URLRequest+Init.swift in Sources */, - C60BE6901D6B2C46006B0364 /* Resource.swift in Sources */, - C6461F021E01678100E0B081 /* RetryNetworkService.swift in Sources */, - C61E778C1E49D8A900D55BB2 /* NetworkTaskMock.swift in Sources */, - C69188671EE6865E00BAD320 /* Resource+Decodable.swift in Sources */, - 7C235E0B1DBF6E8500628DC9 /* NetworkError.swift in Sources */, - C6C21A391F21F90A0004A7EB /* NetworkResponseProcessor.swift in Sources */, - C6F3A3FF211D665300BF0086 /* URL+StaticStringInit.swift in Sources */, - C6F235D51D7DA75000E628D8 /* URLSession+NetworkAccess.swift in Sources */, - C60BE68F1D6B2C46006B0364 /* HTTPMethod.swift in Sources */, - C6576B6E21DDFD25009AC99C /* NetworkService+Result.swift in Sources */, - C6E429721F70ECFF004121F1 /* URLSessionDataTask+NetworkTask.swift in Sources */, - C65AA9A221185F68007529BF /* ContainerNetworkTask.swift in Sources */, - C68FF1F51E1A64CB00A2513F /* Resource+Map.swift in Sources */, - C604250A1D76F79F00FD3B38 /* BasicNetworkService.swift in Sources */, - C60BE6AD1D6B3E81006B0364 /* NetworkTask.swift in Sources */, - C60425081D76F6F400FD3B38 /* NetworkAccess.swift in Sources */, - C61E77871E48CAFE00D55BB2 /* NetworkServiceMock.swift in Sources */, - C60BE68D1D6B2C46006B0364 /* NetworkService.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - C60BE6611D6B2BF3006B0364 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - C6363D901F4ED1950052E9BD /* URLSessionMock.swift in Sources */, - C699E0771D917501006FE7C6 /* NetworkErrorTest.swift in Sources */, - C6A5DED61D760E5000BC38B1 /* NetworkAccessMock.swift in Sources */, - C60425131D7803CA00FD3B38 /* ResourceTest.swift in Sources */, - C6363D8F1F4ED1500052E9BD /* URLSession+NetworkAccessTest.swift in Sources */, - C61E77891E49A57A00D55BB2 /* NetworkServiceMockTest.swift in Sources */, - C65AA9A52118723F007529BF /* ContainerNetworkTaskTest.swift in Sources */, - C6A5DEDA1D76A06000BC38B1 /* TrainModel.swift in Sources */, - 7C653BC91E09325500199993 /* NetworkResponseProcessorTest.swift in Sources */, - C691886A1EE6897900BAD320 /* DecodableResoureTest.swift in Sources */, - C66C7B991FE96F26009B8C78 /* ResourceInspectTest.swift in Sources */, - C60BE6A31D6B3807006B0364 /* NetworkServiceTest.swift in Sources */, - C6C395961E0422AF00413AD2 /* ModifyRequestNetworkService.swift in Sources */, - C6F7E3101E49DCBA00FA625F /* NetworkTaskMockTests.swift in Sources */, - C61E778B1E49B53700D55BB2 /* RetryNetworkserviceTest.swift in Sources */, - C60FF0F31E5C94CD00818031 /* URLRequestTest.swift in Sources */, - C6F3A402211D732C00BF0086 /* URL+StaticStringInitTest.swift in Sources */, - C6363D911F4ED2030052E9BD /* DefaultMocks.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - C60BE6681D6B2BF3006B0364 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = C60BE65A1D6B2BF3006B0364 /* DBNetworkStack */; - targetProxy = C60BE6671D6B2BF3006B0364 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin XCBuildConfiguration section */ - C60BE66D1D6B2BF3006B0364 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - MACOSX_DEPLOYMENT_TARGET = 10.10; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2,3,4"; - TVOS_DEPLOYMENT_TARGET = 9.0; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - WATCHOS_DEPLOYMENT_TARGET = 2.0; - }; - name = Debug; - }; - C60BE66E1D6B2BF3006B0364 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - MACOSX_DEPLOYMENT_TARGET = 10.10; - MTL_ENABLE_DEBUG_INFO = NO; - SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2,3,4"; - TVOS_DEPLOYMENT_TARGET = 9.0; - VALIDATE_PRODUCT = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - WATCHOS_DEPLOYMENT_TARGET = 2.0; - }; - name = Release; - }; - C60BE6701D6B2BF3006B0364 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - APPLICATION_EXTENSION_API_ONLY = YES; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - FRAMEWORK_SEARCH_PATHS = "$(inherited)"; - INFOPLIST_FILE = Source/Info.plist; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.dbsystel.DBNetworkStack; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - C60BE6711D6B2BF3006B0364 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - APPLICATION_EXTENSION_API_ONLY = YES; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - FRAMEWORK_SEARCH_PATHS = "$(inherited)"; - INFOPLIST_FILE = Source/Info.plist; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.dbsystel.DBNetworkStack; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - }; - name = Release; - }; - C60BE6731D6B2BF3006B0364 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = "$(inherited)"; - INFOPLIST_FILE = Tests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks @loader_path/../Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.dbsystel.DBNetworkStackTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - C60BE6741D6B2BF3006B0364 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = "$(inherited)"; - INFOPLIST_FILE = Tests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks @loader_path/../Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.dbsystel.DBNetworkStackTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - C60BE6551D6B2BF3006B0364 /* Build configuration list for PBXProject "DBNetworkStack" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C60BE66D1D6B2BF3006B0364 /* Debug */, - C60BE66E1D6B2BF3006B0364 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - C60BE66F1D6B2BF3006B0364 /* Build configuration list for PBXNativeTarget "DBNetworkStack" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C60BE6701D6B2BF3006B0364 /* Debug */, - C60BE6711D6B2BF3006B0364 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - C60BE6721D6B2BF3006B0364 /* Build configuration list for PBXNativeTarget "DBNetworkStackTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C60BE6731D6B2BF3006B0364 /* Debug */, - C60BE6741D6B2BF3006B0364 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = C60BE6521D6B2BF3006B0364 /* Project object */; -} diff --git a/DBNetworkStack.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/DBNetworkStack.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index a3955dd..0000000 --- a/DBNetworkStack.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/DBNetworkStack.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/DBNetworkStack.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d9810..0000000 --- a/DBNetworkStack.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/DBNetworkStack.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/DBNetworkStack.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index 0c67376..0000000 --- a/DBNetworkStack.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/DBNetworkStack.xcodeproj/xcshareddata/xcschemes/DBNetworkStack.xcscheme b/DBNetworkStack.xcodeproj/xcshareddata/xcschemes/DBNetworkStack.xcscheme deleted file mode 100644 index ea2f0b6..0000000 --- a/DBNetworkStack.xcodeproj/xcshareddata/xcschemes/DBNetworkStack.xcscheme +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/DBNetworkStack.xcodeproj/xcuserdata/lukaslaschmidt.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/DBNetworkStack.xcodeproj/xcuserdata/lukaslaschmidt.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist deleted file mode 100644 index fe2b454..0000000 --- a/DBNetworkStack.xcodeproj/xcuserdata/lukaslaschmidt.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/DBNetworkStack.xcodeproj/xcuserdata/lukaslaschmidt.xcuserdatad/xcschemes/xcschememanagement.plist b/DBNetworkStack.xcodeproj/xcuserdata/lukaslaschmidt.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index dbf15c7..0000000 --- a/DBNetworkStack.xcodeproj/xcuserdata/lukaslaschmidt.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,27 +0,0 @@ - - - - - SchemeUserState - - DBNetworkStack.xcscheme_^#shared#^_ - - orderHint - 0 - - - SuppressBuildableAutocreation - - C60BE65A1D6B2BF3006B0364 - - primary - - - C60BE6641D6B2BF3006B0364 - - primary - - - - - diff --git a/DBNetworkStack.xcworkspace/contents.xcworkspacedata b/DBNetworkStack.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 73f046b..0000000 --- a/DBNetworkStack.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - diff --git a/DBNetworkStack.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/DBNetworkStack.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d9810..0000000 --- a/DBNetworkStack.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/DBNetworkStack.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/DBNetworkStack.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index 0c67376..0000000 --- a/DBNetworkStack.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/JSONExample.playground/Contents.swift b/JSONExample.playground/Contents.swift deleted file mode 100644 index 93d98fe..0000000 --- a/JSONExample.playground/Contents.swift +++ /dev/null @@ -1,25 +0,0 @@ -import DBNetworkStack -import PlaygroundSupport - -//Setup Playground environment -PlaygroundPage.current.needsIndefiniteExecution = true -URLCache.shared = URLCache(memoryCapacity: 0, diskCapacity: 0, diskPath: nil) - -//Prepare NetworkAccess & NetworkService -let networkAccess = URLSession(configuration: .default) -let networkService = BasicNetworkService(networkAccess: networkAccess) - -struct IPOrigin: Decodable { - let origin: String -} - -let url = URL(staticString: "https://www.httpbin.org") -let request = URLRequest(path: "ip", baseURL: url) - -let resource = Resource(request: request, decoder: JSONDecoder()) - -networkService.request(resource, onCompletionWithResponse: { origin, response in - print(origin, response) -}, onError: { error in - print(error) -}) diff --git a/JSONExample.playground/contents.xcplayground b/JSONExample.playground/contents.xcplayground deleted file mode 100644 index 5da2641..0000000 --- a/JSONExample.playground/contents.xcplayground +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/SimpleDemo.playground/Contents.swift b/SimpleDemo.playground/Contents.swift deleted file mode 100644 index 85ae20b..0000000 --- a/SimpleDemo.playground/Contents.swift +++ /dev/null @@ -1,21 +0,0 @@ -import DBNetworkStack -import PlaygroundSupport - -//Setup Playground environment -PlaygroundPage.current.needsIndefiniteExecution = true -URLCache.shared = URLCache(memoryCapacity: 0, diskCapacity: 0, diskPath: nil) - -//Prepare NetworkAccess & NetworkService -let networkAccess = URLSession(configuration: .default) -let networkService = BasicNetworkService(networkAccess: networkAccess) - -//Create a Resource with a given URLRequest and parsing -let url = URL(staticString: "https://bahn.de") -let request = URLRequest(path: "p/view/index.shtml", baseURL: url) -let resource = Resource(request: request, parse: { String(data: $0, encoding: .utf8) }) - -networkService.request(resource, onCompletion: { htmlText in - print(htmlText) - }, onError: { error in - print(error) -}) diff --git a/SimpleDemo.playground/contents.xcplayground b/SimpleDemo.playground/contents.xcplayground deleted file mode 100644 index 5da2641..0000000 --- a/SimpleDemo.playground/contents.xcplayground +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/Source/DBNetworkStack.h b/Source/DBNetworkStack.h deleted file mode 100644 index d7ac17c..0000000 --- a/Source/DBNetworkStack.h +++ /dev/null @@ -1,34 +0,0 @@ -// -// Copyright (C) 2017 DB Systel GmbH. -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -#import - -//! Project version number for DBNetworkStack. -FOUNDATION_EXPORT double DBNetworkStackVersionNumber; - -//! Project version string for DBNetworkStack. -FOUNDATION_EXPORT const unsigned char DBNetworkStackVersionString[]; - -// In this header, you should import all the public headers of your framework using statements like #import - - diff --git a/Source/Info.plist b/Source/Info.plist deleted file mode 100644 index 7e7479f..0000000 --- a/Source/Info.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - FMWK - CFBundleShortVersionString - 2.0.0 - CFBundleSignature - ???? - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - NSPrincipalClass - - - diff --git a/Source/NetworkTask.swift b/Source/NetworkTask.swift index aa17151..ef12d7b 100644 --- a/Source/NetworkTask.swift +++ b/Source/NetworkTask.swift @@ -26,7 +26,7 @@ import Foundation /** `NetworkTaskRepresenting` is a task which runs async to fetch data. */ -public protocol NetworkTask: class { +public protocol NetworkTask: AnyObject { /** Cancels a task. */ diff --git a/Tests/DBNetworkStackTests/ContainerNetworkTaskTest.swift b/Tests/ContainerNetworkTaskTest.swift similarity index 100% rename from Tests/DBNetworkStackTests/ContainerNetworkTaskTest.swift rename to Tests/ContainerNetworkTaskTest.swift diff --git a/Tests/DBNetworkStackTests/DecodableResoureTest.swift b/Tests/DecodableResoureTest.swift similarity index 100% rename from Tests/DBNetworkStackTests/DecodableResoureTest.swift rename to Tests/DecodableResoureTest.swift diff --git a/Tests/DBNetworkStackTests/DefaultMocks.swift b/Tests/DefaultMocks.swift similarity index 100% rename from Tests/DBNetworkStackTests/DefaultMocks.swift rename to Tests/DefaultMocks.swift diff --git a/Tests/Info.plist b/Tests/Info.plist deleted file mode 100644 index ba72822..0000000 --- a/Tests/Info.plist +++ /dev/null @@ -1,24 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - - diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift deleted file mode 100644 index 6cf64de..0000000 --- a/Tests/LinuxMain.swift +++ /dev/null @@ -1,35 +0,0 @@ -// -// URLSessionNetworkAccessTest.swift -// -// Copyright (C) 2016 DB Systel GmbH. -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// Created by Lukas Schmidt on 05.12.16. -// - -import XCTest -@testable import DBNetworkStackTests - -XCTMain([ - testCase(ResourceTest.allTests), - testCase(URLSessionNetworkAccessTest.allTests), - testCase(NetworkRequestTest.allTests) - ]) diff --git a/Tests/DBNetworkStackTests/ModifyRequestNetworkService.swift b/Tests/ModifyRequestNetworkService.swift similarity index 100% rename from Tests/DBNetworkStackTests/ModifyRequestNetworkService.swift rename to Tests/ModifyRequestNetworkService.swift diff --git a/Tests/DBNetworkStackTests/NetworkAccessMock.swift b/Tests/NetworkAccessMock.swift similarity index 100% rename from Tests/DBNetworkStackTests/NetworkAccessMock.swift rename to Tests/NetworkAccessMock.swift diff --git a/Tests/DBNetworkStackTests/NetworkErrorTest.swift b/Tests/NetworkErrorTest.swift similarity index 100% rename from Tests/DBNetworkStackTests/NetworkErrorTest.swift rename to Tests/NetworkErrorTest.swift diff --git a/Tests/DBNetworkStackTests/NetworkResponseProcessorTest.swift b/Tests/NetworkResponseProcessorTest.swift similarity index 100% rename from Tests/DBNetworkStackTests/NetworkResponseProcessorTest.swift rename to Tests/NetworkResponseProcessorTest.swift diff --git a/Tests/DBNetworkStackTests/NetworkServiceMockTest.swift b/Tests/NetworkServiceMockTest.swift similarity index 100% rename from Tests/DBNetworkStackTests/NetworkServiceMockTest.swift rename to Tests/NetworkServiceMockTest.swift diff --git a/Tests/DBNetworkStackTests/NetworkServiceTest.swift b/Tests/NetworkServiceTest.swift similarity index 100% rename from Tests/DBNetworkStackTests/NetworkServiceTest.swift rename to Tests/NetworkServiceTest.swift diff --git a/Tests/DBNetworkStackTests/NetworkTaskMockTests.swift b/Tests/NetworkTaskMockTests.swift similarity index 100% rename from Tests/DBNetworkStackTests/NetworkTaskMockTests.swift rename to Tests/NetworkTaskMockTests.swift diff --git a/Tests/DBNetworkStackTests/ResourceInspectTest.swift b/Tests/ResourceInspectTest.swift similarity index 100% rename from Tests/DBNetworkStackTests/ResourceInspectTest.swift rename to Tests/ResourceInspectTest.swift diff --git a/Tests/DBNetworkStackTests/ResourceTest.swift b/Tests/ResourceTest.swift similarity index 100% rename from Tests/DBNetworkStackTests/ResourceTest.swift rename to Tests/ResourceTest.swift diff --git a/Tests/DBNetworkStackTests/RetryNetworkserviceTest.swift b/Tests/RetryNetworkserviceTest.swift similarity index 100% rename from Tests/DBNetworkStackTests/RetryNetworkserviceTest.swift rename to Tests/RetryNetworkserviceTest.swift diff --git a/Tests/DBNetworkStackTests/TrainModel.swift b/Tests/TrainModel.swift similarity index 100% rename from Tests/DBNetworkStackTests/TrainModel.swift rename to Tests/TrainModel.swift diff --git a/Tests/DBNetworkStackTests/URL+StaticStringInitTest.swift b/Tests/URL+StaticStringInitTest.swift similarity index 100% rename from Tests/DBNetworkStackTests/URL+StaticStringInitTest.swift rename to Tests/URL+StaticStringInitTest.swift diff --git a/Tests/DBNetworkStackTests/URLRequestTest.swift b/Tests/URLRequestTest.swift similarity index 100% rename from Tests/DBNetworkStackTests/URLRequestTest.swift rename to Tests/URLRequestTest.swift diff --git a/Tests/DBNetworkStackTests/URLSession+NetworkAccessTest.swift b/Tests/URLSession+NetworkAccessTest.swift similarity index 100% rename from Tests/DBNetworkStackTests/URLSession+NetworkAccessTest.swift rename to Tests/URLSession+NetworkAccessTest.swift diff --git a/Tests/DBNetworkStackTests/URLSessionMock.swift b/Tests/URLSessionMock.swift similarity index 100% rename from Tests/DBNetworkStackTests/URLSessionMock.swift rename to Tests/URLSessionMock.swift From 3f764dd1c8c59cde5d191ced72c8dd101e520dae Mon Sep 17 00:00:00 2001 From: Lukas Schmidt Date: Mon, 6 Sep 2021 16:14:04 +0200 Subject: [PATCH 05/17] Adds ds Store files to ignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index cab8c69..2103fad 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ xcuserdata/ ## Other *.moved-aside *.xcuserstate +.DS_Store ## Obj-C/Swift specific *.hmap From 9d7c75ce72990238e812697ef5284e60d2f0bf5b Mon Sep 17 00:00:00 2001 From: Lukas Schmidt Date: Mon, 6 Sep 2021 16:15:17 +0200 Subject: [PATCH 06/17] Replaces travis with github actions --- .github/workflows/build.yml | 13 ++++++++++++ .travis.yml | 40 ------------------------------------- 2 files changed, 13 insertions(+), 40 deletions(-) create mode 100644 .github/workflows/build.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..7afe662 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,13 @@ +on: push +name: Build +jobs: + test: + name: Build + runs-on: macOS-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + ref: ${{ github.ref }} + - name: Build and test + run: swift test diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index a25e457..0000000 --- a/.travis.yml +++ /dev/null @@ -1,40 +0,0 @@ -matrix: - allow_failures: - - os: linux - include: - - os: linux - dist: trusty - sudo: required - language: generic - before_install: - - wget -q -O - https://swift.org/keys/all-keys.asc | gpg --import - - - cd .. - - export SWIFT_VERSION=swift-4.0.3-RELEASE - - wget https://swift.org/builds/swift-4.0.3-release/ubuntu1404/$SWIFT_VERSION/$SWIFT_VERSION-ubuntu14.04.tar.gz - - tar xzf $SWIFT_VERSION-ubuntu14.04.tar.gz - - export PATH="${PWD}/${SWIFT_VERSION}-ubuntu14.04/usr/bin:${PATH}" - - cd DBNetworkStack - script: - - swift test --verbose - - os: osx - osx_image: xcode11 - env: "macOS" - skip-cleanup: true - before_install: - - gem install jazzy - script: - - set -o pipefail && xcodebuild -scheme DBNetworkStack -destination "platform=macOS" test | xcpretty - - set -o pipefail && xcodebuild -scheme DBNetworkStack -destination "platform=tvOS Simulator,name=Apple TV" test | xcpretty - - set -o pipefail && xcodebuild -scheme DBNetworkStack -destination "platform=watchOS Simulator,name=Apple Watch Series 4 - 40mm" build | xcpretty - - set -o pipefail && xcodebuild -scheme DBNetworkStack -destination "platform=iOS Simulator,name=iPhone 8" test | xcpretty - - swift test & pod spec lint --allow-warnings & carthage build --no-skip-current - - jazzy --clean --author "DBSystel" --github_url https://github.com/dbsystel/DBNetworkStack --module DBNetworkStack --output docs - after_success: - - bash <(curl -s https://codecov.io/bash) - deploy: - provider: pages - local_dir: docs - skip_cleanup: true - github_token: $GITHUB_TOKEN - on: - branch: master From 366c7deadc08df1dbc695a13ddc1bcaca9603cb0 Mon Sep 17 00:00:00 2001 From: Lukas Schmidt Date: Tue, 7 Sep 2021 08:07:41 +0200 Subject: [PATCH 07/17] Removes Carthage support --- README.md | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/README.md b/README.md index d2303bd..f7dddf3 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ [![Build Status](https://travis-ci.org/dbsystel/DBNetworkStack.svg?branch=develop)](https://travis-ci.org/dbsystel/DBNetworkStack) [![codebeat badge](https://codebeat.co/badges/e438e768-249d-4e9f-8dd8-32928537740e)](https://codebeat.co/projects/github-com-dbsystel-dbnetworkstack-develop) [![codecov](https://codecov.io/gh/dbsystel/DBNetworkStack/branch/develop/graph/badge.svg)](https://codecov.io/gh/dbsystel/DBNetworkStack) -[![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) [![Swift Package Manager compatible](https://img.shields.io/badge/Swift%20Package%20Manager-compatible-brightgreen.svg)](https://github.com/apple/swift-package-manager) | | Main Features | @@ -114,16 +113,6 @@ Specify the following in your `Package.swift`: .package(url: "https://github.com/dbsystel/DBNetworkStack", from: "2.0.0"), ``` -### Carthage - -[Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. - -Specify the following in your `Cartfile`: - -```ogdl -github "dbsystel/dbnetworkstack" ~> 2.0 -``` - ## Contributing Feel free to submit a pull request with new features, improvements on tests or documentation and bug fixes. Keep in mind that we welcome code that is well tested and documented. From 1645c171501c1423efbc203b187da806dc8e94b7 Mon Sep 17 00:00:00 2001 From: Lukas Schmidt Date: Tue, 7 Sep 2021 09:06:40 +0200 Subject: [PATCH 08/17] Adds ResourceWithError --- Source/NetworkService+ResourceWithError.swift | 212 ++++++++++++++++++ Source/Resource+Decodable.swift | 14 ++ Source/Resource+Map.swift | 19 ++ Source/Resource+Void.swift | 12 + Source/ResourceWithError.swift | 59 +++++ Tests/NetworkServiceWithErrorTest.swift | 167 ++++++++++++++ Tests/ResourceWithErrorTest.swift | 64 ++++++ Tests/TrainModel.swift | 2 +- 8 files changed, 548 insertions(+), 1 deletion(-) create mode 100644 Source/NetworkService+ResourceWithError.swift create mode 100644 Source/ResourceWithError.swift create mode 100644 Tests/NetworkServiceWithErrorTest.swift create mode 100644 Tests/ResourceWithErrorTest.swift diff --git a/Source/NetworkService+ResourceWithError.swift b/Source/NetworkService+ResourceWithError.swift new file mode 100644 index 0000000..0842392 --- /dev/null +++ b/Source/NetworkService+ResourceWithError.swift @@ -0,0 +1,212 @@ +// +// Copyright (C) 2021 DB Systel GmbH. +// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + +import Foundation + +extension NetworkService { + + /** + Fetches a resource asynchronously from remote location. Execution of the requests starts immediately. + Execution happens on no specific queue. It dependes on the network access which queue is used. + Once execution is finished either the completion block or the error block gets called. + You decide on which queue these blocks get executed. + + **Example**: + ```swift + let networkService: NetworkService = // + let resource: ResourceWithError = // + + networkService.request(queue: .main, resource: resource, onCompletionWithResponse: { htmlText, response in + print(htmlText, response) + }, onError: { error in + // Handle errors + }) + ``` + + - parameter queue: The `DispatchQueue` to execute the completion and error block on. + - parameter resource: The resource you want to fetch. + - parameter onCompletionWithResponse: Callback which gets called when fetching and transforming into model succeeds. + - parameter onError: Callback which gets called with an custom error. + + - returns: a running network task + */ + @discardableResult + public func request( + queue: DispatchQueue, + resource: ResourceWithError, + onCompletionWithResponse: @escaping (Result, HTTPURLResponse) -> Void, + onError: @escaping (E) -> Void + ) -> NetworkTask { + let resourceWithoutError = Resource(request: resource.request, parse: resource.parse) + return request(queue: queue, resource: resourceWithoutError, onCompletionWithResponse: onCompletionWithResponse) { networkError in + onError(resource.mapError(networkError)) + } + } + + /** + Fetches a resource asynchronously from remote location. Execution of the requests starts immediately. + Execution happens on no specific queue. It dependes on the network access which queue is used. + Once execution is finished either the completion block or the error block gets called. + These blocks are called on the main queue. + + **Example**: + ```swift + let networkService: NetworkService = // + let resource: ResourceWithError = // + + networkService.request(resource, onCompletion: { htmlText in + print(htmlText) + }, onError: { error in + // Handle errors + }) + ``` + + - parameter resource: The resource you want to fetch. + - parameter onComplition: Callback which gets called when fetching and transforming into model succeeds. + - parameter onError: Callback which gets called with an custom error. + + - returns: a running network task + */ + @discardableResult + public func request( + _ resource: ResourceWithError, + onCompletion: @escaping (Result) -> Void, + onError: @escaping (E) -> Void + ) -> NetworkTask { + return request( + queue: .main, + resource: resource, + onCompletionWithResponse: { model, _ in onCompletion(model) }, + onError: onError + ) + } + + /** + Fetches a resource asynchronously from remote location. Execution of the requests starts immediately. + Execution happens on no specific queue. It dependes on the network access which queue is used. + Once execution is finished either the completion block or the error block gets called. + You decide on which queue these blocks get executed. + + **Example**: + ```swift + let networkService: NetworkService = // + let resource: ResourceWithError = // + + networkService.request(queue: .main, resource: resource, onCompletionWithResponse: { htmlText, response in + print(htmlText, response) + }, onError: { error in + // Handle errors + }) + ``` + + - parameter queue: The `DispatchQueue` to execute the completion and error block on. + - parameter resource: The resource you want to fetch. + - parameter onCompletionWithResponse: Callback which gets called when fetching and transforming into model succeeds. + - parameter onError: Callback which gets called with an custom error. + + - returns: a running network task + */ + @discardableResult + func request( + queue: DispatchQueue = .main, + resource: ResourceWithError, + onCompletionWithResponse: @escaping (Swift.Result<(Result, HTTPURLResponse), E>) -> Void + ) -> NetworkTask { + return request( + queue: queue, + resource: resource, + onCompletionWithResponse: { result, response in + onCompletionWithResponse(.success((result, response))) + }, onError: { error in + onCompletionWithResponse(.failure(error)) + } + ) + } + + /** + Fetches a resource asynchronously from remote location. Execution of the requests starts immediately. + Execution happens on no specific queue. It dependes on the network access which queue is used. + Once execution is finished either the completion block or the error block gets called. + These blocks are called on the main queue. + + **Example**: + ```swift + let networkService: NetworkService = // + let resource: ResourceWithError = // + + networkService.request(resource, onCompletion: { htmlText in + print(htmlText) + }, onError: { error in + // Handle errors + }) + ``` + + - parameter resource: The resource you want to fetch. + - parameter onComplition: Callback which gets called when fetching and transforming into model succeeds. + - parameter onError: Callback which gets called with an custom error. + + - returns: a running network task + */ + @discardableResult + public func request( + _ resource: ResourceWithError, + onCompletion: @escaping (Swift.Result) -> Void + ) -> NetworkTask { + return request( + queue: .main, + resource: resource, + onCompletionWithResponse: { model, _ in onCompletion(.success(model)) }, + onError: { onCompletion(.failure($0))} + ) + } + + /** + Fetches a resource asynchronously from remote location. Execution of the requests starts immediately. + Execution happens on no specific queue. It dependes on the network access which queue is used. + Once execution is finished either the completion block or the error block gets called. + These blocks are called on the main queue. + + **Example**: + ```swift + let networkService: NetworkService = // + let resource: Resource = // + + networkService.request(resource, onCompletionWithResponse: { htmlText, httpResponse in + print(htmlText, httpResponse) + }, onError: { error in + // Handle errors + }) + ``` + + - parameter resource: The resource you want to fetch. + - parameter onCompletion: Callback which gets called when fetching and transforming into model succeeds. + - parameter onError: Callback which gets called when fetching or transforming fails. + + - returns: a running network task + */ + @discardableResult + func request(_ resource: ResourceWithError, onCompletionWithResponse: @escaping (Result, HTTPURLResponse) -> Void, + onError: @escaping (E) -> Void) -> NetworkTask { + return request(queue: .main, resource: resource, onCompletionWithResponse: onCompletionWithResponse, onError: onError) + } +} diff --git a/Source/Resource+Decodable.swift b/Source/Resource+Decodable.swift index 7526422..ed738e8 100644 --- a/Source/Resource+Decodable.swift +++ b/Source/Resource+Decodable.swift @@ -35,3 +35,17 @@ extension Resource where Model: Decodable { self.init(request: request, parse: { try decoder.decode(Model.self, from: $0) }) } } + +extension ResourceWithError where Model: Decodable { + + /// Creates an instace of Resource where the result type is `Decodable` and + /// can be decoded with the given decoder + /// + /// - Parameters: + /// - request: The request to get the remote data payload + /// - decoder: a decoder which can decode the payload into the model type + /// - mapError: a closure which maps to Error + public init(request: URLRequest, decoder: JSONDecoder, mapError: @escaping (_ networkError: NetworkError) -> E) { + self.init(request: request, parse: { try decoder.decode(Model.self, from: $0) }, mapError: mapError) + } +} diff --git a/Source/Resource+Map.swift b/Source/Resource+Map.swift index 8a86dc9..5ef7ae3 100644 --- a/Source/Resource+Map.swift +++ b/Source/Resource+Map.swift @@ -33,3 +33,22 @@ extension Resource { }) } } + +extension ResourceWithError { + + /// Maps a resource result to a different resource. This is useful when you have result of R which contains T and your API request a resource of T, + /// + /// Error parsing is not changed + /// + /// - Parameter transform: transforms the original result of the resource + /// - Returns: the transformed resource + public func map(transform: @escaping (Model) throws -> T) -> ResourceWithError { + return ResourceWithError( + request: request, + parse: { data in + return try transform(try self.parse(data)) + }, + mapError: mapError + ) + } +} diff --git a/Source/Resource+Void.swift b/Source/Resource+Void.swift index 7237e43..9c961c0 100644 --- a/Source/Resource+Void.swift +++ b/Source/Resource+Void.swift @@ -17,3 +17,15 @@ public extension Resource where Model == Void { self.init(request: request, parse: { _ in }) } } + +extension ResourceWithError where Model == Void { + + /// Creates an instace of Resource where the result type is `Void` + /// + /// - Parameters: + /// - request: The request to get the remote data payload + /// - mapError: a closure which maps to Error + public init(request: URLRequest, mapError: @escaping (_ networkError: NetworkError) -> E) { + self.init(request: request, parse: { _ in }, mapError: mapError) + } +} diff --git a/Source/ResourceWithError.swift b/Source/ResourceWithError.swift new file mode 100644 index 0000000..9cfca39 --- /dev/null +++ b/Source/ResourceWithError.swift @@ -0,0 +1,59 @@ +// +// Copyright (C) 2021 DB Systel GmbH. +// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + +import Foundation + +/** + `ResourceWithError` describes a remote resource of generic type and generic error. + The type can be fetched via HTTP(S) and parsed into the coresponding model object. + + **Example**: + ```swift + let request: URLRequest = // + let resource: ResourceWithError = Resource(request: request, parse: { data in + String(data: data, encoding: .utf8) + }, mapError: { networkError in + return CustomError(networkError) + }) + ``` + */ +public struct ResourceWithError { + /// The request to fetch the resource remote payload + public let request: URLRequest + + /// Parses data into given model. + public let parse: (_ data: Data) throws -> Model + public let mapError: (_ networkError: NetworkError) -> E + + /// Creates a type safe resource, which can be used to fetch it with NetworkService + /// + /// - Parameters: + /// - request: The request to get the remote data payload + /// - parse: Parses data fetched with the request into given Model + + public init(request: URLRequest, parse: @escaping (Data) throws -> Model, mapError: @escaping (_ networkError: NetworkError) -> E) { + self.request = request + self.parse = parse + self.mapError = mapError + } +} diff --git a/Tests/NetworkServiceWithErrorTest.swift b/Tests/NetworkServiceWithErrorTest.swift new file mode 100644 index 0000000..a759d78 --- /dev/null +++ b/Tests/NetworkServiceWithErrorTest.swift @@ -0,0 +1,167 @@ +// +// Copyright (C) 2017 DB Systel GmbH. +// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + +import Foundation +import XCTest +@testable import DBNetworkStack + +enum CustomError: Error { + case error + + init(networkError: NetworkError) { + self = .error + } +} + +class NetworkServiceWithErrorTest: XCTestCase { + + var networkService: NetworkService! + + var networkAccess = NetworkAccessMock() + + let trainName = "ICE" + + var resource: ResourceWithError { + let request = URLRequest(path: "train", baseURL: .defaultMock) + return ResourceWithError(request: request, decoder: JSONDecoder(), mapError: { CustomError(networkError: $0) }) + } + + override func setUp() { + networkService = BasicNetworkService(networkAccess: networkAccess) + } + + func testRequest_withValidResponse() { + //Given + networkAccess.changeMock(data: Train.validJSONData, response: .defaultMock, error: nil) + let expection = expectation(description: "loadValidRequest") + + //When + networkService.request(resource, onCompletionWithResponse: { train, response in + XCTAssertEqual(train.name, self.trainName) + XCTAssertEqual(response, .defaultMock) + expection.fulfill() + }, onError: { _ in + XCTFail("Should not call error block") + }) + + waitForExpectations(timeout: 1, handler: nil) + + //Then + XCTAssertEqual(networkAccess.request?.url?.absoluteString, "https://bahn.de/train") + } + + func testRequest_withError() { + //Given + networkAccess.changeMock(data: nil, response: nil, error: nil) + let expection = expectation(description: "testNoData") + + //When + var capturedError: CustomError? + networkService.request(resource, onCompletion: { _ in + XCTFail("Should not call success block") + }, onError: { error in + capturedError = error + expection.fulfill() + }) + + //Then + waitForExpectations(timeout: 1, handler: nil) + + XCTAssertEqual(capturedError, .error) + } + + + func testGIVEN_aRequest_WHEN_requestWithResultResponse_THEN_ShouldRespond() { + // GIVEN + + networkAccess.changeMock(data: Train.validJSONData, response: .defaultMock, error: nil) + let expection = expectation(description: "loadValidRequest") + var expectedResult: Result? + + //When + networkService.request(resource, onCompletion: { result in + expectedResult = result + expection.fulfill() + }) + + waitForExpectations(timeout: 1, handler: nil) + + //Then + switch expectedResult { + case .success(let train)?: + XCTAssertEqual(train.name, self.trainName) + case .failure?: + XCTFail("Should be an error") + case nil: + XCTFail("Result should not be nil") + } + XCTAssertEqual(networkAccess.request?.url?.absoluteString, "https://bahn.de/train") + } + + func testGIVEN_aRequest_WHEN_requestWithResultErrorResponse_THEN_ShouldError() { + //Given + networkAccess.changeMock(data: nil, response: nil, error: nil) + var expectedResult: Result? + let expection = expectation(description: "testNoData") + + //When + + networkService.request(resource, onCompletion: { result in + expectedResult = result + expection.fulfill() + }) + + //Then + waitForExpectations(timeout: 1, handler: nil) + + XCTAssertEqual(expectedResult, .failure(.error)) + } + + func testGIVEN_aRequest_WHEN_requestWithResultAndResponse_THEN_ShouldRespond() { + // GIVEN + + networkAccess.changeMock(data: Train.validJSONData, response: .defaultMock, error: nil) + let expection = expectation(description: "loadValidRequest") + var expectedResult: Result<(Train, HTTPURLResponse), CustomError>? + + //When + networkService.request(resource: resource) { (result) in + expectedResult = result + expection.fulfill() + } + + waitForExpectations(timeout: 1, handler: nil) + + //Then + switch expectedResult { + case .success(let result)?: + XCTAssertEqual(result.0.name, self.trainName) + XCTAssertEqual(result.1, .defaultMock) + case .failure?: + XCTFail("Should be an error") + case nil: + XCTFail("Result should not be nil") + } + XCTAssertEqual(networkAccess.request?.url?.absoluteString, "https://bahn.de/train") + } +} diff --git a/Tests/ResourceWithErrorTest.swift b/Tests/ResourceWithErrorTest.swift new file mode 100644 index 0000000..9ea0e08 --- /dev/null +++ b/Tests/ResourceWithErrorTest.swift @@ -0,0 +1,64 @@ +// +// Copyright (C) 2021 DB Systel GmbH. +// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + +import Foundation +import XCTest +import DBNetworkStack + +class ResourceWithErrorTest: XCTestCase { + + func testResource() { + //Given + let validData: Data! = "ICE".data(using: .utf8) + + let resource = ResourceWithError( + request: URLRequest.defaultMock, + parse: { String(data: $0, encoding: .utf8) }, + mapError: { $0 } + ) + + //When + let name = try? resource.parse(validData) + + //Then + XCTAssertEqual(name ?? nil, "ICE") + } + + func testResourceMapError() { + //Given + enum CustomError: Error{ + case error + } + let resource = ResourceWithError( + request: URLRequest.defaultMock, + mapError: { _ in return .error } + ) + + //When + let mappedError = resource.mapError(.unknownError) + + //Then + XCTAssertEqual(mappedError, .error) + } + +} diff --git a/Tests/TrainModel.swift b/Tests/TrainModel.swift index 6ed3233..4c31db1 100644 --- a/Tests/TrainModel.swift +++ b/Tests/TrainModel.swift @@ -24,7 +24,7 @@ import Foundation import DBNetworkStack -struct Train: Decodable { +struct Train: Decodable, Equatable { let name: String } From a132c52aa8bff56bddfdefdedd50277c42762488 Mon Sep 17 00:00:00 2001 From: Lukas Schmidt Date: Tue, 7 Sep 2021 12:17:58 +0200 Subject: [PATCH 09/17] Improves NetworkServiceMock --- Source/NetworkServiceMock.swift | 44 ++++++++++--- Tests/NetworkServiceMockTest.swift | 96 +++++++++++++++++++---------- Tests/RetryNetworkserviceTest.swift | 22 +++---- 3 files changed, 109 insertions(+), 53 deletions(-) diff --git a/Source/NetworkServiceMock.swift b/Source/NetworkServiceMock.swift index f5dcb86..11fe5ba 100644 --- a/Source/NetworkServiceMock.swift +++ b/Source/NetworkServiceMock.swift @@ -25,13 +25,13 @@ import Foundation import Dispatch struct NetworkServiceMockCallback { - let onErrorCallback: ((NetworkError) -> Void)? - let onTypedSuccess: ((Any, HTTPURLResponse) -> Void)? + let onErrorCallback: (NetworkError) -> Void + let onTypedSuccess: (Any, HTTPURLResponse) throws -> Void init(resource: Resource, onCompletionWithResponse: @escaping (Result, HTTPURLResponse) -> Void, onError: @escaping (NetworkError) -> Void) { onTypedSuccess = { anyResult, response in guard let typedResult = anyResult as? Result else { - fatalError("Extected type of \(Result.self) but got \(anyResult.self)") + throw NetworkServiceMock.Error.typeMismatch } onCompletionWithResponse(typedResult, response) } @@ -97,6 +97,20 @@ struct NetworkServiceMockCallback { - seealso: `NetworkService` */ public final class NetworkServiceMock: NetworkService { + + public enum Error: Swift.Error, CustomDebugStringConvertible { + case missingRequest + case typeMismatch + + public var debugDescription: String { + switch self { + case .missingRequest: + return "Could not return because no request" + case .typeMismatch: + return "Return type does not match requested type" + } + } + } /// Count of all started requests public var requestCount: Int { @@ -107,6 +121,10 @@ public final class NetworkServiceMock: NetworkService { public var lastRequest: URLRequest? { return lastRequests.last } + + public var pendingRequestCount: Int { + return callbacks.count + } /// All executed requests. public private(set) var lastRequests: [URLRequest] = [] @@ -161,19 +179,27 @@ public final class NetworkServiceMock: NetworkService { /// /// - Parameters: /// - error: the error which gets passed to the caller - public func returnError(with error: NetworkError) { - callbacks.removeFirst().onErrorCallback?(error) + /// + /// - Throws: An error of type `NetworkServiceMock.Error` + public func returnError(with error: NetworkError) throws { + guard !callbacks.isEmpty else { + throw Error.missingRequest + } + callbacks.removeFirst().onErrorCallback(error) } /// Will return a successful request, by using the given type `T` as serialized result of a request. /// - /// **Warning:** This will crash if type `T` does not match your expected ResponseType of your current request - /// /// - Parameters: /// - data: the mock response from the server. `Data()` by default /// - httpResponse: the mock `HTTPURLResponse` from the server. `HTTPURLResponse()` by default - public func returnSuccess(with serializedResponse: T, httpResponse: HTTPURLResponse = HTTPURLResponse()) { - callbacks.removeFirst().onTypedSuccess?(serializedResponse, httpResponse) + /// + /// - Throws: An error of type `NetworkServiceMock.Error` + public func returnSuccess(with serializedResponse: T, httpResponse: HTTPURLResponse = HTTPURLResponse()) throws { + guard !callbacks.isEmpty else { + throw Error.missingRequest + } + try callbacks.removeFirst().onTypedSuccess(serializedResponse, httpResponse) } } diff --git a/Tests/NetworkServiceMockTest.swift b/Tests/NetworkServiceMockTest.swift index 3e6e3b6..0b71b2e 100644 --- a/Tests/NetworkServiceMockTest.swift +++ b/Tests/NetworkServiceMockTest.swift @@ -52,7 +52,7 @@ class NetworkServiceMockTest: XCTestCase { XCTAssertEqual(networkServiceMock.lastRequests, [resource.request, resource.request]) } - func testReturnSuccessWithData() { + func testReturnSuccessWithData() throws { //Given var capturedResult: Int? var executionCount: Int = 0 @@ -62,14 +62,14 @@ class NetworkServiceMockTest: XCTestCase { capturedResult = result executionCount += 1 }, onError: { _ in }) - networkServiceMock.returnSuccess(with: 1) + try networkServiceMock.returnSuccess(with: 1) //Then XCTAssertEqual(capturedResult, 1) XCTAssertEqual(executionCount, 1) } - func testCorrectOrderOfReturnSuccessWithDataForMultipleRequests() { + func testCorrectOrderOfReturnSuccessWithDataForMultipleRequests() throws { //Given var called1First = false var called2First = false @@ -85,15 +85,15 @@ class NetworkServiceMockTest: XCTestCase { called2First = true } }, onError: { _ in }) - networkServiceMock.returnSuccess(with: 0) - networkServiceMock.returnSuccess(with: 0) + try networkServiceMock.returnSuccess(with: 0) + try networkServiceMock.returnSuccess(with: 0) //Then XCTAssertTrue(called1First) XCTAssertFalse(called2First) } - func testRequestSuccessWithDataChaining() { + func testRequestSuccessWithDataChaining() throws { //Given var executionCount1: Int = 0 var executionCount2: Int = 0 @@ -105,15 +105,15 @@ class NetworkServiceMockTest: XCTestCase { executionCount2 += 1 }, onError: { _ in }) }, onError: { _ in }) - networkServiceMock.returnSuccess(with: 0) - networkServiceMock.returnSuccess(with: 0) + try networkServiceMock.returnSuccess(with: 0) + try networkServiceMock.returnSuccess(with: 0) //Then XCTAssertEqual(executionCount1, 1) XCTAssertEqual(executionCount2, 1) } - func testReturnSuccessWithDataForAllRequests() { + func testReturnSuccessWithDataForAllRequests() throws { //Given var executionCount1: Int = 0 var executionCount2: Int = 0 @@ -125,15 +125,15 @@ class NetworkServiceMockTest: XCTestCase { networkServiceMock.request(resource, onCompletion: { _ in executionCount2 += 1 }, onError: { _ in }) - networkServiceMock.returnSuccess(with: 0) - networkServiceMock.returnSuccess(with: 0) + try networkServiceMock.returnSuccess(with: 0) + try networkServiceMock.returnSuccess(with: 0) //Then XCTAssertEqual(executionCount1, 1) XCTAssertEqual(executionCount2, 1) } - func testReturnSuccessWithSerializedData() { + func testReturnSuccessWithSerializedData() throws { //Given var capturedResult: Int? var executionCount: Int = 0 @@ -143,14 +143,14 @@ class NetworkServiceMockTest: XCTestCase { capturedResult = result executionCount += 1 }, onError: { _ in }) - networkServiceMock.returnSuccess(with: 10) + try networkServiceMock.returnSuccess(with: 10) //Then XCTAssertEqual(capturedResult, 10) XCTAssertEqual(executionCount, 1) } - func testCorrectOrderOfReturnSuccessWithSerializedDataForMultipleRequests() { + func testCorrectOrderOfReturnSuccessWithSerializedDataForMultipleRequests() throws { //Given var capturedResult1: Int? var capturedResult2: Int? @@ -162,15 +162,15 @@ class NetworkServiceMockTest: XCTestCase { networkServiceMock.request(resource, onCompletion: { result in capturedResult2 = result }, onError: { _ in }) - networkServiceMock.returnSuccess(with: 10) - networkServiceMock.returnSuccess(with: 20) + try networkServiceMock.returnSuccess(with: 10) + try networkServiceMock.returnSuccess(with: 20) //Then XCTAssertEqual(capturedResult1, 10) XCTAssertEqual(capturedResult2, 20) } - func testRequestSuccessWithSerializedDataChaining() { + func testRequestSuccessWithSerializedDataChaining() throws { //Given var executionCount1: Int = 0 var executionCount2: Int = 0 @@ -182,15 +182,15 @@ class NetworkServiceMockTest: XCTestCase { executionCount2 += 1 }, onError: { _ in }) }, onError: { _ in }) - networkServiceMock.returnSuccess(with: 10) - networkServiceMock.returnSuccess(with: 20) + try networkServiceMock.returnSuccess(with: 10) + try networkServiceMock.returnSuccess(with: 20) //Then XCTAssertEqual(executionCount1, 1) XCTAssertEqual(executionCount2, 1) } - func testReturnSuccessWithSerializedDataForAllRequests() { + func testReturnSuccessWithSerializedDataForAllRequests() throws { //Given var executionCount1: Int = 0 var executionCount2: Int = 0 @@ -202,15 +202,15 @@ class NetworkServiceMockTest: XCTestCase { networkServiceMock.request(resource, onCompletion: { _ in executionCount2 += 1 }, onError: { _ in }) - networkServiceMock.returnSuccess(with: 10) - networkServiceMock.returnSuccess(with: 10) + try networkServiceMock.returnSuccess(with: 10) + try networkServiceMock.returnSuccess(with: 10) //Then XCTAssertEqual(executionCount1, 1) XCTAssertEqual(executionCount2, 1) } - func testReturnError() { + func testReturnError() throws { //Given var capturedError: NetworkError? var executionCount: Int = 0 @@ -220,7 +220,7 @@ class NetworkServiceMockTest: XCTestCase { capturedError = error executionCount += 1 }) - networkServiceMock.returnError(with: .unknownError) + try networkServiceMock.returnError(with: .unknownError) //Then if let error = capturedError, case .unknownError = error { @@ -231,7 +231,7 @@ class NetworkServiceMockTest: XCTestCase { XCTAssertEqual(executionCount, 1) } - func testCorrectOrderOfReturnErrorForMultipleRequests() { + func testCorrectOrderOfReturnErrorForMultipleRequests() throws { //Given var capturedError1: NetworkError? var capturedError2: NetworkError? @@ -243,8 +243,8 @@ class NetworkServiceMockTest: XCTestCase { networkServiceMock.request(resource, onCompletion: { _ in }, onError: { error in capturedError2 = error }) - networkServiceMock.returnError(with: .unknownError) - networkServiceMock.returnError(with: .cancelled) + try networkServiceMock.returnError(with: .unknownError) + try networkServiceMock.returnError(with: .cancelled) //Then if case .unknownError? = capturedError1, case .cancelled? = capturedError2 { @@ -254,7 +254,7 @@ class NetworkServiceMockTest: XCTestCase { } } - func testRequestErrorChaining() { + func testRequestErrorChaining() throws { //Given var executionCount1: Int = 0 var executionCount2: Int = 0 @@ -267,15 +267,15 @@ class NetworkServiceMockTest: XCTestCase { }) }) - networkServiceMock.returnError(with: .unknownError) - networkServiceMock.returnError(with: .unknownError) + try networkServiceMock.returnError(with: .unknownError) + try networkServiceMock.returnError(with: .unknownError) //Then XCTAssertEqual(executionCount1, 1) XCTAssertEqual(executionCount2, 1) } - func testReturnErrorsForAllRequests() { + func testReturnErrorsForAllRequests() throws { //Given var executionCount1: Int = 0 var executionCount2: Int = 0 @@ -287,12 +287,42 @@ class NetworkServiceMockTest: XCTestCase { networkServiceMock.request(resource, onCompletion: { _ in }, onError: { _ in executionCount2 += 1 }) - networkServiceMock.returnError(with: .unknownError) - networkServiceMock.returnError(with: .unknownError) + try networkServiceMock.returnError(with: .unknownError) + try networkServiceMock.returnError(with: .unknownError) //Then XCTAssertEqual(executionCount1, 1) XCTAssertEqual(executionCount2, 1) } + func testReturnSuccessMismatchType() { + //When + networkServiceMock.request(resource, onCompletion: { _ in }, onError: { _ in }) + + //Then + XCTAssertThrowsError(try networkServiceMock.returnSuccess(with: "Mismatch Type")) + } + + func testReturnSuccessMissingRequest() { + //Then + XCTAssertThrowsError(try networkServiceMock.returnSuccess(with: 1)) + } + + func testReturnErrorMissingRequest() { + //Then + XCTAssertThrowsError(try networkServiceMock.returnError(with: .unknownError)) + } + + func testPendingRequestCountEmpty() { + XCTAssertEqual(networkServiceMock.pendingRequestCount, 0) + } + + func testPendingRequestCountNotEmpty() { + //When + networkServiceMock.request(resource, onCompletion: { _ in }, onError: { _ in }) + + //Then + XCTAssertEqual(networkServiceMock.pendingRequestCount, 1) + } + } diff --git a/Tests/RetryNetworkserviceTest.swift b/Tests/RetryNetworkserviceTest.swift index 4714103..3722e2f 100644 --- a/Tests/RetryNetworkserviceTest.swift +++ b/Tests/RetryNetworkserviceTest.swift @@ -41,7 +41,7 @@ class RetryNetworkserviceTest: XCTestCase { super.tearDown() } - func testRetryRequest_shouldRetry() { + func testRetryRequest_shouldRetry() throws { //Given let errorCount = 2 let numberOfRetries = 2 @@ -59,16 +59,16 @@ class RetryNetworkserviceTest: XCTestCase { }, onError: { _ in XCTFail("Expects to not call error block") }) - (0.. Date: Sun, 19 Dec 2021 18:19:26 +0100 Subject: [PATCH 10/17] Adds support for asny await --- Source/NetworkService+Async.swift | 24 ++++++++++++++++++++++ Tests/NetworkServiceTest.swift | 34 +++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 Source/NetworkService+Async.swift diff --git a/Source/NetworkService+Async.swift b/Source/NetworkService+Async.swift new file mode 100644 index 0000000..8375a3f --- /dev/null +++ b/Source/NetworkService+Async.swift @@ -0,0 +1,24 @@ +// +// File.swift +// +// +// Created by Lukas Schmidt on 19.12.21. +// + +import Foundation + +@available(watchOS 6.0, *) +@available(macOS 10.15.0, *) +@available(iOS 13.0.0, *) +public extension NetworkService { + + @discardableResult + func request(_ resource: Resource) async throws -> (Result, HTTPURLResponse) { + return try await withCheckedThrowingContinuation({ coninuation in + request(resource: resource, onCompletionWithResponse: { + coninuation.resume(with: $0) + }) + }) + } + +} diff --git a/Tests/NetworkServiceTest.swift b/Tests/NetworkServiceTest.swift index fe5ca54..d1d940d 100644 --- a/Tests/NetworkServiceTest.swift +++ b/Tests/NetworkServiceTest.swift @@ -238,4 +238,38 @@ class NetworkServiceTest: XCTestCase { } XCTAssertEqual(networkAccess.request?.url?.absoluteString, "https://bahn.de/train") } + + @available(watchOS 6.0, *) + @available(macOS 10.15.0, *) + @available(iOS 13.0.0, *) + func testGIVEN_aRequest_WHEN_requestWithAsyncResultAndResponse_THEN_ShouldRespond() async throws { + // GIVEN + networkAccess.changeMock(data: Train.validJSONData, response: .defaultMock, error: nil) + + //When + let (result, response) = try await networkService.request(resource) + + + //Then + XCTAssertEqual(result.name, self.trainName) + XCTAssertEqual(response, .defaultMock) + XCTAssertEqual(networkAccess.request?.url?.absoluteString, "https://bahn.de/train") + } + + @available(watchOS 6.0, *) + @available(macOS 10.15.0, *) + @available(iOS 13.0.0, *) + func testGIVEN_aRequest_WHEN_requestWithAsyncResultAndResponse_THEN_ShouldThwo() async { + // GIVEN + let error = NSError(domain: "", code: 0, userInfo: nil) + networkAccess.changeMock(data: nil, response: nil, error: error) + + //When + do { + try await networkService.request(resource) + XCTFail("Schould throw") + } catch let error { + XCTAssertTrue(error is NetworkError) + } + } } From 6e445110547534767efd9290c69d69f997880739 Mon Sep 17 00:00:00 2001 From: Lukas Schmidt Date: Sun, 19 Dec 2021 18:25:38 +0100 Subject: [PATCH 11/17] Adds documentation --- Source/NetworkService+Async.swift | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Source/NetworkService+Async.swift b/Source/NetworkService+Async.swift index 8375a3f..78464be 100644 --- a/Source/NetworkService+Async.swift +++ b/Source/NetworkService+Async.swift @@ -12,6 +12,21 @@ import Foundation @available(iOS 13.0.0, *) public extension NetworkService { + /** + Fetches a resource asynchronously from remote location. Execution of the requests starts immediately. + + **Example**: + ```swift + let networkService: NetworkService = // + let resource: Resource = // + + let (result, response) = try await networkService.request(resource) + ``` + + - parameter resource: The resource you want to fetch. + + - returns: a touple containing the parsed result and the HTTP response + */ @discardableResult func request(_ resource: Resource) async throws -> (Result, HTTPURLResponse) { return try await withCheckedThrowingContinuation({ coninuation in From 7868eadfdfe1865af728b8cb8dc82f55b65f80ab Mon Sep 17 00:00:00 2001 From: Lukas Schmidt Date: Sun, 19 Dec 2021 18:30:43 +0100 Subject: [PATCH 12/17] Update package file --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index db04b99..edc0cc5 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:5.0 +// swift-tools-version:5.5 // // Package.swift // From ba0f5777b62527df7240954ff7779b381dd9285f Mon Sep 17 00:00:00 2001 From: Lukas Schmidt Date: Mon, 20 Dec 2021 10:10:51 +0100 Subject: [PATCH 13/17] Adds throws doc --- Source/NetworkService+Async.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/NetworkService+Async.swift b/Source/NetworkService+Async.swift index 78464be..0124bd2 100644 --- a/Source/NetworkService+Async.swift +++ b/Source/NetworkService+Async.swift @@ -26,6 +26,7 @@ public extension NetworkService { - parameter resource: The resource you want to fetch. - returns: a touple containing the parsed result and the HTTP response + - Throws: A `NetworkError` */ @discardableResult func request(_ resource: Resource) async throws -> (Result, HTTPURLResponse) { From 48a8fab404fc88fd88b3a897df13b584c94e26e4 Mon Sep 17 00:00:00 2001 From: Lukas Schmidt Date: Mon, 20 Dec 2021 10:23:44 +0100 Subject: [PATCH 14/17] improves available --- Source/NetworkService+Async.swift | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Source/NetworkService+Async.swift b/Source/NetworkService+Async.swift index 0124bd2..48177d6 100644 --- a/Source/NetworkService+Async.swift +++ b/Source/NetworkService+Async.swift @@ -7,9 +7,7 @@ import Foundation -@available(watchOS 6.0, *) -@available(macOS 10.15.0, *) -@available(iOS 13.0.0, *) +@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) public extension NetworkService { /** From 4aa29757d6227c7c30602b4ffa5c03c0056cb20a Mon Sep 17 00:00:00 2001 From: Lukas Schmidt Date: Mon, 20 Dec 2021 11:19:27 +0100 Subject: [PATCH 15/17] Async await for ResourceWithError --- Source/NetworkService+Async.swift | 25 +++++++++++++++++++++ Tests/NetworkServiceTest.swift | 8 ++----- Tests/NetworkServiceWithErrorTest.swift | 30 +++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 6 deletions(-) diff --git a/Source/NetworkService+Async.swift b/Source/NetworkService+Async.swift index 48177d6..42dc21b 100644 --- a/Source/NetworkService+Async.swift +++ b/Source/NetworkService+Async.swift @@ -35,4 +35,29 @@ public extension NetworkService { }) } + /** + Fetches a resource asynchronously from remote location. Execution of the requests starts immediately. + + **Example**: + ```swift + let networkService: NetworkService = // + let resource: ResourceWithError = // + + let (result, response) = try await networkService.request(resource) + ``` + + - parameter resource: The resource you want to fetch. + + - returns: a touple containing the parsed result and the HTTP response + - Throws: Custom Error provided by ResourceWithError + */ + @discardableResult + func request(_ resource: ResourceWithError) async throws -> (Result, HTTPURLResponse) { + return try await withCheckedThrowingContinuation({ coninuation in + request(resource: resource, onCompletionWithResponse: { + coninuation.resume(with: $0) + }) + }) + } + } diff --git a/Tests/NetworkServiceTest.swift b/Tests/NetworkServiceTest.swift index d1d940d..674649b 100644 --- a/Tests/NetworkServiceTest.swift +++ b/Tests/NetworkServiceTest.swift @@ -239,9 +239,7 @@ class NetworkServiceTest: XCTestCase { XCTAssertEqual(networkAccess.request?.url?.absoluteString, "https://bahn.de/train") } - @available(watchOS 6.0, *) - @available(macOS 10.15.0, *) - @available(iOS 13.0.0, *) + @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) func testGIVEN_aRequest_WHEN_requestWithAsyncResultAndResponse_THEN_ShouldRespond() async throws { // GIVEN networkAccess.changeMock(data: Train.validJSONData, response: .defaultMock, error: nil) @@ -256,9 +254,7 @@ class NetworkServiceTest: XCTestCase { XCTAssertEqual(networkAccess.request?.url?.absoluteString, "https://bahn.de/train") } - @available(watchOS 6.0, *) - @available(macOS 10.15.0, *) - @available(iOS 13.0.0, *) + @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) func testGIVEN_aRequest_WHEN_requestWithAsyncResultAndResponse_THEN_ShouldThwo() async { // GIVEN let error = NSError(domain: "", code: 0, userInfo: nil) diff --git a/Tests/NetworkServiceWithErrorTest.swift b/Tests/NetworkServiceWithErrorTest.swift index a759d78..3f71e3c 100644 --- a/Tests/NetworkServiceWithErrorTest.swift +++ b/Tests/NetworkServiceWithErrorTest.swift @@ -164,4 +164,34 @@ class NetworkServiceWithErrorTest: XCTestCase { } XCTAssertEqual(networkAccess.request?.url?.absoluteString, "https://bahn.de/train") } + + @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) + func testGIVEN_aRequest_WHEN_requestWithAsyncResultAndResponse_THEN_ShouldRespond() async throws { + // GIVEN + networkAccess.changeMock(data: Train.validJSONData, response: .defaultMock, error: nil) + + //When + let (result, response) = try await networkService.request(resource) + + + //Then + XCTAssertEqual(result.name, self.trainName) + XCTAssertEqual(response, .defaultMock) + XCTAssertEqual(networkAccess.request?.url?.absoluteString, "https://bahn.de/train") + } + + @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) + func testGIVEN_aRequest_WHEN_requestWithAsyncResultAndResponse_THEN_ShouldThwo() async { + // GIVEN + let error = NSError(domain: "", code: 0, userInfo: nil) + networkAccess.changeMock(data: nil, response: nil, error: error) + + //When + do { + try await networkService.request(resource) + XCTFail("Schould throw") + } catch let error { + XCTAssertTrue(error is CustomError) + } + } } From e60d49d88bd880d4a8ac4e8f57f444478b38a727 Mon Sep 17 00:00:00 2001 From: Lukas Schmidt Date: Mon, 10 Jan 2022 14:15:22 +0100 Subject: [PATCH 16/17] cancel support --- Source/NetworkService+Async.swift | 26 ++++++++++++++++++++------ Tests/NetworkServiceTest.swift | 19 +++++++++++++++++++ 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/Source/NetworkService+Async.swift b/Source/NetworkService+Async.swift index 42dc21b..df9ad99 100644 --- a/Source/NetworkService+Async.swift +++ b/Source/NetworkService+Async.swift @@ -28,10 +28,17 @@ public extension NetworkService { */ @discardableResult func request(_ resource: Resource) async throws -> (Result, HTTPURLResponse) { - return try await withCheckedThrowingContinuation({ coninuation in - request(resource: resource, onCompletionWithResponse: { - coninuation.resume(with: $0) + var task: NetworkTask? + let cancel = { task?.cancel() } + return try await withTaskCancellationHandler(operation: { + try Task.checkCancellation() + return try await withCheckedThrowingContinuation({ coninuation in + task = request(resource: resource, onCompletionWithResponse: { + coninuation.resume(with: $0) + }) }) + }, onCancel: { + cancel() }) } @@ -53,10 +60,17 @@ public extension NetworkService { */ @discardableResult func request(_ resource: ResourceWithError) async throws -> (Result, HTTPURLResponse) { - return try await withCheckedThrowingContinuation({ coninuation in - request(resource: resource, onCompletionWithResponse: { - coninuation.resume(with: $0) + var task: NetworkTask? + let cancel = { task?.cancel() } + return try await withTaskCancellationHandler(operation: { + try Task.checkCancellation() + return try await withCheckedThrowingContinuation({ coninuation in + task = request(resource: resource, onCompletionWithResponse: { + coninuation.resume(with: $0) + }) }) + }, onCancel: { + cancel() }) } diff --git a/Tests/NetworkServiceTest.swift b/Tests/NetworkServiceTest.swift index 674649b..7809b67 100644 --- a/Tests/NetworkServiceTest.swift +++ b/Tests/NetworkServiceTest.swift @@ -268,4 +268,23 @@ class NetworkServiceTest: XCTestCase { XCTAssertTrue(error is NetworkError) } } + + @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) + func testGIVEN_aRequest_WHEN_requestWithAsyncResultAndResponseAndCancel_THEN_ShouldThwo() async { + // GIVEN + let error = NSError(domain: "", code: 0, userInfo: nil) + networkAccess.changeMock(data: nil, response: nil, error: error) + + //When + let task = Task { + try await networkService.request(resource) + } + task.cancel() + let result = await task.result + if case .failure(let error) = result, let networkError = error as? CancellationError { + + } else { + XCTFail("Schould throw") + } + } } From a3bfde342a8c46bf4cb7e8ecae3e883fbb631c00 Mon Sep 17 00:00:00 2001 From: Lukas Schmidt Date: Tue, 11 Jan 2022 07:16:34 +0100 Subject: [PATCH 17/17] prepare release --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index f7dddf3..9702993 100644 --- a/README.md +++ b/README.md @@ -98,8 +98,6 @@ The following table shows all the protocols and their default implementations. ## Requirements - iOS 9.0+ / macOS 10.10+ / tvOS 9.0+ / watchOS 2.0+ -- Xcode 10.2+ -- Swift 5.0 ## Installation @@ -110,7 +108,7 @@ The following table shows all the protocols and their default implementations. Specify the following in your `Package.swift`: ```swift -.package(url: "https://github.com/dbsystel/DBNetworkStack", from: "2.0.0"), +.package(url: "https://github.com/dbsystel/DBNetworkStack", from: "2.1.0"), ``` ## Contributing