diff --git a/.gitignore b/.gitignore index 052a62a..cab8c69 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,65 @@ -Carthage/* +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData/ + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +*.moved-aside +*.xcuserstate + +## Obj-C/Swift specific +*.hmap +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +# Pods/ + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output \ No newline at end of file diff --git a/.swiftlint.yml b/.swiftlint.yml index 4ce6ee0..49043d3 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -1,10 +1,10 @@ disabled_rules: # rule identifiers to exclude from running - trailing_whitespace + - missing_docs opt_in_rules: # some rules are only opt-in - conditional_returns_on_newline - force_unwrapping - empty_count - - missing_docs - vertical_whitespace - private_outlet excluded: # paths to ignore during linting. Takes precedence over `included`. @@ -14,7 +14,7 @@ excluded: # paths to ignore during linting. Takes precedence over `included`. force_cast: warning # implicitly force_try: severity: warning # explicitly -line_length: 140 +line_length: 160 function_parameter_count: warning: 10 error: 15 @@ -40,4 +40,5 @@ variable_name: excluded: # excluded via string array - id - URL + - url reporter: "xcode" # reporter type (xcode, json, csv, checkstyle, junit) \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..cf13bfd --- /dev/null +++ b/.travis.yml @@ -0,0 +1,11 @@ +language: objective-c +osx_image: xcode8.1 + +env: + - ACTION=test PLATFORM=Mac DESTINATION='platform=OS X' COVERAGE='-enableCodeCoverage NO' + - ACTION=test PLATFORM=iOS DESTINATION='platform=iOS Simulator,name=iPhone SE' COVERAGE='-enableCodeCoverage NO' + - ACTION=build PLATFORM=watchOS DESTINATION='platform=watchOS Simulator,name=Apple Watch - 38mm' COVERAGE='' + - ACTION=test PLATFORM=tvOS DESTINATION='platform=tvOS Simulator,name=Apple TV 1080p' COVERAGE='-enableCodeCoverage NO' + +script: + - set -o pipefail && xcodebuild -scheme DBNetworkStack -destination "$DESTINATION" $ACTION CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO $COVERAGE | xcpretty \ No newline at end of file diff --git a/DBNetworkStack.xcodeproj/project.pbxproj b/DBNetworkStack.xcodeproj/project.pbxproj index f75260d..0a9d59e 100644 --- a/DBNetworkStack.xcodeproj/project.pbxproj +++ b/DBNetworkStack.xcodeproj/project.pbxproj @@ -7,37 +7,45 @@ objects = { /* Begin PBXBuildFile section */ + 7C235E0B1DBF6E8500628DC9 /* DBNetworkStackError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C235E0A1DBF6E8500628DC9 /* DBNetworkStackError.swift */; }; + 7C40B9E31D9A9A7000620563 /* MultipartFormDataUploadAccessProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C40B9E21D9A9A7000620563 /* MultipartFormDataUploadAccessProviding.swift */; }; + 7C40B9E51D9AA38600620563 /* MultipartFormDataRepresenting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C40B9E41D9AA38600620563 /* MultipartFormDataRepresenting.swift */; }; + 7C40B9E71D9AA48200620563 /* MultipartFormDataUploadServiceProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C40B9E61D9AA48200620563 /* MultipartFormDataUploadServiceProviding.swift */; }; + 7C40B9E91D9AA4B800620563 /* MultipartFormDataResourceModelling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C40B9E81D9AA4B800620563 /* MultipartFormDataResourceModelling.swift */; }; + 7C40B9EB1D9AA4DE00620563 /* MultipartFormDataResource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C40B9EA1D9AA4DE00620563 /* MultipartFormDataResource.swift */; }; + 7C40B9F61D9D028000620563 /* MultipartFormDataUploadService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C40B9F51D9D028000620563 /* MultipartFormDataUploadService.swift */; }; + 7C40B9FA1D9D0F6D00620563 /* BaseURLProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C40B9F91D9D0F6D00620563 /* BaseURLProviding.swift */; }; + 7C40B9FC1D9D661B00620563 /* UploadAccessServiceMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C40B9FB1D9D661B00620563 /* UploadAccessServiceMock.swift */; }; + 7C40B9FE1D9D66A600620563 /* NetworkTaskMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C40B9FD1D9D66A600620563 /* NetworkTaskMock.swift */; }; + 7C40BA001D9D67CD00620563 /* MultipartFormDataUploadServiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C40B9FF1D9D67CD00620563 /* MultipartFormDataUploadServiceTests.swift */; }; C60425081D76F6F400FD3B38 /* NetworkAccessProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60425071D76F6F400FD3B38 /* NetworkAccessProviding.swift */; }; C604250A1D76F79F00FD3B38 /* NetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60425091D76F79F00FD3B38 /* NetworkService.swift */; }; - C604250E1D76FF0300FD3B38 /* AlamofireNetworkAccessTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C604250D1D76FF0300FD3B38 /* AlamofireNetworkAccessTest.swift */; }; - C60425101D78002400FD3B38 /* JSONArrayRessourceTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C604250F1D78002400FD3B38 /* JSONArrayRessourceTest.swift */; }; - C60425131D7803CA00FD3B38 /* RessourceTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60425121D7803CA00FD3B38 /* RessourceTest.swift */; }; + C60425101D78002400FD3B38 /* JSONArrayResourceTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C604250F1D78002400FD3B38 /* JSONArrayResourceTest.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 */; }; C60BE68B1D6B2C46006B0364 /* NetworkRequestRepresening.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60BE67B1D6B2C46006B0364 /* NetworkRequestRepresening.swift */; }; - C60BE68C1D6B2C46006B0364 /* RessourceModeling.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60BE67C1D6B2C46006B0364 /* RessourceModeling.swift */; }; - C60BE68D1D6B2C46006B0364 /* ResourceServiceProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60BE67D1D6B2C46006B0364 /* ResourceServiceProviding.swift */; }; - C60BE68E1D6B2C46006B0364 /* JSONRessourceModeling.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60BE67E1D6B2C46006B0364 /* JSONRessourceModeling.swift */; }; + C60BE68C1D6B2C46006B0364 /* ResourceModeling.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60BE67C1D6B2C46006B0364 /* ResourceModeling.swift */; }; + C60BE68D1D6B2C46006B0364 /* NetworkServiceProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60BE67D1D6B2C46006B0364 /* NetworkServiceProviding.swift */; }; + C60BE68E1D6B2C46006B0364 /* JSONResourceModeling.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60BE67E1D6B2C46006B0364 /* JSONResourceModeling.swift */; }; C60BE68F1D6B2C46006B0364 /* HTTPMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60BE67F1D6B2C46006B0364 /* HTTPMethod.swift */; }; - C60BE6901D6B2C46006B0364 /* Ressource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60BE6801D6B2C46006B0364 /* Ressource.swift */; }; - C60BE6911D6B2C46006B0364 /* JSONRessource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60BE6811D6B2C46006B0364 /* JSONRessource.swift */; }; - C60BE6921D6B2C46006B0364 /* JSONArrayRessource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60BE6821D6B2C46006B0364 /* JSONArrayRessource.swift */; }; + C60BE6901D6B2C46006B0364 /* Resource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60BE6801D6B2C46006B0364 /* Resource.swift */; }; + C60BE6911D6B2C46006B0364 /* JSONResource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60BE6811D6B2C46006B0364 /* JSONResource.swift */; }; + C60BE6921D6B2C46006B0364 /* JSONArrayResource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60BE6821D6B2C46006B0364 /* JSONArrayResource.swift */; }; C60BE6931D6B2C46006B0364 /* NetworkRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60BE6831D6B2C46006B0364 /* NetworkRequest.swift */; }; - C60BE6A11D6B3807006B0364 /* AlamofireMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60BE69E1D6B3807006B0364 /* AlamofireMock.swift */; }; - C60BE6A21D6B3807006B0364 /* NetworkRequestMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60BE69F1D6B3807006B0364 /* NetworkRequestMock.swift */; }; C60BE6A31D6B3807006B0364 /* NetworkServiceTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60BE6A01D6B3807006B0364 /* NetworkServiceTest.swift */; }; - C60BE6AD1D6B3E81006B0364 /* NetworkTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60BE6AC1D6B3E81006B0364 /* NetworkTask.swift */; }; - C60BE6AF1D6C24E6006B0364 /* DBNetworkStackError.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60BE6AE1D6C24E6006B0364 /* DBNetworkStackError.swift */; }; + C60BE6AD1D6B3E81006B0364 /* NetworkTaskRepresenting.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60BE6AC1D6B3E81006B0364 /* NetworkTaskRepresenting.swift */; }; + C61348B91DACB4F2000F0583 /* ArrayResourceModeling.swift in Sources */ = {isa = PBXBuildFile; fileRef = C61348B81DACB4F2000F0583 /* ArrayResourceModeling.swift */; }; C65F087B1D757A3C00239CC1 /* JSONMappable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C65F087A1D757A3C00239CC1 /* JSONMappable.swift */; }; C65F08821D75AC8D00239CC1 /* BaseURLKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = C65F08811D75AC8D00239CC1 /* BaseURLKey.swift */; }; C6816E211D87C51C003B699A /* URLSessionNetworkAccessTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6816E201D87C51C003B699A /* URLSessionNetworkAccessTest.swift */; }; C68CC28F1D8BED570019D940 /* BaseURLKeyTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C68CC28E1D8BED570019D940 /* BaseURLKeyTest.swift */; }; C699E0771D917501006FE7C6 /* DBNetworkStackErrorTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C699E0761D917501006FE7C6 /* DBNetworkStackErrorTest.swift */; }; - C6A5DED41D760CC900BC38B1 /* JSONRessourceTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6A5DED31D760CC900BC38B1 /* JSONRessourceTest.swift */; }; + C6A5DED41D760CC900BC38B1 /* JSONResourceTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6A5DED31D760CC900BC38B1 /* JSONResourceTest.swift */; }; C6A5DED61D760E5000BC38B1 /* NetworkServiceMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6A5DED51D760E5000BC38B1 /* NetworkServiceMock.swift */; }; C6A5DEDA1D76A06000BC38B1 /* TrainModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6A5DED91D76A06000BC38B1 /* TrainModel.swift */; }; + C6AB45D91DA3DB4D00FD41D2 /* MulitpartFormDataRepresentingMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6AB45D81DA3DB4D00FD41D2 /* MulitpartFormDataRepresentingMock.swift */; }; C6C86F531D910CE500D6E59E /* NetworkRequestTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6C86F521D910CE500D6E59E /* NetworkRequestTest.swift */; }; - C6F235D31D7DA71F00E628D8 /* AlamofireNetworkAccess.swift in Sources */ = {isa = PBXBuildFile; fileRef = C60BE6841D6B2C46006B0364 /* AlamofireNetworkAccess.swift */; }; C6F235D51D7DA75000E628D8 /* URLSessionNetworkAccess.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6F235D41D7DA75000E628D8 /* URLSessionNetworkAccess.swift */; }; /* End PBXBuildFile section */ @@ -52,41 +60,49 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 7C235E0A1DBF6E8500628DC9 /* DBNetworkStackError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DBNetworkStackError.swift; sourceTree = ""; }; + 7C40B9E21D9A9A7000620563 /* MultipartFormDataUploadAccessProviding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = MultipartFormDataUploadAccessProviding.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + 7C40B9E41D9AA38600620563 /* MultipartFormDataRepresenting.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MultipartFormDataRepresenting.swift; sourceTree = ""; }; + 7C40B9E61D9AA48200620563 /* MultipartFormDataUploadServiceProviding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = MultipartFormDataUploadServiceProviding.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + 7C40B9E81D9AA4B800620563 /* MultipartFormDataResourceModelling.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = MultipartFormDataResourceModelling.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + 7C40B9EA1D9AA4DE00620563 /* MultipartFormDataResource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = MultipartFormDataResource.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + 7C40B9F51D9D028000620563 /* MultipartFormDataUploadService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = MultipartFormDataUploadService.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + 7C40B9F91D9D0F6D00620563 /* BaseURLProviding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = BaseURLProviding.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + 7C40B9FB1D9D661B00620563 /* UploadAccessServiceMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = UploadAccessServiceMock.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + 7C40B9FD1D9D66A600620563 /* NetworkTaskMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = NetworkTaskMock.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + 7C40B9FF1D9D67CD00620563 /* MultipartFormDataUploadServiceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = MultipartFormDataUploadServiceTests.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; C60425071D76F6F400FD3B38 /* NetworkAccessProviding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = NetworkAccessProviding.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; C60425091D76F79F00FD3B38 /* NetworkService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = NetworkService.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; - C604250D1D76FF0300FD3B38 /* AlamofireNetworkAccessTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = AlamofireNetworkAccessTest.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; - C604250F1D78002400FD3B38 /* JSONArrayRessourceTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSONArrayRessourceTest.swift; sourceTree = ""; }; - C60425121D7803CA00FD3B38 /* RessourceTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RessourceTest.swift; sourceTree = ""; }; + C604250F1D78002400FD3B38 /* JSONArrayResourceTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = JSONArrayResourceTest.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; path = Info.plist; sourceTree = ""; }; + C60BE66C1D6B2BF3006B0364 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = DBNetworkStackTests/Info.plist; sourceTree = ""; }; C60BE67B1D6B2C46006B0364 /* NetworkRequestRepresening.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = NetworkRequestRepresening.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; - C60BE67C1D6B2C46006B0364 /* RessourceModeling.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RessourceModeling.swift; sourceTree = ""; }; - C60BE67D1D6B2C46006B0364 /* ResourceServiceProviding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = ResourceServiceProviding.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; - C60BE67E1D6B2C46006B0364 /* JSONRessourceModeling.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = JSONRessourceModeling.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + C60BE67C1D6B2C46006B0364 /* ResourceModeling.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = ResourceModeling.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + C60BE67D1D6B2C46006B0364 /* NetworkServiceProviding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = NetworkServiceProviding.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + C60BE67E1D6B2C46006B0364 /* JSONResourceModeling.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = JSONResourceModeling.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; C60BE67F1D6B2C46006B0364 /* HTTPMethod.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTTPMethod.swift; sourceTree = ""; }; - C60BE6801D6B2C46006B0364 /* Ressource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Ressource.swift; sourceTree = ""; }; - C60BE6811D6B2C46006B0364 /* JSONRessource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSONRessource.swift; sourceTree = ""; }; - C60BE6821D6B2C46006B0364 /* JSONArrayRessource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSONArrayRessource.swift; sourceTree = ""; }; + C60BE6801D6B2C46006B0364 /* Resource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = Resource.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + C60BE6811D6B2C46006B0364 /* JSONResource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = JSONResource.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + C60BE6821D6B2C46006B0364 /* JSONArrayResource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = JSONArrayResource.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; C60BE6831D6B2C46006B0364 /* NetworkRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = NetworkRequest.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; - C60BE6841D6B2C46006B0364 /* AlamofireNetworkAccess.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = AlamofireNetworkAccess.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; - C60BE69E1D6B3807006B0364 /* AlamofireMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = AlamofireMock.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; - C60BE69F1D6B3807006B0364 /* NetworkRequestMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkRequestMock.swift; sourceTree = ""; }; - C60BE6A01D6B3807006B0364 /* NetworkServiceTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkServiceTest.swift; sourceTree = ""; }; - C60BE6AC1D6B3E81006B0364 /* NetworkTask.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkTask.swift; sourceTree = ""; }; - C60BE6AE1D6C24E6006B0364 /* DBNetworkStackError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DBNetworkStackError.swift; sourceTree = ""; }; + C60BE6A01D6B3807006B0364 /* NetworkServiceTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = NetworkServiceTest.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + C60BE6AC1D6B3E81006B0364 /* NetworkTaskRepresenting.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = NetworkTaskRepresenting.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + C61348B81DACB4F2000F0583 /* ArrayResourceModeling.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = ArrayResourceModeling.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; C65F087A1D757A3C00239CC1 /* JSONMappable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSONMappable.swift; sourceTree = ""; }; C65F08811D75AC8D00239CC1 /* BaseURLKey.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseURLKey.swift; sourceTree = ""; }; - C6816E201D87C51C003B699A /* URLSessionNetworkAccessTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLSessionNetworkAccessTest.swift; sourceTree = ""; }; + C6816E201D87C51C003B699A /* URLSessionNetworkAccessTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = URLSessionNetworkAccessTest.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; C68CC28E1D8BED570019D940 /* BaseURLKeyTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseURLKeyTest.swift; sourceTree = ""; }; C699E0761D917501006FE7C6 /* DBNetworkStackErrorTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DBNetworkStackErrorTest.swift; sourceTree = ""; }; - C6A5DED31D760CC900BC38B1 /* JSONRessourceTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSONRessourceTest.swift; sourceTree = ""; }; - C6A5DED51D760E5000BC38B1 /* NetworkServiceMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkServiceMock.swift; sourceTree = ""; }; + C6A5DED31D760CC900BC38B1 /* JSONResourceTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = JSONResourceTest.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + C6A5DED51D760E5000BC38B1 /* NetworkServiceMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = NetworkServiceMock.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; C6A5DED91D76A06000BC38B1 /* TrainModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TrainModel.swift; sourceTree = ""; }; + C6AB45D81DA3DB4D00FD41D2 /* MulitpartFormDataRepresentingMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MulitpartFormDataRepresentingMock.swift; sourceTree = ""; }; C6C86F521D910CE500D6E59E /* NetworkRequestTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = NetworkRequestTest.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; - C6F235D41D7DA75000E628D8 /* URLSessionNetworkAccess.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLSessionNetworkAccess.swift; sourceTree = ""; }; + C6F235D41D7DA75000E628D8 /* URLSessionNetworkAccess.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = URLSessionNetworkAccess.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -111,7 +127,7 @@ C60425111D7801A400FD3B38 /* protocol */ = { isa = PBXGroup; children = ( - C60BE67E1D6B2C46006B0364 /* JSONRessourceModeling.swift */, + C60BE67E1D6B2C46006B0364 /* JSONResourceModeling.swift */, ); name = protocol; sourceTree = ""; @@ -121,6 +137,7 @@ children = ( C60BE65D1D6B2BF3006B0364 /* DBNetworkStack */, C60BE6691D6B2BF3006B0364 /* DBNetworkStackTests */, + C60BE66C1D6B2BF3006B0364 /* Info.plist */, C60BE65C1D6B2BF3006B0364 /* Products */, ); sourceTree = ""; @@ -140,14 +157,15 @@ C60BE6A91D6B39BF006B0364 /* JSONParsing */, C60BE6A81D6B399A006B0364 /* protocol */, C60BE67F1D6B2C46006B0364 /* HTTPMethod.swift */, - C60BE6801D6B2C46006B0364 /* Ressource.swift */, + C60BE6801D6B2C46006B0364 /* Resource.swift */, + 7C40B9EA1D9AA4DE00620563 /* MultipartFormDataResource.swift */, C60BE6831D6B2C46006B0364 /* NetworkRequest.swift */, - C60BE6841D6B2C46006B0364 /* AlamofireNetworkAccess.swift */, C6F235D41D7DA75000E628D8 /* URLSessionNetworkAccess.swift */, C60425091D76F79F00FD3B38 /* NetworkService.swift */, - C60BE6AE1D6C24E6006B0364 /* DBNetworkStackError.swift */, + 7C40B9F51D9D028000620563 /* MultipartFormDataUploadService.swift */, C60BE65E1D6B2BF3006B0364 /* DBNetworkStack.h */, C60BE6601D6B2BF3006B0364 /* Info.plist */, + 7C235E0A1DBF6E8500628DC9 /* DBNetworkStackError.swift */, ); path = DBNetworkStack; sourceTree = ""; @@ -158,15 +176,14 @@ C6A5DED81D76A05300BC38B1 /* Helpers */, C6A5DED21D760C9E00BC38B1 /* Mocks */, C60BE6A01D6B3807006B0364 /* NetworkServiceTest.swift */, - C604250D1D76FF0300FD3B38 /* AlamofireNetworkAccessTest.swift */, - C6A5DED31D760CC900BC38B1 /* JSONRessourceTest.swift */, - C604250F1D78002400FD3B38 /* JSONArrayRessourceTest.swift */, - C60425121D7803CA00FD3B38 /* RessourceTest.swift */, + C6A5DED31D760CC900BC38B1 /* JSONResourceTest.swift */, + C604250F1D78002400FD3B38 /* JSONArrayResourceTest.swift */, + C60425121D7803CA00FD3B38 /* ResourceTest.swift */, C6816E201D87C51C003B699A /* URLSessionNetworkAccessTest.swift */, C6C86F521D910CE500D6E59E /* NetworkRequestTest.swift */, - C60BE66C1D6B2BF3006B0364 /* Info.plist */, C68CC28E1D8BED570019D940 /* BaseURLKeyTest.swift */, C699E0761D917501006FE7C6 /* DBNetworkStackErrorTest.swift */, + 7C40B9FF1D9D67CD00620563 /* MultipartFormDataUploadServiceTests.swift */, ); path = DBNetworkStackTests; sourceTree = ""; @@ -174,12 +191,18 @@ C60BE6A81D6B399A006B0364 /* protocol */ = { isa = PBXGroup; children = ( + C60BE67C1D6B2C46006B0364 /* ResourceModeling.swift */, + C61348B81DACB4F2000F0583 /* ArrayResourceModeling.swift */, C60BE67B1D6B2C46006B0364 /* NetworkRequestRepresening.swift */, - C60BE67C1D6B2C46006B0364 /* RessourceModeling.swift */, - C60BE67D1D6B2C46006B0364 /* ResourceServiceProviding.swift */, - C60BE6AC1D6B3E81006B0364 /* NetworkTask.swift */, + C60BE67D1D6B2C46006B0364 /* NetworkServiceProviding.swift */, + C60BE6AC1D6B3E81006B0364 /* NetworkTaskRepresenting.swift */, C65F08811D75AC8D00239CC1 /* BaseURLKey.swift */, C60425071D76F6F400FD3B38 /* NetworkAccessProviding.swift */, + 7C40B9E21D9A9A7000620563 /* MultipartFormDataUploadAccessProviding.swift */, + 7C40B9E61D9AA48200620563 /* MultipartFormDataUploadServiceProviding.swift */, + 7C40B9E41D9AA38600620563 /* MultipartFormDataRepresenting.swift */, + 7C40B9E81D9AA4B800620563 /* MultipartFormDataResourceModelling.swift */, + 7C40B9F91D9D0F6D00620563 /* BaseURLProviding.swift */, ); name = protocol; sourceTree = ""; @@ -188,8 +211,8 @@ isa = PBXGroup; children = ( C60425111D7801A400FD3B38 /* protocol */, - C60BE6811D6B2C46006B0364 /* JSONRessource.swift */, - C60BE6821D6B2C46006B0364 /* JSONArrayRessource.swift */, + C60BE6811D6B2C46006B0364 /* JSONResource.swift */, + C60BE6821D6B2C46006B0364 /* JSONArrayResource.swift */, C65F087A1D757A3C00239CC1 /* JSONMappable.swift */, ); name = JSONParsing; @@ -198,9 +221,10 @@ C6A5DED21D760C9E00BC38B1 /* Mocks */ = { isa = PBXGroup; children = ( - C60BE69E1D6B3807006B0364 /* AlamofireMock.swift */, - C60BE69F1D6B3807006B0364 /* NetworkRequestMock.swift */, C6A5DED51D760E5000BC38B1 /* NetworkServiceMock.swift */, + 7C40B9FB1D9D661B00620563 /* UploadAccessServiceMock.swift */, + 7C40B9FD1D9D66A600620563 /* NetworkTaskMock.swift */, + C6AB45D81DA3DB4D00FD41D2 /* MulitpartFormDataRepresentingMock.swift */, ); name = Mocks; sourceTree = ""; @@ -271,14 +295,16 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0730; - LastUpgradeCheck = 0730; + LastUpgradeCheck = 0810; ORGANIZATIONNAME = DBSystel; TargetAttributes = { C60BE65A1D6B2BF3006B0364 = { CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 0800; }; C60BE6641D6B2BF3006B0364 = { CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 0800; }; }; }; @@ -339,23 +365,30 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + C61348B91DACB4F2000F0583 /* ArrayResourceModeling.swift in Sources */, C60BE6931D6B2C46006B0364 /* NetworkRequest.swift in Sources */, - C60BE6911D6B2C46006B0364 /* JSONRessource.swift in Sources */, - C60BE6901D6B2C46006B0364 /* Ressource.swift in Sources */, - C60BE6921D6B2C46006B0364 /* JSONArrayRessource.swift in Sources */, + C60BE6911D6B2C46006B0364 /* JSONResource.swift in Sources */, + 7C40B9EB1D9AA4DE00620563 /* MultipartFormDataResource.swift in Sources */, + C60BE6901D6B2C46006B0364 /* Resource.swift in Sources */, + 7C40B9E91D9AA4B800620563 /* MultipartFormDataResourceModelling.swift in Sources */, + 7C40B9E31D9A9A7000620563 /* MultipartFormDataUploadAccessProviding.swift in Sources */, + C60BE6921D6B2C46006B0364 /* JSONArrayResource.swift in Sources */, C65F08821D75AC8D00239CC1 /* BaseURLKey.swift in Sources */, + 7C40B9F61D9D028000620563 /* MultipartFormDataUploadService.swift in Sources */, + 7C235E0B1DBF6E8500628DC9 /* DBNetworkStackError.swift in Sources */, C65F087B1D757A3C00239CC1 /* JSONMappable.swift in Sources */, - C60BE68E1D6B2C46006B0364 /* JSONRessourceModeling.swift in Sources */, + C60BE68E1D6B2C46006B0364 /* JSONResourceModeling.swift in Sources */, C6F235D51D7DA75000E628D8 /* URLSessionNetworkAccess.swift in Sources */, - C60BE68C1D6B2C46006B0364 /* RessourceModeling.swift in Sources */, - C6F235D31D7DA71F00E628D8 /* AlamofireNetworkAccess.swift in Sources */, + C60BE68C1D6B2C46006B0364 /* ResourceModeling.swift in Sources */, C60BE68F1D6B2C46006B0364 /* HTTPMethod.swift in Sources */, C604250A1D76F79F00FD3B38 /* NetworkService.swift in Sources */, - C60BE6AD1D6B3E81006B0364 /* NetworkTask.swift in Sources */, + 7C40B9E51D9AA38600620563 /* MultipartFormDataRepresenting.swift in Sources */, + 7C40B9FA1D9D0F6D00620563 /* BaseURLProviding.swift in Sources */, + 7C40B9E71D9AA48200620563 /* MultipartFormDataUploadServiceProviding.swift in Sources */, + C60BE6AD1D6B3E81006B0364 /* NetworkTaskRepresenting.swift in Sources */, C60425081D76F6F400FD3B38 /* NetworkAccessProviding.swift in Sources */, - C60BE68D1D6B2C46006B0364 /* ResourceServiceProviding.swift in Sources */, + C60BE68D1D6B2C46006B0364 /* NetworkServiceProviding.swift in Sources */, C60BE68B1D6B2C46006B0364 /* NetworkRequestRepresening.swift in Sources */, - C60BE6AF1D6C24E6006B0364 /* DBNetworkStackError.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -364,18 +397,19 @@ buildActionMask = 2147483647; files = ( C6C86F531D910CE500D6E59E /* NetworkRequestTest.swift in Sources */, + 7C40B9FE1D9D66A600620563 /* NetworkTaskMock.swift in Sources */, C699E0771D917501006FE7C6 /* DBNetworkStackErrorTest.swift in Sources */, C6A5DED61D760E5000BC38B1 /* NetworkServiceMock.swift in Sources */, - C60425131D7803CA00FD3B38 /* RessourceTest.swift in Sources */, - C60BE6A11D6B3807006B0364 /* AlamofireMock.swift in Sources */, + C60425131D7803CA00FD3B38 /* ResourceTest.swift in Sources */, + 7C40BA001D9D67CD00620563 /* MultipartFormDataUploadServiceTests.swift in Sources */, C6A5DEDA1D76A06000BC38B1 /* TrainModel.swift in Sources */, C6816E211D87C51C003B699A /* URLSessionNetworkAccessTest.swift in Sources */, - C60425101D78002400FD3B38 /* JSONArrayRessourceTest.swift in Sources */, + C60425101D78002400FD3B38 /* JSONArrayResourceTest.swift in Sources */, C60BE6A31D6B3807006B0364 /* NetworkServiceTest.swift in Sources */, C68CC28F1D8BED570019D940 /* BaseURLKeyTest.swift in Sources */, - C60BE6A21D6B3807006B0364 /* NetworkRequestMock.swift in Sources */, - C604250E1D76FF0300FD3B38 /* AlamofireNetworkAccessTest.swift in Sources */, - C6A5DED41D760CC900BC38B1 /* JSONRessourceTest.swift in Sources */, + C6AB45D91DA3DB4D00FD41D2 /* MulitpartFormDataRepresentingMock.swift in Sources */, + 7C40B9FC1D9D661B00620563 /* UploadAccessServiceMock.swift in Sources */, + C6A5DED41D760CC900BC38B1 /* JSONResourceTest.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -404,8 +438,10 @@ 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_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -429,14 +465,18 @@ 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; SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 2.3; - TARGETED_DEVICE_FAMILY = "1,2"; + SWIFT_VERSION = 3.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; }; @@ -454,8 +494,10 @@ 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_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -473,13 +515,18 @@ 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; SDKROOT = iphoneos; - SWIFT_VERSION = 2.3; - TARGETED_DEVICE_FAMILY = "1,2"; + SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 3.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; }; @@ -488,6 +535,8 @@ 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; @@ -500,6 +549,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -508,6 +558,8 @@ 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; @@ -519,6 +571,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.dbsystel.DBNetworkStack; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; }; name = Release; }; @@ -528,8 +581,10 @@ FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = DBNetworkStackTests/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)"; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -539,8 +594,10 @@ FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = DBNetworkStackTests/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)"; + SWIFT_VERSION = 3.0; }; name = Release; }; diff --git a/DBNetworkStack.xcodeproj/xcshareddata/xcschemes/DBNetworkStack.xcscheme b/DBNetworkStack.xcodeproj/xcshareddata/xcschemes/DBNetworkStack.xcscheme index 5099767..2ff83a9 100644 --- a/DBNetworkStack.xcodeproj/xcshareddata/xcschemes/DBNetworkStack.xcscheme +++ b/DBNetworkStack.xcodeproj/xcshareddata/xcschemes/DBNetworkStack.xcscheme @@ -1,6 +1,6 @@ + location = "group:JSONExample.playground"> + + diff --git a/DBNetworkStack.xcworkspace/xcuserdata/lukaslaschmidt.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/DBNetworkStack.xcworkspace/xcuserdata/lukaslaschmidt.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist deleted file mode 100644 index ed9a9b4..0000000 --- a/DBNetworkStack.xcworkspace/xcuserdata/lukaslaschmidt.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/DBNetworkStack/AlamofireNetworkAccess.swift b/DBNetworkStack/AlamofireNetworkAccess.swift deleted file mode 100644 index 487c751..0000000 --- a/DBNetworkStack/AlamofireNetworkAccess.swift +++ /dev/null @@ -1,73 +0,0 @@ -// -// NetworkService.swift -// DBNetworkStack -// -// Legal Notice! DB Systel GmbH proprietary License! -// -// Copyright (C) 2015 DB Systel GmbH -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// This code is protected by copyright law and is the exclusive property of -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// Consent to use ("licence") shall be granted solely on the basis of a -// written licence agreement signed by the customer and DB Systel GmbH. Any -// other use, in particular copying, redistribution, publication or -// modification of this code without written permission of DB Systel GmbH is -// expressly prohibited. - -// In the event of any permitted copying, redistribution or publication of -// this code, no changes in or deletion of author attribution, trademark -// legend or copyright notice shall be made. -// -// Created by Lukas Schmidt on 21.07.16. -// - -import Foundation -//import Alamofire -// -//public struct AlamofireNetworkAccess: NetworkAccessProviding { -// public typealias RequestMethod = (method: Alamofire.Method, URLString: URLStringConvertible, parameters: [String : AnyObject]?, encoding: Alamofire.ParameterEncoding, headers: [String : String]?) -> NetworkRequestModeling -// private let requestFunction: RequestMethod -// -// /** -// Creates an `AlamofireNetworkService` instance with an underlying Alamofire implementation -// -// - parameter requestFunction: A function of type `RequestMethod` similar to `Alamofire.Request` which can fetch data. -// */ -// public init(requestFunction: RequestMethod = Alamofire.request, endPoints: Dictionary) { -// self.requestFunction = requestFunction -// } -// -// public func load(request request: NetworkRequestRepresening, relativeToBaseURL baseURL: NSURL, callback: (NSData?, NSHTTPURLResponse?, NSError?) -> ()) -> CancelableRequest { -// guard let absoluteURL = NSURL(string: request.path, relativeToURL: baseURL) else { -// fatalError("Error createing absolute URL from path: \(request.path), with baseURL: \(baseURL)") -// } -// -// let request = requestFunction(method: request.HTTPMethod.alamofireMethod, -// URLString: absoluteURL, -// parameters: request.parameter, -// encoding: Alamofire.ParameterEncoding.URL, -// headers: request.allHTTPHeaderFields) -// request.response(queue: nil) { _, response, data, error in -// callback(data, response, error) -// } -// -// return request -// } -//} -// -//extension DBNetworkStack.HTTPMethod { -// var alamofireMethod: Alamofire.Method { -// return Alamofire.Method(rawValue: self.rawValue)! -// } -//} -// -// -///** -// Abstracts Alamofire.Request to make it testable -//*/ -//public protocol NetworkRequestModeling: CancelableRequest { -// func response(queue queue: dispatch_queue_t?, completionHandler: (NSURLRequest?, NSHTTPURLResponse?, NSData?, NSError?) -> Void) -> Self -//} -//extension Alamofire.Request: NetworkRequestModeling { } diff --git a/DBNetworkStack/ArrayResourceModeling.swift b/DBNetworkStack/ArrayResourceModeling.swift new file mode 100644 index 0000000..2fe607c --- /dev/null +++ b/DBNetworkStack/ArrayResourceModeling.swift @@ -0,0 +1,37 @@ +// +// ArrayResourceModeling.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 11.10.16. +// + +import Foundation + +/** + `ArrayResourceModeling` describes a remote resource of generic type structured in an array. + The resource type can be fetched via HTTP(s) and parsed into the coresponding model object. + */ +public protocol ArrayResourceModeling: ResourceModeling { + associatedtype Element + associatedtype Model = Array +} diff --git a/DBNetworkStack/BaseURLKey.swift b/DBNetworkStack/BaseURLKey.swift index c31185a..391ba44 100644 --- a/DBNetworkStack/BaseURLKey.swift +++ b/DBNetworkStack/BaseURLKey.swift @@ -1,24 +1,26 @@ // // BaseURLKey.swift -// DBNetworkStack // -// Legal Notice! DB Systel GmbH proprietary License! -// -// Copyright (C) 2015 DB Systel GmbH -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// This code is protected by copyright law and is the exclusive property of +// Copyright (C) 2016 DB Systel GmbH. // DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// Consent to use ("licence") shall be granted solely on the basis of a -// written licence agreement signed by the customer and DB Systel GmbH. Any -// other use, in particular copying, redistribution, publication or -// modification of this code without written permission of DB Systel GmbH is -// expressly prohibited. - -// In the event of any permitted copying, redistribution or publication of -// this code, no changes in or deletion of author attribution, trademark -// legend or copyright notice shall be made. +// +// 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 30.08.16. // diff --git a/DBNetworkStack/BaseURLProviding.swift b/DBNetworkStack/BaseURLProviding.swift new file mode 100644 index 0000000..efea38c --- /dev/null +++ b/DBNetworkStack/BaseURLProviding.swift @@ -0,0 +1,57 @@ +// +// BaseURLProviding.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 Christian Himmelsbach on 29.09.16. +// + +import Foundation + +internal protocol BaseURLProviding { + + var endPoints: [String: URL] {get} + /** + Provides an baseURL for a given resource. + + To be more flexible, a request does only contain a path and not a full URL. + Mapping has to be done in the service to get an registerd baseURL for the request. + + - parameter resource: The resource you want to get a baseURL for. + + - return matching baseURL to the given resource + */ + func baseURL(with resource: T) -> URL +} + +extension BaseURLProviding { + + func baseURL(with resource: T) -> URL { + + guard let baseURL = endPoints[resource.request.baseURLKey.name] else { + fatalError("Missing baseurl for key: \(resource.request.baseURLKey.name)") + } + + return baseURL + } + +} diff --git a/DBNetworkStack/DBNetworkStack.h b/DBNetworkStack/DBNetworkStack.h index 1bba1c0..1205f6a 100644 --- a/DBNetworkStack/DBNetworkStack.h +++ b/DBNetworkStack/DBNetworkStack.h @@ -1,12 +1,31 @@ // // DBNetworkStack.h -// DBNetworkStack +// +// 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 22.08.16. -// Copyright © 2016 DBSystel. All rights reserved. // -#import +#import //! Project version number for DBNetworkStack. FOUNDATION_EXPORT double DBNetworkStackVersionNumber; diff --git a/DBNetworkStack/DBNetworkStackError.swift b/DBNetworkStack/DBNetworkStackError.swift index 37d72bb..f67b42b 100644 --- a/DBNetworkStack/DBNetworkStackError.swift +++ b/DBNetworkStack/DBNetworkStackError.swift @@ -1,24 +1,26 @@ // -// Error.swift -// DBNetworkStack +// DBNetworkStackError.swift // -// Legal Notice! DB Systel GmbH proprietary License! -// -// Copyright (C) 2015 DB Systel GmbH -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// This code is protected by copyright law and is the exclusive property of +// Copyright (C) 2016 DB Systel GmbH. // DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// Consent to use ("licence") shall be granted solely on the basis of a -// written licence agreement signed by the customer and DB Systel GmbH. Any -// other use, in particular copying, redistribution, publication or -// modification of this code without written permission of DB Systel GmbH is -// expressly prohibited. - -// In the event of any permitted copying, redistribution or publication of -// this code, no changes in or deletion of author attribution, trademark -// legend or copyright notice shall be made. +// +// 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 23.08.16. // @@ -28,29 +30,59 @@ import Foundation /** `DBNetworkStackError` provides a collection of error types which can occur during execution. */ -public enum DBNetworkStackError: ErrorType { - case UnknownError - case Unauthorized(response: NSHTTPURLResponse) - case ClientError(response: NSHTTPURLResponse?) - case SerializationError(description: String, data: NSData?) - case RequestError(error: NSError) - case ServerError(response: NSHTTPURLResponse?) - case MissingBaseURL +public enum DBNetworkStackError: Error { + case unknownError + case unauthorized(response: HTTPURLResponse) + case clientError(response: HTTPURLResponse?) + case serializationError(description: String, data: Data?) + case requestError(error: Error) + case serverError(response: HTTPURLResponse?) + case missingBaseURL - init?(response: NSHTTPURLResponse?) { + init?(response: HTTPURLResponse?) { guard let response = response else { return nil } switch response.statusCode { case 200..<300: return nil case 401: - self = .Unauthorized(response: response) + self = .unauthorized(response: response) case 400...451: - self = .ClientError(response: response) + self = .clientError(response: response) case 500...511: - self = .ServerError(response: response) + self = .serverError(response: response) default: return nil } } + +} + +extension DBNetworkStackError : CustomDebugStringConvertible { + + public var debugDescription: String { + var result = "" + + switch self { + case .unknownError: + result = "Unknown error" + case .unauthorized(let response): + result = "Authorization error: \(response)" + case .clientError(let response): + result = "Client error: \(response)" + case .serializationError(let description, let data): + result = "Serialization error: \(description)" + if let data = data, let string = String(data: data, encoding: String.Encoding.utf8) { + result.append("\n\tdata: \(string)") + } + case .requestError(let error): + result = "Request error: \(error)" + case .serverError(let response): + result = "Server error: \(response)" + case .missingBaseURL: + result = "Missing base url error" + } + + return result + } } diff --git a/DBNetworkStack/HTTPMethod.swift b/DBNetworkStack/HTTPMethod.swift index 7c0d81a..2e22cf0 100644 --- a/DBNetworkStack/HTTPMethod.swift +++ b/DBNetworkStack/HTTPMethod.swift @@ -1,24 +1,26 @@ // // HTTPMethod.swift -// DBNetworkStack // -// Legal Notice! DB Systel GmbH proprietary License! -// -// Copyright (C) 2015 DB Systel GmbH -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// This code is protected by copyright law and is the exclusive property of +// Copyright (C) 2016 DB Systel GmbH. // DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// Consent to use ("licence") shall be granted solely on the basis of a -// written licence agreement signed by the customer and DB Systel GmbH. Any -// other use, in particular copying, redistribution, publication or -// modification of this code without written permission of DB Systel GmbH is -// expressly prohibited. - -// In the event of any permitted copying, redistribution or publication of -// this code, no changes in or deletion of author attribution, trademark -// legend or copyright notice shall be made. +// +// 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 21.07.16. // diff --git a/DBNetworkStack/Info.plist b/DBNetworkStack/Info.plist index d3de8ee..6019f05 100644 --- a/DBNetworkStack/Info.plist +++ b/DBNetworkStack/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.0 + 0.2.0 CFBundleSignature ???? CFBundleVersion diff --git a/DBNetworkStack/JSONArrayResource.swift b/DBNetworkStack/JSONArrayResource.swift new file mode 100644 index 0000000..9cf6b63 --- /dev/null +++ b/DBNetworkStack/JSONArrayResource.swift @@ -0,0 +1,51 @@ +// +// JSONListResource.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 27.07.16. +// + +import Foundation + +/** + `JSONResource` represents a network resource in JSON, which can be parsed into an array of Model Types. + + The root JSON payload must be an array. + + See `ResourceModeling` for more details. + */ +public struct JSONArrayResource: JSONResourceModeling, ArrayResourceModeling { + public typealias Element = Element_ + public let request: NetworkRequestRepresening + public var parse: (_ data: Data) throws -> Array { + return parseFunction + } + + public init(request: NetworkRequestRepresening) { + self.request = request + } + + public func parse(_ jsonPayload: Array>) throws -> Array { + return try Array(JSONArray: jsonPayload) + } +} diff --git a/DBNetworkStack/JSONArrayRessource.swift b/DBNetworkStack/JSONArrayRessource.swift deleted file mode 100644 index 5e5ee92..0000000 --- a/DBNetworkStack/JSONArrayRessource.swift +++ /dev/null @@ -1,48 +0,0 @@ -// -// JSONListRessource.swift -// DBNetworkStack -// -// Legal Notice! DB Systel GmbH proprietary License! -// -// Copyright (C) 2015 DB Systel GmbH -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// This code is protected by copyright law and is the exclusive property of -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// Consent to use ("licence") shall be granted solely on the basis of a -// written licence agreement signed by the customer and DB Systel GmbH. Any -// other use, in particular copying, redistribution, publication or -// modification of this code without written permission of DB Systel GmbH is -// expressly prohibited. - -// In the event of any permitted copying, redistribution or publication of -// this code, no changes in or deletion of author attribution, trademark -// legend or copyright notice shall be made. -// -// Created by Lukas Schmidt on 27.07.16. -// - -import Foundation - -/** - `JSONRessource` represents a network ressource in JSON, which can be parsed into an array of Model Types. - - The root JSON payload must be an array. - - See `RessourceModeling` for more details. - */ -public struct JSONArrayRessource: JSONRessourceModeling { - public let request: NetworkRequestRepresening - public var parse: (data: NSData) throws -> Array { - return parseFunction - } - - public init(request: NetworkRequestRepresening) { - self.request = request - } - - public func parse(jsonPayload: Array>) throws -> Array { - return try Array(JSONArray: jsonPayload) - } -} diff --git a/DBNetworkStack/JSONMappable.swift b/DBNetworkStack/JSONMappable.swift index a4dccfe..891d9c6 100644 --- a/DBNetworkStack/JSONMappable.swift +++ b/DBNetworkStack/JSONMappable.swift @@ -1,24 +1,26 @@ // // JSONMappable.swift -// DBNetworkStack // -// Legal Notice! DB Systel GmbH proprietary License! -// -// Copyright (C) 2015 DB Systel GmbH -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// This code is protected by copyright law and is the exclusive property of +// Copyright (C) 2016 DB Systel GmbH. // DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// Consent to use ("licence") shall be granted solely on the basis of a -// written licence agreement signed by the customer and DB Systel GmbH. Any -// other use, in particular copying, redistribution, publication or -// modification of this code without written permission of DB Systel GmbH is -// expressly prohibited. - -// In the event of any permitted copying, redistribution or publication of -// this code, no changes in or deletion of author attribution, trademark -// legend or copyright notice shall be made. +// +// 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 30.08.16. // @@ -35,11 +37,11 @@ public protocol JSONMappable { /** Creates an instance with a dictionary. */ - init(object: Dictionary) throws + init(object: Dictionary) throws } extension Array where Element: JSONMappable { - init(JSONArray: Array>) throws { + init(JSONArray: Array>) throws { self.init(try JSONArray.map { json in return try Element(object: json) }) diff --git a/DBNetworkStack/JSONResource.swift b/DBNetworkStack/JSONResource.swift new file mode 100644 index 0000000..8ca3a67 --- /dev/null +++ b/DBNetworkStack/JSONResource.swift @@ -0,0 +1,49 @@ +// +// JSONResource.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 22.07.16. +// + +import Foundation +/** + `JSONResource` represents a network resource in JSON, which can be parsed into a Model Type. + + The root JSON payload must be an object. + + See `ResourceModeling` for more details. + */ +public struct JSONResource: JSONResourceModeling { + public let request: NetworkRequestRepresening + public var parse: (_ data: Data) throws -> Model { + return parseFunction + } + + public init(request: NetworkRequestRepresening) { + self.request = request + } + + public func parse(_ jsonPayload: Dictionary) throws -> Model { + return try Model(object: jsonPayload) + } +} diff --git a/DBNetworkStack/JSONResourceModeling.swift b/DBNetworkStack/JSONResourceModeling.swift new file mode 100644 index 0000000..5b0f099 --- /dev/null +++ b/DBNetworkStack/JSONResourceModeling.swift @@ -0,0 +1,88 @@ +// +// JSONResourceModeling.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 27.07.16. +// + +import Foundation +/** + `JSONResourceModeling` discribes resource which can be parsed from JSON into Model Type. + + It speciefies a JSON Container from which the model is parsed and a `parse` function to transform the container into the given Model. + */ +public protocol JSONResourceModeling: ResourceModeling { + /** + The JSON container format represented as an foundation object + e.g. {} becomes Dictionary, [] becomes Array> + */ + associatedtype Container + + /** + Parses a JSON container (Dictionary/Array) to a speciefied generic Model + + - parameter jsonPayload: the json payload as container (Dictionary/Array) + + - returns: The Model + + - Throws: If parsing fails + */ + func parse(_ jsonPayload: Container) throws -> Model +} + +extension JSONResourceModeling { + + /** + Parses JSON to a speciefied generic Model + + - parameter data: the json payload to parse + + - returns: The Model + + - Throws: If parsing fails + */ + func parseFunction(_ data: Data) throws -> Model { + let container: Container = try parseContainer(data) + + return try parse(container) + } + + /** + Parses JSON to speciefied generic Container + + - parameter data: the json payload to parse + + - returns: The container + + - Throws: If parsing fails + */ + fileprivate func parseContainer(_ data: Data) throws -> Container { + let jsonObject = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) + guard let container = jsonObject as? Container else { + let userInfo = ["error": "Expected container of type: \(Container.self), but got \(type(of: (jsonObject) as AnyObject))"] + throw NSError(domain: "Parsing Error", code: 0, userInfo: userInfo) + } + + return container + } +} diff --git a/DBNetworkStack/JSONRessource.swift b/DBNetworkStack/JSONRessource.swift deleted file mode 100644 index 64d40d5..0000000 --- a/DBNetworkStack/JSONRessource.swift +++ /dev/null @@ -1,47 +0,0 @@ -// -// JSONRessource.swift -// DBNetworkStack -// -// Legal Notice! DB Systel GmbH proprietary License! -// -// Copyright (C) 2015 DB Systel GmbH -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// This code is protected by copyright law and is the exclusive property of -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// Consent to use ("licence") shall be granted solely on the basis of a -// written licence agreement signed by the customer and DB Systel GmbH. Any -// other use, in particular copying, redistribution, publication or -// modification of this code without written permission of DB Systel GmbH is -// expressly prohibited. - -// In the event of any permitted copying, redistribution or publication of -// this code, no changes in or deletion of author attribution, trademark -// legend or copyright notice shall be made. -// -// Created by Lukas Schmidt on 22.07.16. -// - -import Foundation -/** - `JSONRessource` represents a network ressource in JSON, which can be parsed into a Model Type. - - The root JSON payload must be an object. - - See `RessourceModeling` for more details. - */ -public struct JSONRessource: JSONRessourceModeling { - public let request: NetworkRequestRepresening - public var parse: (data: NSData) throws -> Model { - return parseFunction - } - - public init(request: NetworkRequestRepresening) { - self.request = request - } - - public func parse(jsonPayload: Dictionary) throws -> Model { - return try Model(object: jsonPayload) - } -} diff --git a/DBNetworkStack/JSONRessourceModeling.swift b/DBNetworkStack/JSONRessourceModeling.swift deleted file mode 100644 index 598c86f..0000000 --- a/DBNetworkStack/JSONRessourceModeling.swift +++ /dev/null @@ -1,86 +0,0 @@ -// -// JSONRessourceModeling.swift -// DBNetworkStack -// -// Legal Notice! DB Systel GmbH proprietary License! -// -// Copyright (C) 2015 DB Systel GmbH -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// This code is protected by copyright law and is the exclusive property of -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// Consent to use ("licence") shall be granted solely on the basis of a -// written licence agreement signed by the customer and DB Systel GmbH. Any -// other use, in particular copying, redistribution, publication or -// modification of this code without written permission of DB Systel GmbH is -// expressly prohibited. - -// In the event of any permitted copying, redistribution or publication of -// this code, no changes in or deletion of author attribution, trademark -// legend or copyright notice shall be made. -// -// Created by Lukas Schmidt on 27.07.16. -// - -import Foundation -/** - `JSONRessourceModeling` discribes ressource which can be parsed from JSON into Model Type. - - It speciefies a JSON Container from which the model is parsed and a `parse` function to transform the container into the given Model. - */ -public protocol JSONRessourceModeling: RessourceModeling { - /** - The JSON container format represented as an foundation object - e.g. {} becomes Dictionary, [] becomes Array> - */ - associatedtype Container - - /** - Parses a JSON container (Dictionary/Array) to a speciefied generic Model - - - parameter jsonPayload: the json payload as container (Dictionary/Array) - - - returns: The Model - - - Throws: If parsing fails - */ - func parse(jsonPayload: Container) throws -> Model -} - -extension JSONRessourceModeling { - - /** - Parses JSON to a speciefied generic Model - - - parameter data: the json payload to parse - - - returns: The Model - - - Throws: If parsing fails - */ - func parseFunction(data: NSData) throws -> Model { - let container: Container = try parseContainer(data) - - return try parse(container) - } - - /** - Parses JSON to speciefied generic Container - - - parameter data: the json payload to parse - - - returns: The container - - - Throws: If parsing fails - */ - private func parseContainer(data: NSData) throws -> Container { - let jsonObject = try NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers) - guard let container = jsonObject as? Container else { - let userInfo = ["error": "Expected container of type: \(Container.self), but got \(jsonObject.dynamicType)"] - throw NSError(domain: "Parsing Error", code: 0, userInfo: userInfo) - } - - return container - } -} diff --git a/DBNetworkStack/MultipartFormDataRepresenting.swift b/DBNetworkStack/MultipartFormDataRepresenting.swift new file mode 100644 index 0000000..c38032f --- /dev/null +++ b/DBNetworkStack/MultipartFormDataRepresenting.swift @@ -0,0 +1,201 @@ +// +// MultipartFormDataRepresenting.swift +// +// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/) +// +// 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 + +/// Constructs `multipart/form-data` for uploads within an HTTP or HTTPS body. There are currently two ways to encode +/// multipart form data. The first way is to encode the data directly in memory. This is very efficient, but can lead +/// to memory issues if the dataset is too large. The second way is designed for larger datasets and will write all the +/// data to a single file on disk with all the proper boundary segmentation. The second approach MUST be used for +/// larger datasets such as video content, otherwise your app may run out of memory when trying to encode the dataset. +/// +/// For more information on `multipart/form-data` in general, please refer to the RFC-2388 and RFC-2045 specs as well +/// and the w3 form documentation. +/// +/// - https://www.ietf.org/rfc/rfc2388.txt +/// - https://www.ietf.org/rfc/rfc2045.txt +/// - https://www.w3.org/TR/html401/interact/forms.html#h-17.13 +protocol MultipartFormDataRepresenting: class { + + // MARK: - Properties + + /// The `Content-Type` header value containing the boundary used to generate the `multipart/form-data`. + var contentType: String { get } + + /// The content length of all body parts used to generate the `multipart/form-data` not including the boundaries. + var contentLength: UInt64 { get } + + /// The boundary used to separate the body parts in the encoded form data. + var boundary: String { get } + + // MARK: - Body Parts + + /** + Creates a body part from the data and appends it to the multipart form data object. + + The body part data will be encoded using the following format: + + - `Content-Disposition: form-data; name=#{name}` (HTTP Header) + - Encoded data + - Multipart form boundary + + - parameter data: The data to encode into the multipart form data. + - parameter name: The name to associate with the data in the `Content-Disposition` HTTP header. + */ + func appendBodyPart(data: Data, name: String) + + /** + Creates a body part from the data and appends it to the multipart form data object. + + The body part data will be encoded using the following format: + + - `Content-Disposition: form-data; name=#{name}` (HTTP Header) + - `Content-Type: #{generated mimeType}` (HTTP Header) + - Encoded data + - Multipart form boundary + + - parameter data: The data to encode into the multipart form data. + - parameter name: The name to associate with the data in the `Content-Disposition` HTTP header. + - parameter mimeType: The MIME type to associate with the data content type in the `Content-Type` HTTP header. + */ + func appendBodyPart(data: Data, name: String, mimeType: String) + + /** + Creates a body part from the data and appends it to the multipart form data object. + + The body part data will be encoded using the following format: + + - `Content-Disposition: form-data; name=#{name}; filename=#{filename}` (HTTP Header) + - `Content-Type: #{mimeType}` (HTTP Header) + - Encoded file data + - Multipart form boundary + + - parameter data: The data to encode into the multipart form data. + - parameter name: The name to associate with the data in the `Content-Disposition` HTTP header. + - parameter fileName: The filename to associate with the data in the `Content-Disposition` HTTP header. + - parameter mimeType: The MIME type to associate with the data in the `Content-Type` HTTP header. + */ + func appendBodyPart(data: Data, name: String, fileName: String, mimeType: String) + + /** + Creates a body part from the file and appends it to the multipart form data object. + + The body part data will be encoded using the following format: + + - `Content-Disposition: form-data; name=#{name}; filename=#{generated filename}` (HTTP Header) + - `Content-Type: #{generated mimeType}` (HTTP Header) + - Encoded file data + - Multipart form boundary + + The filename in the `Content-Disposition` HTTP header is generated from the last path component of the + `fileURL`. The `Content-Type` HTTP header MIME type is generated by mapping the `fileURL` extension to the + system associated MIME type. + + - parameter fileURL: The URL of the file whose content will be encoded into the multipart form data. + - parameter name: The name to associate with the file content in the `Content-Disposition` HTTP header. + */ + func appendBodyPart(fileURL: URL, name: String) + + /** + Creates a body part from the file and appends it to the multipart form data object. + + The body part data will be encoded using the following format: + + - Content-Disposition: form-data; name=#{name}; filename=#{filename} (HTTP Header) + - Content-Type: #{mimeType} (HTTP Header) + - Encoded file data + - Multipart form boundary + + - parameter fileURL: The URL of the file whose content will be encoded into the multipart form data. + - parameter name: The name to associate with the file content in the `Content-Disposition` HTTP header. + - parameter fileName: The filename to associate with the file content in the `Content-Disposition` HTTP header. + - parameter mimeType: The MIME type to associate with the file content in the `Content-Type` HTTP header. + */ + func appendBodyPart(fileURL: URL, name: String, fileName: String, mimeType: String) + + /** + Creates a body part from the stream and appends it to the multipart form data object. + + The body part data will be encoded using the following format: + + - `Content-Disposition: form-data; name=#{name}; filename=#{filename}` (HTTP Header) + - `Content-Type: #{mimeType}` (HTTP Header) + - Encoded stream data + - Multipart form boundary + + - parameter stream: The input stream to encode in the multipart form data. + - parameter length: The content length of the stream. + - parameter name: The name to associate with the stream content in the `Content-Disposition` HTTP header. + - parameter fileName: The filename to associate with the stream content in the `Content-Disposition` HTTP header. + - parameter mimeType: The MIME type to associate with the stream content in the `Content-Type` HTTP header. + */ + func appendBodyPart( + stream: InputStream, + length: UInt64, + name: String, + fileName: String, + mimeType: String) + + /** + Creates a body part with the headers, stream and length and appends it to the multipart form data object. + + The body part data will be encoded using the following format: + + - HTTP headers + - Encoded stream data + - Multipart form boundary + + - parameter stream: The input stream to encode in the multipart form data. + - parameter length: The content length of the stream. + - parameter headers: The HTTP headers for the body part. + */ + func appendBodyPart(stream: InputStream, length: UInt64, headers: [String: String]) + + // MARK: - Data Encoding + + /** + Encodes all the appended body parts into a single `NSData` object. + + It is important to note that this method will load all the appended body parts into memory all at the same + time. This method should only be used when the encoded data will have a small memory footprint. For large data + cases, please use the `writeEncodedDataToDisk(fileURL:completionHandler:)` method. + + - throws: An `NSError` if encoding encounters an error. + + - returns: The encoded `NSData` if encoding is successful. + */ + func encode() throws -> Data + + /** + Writes the appended body parts into the given file URL. + + This process is facilitated by reading and writing with input and output streams, respectively. Thus, + this approach is very memory efficient and should be used for large body part data. + + - parameter fileURL: The file URL to write the multipart form data into. + + - throws: An `NSError` if encoding encounters an error. + */ + func writeEncodedDataToDisk(_ fileURL: URL) throws + +} diff --git a/DBNetworkStack/MultipartFormDataResource.swift b/DBNetworkStack/MultipartFormDataResource.swift new file mode 100644 index 0000000..65a6cc6 --- /dev/null +++ b/DBNetworkStack/MultipartFormDataResource.swift @@ -0,0 +1,43 @@ +// +// MultipartFormDataResource.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 Christian Himmelsbach on 27.09.16. +// + +import Foundation + +struct MultipartFormDataResource: MultipartFormDataResourceModelling { + public var request: NetworkRequestRepresening + public var parse: (_ data: Data) throws -> Model + public var encodingMemoryThreshold: UInt64 + public var encodeInMultipartFormData: (MultipartFormDataRepresenting) -> Void + + public init(request: NetworkRequestRepresening, parse: @escaping (_ data: Data) throws -> Model, + encodingMemoryThreshold: UInt64, encodeInMultipartFormData: @escaping (MultipartFormDataRepresenting) -> Void) { + self.request = request + self.parse = parse + self.encodingMemoryThreshold = encodingMemoryThreshold + self.encodeInMultipartFormData = encodeInMultipartFormData + } +} diff --git a/DBNetworkStack/MultipartFormDataResourceModelling.swift b/DBNetworkStack/MultipartFormDataResourceModelling.swift new file mode 100644 index 0000000..0f89a77 --- /dev/null +++ b/DBNetworkStack/MultipartFormDataResourceModelling.swift @@ -0,0 +1,44 @@ +// +// MultipartFormDataResourceModelling.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 Christian Himmelsbach on 27.09.16. +// + +import Foundation + +/** + `MultipartFormDataResourceModelling` describes a multipart form data resource. + It can be uploaded via HTTP(s) and the response parsed into the coresponding model object. + */ +protocol MultipartFormDataResourceModelling: ResourceModeling { + /** + Encodes all parts to be sent to the remote. + */ + var encodeInMultipartFormData: (MultipartFormDataRepresenting) -> Void { get } + + /** + Defines the size in bytes up to which data is encoded in memory. + */ + var encodingMemoryThreshold: UInt64 { get } +} diff --git a/DBNetworkStack/MultipartFormDataUploadAccessProviding.swift b/DBNetworkStack/MultipartFormDataUploadAccessProviding.swift new file mode 100644 index 0000000..646c66f --- /dev/null +++ b/DBNetworkStack/MultipartFormDataUploadAccessProviding.swift @@ -0,0 +1,55 @@ +// +// MultipartFormDataUploadAccessProviding.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 Christian Himmelsbach on 27.09.16. +// + +import Foundation + +/** + `MultipartFormDataUploadAccessProviding` provides access to the network for multipart formdata Requests. + */ +protocol MultipartFormDataUploadAccessProviding { + + /** + Uploads a multipart formdata resource asynchrony to remote location. + + - parameter request: The resource to upload. + - parameter relativeToBaseURL: The base URL on wich the request is based on + - parameter multipartFormData: Closure which configures the multipart form data body + - parameter encodingMemoryThreshold: Encoding threshold in bytes. + - parameter callback: Callback which gets called when the request finishes. + - parameter onNetworkTaskCreation: Callback which gets called, after encoding data and starting the upload. + The closure gets access to the created network task. + + */ + func upload( + _ request: NetworkRequestRepresening, + relativeToBaseURL baseURL: URL, + multipartFormData: @escaping (MultipartFormDataRepresenting) -> (), + encodingMemoryThreshold: UInt64, + callback: @escaping (Data?, HTTPURLResponse?, Error?) -> (), + onNetworkTaskCreation: @escaping (NetworkTaskRepresenting) -> () + ) +} diff --git a/DBNetworkStack/MultipartFormDataUploadService.swift b/DBNetworkStack/MultipartFormDataUploadService.swift new file mode 100644 index 0000000..73345b1 --- /dev/null +++ b/DBNetworkStack/MultipartFormDataUploadService.swift @@ -0,0 +1,63 @@ +// +// MultipartFormDataUploadService.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 Christian Himmelsbach on 29.09.16. +// + +import Foundation + +/** + `MultipartFormDataUploadService` handles network request for multipart form data resources by using a given MultipartFormDataUploadAccessProviding + */ +final class MultipartFormDataUploadService: MultipartFormDataUploadServiceProviding, NetworkResponseProcessing, BaseURLProviding { + + fileprivate let uploadAccess: MultipartFormDataUploadAccessProviding + let endPoints: Dictionary + + /** + Creates an `MultipartFormDataUploadService` instance with a given uploadAccess and a map of endPoints + + - parameter uploadAccess: Provides basic access to the network. + - parameter endPoints: Map of baseURLKey -> baseURLs + */ + + init(uploadAccess: MultipartFormDataUploadAccessProviding, endPoints: Dictionary) { + self.uploadAccess = uploadAccess + self.endPoints = endPoints + } + + func upload(_ resource: T, onCompletion: @escaping (T.Model) -> (), + onError: @escaping (DBNetworkStackError) -> (), onNetworkTaskCreation: @escaping (NetworkTaskRepresenting) -> Void) { + let baseURL = self.baseURL(with: resource) + uploadAccess.upload(resource.request, relativeToBaseURL: baseURL, multipartFormData: resource.encodeInMultipartFormData, + encodingMemoryThreshold: resource.encodingMemoryThreshold, callback: { data, response, error in + self.processAsyncResponse(response: response, resource: resource, data: data, error: error, onCompletion: onCompletion, onError: onError) + + }, onNetworkTaskCreation: { task in + DispatchQueue.main.async(execute: { + onNetworkTaskCreation(task) + }) + }) + } +} diff --git a/DBNetworkStack/MultipartFormDataUploadServiceProviding.swift b/DBNetworkStack/MultipartFormDataUploadServiceProviding.swift new file mode 100644 index 0000000..7a207fc --- /dev/null +++ b/DBNetworkStack/MultipartFormDataUploadServiceProviding.swift @@ -0,0 +1,50 @@ +// +// MultipartUploadPoviderServiceProviding.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 Christian Himmelsbach on 27.09.16. +// + +import Foundation + +/** + `MultipartFormDataUploadServiceProviding` provides access to upload multipart formdata resources. + */ +protocol MultipartFormDataUploadServiceProviding { + + /** + Uploads a multipart formdata resource to a remote location. + + - parameter resource: The resource to upload to. + - parameter onCompletion: Callback which gets called when uploading and tranforming the response into model succeeds. + - parameter onError: Callback which gets called when uploading or tranforming the response fails. + - parameter onNetworkTaskCreation: Callback which gets called, after encoding data and starting the upload. + The closure gets access to the created network task. + */ + func upload( + _ resource: T, + onCompletion: @escaping (T.Model) -> (), + onError: @escaping (DBNetworkStackError) -> (), + onNetworkTaskCreation: @escaping (NetworkTaskRepresenting) -> () + ) +} diff --git a/DBNetworkStack/NetworkAccessProviding.swift b/DBNetworkStack/NetworkAccessProviding.swift index 587aabe..c264cf3 100644 --- a/DBNetworkStack/NetworkAccessProviding.swift +++ b/DBNetworkStack/NetworkAccessProviding.swift @@ -1,24 +1,26 @@ // // NetworkAccessProviding.swift -// DBNetworkStack // -// Legal Notice! DB Systel GmbH proprietary License! -// -// Copyright (C) 2015 DB Systel GmbH -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// This code is protected by copyright law and is the exclusive property of +// Copyright (C) 2016 DB Systel GmbH. // DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// Consent to use ("licence") shall be granted solely on the basis of a -// written licence agreement signed by the customer and DB Systel GmbH. Any -// other use, in particular copying, redistribution, publication or -// modification of this code without written permission of DB Systel GmbH is -// expressly prohibited. - -// In the event of any permitted copying, redistribution or publication of -// this code, no changes in or deletion of author attribution, trademark -// legend or copyright notice shall be made. +// +// 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 31.08.16. // @@ -30,12 +32,13 @@ import Foundation */ public protocol NetworkAccessProviding { /** - Fetches a ressource asynchrony from remote location. + Fetches a resource asynchrony from remote location. - - parameter request: The ressource you want to fetch. + - parameter request: The resource you want to fetch. - parameter callback: Callback which gets called when the request finishes. - returns: the running network task */ - func load(request request: NSURLRequest, callback: (NSData?, NSHTTPURLResponse?, NSError?) -> ()) -> NetworkTask + func load(request: URLRequest, callback: @escaping (Data?, HTTPURLResponse?, Error?) -> ()) -> NetworkTaskRepresenting + } diff --git a/DBNetworkStack/NetworkRequest.swift b/DBNetworkStack/NetworkRequest.swift index 5a7af3f..f4ff948 100644 --- a/DBNetworkStack/NetworkRequest.swift +++ b/DBNetworkStack/NetworkRequest.swift @@ -1,24 +1,26 @@ // // NetworkRequest.swift -// DBNetworkStack // -// Legal Notice! DB Systel GmbH proprietary License! -// -// Copyright (C) 2015 DB Systel GmbH -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// This code is protected by copyright law and is the exclusive property of +// Copyright (C) 2016 DB Systel GmbH. // DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// Consent to use ("licence") shall be granted solely on the basis of a -// written licence agreement signed by the customer and DB Systel GmbH. Any -// other use, in particular copying, redistribution, publication or -// modification of this code without written permission of DB Systel GmbH is -// expressly prohibited. - -// In the event of any permitted copying, redistribution or publication of -// this code, no changes in or deletion of author attribution, trademark -// legend or copyright notice shall be made. +// +// 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 21.07.16. // @@ -26,20 +28,33 @@ import Foundation /** - See `NetworkRequestRepresening` for details. + `NetworkRequest` represents a network reuqest with all components needed to retrieve correct resources. */ public struct NetworkRequest: NetworkRequestRepresening { public let path: String public let baseURLKey: BaseURLKey public let HTTPMethod: DBNetworkStack.HTTPMethod - public let parameter: Dictionary? - public let body: NSData? + public let parameter: Dictionary? + public let body: Data? public let allHTTPHeaderFields: Dictionary? } public extension NetworkRequest { + // swiftlint:disable line_length - public init(path: String, baseURLKey: BaseURLKey, HTTPMethod: DBNetworkStack.HTTPMethod = .GET, parameter: Dictionary? = nil, body: NSData? = nil, allHTTPHeaderField: Dictionary? = nil) { + + /// Creates a instance of `NetworkRequest` with given parameters + /// + /// - Parameters: + /// - path: the relative path to the source without the base url. + /// - baseURLKey: a key to a baseurl which was registerd at `Networkservice` + /// - HTTPMethod: http method to fetch the request with + /// - parameter: url parameter for the request. + /// - body: the body of the request encoded as data + /// - allHTTPHeaderField: the http headerfileds for the request + public init(path: String, baseURLKey: BaseURLKey, + HTTPMethod: DBNetworkStack.HTTPMethod = .GET, parameter: Dictionary? = nil, + body: Data? = nil, allHTTPHeaderField: Dictionary? = nil) { self.path = path self.baseURLKey = baseURLKey self.HTTPMethod = HTTPMethod diff --git a/DBNetworkStack/NetworkRequestRepresening.swift b/DBNetworkStack/NetworkRequestRepresening.swift index 8963a59..402bd2f 100644 --- a/DBNetworkStack/NetworkRequestRepresening.swift +++ b/DBNetworkStack/NetworkRequestRepresening.swift @@ -1,24 +1,26 @@ // // NetworkResourceRepresening.swift -// DBNetworkStack // -// Legal Notice! DB Systel GmbH proprietary License! -// -// Copyright (C) 2015 DB Systel GmbH -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// This code is protected by copyright law and is the exclusive property of +// Copyright (C) 2016 DB Systel GmbH. // DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// Consent to use ("licence") shall be granted solely on the basis of a -// written licence agreement signed by the customer and DB Systel GmbH. Any -// other use, in particular copying, redistribution, publication or -// modification of this code without written permission of DB Systel GmbH is -// expressly prohibited. - -// In the event of any permitted copying, redistribution or publication of -// this code, no changes in or deletion of author attribution, trademark -// legend or copyright notice shall be made. +// +// 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 21.07.16. // @@ -26,11 +28,11 @@ import Foundation /** - `NetworkRequestRepresening` represents a networkreuqest with all components needed to retrieve correct ressources. + `NetworkRequestRepresening` represents a networkreuqest with all components needed to retrieve correct resources. */ public protocol NetworkRequestRepresening { /** - Path to the remote ressource. + Path to the remote resource. */ var path: String { get } @@ -52,12 +54,12 @@ public protocol NetworkRequestRepresening { /** Parameters which will be send with the request. */ - var parameter: [String : AnyObject]? { get } + var parameter: [String : Any]? { get } /** Data payload of the request */ - var body: NSData? { get } + var body: Data? { get } } extension NetworkRequestRepresening { @@ -67,14 +69,14 @@ extension NetworkRequestRepresening { - parameter baseURL: baseURL for the resulting request. - returns: the equivalent request */ - public func urlRequest(with baseURL: NSURL) -> NSURLRequest { + public func urlRequest(with baseURL: URL) -> URLRequest { let absoluteURL = absoluteURLWith(baseURL) - let request = NSMutableURLRequest(URL: absoluteURL) + let request = NSMutableURLRequest(url: absoluteURL) request.allHTTPHeaderFields = allHTTPHeaderFields - request.HTTPMethod = HTTPMethod.rawValue - request.HTTPBody = body + request.httpMethod = HTTPMethod.rawValue + request.httpBody = body - return request + return request as URLRequest } /** @@ -83,18 +85,18 @@ extension NetworkRequestRepresening { - parameter baseURL: baseURL for the resulting url. - returns: absolute url for the request. */ - private func absoluteURLWith(baseURL: NSURL) -> NSURL { - guard let absoluteURL = NSURL(string: path, relativeToURL: baseURL) else { + fileprivate func absoluteURLWith(_ baseURL: URL) -> URL { + guard let absoluteURL = URL(string: path, relativeTo: baseURL) else { fatalError("Error createing absolute URL from path: \(path), with baseURL: \(baseURL)") } - let urlComponents = NSURLComponents(URL: absoluteURL, resolvingAgainstBaseURL: true) - if let parameter = parameter, let urlComponents = urlComponents where !parameter.isEmpty { + let urlComponents = URLComponents(url: absoluteURL, resolvingAgainstBaseURL: true) + if let parameter = parameter, var urlComponents = urlComponents, !parameter.isEmpty { let percentEncodedQuery = parameter.map({ value in - return "\(value.0)=\(value.1)".stringByAddingPercentEncodingWithAllowedCharacters(.URLQueryAllowedCharacterSet()) + return "\(value.0)=\(value.1)".addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) }).flatMap { $0 } - urlComponents.percentEncodedQuery = percentEncodedQuery.joinWithSeparator("&") + urlComponents.percentEncodedQuery = percentEncodedQuery.joined(separator: "&") - guard let absoluteURL = urlComponents.URL else { + guard let absoluteURL = urlComponents.url else { fatalError("Error createing absolute URL from path: \(path), with baseURL: \(baseURL)") } return absoluteURL diff --git a/DBNetworkStack/NetworkService.swift b/DBNetworkStack/NetworkService.swift index be66e4a..3e6304d 100644 --- a/DBNetworkStack/NetworkService.swift +++ b/DBNetworkStack/NetworkService.swift @@ -1,37 +1,38 @@ // // NetworkService.swift -// DBNetworkStack // -// Legal Notice! DB Systel GmbH proprietary License! -// -// Copyright (C) 2015 DB Systel GmbH -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// This code is protected by copyright law and is the exclusive property of +// Copyright (C) 2016 DB Systel GmbH. // DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// Consent to use ("licence") shall be granted solely on the basis of a -// written licence agreement signed by the customer and DB Systel GmbH. Any -// other use, in particular copying, redistribution, publication or -// modification of this code without written permission of DB Systel GmbH is -// expressly prohibited. - -// In the event of any permitted copying, redistribution or publication of -// this code, no changes in or deletion of author attribution, trademark -// legend or copyright notice shall be made. +// +// 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 31.08.16. // import Foundation - /** - `NetworkService` handles network request for ressources by using `Alamofire` as the network layer. + `NetworkService` handles network request for resources by using a given `NetworkAccessProviding` */ -public final class NetworkService: NetworkServiceProviding { +public final class NetworkService: NetworkServiceProviding, BaseURLProviding { let networkAccess: NetworkAccessProviding - let endPoints: Dictionary + let endPoints: Dictionary /** Creates an `NetworkService` instance with a given networkAccess and a map of endPoints @@ -39,68 +40,19 @@ public final class NetworkService: NetworkServiceProviding { - parameter networkAccess: provides basic access to the network. - parameter endPoints: map of baseURLKey -> baseURLs */ - public init(networkAccess: NetworkAccessProviding, endPoints: Dictionary) { + public init(networkAccess: NetworkAccessProviding, endPoints: Dictionary) { self.networkAccess = networkAccess self.endPoints = endPoints } - public func request(ressource: T, onCompletion: (T.Model) -> (), onError: (DBNetworkStackError) -> ()) -> NetworkTask { - guard let baseURL = baseURL(with: ressource) else { - fatalError("Missing baseurl for key: \(ressource.request.baseURLKey.name)") - } - let reuqest = ressource.request.urlRequest(with: baseURL) + public func request(_ resource: T, onCompletion: @escaping (T.Model) -> (), + onError: @escaping (DBNetworkStackError) -> ()) -> NetworkTaskRepresenting { + let baseURL = self.baseURL(with: resource) + let reuqest = resource.request.urlRequest(with: baseURL) let dataTask = networkAccess.load(request: reuqest, callback: { data, response, error in - do { - let parsed = try self.process(response: response, ressource: ressource, data: data, error: error) - dispatch_async(dispatch_get_main_queue()) { - onCompletion(parsed) - } - } catch let parsingError as DBNetworkStackError { - dispatch_async(dispatch_get_main_queue()) { - return onError(parsingError) - } - } catch { - dispatch_async(dispatch_get_main_queue()) { - return onError(.UnknownError) - } - } + self.processAsyncResponse(response: response, resource: resource, data: data, error: error, onCompletion: onCompletion, onError: onError) }) return dataTask } - - public func process(response response: NSHTTPURLResponse?, ressource: T, data: NSData?, error: NSError?) throws -> T.Model { - if let error = error { - throw DBNetworkStackError.RequestError(error: error) - } - if let responseError = DBNetworkStackError(response: response) { - throw responseError - } - guard let data = data else { - throw DBNetworkStackError.SerializationError(description: "No data to serialize revied from the server", data: nil) - } - do { - return try ressource.parse(data: data) - } catch let error as CustomStringConvertible { - throw DBNetworkStackError.SerializationError(description: error.description, data: data) - } catch { - throw DBNetworkStackError.SerializationError(description: "Unknown serialization error", data: data) - } - } - - /** - Provides an baseURL for a given ressource. - - To be more flexible, a request does only contain a path and not a full URL. - Mapping has to be done in the service to get an registerd baseURL for the request. - - - parameter ressource: The ressource you want to get a baseURL for. - - - return matching baseURL to the given ressource - */ - private func baseURL(with ressource: T) -> NSURL? { - return endPoints[ressource.request.baseURLKey.name] - } - - } diff --git a/DBNetworkStack/NetworkServiceProviding.swift b/DBNetworkStack/NetworkServiceProviding.swift new file mode 100644 index 0000000..156cb24 --- /dev/null +++ b/DBNetworkStack/NetworkServiceProviding.swift @@ -0,0 +1,108 @@ +// +// NetworkServiceProviding.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 21.07.16. +// + +import Foundation + +/** + `NetworkServiceProviding` provides access to remote resources. + */ +public protocol NetworkServiceProviding: NetworkResponseProcessing { + /** + Fetches a resource asynchrony from remote location + + - parameter resource: The resource you want to fetch. + - parameter onComplition: Callback which gets called when fetching and tranforming into model succeeds. + - parameter onError: Callback which gets called when fetching or tranforming fails. + + - returns: the request + */ + func request(_ resource: T, onCompletion: @escaping (T.Model) -> (), + onError: @escaping (DBNetworkStackError) -> ()) -> NetworkTaskRepresenting +} + +public protocol NetworkResponseProcessing { + /** + Processes the results of an HTTPRequest and parses the result the matching Model type of the given resource. + + Great error handling should be implemented here as well. + + - parameter response: response from the server. Could be nil + - parameter resource: The resource matching the response. + - parameter data: Returned data. Could be nil. + - parameter error: the return error. Could be nil. + + - returns: the parsed model object. + */ + func process(response: HTTPURLResponse?, resource: T, data: Data?, error: Error?) throws -> T.Model +} + +extension NetworkResponseProcessing { + public func process(response: HTTPURLResponse?, resource: T, data: Data?, error: Error?) throws -> T.Model { + if let error = error { + throw DBNetworkStackError.requestError(error: error) + } + if let responseError = DBNetworkStackError(response: response) { + throw responseError + } + guard let data = data else { + throw DBNetworkStackError.serializationError(description: "No data to serialize revied from the server", data: nil) + } + do { + return try resource.parse(data) + } catch let error as CustomStringConvertible { + throw DBNetworkStackError.serializationError(description: error.description, data: data) + } catch { + throw DBNetworkStackError.serializationError(description: "Unknown serialization error", data: data) + } + } +} + +extension NetworkResponseProcessing { + func processAsyncResponse(response: HTTPURLResponse?, resource: T, data: Data?, + error: Error?, onCompletion: @escaping (T.Model) -> (), onError: @escaping (DBNetworkStackError) -> ()) { + do { + let parsed = try self.process( + response: response, + resource: resource, + data: data, + error: error + ) + DispatchQueue.main.async { + onCompletion(parsed) + } + } catch let parsingError as DBNetworkStackError { + DispatchQueue.main.async { + return onError(parsingError) + } + } catch { + DispatchQueue.main.async { + return onError(.unknownError) + } + } + } + +} diff --git a/DBNetworkStack/NetworkTask.swift b/DBNetworkStack/NetworkTask.swift deleted file mode 100644 index d9f4640..0000000 --- a/DBNetworkStack/NetworkTask.swift +++ /dev/null @@ -1,51 +0,0 @@ -// -// CancelableRequest.swift -// DBNetworkStack -// -// Legal Notice! DB Systel GmbH proprietary License! -// -// Copyright (C) 2015 DB Systel GmbH -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// This code is protected by copyright law and is the exclusive property of -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// Consent to use ("licence") shall be granted solely on the basis of a -// written licence agreement signed by the customer and DB Systel GmbH. Any -// other use, in particular copying, redistribution, publication or -// modification of this code without written permission of DB Systel GmbH is -// expressly prohibited. - -// In the event of any permitted copying, redistribution or publication of -// this code, no changes in or deletion of author attribution, trademark -// legend or copyright notice shall be made. -// -// Created by Lukas Schmidt on 22.08.16. -// - -import Foundation - -/** - `NetworkTask` is a task which runs async to fetch data. - */ -public protocol NetworkTask { - /** - Cancels a task. - */ - func cancel() - - /** - Resumes a task. - */ - func resume() - - /** - Suspends a task. - */ - func suspend() - - /** - Contains the current progress of a running task. - */ - var progress: NSProgress { get } -} diff --git a/DBNetworkStack/NetworkTaskRepresenting.swift b/DBNetworkStack/NetworkTaskRepresenting.swift new file mode 100644 index 0000000..509523d --- /dev/null +++ b/DBNetworkStack/NetworkTaskRepresenting.swift @@ -0,0 +1,53 @@ +// +// NetworkTaskRepresenting.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 22.08.16. +// + +import Foundation + +/** + `NetworkTaskRepresenting` is a task which runs async to fetch data. + */ +public protocol NetworkTaskRepresenting { + /** + Cancels a task. + */ + func cancel() + + /** + Resumes a task. + */ + func resume() + + /** + Suspends a task. + */ + func suspend() + + /** + Contains the current progress of a running task. + */ + var progress: Progress { get } +} diff --git a/DBNetworkStack/Resource.swift b/DBNetworkStack/Resource.swift new file mode 100644 index 0000000..36f2248 --- /dev/null +++ b/DBNetworkStack/Resource.swift @@ -0,0 +1,42 @@ +// +// Resource.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 21.07.16. +// + +import Foundation + +/** + `Resource` describes a remote resource of generic type. + The type can be fetched via HTTP(s) and parsed into the coresponding model object. + */ +public struct Resource: ResourceModeling { + public let request: NetworkRequestRepresening + public let parse: (_ data: Data) throws -> Model + + public init(request: NetworkRequestRepresening, parse: @escaping (Data) throws -> Model) { + self.request = request + self.parse = parse + } +} diff --git a/DBNetworkStack/ResourceModeling.swift b/DBNetworkStack/ResourceModeling.swift new file mode 100644 index 0000000..8689ecd --- /dev/null +++ b/DBNetworkStack/ResourceModeling.swift @@ -0,0 +1,48 @@ +// +// ResourceModeling.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 21.07.16. +// + +import Foundation +/** + `ResourceModeling` describes a remote resource of generic type. + The type can be fetched via HTTP(s) and parsed into the coresponding model object. + */ +public protocol ResourceModeling { + /** + Model object which coresponds to the remote resource + */ + associatedtype Model + + /** + The request to get the remote data payload + */ + var request: NetworkRequestRepresening { get } + + /** + Parses data into given Model + */ + var parse: (_ data: Data) throws -> Model { get } +} diff --git a/DBNetworkStack/ResourceServiceProviding.swift b/DBNetworkStack/ResourceServiceProviding.swift deleted file mode 100644 index bf7dd5e..0000000 --- a/DBNetworkStack/ResourceServiceProviding.swift +++ /dev/null @@ -1,57 +0,0 @@ -// -// ResourceServiceProviding.swift -// DBNetworkStack -// -// Legal Notice! DB Systel GmbH proprietary License! -// -// Copyright (C) 2015 DB Systel GmbH -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// This code is protected by copyright law and is the exclusive property of -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// Consent to use ("licence") shall be granted solely on the basis of a -// written licence agreement signed by the customer and DB Systel GmbH. Any -// other use, in particular copying, redistribution, publication or -// modification of this code without written permission of DB Systel GmbH is -// expressly prohibited. - -// In the event of any permitted copying, redistribution or publication of -// this code, no changes in or deletion of author attribution, trademark -// legend or copyright notice shall be made. -// -// Created by Lukas Schmidt on 21.07.16. -// - -import Foundation - -/** - `NetworkServiceProviding` provides access to remote ressources. - */ -public protocol NetworkServiceProviding { - /** - Fetches a ressource asynchrony from remote location - - - parameter ressource: The ressource you want to fetch. - - parameter onComplition: Callback which gets called when fetching and tranforming into model succeeds. - - parameter onError: Callback which gets called when fetching or tranforming fails. - - - returns: the request - */ - func request(ressource: T, onCompletion: (T.Model) -> (), onError: (DBNetworkStackError) -> ()) -> NetworkTask - - /** - Processes the results of an HTTPRequest and parses the result the matching Model type of the given ressource. - - Great error handling should be implemented here as well. - - - parameter response: response from the server. Could be nil - - parameter ressource: The ressource matching the response. - - parameter data: Returned data. Could be nil. - - parameter error: the return error. Could be nil. - - - returns: the parsed model object. - */ - func process(response response: NSHTTPURLResponse?, ressource: T, data: NSData?, error: NSError?) throws -> T.Model - -} diff --git a/DBNetworkStack/Ressource.swift b/DBNetworkStack/Ressource.swift deleted file mode 100644 index 599df75..0000000 --- a/DBNetworkStack/Ressource.swift +++ /dev/null @@ -1,37 +0,0 @@ -// -// Ressource.swift -// DBNetworkStack -// -// Legal Notice! DB Systel GmbH proprietary License! -// -// Copyright (C) 2015 DB Systel GmbH -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// This code is protected by copyright law and is the exclusive property of -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// Consent to use ("licence") shall be granted solely on the basis of a -// written licence agreement signed by the customer and DB Systel GmbH. Any -// other use, in particular copying, redistribution, publication or -// modification of this code without written permission of DB Systel GmbH is -// expressly prohibited. - -// In the event of any permitted copying, redistribution or publication of -// this code, no changes in or deletion of author attribution, trademark -// legend or copyright notice shall be made. -// -// Created by Lukas Schmidt on 21.07.16. -// - -import Foundation - - -public struct Ressource: RessourceModeling { - public let request: NetworkRequestRepresening - public let parse: (data: NSData) throws -> Model - - public init(request: NetworkRequestRepresening, parse: (NSData) throws -> Model) { - self.request = request - self.parse = parse - } -} diff --git a/DBNetworkStack/RessourceModeling.swift b/DBNetworkStack/RessourceModeling.swift deleted file mode 100644 index 2252c58..0000000 --- a/DBNetworkStack/RessourceModeling.swift +++ /dev/null @@ -1,46 +0,0 @@ -// -// RessourceModeling.swift -// DBNetworkStack -// -// Legal Notice! DB Systel GmbH proprietary License! -// -// Copyright (C) 2015 DB Systel GmbH -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// This code is protected by copyright law and is the exclusive property of -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// Consent to use ("licence") shall be granted solely on the basis of a -// written licence agreement signed by the customer and DB Systel GmbH. Any -// other use, in particular copying, redistribution, publication or -// modification of this code without written permission of DB Systel GmbH is -// expressly prohibited. - -// In the event of any permitted copying, redistribution or publication of -// this code, no changes in or deletion of author attribution, trademark -// legend or copyright notice shall be made. -// -// Created by Lukas Schmidt on 21.07.16. -// - -import Foundation -/** - `RessourceModeling` describes a remote ressource of generic type. - The type can be fetched via HTTP(s) and parsed into the coresponding model object. - */ -public protocol RessourceModeling { - /** - Model object which coresponds to the remote ressource - */ - associatedtype Model - - /** - The request to get the remote data payload - */ - var request: NetworkRequestRepresening { get } - - /** - Parses data into given Model - */ - var parse: (data: NSData) throws -> Model { get } -} diff --git a/DBNetworkStack/URLSessionNetworkAccess.swift b/DBNetworkStack/URLSessionNetworkAccess.swift index 7b37445..a0073cc 100644 --- a/DBNetworkStack/URLSessionNetworkAccess.swift +++ b/DBNetworkStack/URLSessionNetworkAccess.swift @@ -1,24 +1,26 @@ // // URLSessionNetworkAccess.swift -// DBNetworkStack // -// Legal Notice! DB Systel GmbH proprietary License! -// -// Copyright (C) 2015 DB Systel GmbH -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// This code is protected by copyright law and is the exclusive property of +// Copyright (C) 2016 DB Systel GmbH. // DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// Consent to use ("licence") shall be granted solely on the basis of a -// written licence agreement signed by the customer and DB Systel GmbH. Any -// other use, in particular copying, redistribution, publication or -// modification of this code without written permission of DB Systel GmbH is -// expressly prohibited. - -// In the event of any permitted copying, redistribution or publication of -// this code, no changes in or deletion of author attribution, trademark -// legend or copyright notice shall be made. +// +// 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.09.16. // @@ -28,24 +30,31 @@ import Foundation /** Adds conformens to `NetworkAccessProviding`. `NSURLSession` can now be used as a networkprovider. */ -extension NSURLSession: NetworkAccessProviding { - public func load(request request: NSURLRequest, callback: (NSData?, NSHTTPURLResponse?, NSError?) -> ()) -> NetworkTask { - let task = dataTaskWithRequest(request) { data, response, error in - callback(data, response as? NSHTTPURLResponse, error) - } - task.resume() - - return task - } -} +extension URLSession: URLSessionProtocol {} -extension NSURLSessionTask: NetworkTask { - public var progress: NSProgress { +extension URLSessionDataTask: NetworkTaskRepresenting { + public var progress: Progress { let totalBytesExpected = response?.expectedContentLength ?? NSURLSessionTransferSizeUnknown - let progress = NSProgress(totalUnitCount: totalBytesExpected) + let progress = Progress(totalUnitCount: totalBytesExpected) progress.totalUnitCount = totalBytesExpected progress.completedUnitCount = countOfBytesReceived return progress } } + +public protocol URLSessionProtocol: NetworkAccessProviding { + func dataTask(with request: URLRequest, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask +} + +public extension URLSessionProtocol { + func load(request: URLRequest, callback: @escaping (Data?, HTTPURLResponse?, Error?) -> ()) -> NetworkTaskRepresenting { + let task = dataTask(with: request, completionHandler: { data, response, error in + callback(data, response as? HTTPURLResponse, error) + }) + + task.resume() + + return task + } +} diff --git a/DBNetworkStackTests/AlamofireMock.swift b/DBNetworkStackTests/AlamofireMock.swift deleted file mode 100644 index c072348..0000000 --- a/DBNetworkStackTests/AlamofireMock.swift +++ /dev/null @@ -1,49 +0,0 @@ -// -// AlamofireMock.swift -// DBNetworkStack -// -// Legal Notice! DB Systel GmbH proprietary License! -// -// Copyright (C) 2015 DB Systel GmbH -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// This code is protected by copyright law and is the exclusive property of -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// Consent to use ("licence") shall be granted solely on the basis of a -// written licence agreement signed by the customer and DB Systel GmbH. Any -// other use, in particular copying, redistribution, publication or -// modification of this code without written permission of DB Systel GmbH is -// expressly prohibited. - -// In the event of any permitted copying, redistribution or publication of -// this code, no changes in or deletion of author attribution, trademark -// legend or copyright notice shall be made. -// -// Created by Lukas Schmidt on 26.07.16. -// - -import Foundation -//import Alamofire -//@testable import DBNetworkStack -// -//class AlamofireMock { -// var method: Alamofire.Method? -// var URLString: URLStringConvertible? -// var parameter: [String : AnyObject]? -// var encoding: Alamofire.ParameterEncoding? -// var headers: [String : String]? -// -// var returnedRequest: NetworkRequestModeling? -// -// -// func request(method method: Alamofire.Method, URLString: URLStringConvertible, parameters: [String : AnyObject]? , encoding: Alamofire.ParameterEncoding, headers: [String : String]?) -> NetworkRequestModeling { -// self.method = method -// self.URLString = URLString -// self.parameter = parameters -// self.encoding = encoding -// self.headers = headers -// -// return returnedRequest ?? NetworkRequestMock() -// } -//} \ No newline at end of file diff --git a/DBNetworkStackTests/AlamofireNetworkAccessTest.swift b/DBNetworkStackTests/AlamofireNetworkAccessTest.swift deleted file mode 100644 index 3b3e6f0..0000000 --- a/DBNetworkStackTests/AlamofireNetworkAccessTest.swift +++ /dev/null @@ -1,63 +0,0 @@ -// -// AlamofireNetworkAccessTest.swift -// DBNetworkStack -// -// Legal Notice! DB Systel GmbH proprietary License! -// -// Copyright (C) 2015 DB Systel GmbH -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// This code is protected by copyright law and is the exclusive property of -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// Consent to use ("licence") shall be granted solely on the basis of a -// written licence agreement signed by the customer and DB Systel GmbH. Any -// other use, in particular copying, redistribution, publication or -// modification of this code without written permission of DB Systel GmbH is -// expressly prohibited. - -// In the event of any permitted copying, redistribution or publication of -// this code, no changes in or deletion of author attribution, trademark -// legend or copyright notice shall be made. -// -// Created by Lukas Schmidt on 31.08.16. -// - -import XCTest -@testable import DBNetworkStack - - -//class AlamofireNetworkAccessTest: XCTestCase { -// -// var alamofireMock = AlamofireMock() -// var networkAccess: AlamofireNetworkAccessProvider! -// -// override func setUp() { -// networkAccess = AlamofireNetworkAccessProvider(requestFunction: alamofireMock.request, endPoints: [TestEndPoints.EndPoint.name: NSURL()]) -// } -// -// func testValidRequest() { -// //Given -// let parameter: [String: AnyObject] = ["id": 1, "name": "ICE"] -// let headers = ["testHeaderField": "testHeaderValue"] -// let request = NetworkRequest(path:"/train", baseURLKey: TestEndPoints.EndPoint, HTTPMethod: .GET, parameter: parameter, allHTTPHeaderField: headers) -// let baseURL = NSURL(string: "https://bahn.de")! -// -// //When -// networkAccess.load(request: request, relativeToBaseURL: baseURL, callback: { _, _, _ in -// -// }) -// -// //Then -// XCTAssertEqual(alamofireMock.URLString?.URLString, "https://bahn.de/train") -// XCTAssertEqual(alamofireMock.method, HTTPMethod.GET.alamofireMethod) -// //XCTAssertEqual(alamofireMock.parameters, url.URLString) -// -// //XCTAssert(alamofireMock.encoding! == Alamofire.ParameterEncoding.URL) -// XCTAssertEqual(alamofireMock.headers!, headers) -// XCTAssertEqual(alamofireMock.parameter?.count, 2) -// XCTAssertEqual(alamofireMock.parameter?["id"] as? Int, 1) -// XCTAssertEqual(alamofireMock.parameter?["name"] as? String, "ICE") -// -// } -//} \ No newline at end of file diff --git a/DBNetworkStackTests/BaseURLKeyTest.swift b/DBNetworkStackTests/BaseURLKeyTest.swift index eb9c2fa..5d1a345 100644 --- a/DBNetworkStackTests/BaseURLKeyTest.swift +++ b/DBNetworkStackTests/BaseURLKeyTest.swift @@ -1,24 +1,26 @@ // // BaseURLKeyTest.swift -// DBNetworkStack // -// Legal Notice! DB Systel GmbH proprietary License! -// -// Copyright (C) 2015 DB Systel GmbH -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// This code is protected by copyright law and is the exclusive property of +// Copyright (C) 2016 DB Systel GmbH. // DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// Consent to use ("licence") shall be granted solely on the basis of a -// written licence agreement signed by the customer and DB Systel GmbH. Any -// other use, in particular copying, redistribution, publication or -// modification of this code without written permission of DB Systel GmbH is -// expressly prohibited. - -// In the event of any permitted copying, redistribution or publication of -// this code, no changes in or deletion of author attribution, trademark -// legend or copyright notice shall be made. +// +// 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 16.09.16. // diff --git a/DBNetworkStackTests/DBNetworkStackErrorTest.swift b/DBNetworkStackTests/DBNetworkStackErrorTest.swift index 6416e14..b7110a0 100644 --- a/DBNetworkStackTests/DBNetworkStackErrorTest.swift +++ b/DBNetworkStackTests/DBNetworkStackErrorTest.swift @@ -1,20 +1,39 @@ // // DBNetworkStackErrorTest.swift -// DBNetworkStack +// +// 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 20.09.16. -// Copyright © 2016 DBSystel. All rights reserved. // import XCTest @testable import DBNetworkStack class DBNetworkStackErrorTest: XCTestCase { - + let url: URL! = URL(string: "https://bahn.de") func testInitFrom400() { //Given let statusCode = 400 - let response = NSHTTPURLResponse(URL: NSURL(), statusCode: statusCode, HTTPVersion: nil, headerFields: nil) + let response = HTTPURLResponse(url: url, statusCode: statusCode, httpVersion: nil, headerFields: nil) //When guard let error = DBNetworkStackError(response: response) else { @@ -23,7 +42,7 @@ class DBNetworkStackErrorTest: XCTestCase { //Then switch error { - case .ClientError(let response): + case .clientError(let response): XCTAssertEqual(response, response) default: XCTFail() @@ -33,7 +52,7 @@ class DBNetworkStackErrorTest: XCTestCase { func testInitFrom401() { //Given let statusCode = 401 - let response = NSHTTPURLResponse(URL: NSURL(), statusCode: statusCode, HTTPVersion: nil, headerFields: nil) + let response = HTTPURLResponse(url: url, statusCode: statusCode, httpVersion: nil, headerFields: nil) //When guard let error = DBNetworkStackError(response: response) else { @@ -42,7 +61,7 @@ class DBNetworkStackErrorTest: XCTestCase { //Then switch error { - case .Unauthorized(let response): + case .unauthorized(let response): XCTAssertEqual(response, response) default: XCTFail() @@ -52,7 +71,7 @@ class DBNetworkStackErrorTest: XCTestCase { func testInitFrom2xx() { //Given let statusCode = 200 - let response = NSHTTPURLResponse(URL: NSURL(), statusCode: statusCode, HTTPVersion: nil, headerFields: nil) + let response = HTTPURLResponse(url: url, statusCode: statusCode, httpVersion: nil, headerFields: nil) //When let error = DBNetworkStackError(response: response) @@ -64,7 +83,7 @@ class DBNetworkStackErrorTest: XCTestCase { func testInitFrom5xx() { //Given let statusCode = 511 - let response = NSHTTPURLResponse(URL: NSURL(), statusCode: statusCode, HTTPVersion: nil, headerFields: nil) + let response = HTTPURLResponse(url: url, statusCode: statusCode, httpVersion: nil, headerFields: nil) //When guard let error = DBNetworkStackError(response: response) else { @@ -73,7 +92,7 @@ class DBNetworkStackErrorTest: XCTestCase { //Then switch error { - case .ServerError(let response): + case .serverError(let response): XCTAssertEqual(response, response) default: XCTFail() @@ -83,7 +102,7 @@ class DBNetworkStackErrorTest: XCTestCase { func testInitFromInvalid() { //Given let statusCode = 900 - let response = NSHTTPURLResponse(URL: NSURL(), statusCode: statusCode, HTTPVersion: nil, headerFields: nil) + let response = HTTPURLResponse(url: url, statusCode: statusCode, httpVersion: nil, headerFields: nil) //When let error = DBNetworkStackError(response: response) diff --git a/DBNetworkStackTests/JSONArrayResourceTest.swift b/DBNetworkStackTests/JSONArrayResourceTest.swift new file mode 100644 index 0000000..7115a36 --- /dev/null +++ b/DBNetworkStackTests/JSONArrayResourceTest.swift @@ -0,0 +1,73 @@ +// +// JSONArrayResourceTest.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 01.09.16. +// + +import XCTest +@testable import DBNetworkStack + +class JSONArrayResourceTest: XCTestCase { + func testResource() { + //Given + let request = NetworkRequest(path: "/trains", baseURLKey: "") + let resource = JSONArrayResource(request: request) + + //When + let fetchedTrains = try? resource.parse(Train.validJSONArrayData) + + //Then + XCTAssertNotNil(fetchedTrains) + XCTAssertEqual(fetchedTrains?.count, 3) + XCTAssertEqual(fetchedTrains?.first?.name, "ICE") + XCTAssertEqual(fetchedTrains?.last?.name, "TGV") + } + + func testResourceWithInvalidData() { + //Given + let request = NetworkRequest(path: "/trains", baseURLKey: "") + let resource = JSONArrayResource(request: request) + + //When + do { + let _ = try resource.parse(Train.invalidJSONData) + XCTFail() + } catch { + + } + } + + func testResourceWithInvalidContainer() { + //Given + let request = NetworkRequest(path: "/trains", baseURLKey: "") + let resource = JSONArrayResource(request: request) + + //When + do { + let _ = try resource.parse(Train.validJSONData) + XCTFail() + } catch { + } + } +} diff --git a/DBNetworkStackTests/JSONArrayRessourceTest.swift b/DBNetworkStackTests/JSONArrayRessourceTest.swift deleted file mode 100644 index 0809f00..0000000 --- a/DBNetworkStackTests/JSONArrayRessourceTest.swift +++ /dev/null @@ -1,71 +0,0 @@ -// -// JSONArrayRessourceTest.swift -// DBNetworkStack -// -// Legal Notice! DB Systel GmbH proprietary License! -// -// Copyright (C) 2015 DB Systel GmbH -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// This code is protected by copyright law and is the exclusive property of -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// Consent to use ("licence") shall be granted solely on the basis of a -// written licence agreement signed by the customer and DB Systel GmbH. Any -// other use, in particular copying, redistribution, publication or -// modification of this code without written permission of DB Systel GmbH is -// expressly prohibited. - -// In the event of any permitted copying, redistribution or publication of -// this code, no changes in or deletion of author attribution, trademark -// legend or copyright notice shall be made. -// -// Created by Lukas Schmidt on 01.09.16. -// - -import XCTest -@testable import DBNetworkStack - -class JSONArrayRessourceTest: XCTestCase { - func testRessource() { - //Given - let request = NetworkRequest(path: "/trains", baseURLKey: "") - let ressource = JSONArrayRessource(request: request) - - //When - let fetchedTrains = try? ressource.parse(data: Train.validJSONArrayData) - - //Then - XCTAssertNotNil(fetchedTrains) - XCTAssertEqual(fetchedTrains?.count, 3) - XCTAssertEqual(fetchedTrains?.first?.name, "ICE") - XCTAssertEqual(fetchedTrains?.last?.name, "TGV") - } - - func testRessourceWithInvalidData() { - //Given - let request = NetworkRequest(path: "/trains", baseURLKey: "") - let ressource = JSONArrayRessource(request: request) - - //When - do { - let _ = try ressource.parse(data: Train.invalidJSONData) - XCTFail() - } catch { - - } - } - - func testRessourceWithInvalidContainer() { - //Given - let request = NetworkRequest(path: "/trains", baseURLKey: "") - let ressource = JSONArrayRessource(request: request) - - //When - do { - let _ = try ressource.parse(data: Train.validJSONData) - XCTFail() - } catch { - } - } -} diff --git a/DBNetworkStackTests/JSONResourceTest.swift b/DBNetworkStackTests/JSONResourceTest.swift new file mode 100644 index 0000000..480009d --- /dev/null +++ b/DBNetworkStackTests/JSONResourceTest.swift @@ -0,0 +1,58 @@ +// +// JSONResourceTest.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 30.08.16. +// + +import XCTest +@testable import DBNetworkStack + +class JSONResourceTest: XCTestCase { + func testResource() { + //Given + let request = NetworkRequest(path: "/train", baseURLKey: "") + let resource = JSONResource(request: request) + + //When + let fetchedTrain = try? resource.parse(Train.validJSONData) + + //Then + XCTAssertNotNil(fetchedTrain) + XCTAssertEqual(fetchedTrain?.name, "ICE") + } + + func testResourceWithInvalidData() { + //Given + let request = NetworkRequest(path: "/train", baseURLKey: "") + let resource = JSONResource(request: request) + + //When + do { + let _ = try resource.parse(Train.invalidJSONData) + XCTFail() + } catch { + } + } + +} diff --git a/DBNetworkStackTests/JSONRessourceTest.swift b/DBNetworkStackTests/JSONRessourceTest.swift deleted file mode 100644 index a7584b8..0000000 --- a/DBNetworkStackTests/JSONRessourceTest.swift +++ /dev/null @@ -1,59 +0,0 @@ -// -// JSONRessourceTest.swift -// DBNetworkStack -// -// Legal Notice! DB Systel GmbH proprietary License! -// -// Copyright (C) 2015 DB Systel GmbH -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// This code is protected by copyright law and is the exclusive property of -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// Consent to use ("licence") shall be granted solely on the basis of a -// written licence agreement signed by the customer and DB Systel GmbH. Any -// other use, in particular copying, redistribution, publication or -// modification of this code without written permission of DB Systel GmbH is -// expressly prohibited. - -// In the event of any permitted copying, redistribution or publication of -// this code, no changes in or deletion of author attribution, trademark -// legend or copyright notice shall be made. -// -// Created by Lukas Schmidt on 30.08.16. -// - -import XCTest -@testable import DBNetworkStack - -class JSONRessourceTest: XCTestCase { - func testRessource() { - //Given - let request = NetworkRequest(path: "/train", baseURLKey: "") - let ressource = JSONRessource(request: request) - - //When - let fetchedTrain = try! ressource.parse(data: Train.validJSONData) - - - //Then - XCTAssertNotNil(fetchedTrain) - XCTAssertEqual(fetchedTrain.name, "ICE") - } - - func testRessourceWithInvalidData() { - //Given - let request = NetworkRequest(path: "/train", baseURLKey: "") - let ressource = JSONRessource(request: request) - - //When - do { - let _ = try ressource.parse(data: Train.invalidJSONData) - XCTFail() - } catch { - } - } - -} - - diff --git a/DBNetworkStackTests/MulitpartFormDataRepresentingMock.swift b/DBNetworkStackTests/MulitpartFormDataRepresentingMock.swift new file mode 100644 index 0000000..6f52c97 --- /dev/null +++ b/DBNetworkStackTests/MulitpartFormDataRepresentingMock.swift @@ -0,0 +1,51 @@ +// +// MulitpartFormDataRepresentingMock.swift +// DBNetworkStack +// +// Created by Lukas Schmidt on 04.10.16. +// Copyright © 2016 DBSystel. All rights reserved. +// + +import Foundation +@testable import DBNetworkStack + +//class MulitpartFormDataRepresentingMock: MultipartFormDataRepresenting { +// var contentType: String = "multipart/form-data" +// var contentLength: UInt64 = 128 +// var boundary: String = "" +// +// func appendBodyPart(data data: Data, name: String) { +// +// } +// +// func appendBodyPart(data data: Data, name: String, mimeType: String) { +// +// } +// +// func appendBodyPart(fileURL fileURL: URL, name: String, fileName: String, mimeType: String) { +// +// } +// +// func appendBodyPart(fileURL fileURL: URL, name: String) { +// +// } +// +// func appendBodyPart(data data: Data, name: String, fileName: String, mimeType: String) { +// } +// +// func appendBodyPart(stream stream: InputStream, length: UInt64, headers: [String : String]) { +// +// } +// +// func appendBodyPart(stream stream: InputStream, length: UInt64, name: String, fileName: String, mimeType: String) { +// +// } +// +// func encode() throws -> Data { +// return Data() +// } +// +// func writeEncodedDataToDisk(_ fileURL: URL) throws { +// +// } +//} diff --git a/DBNetworkStackTests/MultipartFormDataUploadServiceTests.swift b/DBNetworkStackTests/MultipartFormDataUploadServiceTests.swift new file mode 100644 index 0000000..4bc9c55 --- /dev/null +++ b/DBNetworkStackTests/MultipartFormDataUploadServiceTests.swift @@ -0,0 +1,69 @@ +// +// MultipartFormDataUploadServiceTests.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 Christian Himmelsbach on 29.09.16. +// + +import XCTest +@testable import DBNetworkStack + +//class MultipartFormDataUploadServiceTests: XCTestCase { +// +// var networkAccess = UploadAccessServiceMock() +// var service: MultipartFormDataUploadServiceProviding! +// +// override func setUp() { +// super.setUp() +// let url: URL! = URL(string: "http://bahn.de") +// service = MultipartFormDataUploadService( +// uploadAccess: networkAccess, +// endPoints: [ TestEndPoints.endPoint.name: url] +// ) +// } +// +// func testUpload() { +// //Given +// let request = NetworkRequest(path: "/train", baseURLKey: TestEndPoints.endPoint) +// let resource = MultipartFormDataResource(request: request, parse: { $0 }, +// encodingMemoryThreshold: 200, encodeInMultipartFormData: { +// formdata in +// }) +// networkAccess.changeMock(data: Train.validJSONData, response: nil, error: nil) +// var didCreateTask = false +// //When +// let expection = expectation(description: "loadValidRequest") +// service.upload(resource, onCompletion: { data in +// XCTAssertEqual(Train.validJSONData, data) +// XCTAssert(didCreateTask) +// expection.fulfill() +// }, onError: { err in +// print(err) +// XCTFail() +// }, onNetworkTaskCreation: { task in +// didCreateTask = true +// }) +// waitForExpectations(timeout: 5, handler: nil) +// } +// +//} diff --git a/DBNetworkStackTests/NetworkRequestMock.swift b/DBNetworkStackTests/NetworkRequestMock.swift deleted file mode 100644 index 559b4d3..0000000 --- a/DBNetworkStackTests/NetworkRequestMock.swift +++ /dev/null @@ -1,50 +0,0 @@ -// -// NetworkRequestMock.swift -// DBNetworkStack -// -// Legal Notice! DB Systel GmbH proprietary License! -// -// Copyright (C) 2015 DB Systel GmbH -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// This code is protected by copyright law and is the exclusive property of -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// Consent to use ("licence") shall be granted solely on the basis of a -// written licence agreement signed by the customer and DB Systel GmbH. Any -// other use, in particular copying, redistribution, publication or -// modification of this code without written permission of DB Systel GmbH is -// expressly prohibited. - -// In the event of any permitted copying, redistribution or publication of -// this code, no changes in or deletion of author attribution, trademark -// legend or copyright notice shall be made. -// -// Created by Lukas Schmidt on 26.07.16. -// - -import Foundation -@testable import DBNetworkStack - -//class NetworkRequestMock: NetworkRequestModeling { -// let data: NSData? -// let error: NSError? -// -// init(data: NSData?, error: NSError? = nil) { -// self.data = data -// self.error = error -// } -// -// convenience init() { -// self.init(data: nil, error: nil) -// } -// -// func response(queue queue: dispatch_queue_t?, completionHandler: (NSURLRequest?, NSHTTPURLResponse?, NSData?, NSError?) -> Void) -> Self { -// completionHandler(nil, nil, data, error) -// return self -// } -// -// func cancel() { -// -// } -//} \ No newline at end of file diff --git a/DBNetworkStackTests/NetworkRequestTest.swift b/DBNetworkStackTests/NetworkRequestTest.swift index cb0fe5e..01b08fb 100644 --- a/DBNetworkStackTests/NetworkRequestTest.swift +++ b/DBNetworkStackTests/NetworkRequestTest.swift @@ -1,9 +1,28 @@ // // NetworkRequestTest.swift -// DBNetworkStack +// +// 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 20.09.16. -// Copyright © 2016 DBSystel. All rights reserved. // import XCTest @@ -16,20 +35,22 @@ class NetworkRequestTest: XCTestCase { let path = "/index.html" let baseURLKey = "Key" let httpMethod = HTTPMethod.GET - let parameter = ["test1": 1, "test2": "2"] - let body = "hallo body data".dataUsingEncoding(NSUTF8StringEncoding)! + let parameter: [String : Any] = ["test1": 1, "test2": "2"] as [String : Any] + let body: Data! = "hallo body data".data(using: String.Encoding.utf8) let headerFields: Dictionary = [:] - let baseURL = NSURL(string: "https://www.bahn.de/")! - + let baseURL: URL! = URL(string: "https://www.bahn.de/") + //When - let request = NetworkRequest(path: path, baseURLKey: baseURLKey, HTTPMethod: httpMethod, parameter: parameter, body: body, allHTTPHeaderFields: headerFields) + let request = NetworkRequest(path: path, baseURLKey: baseURLKey, + HTTPMethod: httpMethod, parameter: parameter, + body: body, allHTTPHeaderFields: headerFields) //Then let urlRequest = request.urlRequest(with: baseURL) - XCTAssertEqual(urlRequest.URL?.absoluteString, "https://www.bahn.de/index.html?test2=2&test1=1") - XCTAssertEqual(urlRequest.HTTPMethod, httpMethod.rawValue) - XCTAssertEqual(urlRequest.HTTPBody, body) + XCTAssertEqual(urlRequest.url?.absoluteString, "https://www.bahn.de/index.html?test1=1&test2=2") + XCTAssertEqual(urlRequest.httpMethod, httpMethod.rawValue) + XCTAssertEqual(urlRequest.httpBody, body) XCTAssertEqual(urlRequest.allHTTPHeaderFields!, headerFields) } } diff --git a/DBNetworkStackTests/NetworkServiceMock.swift b/DBNetworkStackTests/NetworkServiceMock.swift index 4c6d279..879bdb9 100644 --- a/DBNetworkStackTests/NetworkServiceMock.swift +++ b/DBNetworkStackTests/NetworkServiceMock.swift @@ -1,24 +1,26 @@ // // NetworkServiceMock.swift -// DBNetworkStack // -// Legal Notice! DB Systel GmbH proprietary License! -// -// Copyright (C) 2015 DB Systel GmbH -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// This code is protected by copyright law and is the exclusive property of +// Copyright (C) 2016 DB Systel GmbH. // DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// Consent to use ("licence") shall be granted solely on the basis of a -// written licence agreement signed by the customer and DB Systel GmbH. Any -// other use, in particular copying, redistribution, publication or -// modification of this code without written permission of DB Systel GmbH is -// expressly prohibited. - -// In the event of any permitted copying, redistribution or publication of -// this code, no changes in or deletion of author attribution, trademark -// legend or copyright notice shall be made. +// +// 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 30.08.16. // @@ -26,40 +28,21 @@ import Foundation import DBNetworkStack -class NetworkTaskMock: NetworkTask { - var isCanceld = false - func cancel() { - isCanceld = true - } - - func resume() { - - } - - func suspend() { - - } - - var progress: NSProgress { - return NSProgress() - } -} - class NetworkAccessMock: NetworkAccessProviding { - private(set) var data: NSData? - private(set) var response: NSHTTPURLResponse? - private(set) var error: NSError? + fileprivate(set) var data: Data? + fileprivate(set) var response: HTTPURLResponse? + fileprivate(set) var error: NSError? - private(set) var request: NSURLRequest? + fileprivate(set) var request: URLRequest? - func load(request request: NSURLRequest, callback: (NSData?, NSHTTPURLResponse?, NSError?) -> ()) -> NetworkTask { + func load(request: URLRequest, callback: @escaping (Data?, HTTPURLResponse?, Error?) -> ()) -> NetworkTaskRepresenting { self.request = request callback(data, response, error) return NetworkTaskMock() } - func changeMock(data data: NSData?, response: NSHTTPURLResponse?, error: NSError?) { + func changeMock(data: Data?, response: HTTPURLResponse?, error: NSError?) { self.data = data self.response = response self.error = error diff --git a/DBNetworkStackTests/NetworkServiceTest.swift b/DBNetworkStackTests/NetworkServiceTest.swift index 975c88e..9e12741 100644 --- a/DBNetworkStackTests/NetworkServiceTest.swift +++ b/DBNetworkStackTests/NetworkServiceTest.swift @@ -1,24 +1,26 @@ // // NetworkServiceTest.swift -// DBNetworkStack // -// Legal Notice! DB Systel GmbH proprietary License! -// -// Copyright (C) 2015 DB Systel GmbH -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// This code is protected by copyright law and is the exclusive property of +// Copyright (C) 2016 DB Systel GmbH. // DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// Consent to use ("licence") shall be granted solely on the basis of a -// written licence agreement signed by the customer and DB Systel GmbH. Any -// other use, in particular copying, redistribution, publication or -// modification of this code without written permission of DB Systel GmbH is -// expressly prohibited. - -// In the event of any permitted copying, redistribution or publication of -// this code, no changes in or deletion of author attribution, trademark -// legend or copyright notice shall be made. +// +// 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 26.07.16. // @@ -27,7 +29,7 @@ import XCTest @testable import DBNetworkStack enum TestEndPoints: BaseURLKey { - case EndPoint + case endPoint var name: String { return "endPointTestKey" @@ -38,9 +40,9 @@ class NetworkServiceTest: XCTestCase { var networkService: NetworkServiceProviding! var networkAccess = NetworkAccessMock() - let trainName: NSString = "ICE" + let trainName: String = "ICE" - let baseURL = NSURL(string: "//bahn.de")! + let baseURL: URL! = URL(string: "//bahn.de") override func setUp() { networkService = NetworkService(networkAccess: networkAccess, endPoints: ["endPointTestKey": baseURL]) @@ -48,39 +50,38 @@ class NetworkServiceTest: XCTestCase { func testValidRequest() { //Given - let request = NetworkRequest(path: "/train", baseURLKey: TestEndPoints.EndPoint) - let ressource = JSONRessource(request: request) + let request = NetworkRequest(path: "/train", baseURLKey: TestEndPoints.endPoint) + let resource = JSONResource(request: request) networkAccess.changeMock(data: Train.validJSONData, response: nil, error: nil) //When - let expection = expectationWithDescription("loadValidRequest") - networkService.request(ressource, onCompletion: { train in + let expection = expectation(description: "loadValidRequest") + _ = networkService.request(resource, onCompletion: { train in //Then XCTAssertEqual(train.name, self.trainName) - XCTAssertEqual(self.networkAccess.request?.URL?.absoluteString, "//bahn.de/train") + XCTAssertEqual(self.networkAccess.request?.url?.absoluteString, "//bahn.de/train") expection.fulfill() }, onError: { err in XCTFail() }) - waitForExpectationsWithTimeout(1, handler: nil) + waitForExpectations(timeout: 1, handler: nil) } func testNoData() { //Given - let request = NetworkRequest(path:"/train", baseURLKey: TestEndPoints.EndPoint) - let ressource = JSONRessource(request: request) + let request = NetworkRequest(path:"/train", baseURLKey: TestEndPoints.endPoint) + let resource = JSONResource(request: request) networkAccess.changeMock(data: nil, response: nil, error: nil) - //When - let expection = expectationWithDescription("testNoData") - networkService.request(ressource, onCompletion: { fetchedTrain in + let expection = expectation(description: "testNoData") + _ = networkService.request(resource, onCompletion: { fetchedTrain in XCTFail() }, onError: { error in switch error { - case .SerializationError(let description, let data): + case .serializationError(let description, let data): XCTAssertEqual("No data to serialize revied from the server", description) XCTAssertNil(data) expection.fulfill() @@ -89,97 +90,93 @@ class NetworkServiceTest: XCTestCase { } }) - waitForExpectationsWithTimeout(1, handler: nil) + waitForExpectations(timeout: 1, handler: nil) } func testInvalidData() { //Given - let request = NetworkRequest(path:"/train", baseURLKey: TestEndPoints.EndPoint) - let ressource = JSONRessource(request: request) + let request = NetworkRequest(path:"/train", baseURLKey: TestEndPoints.endPoint) + let resource = JSONResource(request: request) networkAccess.changeMock(data: Train.invalidJSONData, response: nil, error: nil) - //When - let expection = expectationWithDescription("testInvalidData") - networkService.request(ressource, onCompletion: { fetchedTrain in + let expection = expectation(description: "testInvalidData") + _ = networkService.request(resource, onCompletion: { fetchedTrain in XCTFail() }, onError: { error in //Then switch error { - case .SerializationError(_, _): + case .serializationError(_, _): expection.fulfill() default: XCTFail() } }) - waitForExpectationsWithTimeout(1, handler: nil) + waitForExpectations(timeout: 1, handler: nil) } func testInvalidJSONKeyData() { //Given - let request = NetworkRequest(path:"/train", baseURLKey: TestEndPoints.EndPoint) - let ressource = JSONRessource(request: request) + let request = NetworkRequest(path:"/train", baseURLKey: TestEndPoints.endPoint) + let resource = JSONResource(request: request) networkAccess.changeMock(data: Train.JSONDataWithInvalidKey, response: nil, error: nil) //When - let expection = expectationWithDescription("testInvalidJSONKeyData") - networkService.request(ressource, onCompletion: { fetchedTrain in + let expection = expectation(description: "testInvalidJSONKeyData") + _ = networkService.request(resource, onCompletion: { fetchedTrain in XCTFail() }, onError: { error in switch error { - case .SerializationError(_, _): + case .serializationError(_, _): expection.fulfill() default: XCTFail() } }) - waitForExpectationsWithTimeout(1, handler: nil) + waitForExpectations(timeout: 1, handler: nil) } - func testOnError() { //Given let error = NSError(domain: "", code: 0, userInfo: nil) - let request = NetworkRequest(path:"/train", baseURLKey: TestEndPoints.EndPoint) - let ressource = JSONRessource(request: request) + let request = NetworkRequest(path:"/train", baseURLKey: TestEndPoints.endPoint) + let resource = JSONResource(request: request) networkAccess.changeMock(data: nil, response: nil, error: error) - //When - let expection = expectationWithDescription("testOnError") - networkService.request(ressource, onCompletion: { fetchedTrain in + let expection = expectation(description: "testOnError") + _ = networkService.request(resource, onCompletion: { fetchedTrain in }, onError: { resultError in //Then switch resultError { - case .RequestError(let err): - XCTAssertEqual(err, error) + case .requestError(let err): + XCTAssertEqual(err as NSError, error) expection.fulfill() default: XCTFail() } }) - - waitForExpectationsWithTimeout(1, handler: nil) + waitForExpectations(timeout: 1, handler: nil) } func testOnStatusCodeError() { //Given - let request = NetworkRequest(path:"/train", baseURLKey: TestEndPoints.EndPoint) - let ressource = JSONRessource(request: request) - let response = NSHTTPURLResponse(URL: NSURL(), statusCode: 401, HTTPVersion: nil, headerFields: nil) + let request = NetworkRequest(path:"/train", baseURLKey: TestEndPoints.endPoint) + let resource = JSONResource(request: request) + let url: URL! = URL(string: "https://bahn.de") + let response = HTTPURLResponse(url: url, statusCode: 401, httpVersion: nil, headerFields: nil) networkAccess.changeMock(data: nil, response: response, error: nil) - //When - let expection = expectationWithDescription("testOnError") - networkService.request(ressource, onCompletion: { fetchedTrain in + let expection = expectation(description: "testOnError") + _ = networkService.request(resource, onCompletion: { fetchedTrain in }, onError: { resultError in //Then switch resultError { - case .Unauthorized(let res): + case .unauthorized(let res): XCTAssertEqual(res, response) expection.fulfill() default: @@ -187,7 +184,6 @@ class NetworkServiceTest: XCTestCase { } }) - - waitForExpectationsWithTimeout(1, handler: nil) + waitForExpectations(timeout: 1, handler: nil) } } diff --git a/DBNetworkStackTests/NetworkTaskMock.swift b/DBNetworkStackTests/NetworkTaskMock.swift new file mode 100644 index 0000000..79478b6 --- /dev/null +++ b/DBNetworkStackTests/NetworkTaskMock.swift @@ -0,0 +1,48 @@ +// +// NetworkTaskMock.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 Christian Himmelsbach on 29.09.16. +// + +import Foundation +import DBNetworkStack + +class NetworkTaskMock: NetworkTaskRepresenting { + var isCanceld = false + func cancel() { + isCanceld = true + } + + func resume() { + + } + + func suspend() { + + } + + var progress: Progress { + return Progress() + } +} diff --git a/DBNetworkStackTests/ResourceTest.swift b/DBNetworkStackTests/ResourceTest.swift new file mode 100644 index 0000000..54e81ef --- /dev/null +++ b/DBNetworkStackTests/ResourceTest.swift @@ -0,0 +1,60 @@ +// +// ResourceTest.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 01.09.16. +// + +import XCTest +@testable import DBNetworkStack + +class ResourceTest: XCTestCase { + + func testResource() { + //Given + let validData: Data! = "ICE".data(using: String.Encoding.utf8) + + let request = NetworkRequest(path: "/train", baseURLKey: "") + let resource = Resource(request: request, parse: { String(data: $0, encoding: String.Encoding.utf8) }) + + //When + let name = try? resource.parse(validData) + + //Then + XCTAssertNotNil(name) + XCTAssertEqual(name ?? nil, "ICE") + } + + func testResourceWithInvalidData() { + //Given + let validData = Data() + let request = NetworkRequest(path: "/train", baseURLKey: "") + let resource = JSONResource(request: request) + + //When + do { + let _ = try resource.parse(validData) + XCTFail() + } catch { } + } +} diff --git a/DBNetworkStackTests/RessourceTest.swift b/DBNetworkStackTests/RessourceTest.swift deleted file mode 100644 index e705f0b..0000000 --- a/DBNetworkStackTests/RessourceTest.swift +++ /dev/null @@ -1,59 +0,0 @@ -// -// RessourceTest.swift -// DBNetworkStack -// -// Legal Notice! DB Systel GmbH proprietary License! -// -// Copyright (C) 2015 DB Systel GmbH -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// This code is protected by copyright law and is the exclusive property of -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// Consent to use ("licence") shall be granted solely on the basis of a -// written licence agreement signed by the customer and DB Systel GmbH. Any -// other use, in particular copying, redistribution, publication or -// modification of this code without written permission of DB Systel GmbH is -// expressly prohibited. - -// In the event of any permitted copying, redistribution or publication of -// this code, no changes in or deletion of author attribution, trademark -// legend or copyright notice shall be made. -// -// Created by Lukas Schmidt on 01.09.16. -// - -import XCTest -@testable import DBNetworkStack - -class RessourceTest: XCTestCase { - - - func testRessource() { - //Given - let validData = "ICE".dataUsingEncoding(NSUTF8StringEncoding)! - let request = NetworkRequest(path: "/train", baseURLKey: "") - let ressource = Ressource(request: request, parse: { String(data: $0, encoding: NSUTF8StringEncoding) }) - - //When - let name = try? ressource.parse(data: validData) - - - //Then - XCTAssertNotNil(name) - XCTAssertEqual(name!!, "ICE") - } - - func testRessourceWithInvalidData() { - //Given - let validData = NSData() - let request = NetworkRequest(path: "/train", baseURLKey: "") - let ressource = JSONRessource(request: request) - - //When - do { - let _ = try ressource.parse(data: validData) - XCTFail() - } catch { } - } -} diff --git a/DBNetworkStackTests/TrainModel.swift b/DBNetworkStackTests/TrainModel.swift index 399e67c..be48506 100644 --- a/DBNetworkStackTests/TrainModel.swift +++ b/DBNetworkStackTests/TrainModel.swift @@ -1,24 +1,26 @@ // // TrainModel.swift -// DBNetworkStack // -// Legal Notice! DB Systel GmbH proprietary License! -// -// Copyright (C) 2015 DB Systel GmbH -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// This code is protected by copyright law and is the exclusive property of +// Copyright (C) 2016 DB Systel GmbH. // DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// Consent to use ("licence") shall be granted solely on the basis of a -// written licence agreement signed by the customer and DB Systel GmbH. Any -// other use, in particular copying, redistribution, publication or -// modification of this code without written permission of DB Systel GmbH is -// expressly prohibited. - -// In the event of any permitted copying, redistribution or publication of -// this code, no changes in or deletion of author attribution, trademark -// legend or copyright notice shall be made. +// +// 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 31.08.16. // @@ -31,29 +33,29 @@ struct Train { } extension Train: JSONMappable { - init(object: Dictionary) throws { + init(object: Dictionary) throws { if let name = object["name"] as? String { self.name = name - }else { + } else { throw NSError(domain: "", code: 0, userInfo: nil) } } } extension Train { - static var validJSONData: NSData { - return "{ \"name\": \"ICE\"}".dataUsingEncoding(NSUTF8StringEncoding)! + static var validJSONData: Data! { + return "{ \"name\": \"ICE\"}".data(using: String.Encoding.utf8) } - static var invalidJSONData: NSData { - return "{ name: \"ICE\"}".dataUsingEncoding(NSUTF8StringEncoding)! + static var invalidJSONData: Data! { + return "{ name: \"ICE\"}".data(using: String.Encoding.utf8) } - static var JSONDataWithInvalidKey: NSData { - return "{ \"namee\": \"ICE\"}".dataUsingEncoding(NSUTF8StringEncoding)! + static var JSONDataWithInvalidKey: Data! { + return "{ \"namee\": \"ICE\"}".data(using: String.Encoding.utf8) } - static var validJSONArrayData: NSData { - return "[{ \"name\": \"ICE\"}, { \"name\": \"IC\"}, { \"name\": \"TGV\"}]".dataUsingEncoding(NSUTF8StringEncoding)! + static var validJSONArrayData: Data! { + return "[{ \"name\": \"ICE\"}, { \"name\": \"IC\"}, { \"name\": \"TGV\"}]".data(using: String.Encoding.utf8) } } diff --git a/DBNetworkStackTests/URLSessionNetworkAccessTest.swift b/DBNetworkStackTests/URLSessionNetworkAccessTest.swift index 67e46fd..57b7ed2 100644 --- a/DBNetworkStackTests/URLSessionNetworkAccessTest.swift +++ b/DBNetworkStackTests/URLSessionNetworkAccessTest.swift @@ -1,24 +1,26 @@ // // URLSessionNetworkAccessTest.swift -// DBNetworkStack // -// Legal Notice! DB Systel GmbH proprietary License! -// -// Copyright (C) 2015 DB Systel GmbH -// DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// This code is protected by copyright law and is the exclusive property of +// Copyright (C) 2016 DB Systel GmbH. // DB Systel GmbH; Jürgen-Ponto-Platz 1; D-60329 Frankfurt am Main; Germany; http://www.dbsystel.de/ - -// Consent to use ("licence") shall be granted solely on the basis of a -// written licence agreement signed by the customer and DB Systel GmbH. Any -// other use, in particular copying, redistribution, publication or -// modification of this code without written permission of DB Systel GmbH is -// expressly prohibited. - -// In the event of any permitted copying, redistribution or publication of -// this code, no changes in or deletion of author attribution, trademark -// legend or copyright notice shall be made. +// +// 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 13.09.16. // @@ -26,23 +28,72 @@ import XCTest @testable import DBNetworkStack -//class URLSessionNetworkAccessTest: XCTestCase { -// var dataTask: NetworkTask! -// -// func testExample() { -// let expection = expectationWithDescription("wait") -// -// //Given -// let session: NetworkAccessProviding = NSURLSession(configuration: .ephemeralSessionConfiguration()) -// -// let request = NetworkRequest(path: "", baseURLKey: "bahn") -// -// //When -// session.load(request: request, relativeToBaseURL: NSURL(string: "https://www.bahn.de")!, callback: {data, res, error in -// -// expection.fulfill() -// }) -// -// waitForExpectationsWithTimeout(5, handler: nil) -// } -//} +class URLSessionProtocolMock: URLSessionProtocol { + var request: URLRequest? + var callback: ((Data?, URLResponse?, Error?) -> Void)? + + func dataTask(with request: URLRequest, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask { + self.request = request + self.callback = completionHandler + + let url: URL! = URL(string: "http://bahn.de") + return URLSession(configuration: .default).dataTask(with: url) + } +} + +class URLSessionNetworkAccessTest: XCTestCase { + + func testURLSession_MatchesTypeOfNetworkAccess() { + let _: NetworkAccessProviding = URLSession(configuration: .default) + } + + func test_URLSessionCreatsDataTask() { + //Given + let mock = URLSessionProtocolMock() + let url: URL! = URL(string: "http://bahn.de") + let urlRequest = URLRequest(url: url) + + //When + _ = mock.load(request: urlRequest, callback: { _, _, _ in + + }) + + //Then + XCTAssertNotNil(mock.request) + XCTAssertEqual(urlRequest, mock.request) + } + + func testURLSession_CallbackGetsRegistered() { + //Given + let mock = URLSessionProtocolMock() + let url: URL! = URL(string: "http://bahn.de") + let urlRequest = URLRequest(url: url) + var completionHanlderCalled = false + //When + _ = mock.load(request: urlRequest, callback: { _, _, _ in + completionHanlderCalled = true + }) + mock.callback?(nil, nil, nil) + + //Then + XCTAssert(completionHanlderCalled) + } + + func testURLSession_DataTaksGetsResumed() { + //Given + let mock = URLSessionProtocolMock() + let url: URL! = URL(string: "http://bahn.de") + let urlRequest = URLRequest(url: url) + + //When + let task = mock.load(request: urlRequest, callback: { _, _, _ in + }) + + //Then + guard let sessionTask = task as? URLSessionDataTask else { + XCTFail() + return + } + XCTAssert(sessionTask.state == .running) + } +} diff --git a/DBNetworkStackTests/UploadAccessServiceMock.swift b/DBNetworkStackTests/UploadAccessServiceMock.swift new file mode 100644 index 0000000..d4a1184 --- /dev/null +++ b/DBNetworkStackTests/UploadAccessServiceMock.swift @@ -0,0 +1,58 @@ +// +// UploadAccessServiceMock.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 Christian Himmelsbach on 29.09.16. +// + +import Foundation +@testable import DBNetworkStack + +//class UploadAccessServiceMock: MultipartFormDataUploadAccessProviding { +// +// var uploadData: Data? +// +// fileprivate var reponseData: Data? +// fileprivate var responseError: NSError? +// fileprivate var response: HTTPURLResponse? +// fileprivate var multipartFormData: ((MultipartFormDataRepresenting) -> ())? +// +// func upload(_ request: NetworkRequestRepresening, relativeToBaseURL baseURL: URL, multipartFormData: @escaping (MultipartFormDataRepresenting) -> (), +// encodingMemoryThreshold: UInt64, callback: @escaping (Data?, HTTPURLResponse?, Error?) -> (), +// onNetworkTaskCreation: @escaping (NetworkTaskRepresenting) -> ()) { +// DispatchQueue.main.async { +// multipartFormData(MulitpartFormDataRepresentingMock()) +// onNetworkTaskCreation(NetworkTaskMock()) +// +// DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(2.0)*Int64(NSEC_PER_SEC)) / Double(NSEC_PER_SEC), execute: { +// callback(self.reponseData, self.response, self.responseError) +// }) +// } +// } +// +// func changeMock(data: Data?, response: HTTPURLResponse?, error: NSError?) { +// self.reponseData = data +// self.response = response +// self.responseError = error +// } +//} diff --git a/Demo.playground/Contents.swift b/Demo.playground/Contents.swift deleted file mode 100644 index 2dd6344..0000000 --- a/Demo.playground/Contents.swift +++ /dev/null @@ -1,56 +0,0 @@ -//: Playground - noun: a place where people can play - -import UIKit -@testable import DBNetworkStack -import XCPlayground - -XCPlaygroundPage.currentPage.needsIndefiniteExecution = true - -public struct Station { - public let id: String - public let name: String -} - -extension Station: JSONMappable { - public init(object: [String: AnyObject]) throws { - id = object["id"] as! String - name = object["name"] as! String - } -} - -enum BaseURLs: String, BaseURLKey { - case BFA - case BahnDE - - var name: String { - return rawValue - } - - var URL: NSURL { - switch self { - case BFA: - return NSURL(string: "https://dbbfa.herokuapp.com/")! - case .BahnDE: - return NSURL(string: "https://www.bahn.de")! - } - } -} - -let baseURL = BaseURLs.BFA -let urlSessionNetworkAccess = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration()) -let service = NetworkService(networkAccess: urlSessionNetworkAccess, endPoints: [baseURL.name: baseURL.URL]) - -let searchTerm = "Frankfurt" - -let path = ("/v1/station/search") -let request = NetworkRequest(path: path, baseURLKey: baseURL, parameter: ["term": searchTerm]) -request.absoluteURLWith(baseURL.url).absoluteString -let ressource = JSONArrayRessource(request: request) - -let task = service.fetch(ressource, onCompletion: { station in - print(station) - }, onError: { error in - print(error) -}) - -print(task.progress) diff --git a/Demo.playground/timeline.xctimeline b/Demo.playground/timeline.xctimeline deleted file mode 100644 index bf468af..0000000 --- a/Demo.playground/timeline.xctimeline +++ /dev/null @@ -1,6 +0,0 @@ - - - - - diff --git a/JSONExample.playground/Contents.swift b/JSONExample.playground/Contents.swift new file mode 100644 index 0000000..78c9e8e --- /dev/null +++ b/JSONExample.playground/Contents.swift @@ -0,0 +1,34 @@ +//: Playground - noun: a place where people can play + +import DBNetworkStack +import PlaygroundSupport + +PlaygroundPage.current.needsIndefiniteExecution = true + +let url: URL! = URL(string: "https://httpbin.org") +let baseURLKey = "httpBin" + +let networkAccess = URLSession(configuration: .default) +let networkService = NetworkService(networkAccess: networkAccess, endPoints: [baseURLKey: url]) + +struct IPOrigin { + let ipAdress: String +} + +extension IPOrigin: JSONMappable { + init(object: Dictionary) throws { + guard let ipAdress = object["origin"] as? String else { + throw DBNetworkStackError.serializationError(description: "", data: nil) + } + self.ipAdress = ipAdress + } +} + +let request = NetworkRequest(path: "/ip", baseURLKey: baseURLKey) +let resource = JSONResource(request: request) + +networkService.request(resource, onCompletion: { origin in + print(origin) + }, onError: { error in + //Handle errors +}) diff --git a/Demo.playground/contents.xcplayground b/JSONExample.playground/contents.xcplayground similarity index 100% rename from Demo.playground/contents.xcplayground rename to JSONExample.playground/contents.xcplayground diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c3162d0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 DB Systel GmbH + +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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..9070ce0 --- /dev/null +++ b/README.md @@ -0,0 +1,137 @@ +# DBNetworkStack + +[![Build Status](https://travis-ci.org/dbsystel/DBNetworkStack.svg?branch=develop)](https://travis-ci.org/dbsystel/DBNetworkStack) +[![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) + +| | Main Features | +| --------- | ------------------------------ | +| 🛡 | Typed network resources | +| 🏠 | Protocol oriented architecture | +| 🔀 | Exchangeable implementations | +| 🚄 | Extendable API | +| ✅ | Fully unit tested | + +The idea behind this project comes from this [talk.objc.io article](https://talk.objc.io/episodes/S01E01-networking). + +## Basic Demo +Lets say you want to fetch a ``html`` string. + +First you have to create a service, by providing a network access. You can use NSURLSession out of the box or provide your own custom solution by implementing ```NetworkAccessProviding```. In addition you need to register baseURLs endpoints for request mapping. This gives you the flexibility to change your endpoints very easily when your environment changes. + +```swift + +let url = NSURL(string: "https://httpbin.org")! +let baseURLKey = "httpBin" + +let networkAccess = NSURLSession(configuration: .defaultSessionConfiguration()) +let networkService = NetworkService(networkAccess: networkAccess, endPoints: [baseURLKey: url]) + +``` + +Create a resource with a request to fetch your data. + +```swift + +let request = NetworkRequest(path: "/", baseURLKey: baseURLKey) +let resource = Resource(request: request, parse: { String(data: $0, encoding: NSUTF8StringEncoding) }) + +``` +Request your resource and handle the response +```swift +networkService.request(resource, onCompletion: { htmlText in + print(htmlText) +}, onError: { error in + //Handle errors +}) + +``` + +## JSON Mapping Demo +```swift +struct IPOrigin { + let ipAddress: String +} + +extension IPOrigin: JSONMappable { + init(object: Dictionary) throws { + /// Do your mapping + } +} + +let request = NetworkRequest(path: "/ip", baseURLKey: baseURLKey) +let resource = JSONResource(request: request) + +networkService.request(resource, onCompletion: { origin in + print(origin) +}, onError: { error in + //Handle errors +}) +``` + +## Extendability +The following example outlines how to extend DBNetworkStack to support XML response models: + +```swift +protocol XMLMappable { + init(object: Dictionary) throws +} + +struct XMLResource : ResourceModeling { + let request: NetworkRequestRepresening + + init(request: NetworkRequestRepresening) { + self.request = request + } + + var parse: (data: NSData) throws -> T { + return { data in + let xmlObject = // Your data to xml object conversion + try! T(object: xmlObject) as T + } + } +} +``` +```XMLMappable``` defines the protocol, response model objects must conform to. The model class conforming to this protocol is responsible to convert a generic representation of the model into it’s specialized form. +```XMLResource``` defines a resource based on a given ```XMLMappable``` model. The parse function is responsible of converting raw response data to a generic representation. + + +## Protocol oriented architecture / Exchangability + +The following table shows all the protocols and their default implementations. + +| Protocol | Default Implementation | +| -------------------------------- | ---------------------- | +| ```NetworkAccessProviding``` | ```NSURLSession``` | +| ```NetworkServiceProviding``` | ```NetworkService``` | +| ```NetworkRequestRepresenting``` | ```NetworkRequest``` | +| ```NetworkTaskRepresenting``` | ```NSURLSessionTask``` | +| ```ResourceModelling``` | ```Resource``` | + + + +## Requirements + +- iOS 9.0+ / macOS 10.10+ / tvOS 9.0+ / watchOS 2.0+ +- Xcode 8.0+ +- Swift 3.0 + +## Installation + +### 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" ~> 0.1 +``` +## 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. + +## Contact +Lukas Schmidt ([Mail](mailto:lukas.la.schmidt@deutschebahn.com), [@lightsprint09](https://twitter.com/lightsprint09)), +Christian Himmelsbach ([Mail](mailto:christian.himmelsbach@deutschebahn.com)) + +## License +DBNetworkStack is released under the MIT license. See LICENSE for details. diff --git a/SimpleDemo.playground/Contents.swift b/SimpleDemo.playground/Contents.swift new file mode 100644 index 0000000..172f358 --- /dev/null +++ b/SimpleDemo.playground/Contents.swift @@ -0,0 +1,19 @@ +//: Playground - noun: a place where people can play + +import DBNetworkStack +import PlaygroundSupport + +PlaygroundPage.current.needsIndefiniteExecution = true +let url: URL! = URL(string: "https://httpbin.org") +let baseURLKey = "httpBin" + +let networkAccess = URLSession(configuration: .default) +let networkService = NetworkService(networkAccess: networkAccess, endPoints: [baseURLKey: url]) +let request = NetworkRequest(path: "/", baseURLKey: baseURLKey) +let resource = Resource(request: request, parse: { String(data: $0, encoding: .utf8) }) + +networkService.request(resource, onCompletion: { htmlText in + print(htmlText) + }, onError: { error in + //Handle errors +}) diff --git a/SimpleDemo.playground/contents.xcplayground b/SimpleDemo.playground/contents.xcplayground new file mode 100644 index 0000000..5da2641 --- /dev/null +++ b/SimpleDemo.playground/contents.xcplayground @@ -0,0 +1,4 @@ + + + + \ No newline at end of file