Compare commits
No commits in common. "master" and "5.1.0" have entirely different histories.
|
@ -1,4 +1,4 @@
|
|||
// swift-tools-version:5.3
|
||||
// swift-tools-version:5.0
|
||||
|
||||
import PackageDescription
|
||||
|
||||
|
@ -8,16 +8,8 @@ let package = Package(
|
|||
.macOS(.v10_11),
|
||||
],
|
||||
dependencies: [
|
||||
.package(
|
||||
name: "PathKit",
|
||||
url: "https://github.com/kylef/PathKit",
|
||||
from: "1.0.0"
|
||||
),
|
||||
.package(
|
||||
name: "XCERepoConfigurator",
|
||||
url: "https://github.com/XCEssentials/RepoConfigurator",
|
||||
from: "3.0.0"
|
||||
)
|
||||
.package(url: "https://github.com/kylef/PathKit", from: "1.0.0"),
|
||||
.package(url: "https://github.com/XCEssentials/RepoConfigurator", from: "3.0.0")
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
|
|
|
@ -11,7 +11,7 @@ print("--- BEGIN of '\(Executable.name)' script ---")
|
|||
|
||||
// MARK: Parameters
|
||||
|
||||
Spec.BuildSettings.swiftVersion.value = "5.3"
|
||||
Spec.BuildSettings.swiftVersion.value = "5.0"
|
||||
|
||||
let localRepo = try Spec.LocalRepo.current()
|
||||
|
||||
|
|
|
@ -16,7 +16,8 @@ git:
|
|||
language: objective-c # fine for Swift as well
|
||||
|
||||
osx_image:
|
||||
- xcode12
|
||||
- xcode10.2
|
||||
- xcode11
|
||||
|
||||
before_script:
|
||||
# cd ./.setup && swift run && cd ./.. # RUN this manually!
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// swift-tools-version:5.3
|
||||
// swift-tools-version:5.0
|
||||
|
||||
import PackageDescription
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[](LICENSE)
|
||||
[](https://github.com/XCEssentials/APIClient/tags)
|
||||
[](Package.swift)
|
||||
[](https://swift.org)
|
||||
[](https://swift.org)
|
||||
[](Package.swift)
|
||||
[](https://travis-ci.com/XCEssentials/APIClient)
|
||||
|
||||
|
|
|
@ -39,15 +39,20 @@ struct BasicURLRequestFacilitator: URLRequestFacilitator
|
|||
public
|
||||
let sharedPrefixURL: URL
|
||||
|
||||
public
|
||||
let onEncodeRequest: OnEncodeRequest
|
||||
|
||||
// MARK: - Initializers
|
||||
|
||||
public
|
||||
init(
|
||||
sharedPrefixURL: URL,
|
||||
session: URLSession = .shared
|
||||
session: URLSession = .shared,
|
||||
onConfigureRequest: @escaping OnEncodeRequest = URLEncoding.default.encode
|
||||
)
|
||||
{
|
||||
self.sharedPrefixURL = sharedPrefixURL
|
||||
self.session = session
|
||||
self.onEncodeRequest = onConfigureRequest
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,10 +38,7 @@ struct RequestEncodingIssue: URLRequestFacilitatorError
|
|||
|
||||
public
|
||||
enum PrepareRequestIssue: URLRequestFacilitatorError
|
||||
{
|
||||
case conversionIntoDataFailed(Error)
|
||||
case conversionDataIntoJSONObjectFailed(Error)
|
||||
case conversionJSONObjectIntoDictionaryFailed(theObject: Any)
|
||||
{
|
||||
case invalidRelativePath(String)
|
||||
case requestEncodingFailed(RequestEncodingIssue)
|
||||
}
|
||||
|
|
|
@ -28,6 +28,11 @@ import Foundation
|
|||
|
||||
//---
|
||||
|
||||
public
|
||||
typealias OnEncodeRequest = (URLRequest, Parameters?) -> Result<URLRequest, RequestEncodingIssue>
|
||||
|
||||
//---
|
||||
|
||||
public
|
||||
enum HTTPHeaderFieldName: String
|
||||
{
|
||||
|
|
|
@ -24,37 +24,48 @@
|
|||
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
|
||||
//---
|
||||
|
||||
public
|
||||
protocol RequestDefinition: Encodable
|
||||
protocol RequestDefinition
|
||||
{
|
||||
static
|
||||
var relativePath: String { get }
|
||||
|
||||
static
|
||||
var method: HTTPMethod? { get }
|
||||
|
||||
static
|
||||
var parameterEncoding: ParameterEncoding { get }
|
||||
|
||||
static
|
||||
var toDataConverter: (Self) throws -> Data { get }
|
||||
|
||||
static
|
||||
var dataToDictionaryConversionOptions: JSONSerialization.ReadingOptions { get }
|
||||
}
|
||||
|
||||
//---
|
||||
|
||||
public
|
||||
extension RequestDefinition
|
||||
{
|
||||
static
|
||||
var toDataConverter: (Self) throws -> Data { JSONEncoder().encode }
|
||||
extension RequestDefinition {
|
||||
|
||||
/// Parameters for the corresponding URL request.
|
||||
var parameters: Parameters {
|
||||
|
||||
static
|
||||
var dataToDictionaryConversionOptions: JSONSerialization.ReadingOptions { .init() }
|
||||
Mirror
|
||||
.init(reflecting: self)
|
||||
.children
|
||||
.compactMap{
|
||||
|
||||
(child: (label: String?, value: Any)) -> (key: String, value: Any)? in
|
||||
|
||||
//---
|
||||
|
||||
if
|
||||
let key = child.label
|
||||
{
|
||||
return (key, child.value)
|
||||
}
|
||||
else
|
||||
{
|
||||
return nil
|
||||
}
|
||||
}
|
||||
.reduce(into: [:]) {
|
||||
|
||||
result, nextItem in
|
||||
|
||||
//---
|
||||
|
||||
result[nextItem.key] = nextItem.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,73 +34,18 @@ protocol URLRequestFacilitator
|
|||
var session: URLSession { get }
|
||||
|
||||
var sharedPrefixURL: URL { get }
|
||||
}
|
||||
|
||||
// MARK: - Commands - Public
|
||||
|
||||
public
|
||||
extension URLRequestFacilitator
|
||||
{
|
||||
func prepareRequest<R: RequestDefinition>(
|
||||
from definition: R
|
||||
) -> Result<URLRequest, PrepareRequestIssue>
|
||||
{
|
||||
let parametersData: Data
|
||||
|
||||
do
|
||||
{
|
||||
parametersData = try R.toDataConverter(definition)
|
||||
}
|
||||
catch
|
||||
{
|
||||
return .failure(.conversionIntoDataFailed(error))
|
||||
}
|
||||
|
||||
//---
|
||||
|
||||
let parametersObject: Any
|
||||
|
||||
do
|
||||
{
|
||||
parametersObject = try JSONSerialization
|
||||
.jsonObject(
|
||||
with: parametersData,
|
||||
options: R.dataToDictionaryConversionOptions
|
||||
)
|
||||
}
|
||||
catch
|
||||
{
|
||||
return .failure(.conversionDataIntoJSONObjectFailed(error))
|
||||
}
|
||||
|
||||
//---
|
||||
|
||||
guard
|
||||
let parameters = parametersObject as? Parameters
|
||||
else
|
||||
{
|
||||
return .failure(.conversionJSONObjectIntoDictionaryFailed(theObject: parametersObject))
|
||||
}
|
||||
|
||||
//---
|
||||
|
||||
return prepareRequest(
|
||||
R.method,
|
||||
relativePath: R.relativePath,
|
||||
parameterEncoding: R.parameterEncoding,
|
||||
parameters: parameters
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
var onEncodeRequest: OnEncodeRequest { get }
|
||||
}
|
||||
|
||||
// MARK: - Internal methods
|
||||
|
||||
public
|
||||
extension URLRequestFacilitator
|
||||
{
|
||||
func prepareRequest(
|
||||
_ method: HTTPMethod? = nil,
|
||||
relativePath: String,
|
||||
parameterEncoding: ParameterEncoding,
|
||||
parameters: Parameters? = nil
|
||||
) -> Result<URLRequest, PrepareRequestIssue>
|
||||
{
|
||||
|
@ -119,7 +64,7 @@ extension URLRequestFacilitator
|
|||
var result = URLRequest(url: targetURL)
|
||||
result.httpMethod = method?.rawValue
|
||||
|
||||
switch parameterEncoding.encode(result, with: parameters)
|
||||
switch onEncodeRequest(result, parameters)
|
||||
{
|
||||
case .success(let output):
|
||||
return .success(output)
|
||||
|
@ -128,4 +73,15 @@ extension URLRequestFacilitator
|
|||
return .failure(.requestEncodingFailed(error))
|
||||
}
|
||||
}
|
||||
|
||||
func prepareRequest(
|
||||
for definition: RequestDefinition
|
||||
) -> Result<URLRequest, PrepareRequestIssue>
|
||||
{
|
||||
prepareRequest(
|
||||
type(of: definition).method,
|
||||
relativePath: type(of: definition).relativePath,
|
||||
parameters: definition.parameters
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,24 +16,7 @@ class RequestDefinitionTests: XCTestCase
|
|||
static
|
||||
let method: HTTPMethod? = .get
|
||||
|
||||
static
|
||||
let parameterEncoding: ParameterEncoding = URLEncoding.default
|
||||
|
||||
let id: String
|
||||
|
||||
var optionalFlag: Int? = nil
|
||||
}
|
||||
|
||||
var facilitator: URLRequestFacilitator!
|
||||
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
facilitator = BasicURLRequestFacilitator(sharedPrefixURL: .init(string: "host.com")!)
|
||||
}
|
||||
|
||||
override func tearDown() {
|
||||
facilitator = nil
|
||||
super.tearDown()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,26 +24,12 @@ class RequestDefinitionTests: XCTestCase
|
|||
|
||||
extension RequestDefinitionTests
|
||||
{
|
||||
func test_buildParameters_withoutOptional()
|
||||
func test_buildParameters()
|
||||
{
|
||||
let definition = UserRequestDefinition(id: "123")
|
||||
let request = try! facilitator.prepareRequest(from: definition).get()
|
||||
let components = URLComponents(string: request.url!.absoluteString)!
|
||||
let sut = components.queryItems!
|
||||
let sut = UserRequestDefinition(id: "123").parameters
|
||||
|
||||
XCTAssertEqual(sut.count, 1)
|
||||
XCTAssertTrue(sut.contains(where: { $0.name == "id" && $0.value == "123" }))
|
||||
}
|
||||
|
||||
func test_buildParameters_withOptional()
|
||||
{
|
||||
let definition = UserRequestDefinition(id: "123", optionalFlag: 22)
|
||||
let request = try! facilitator.prepareRequest(from: definition).get()
|
||||
let components = URLComponents(string: request.url!.absoluteString)!
|
||||
let sut = components.queryItems!
|
||||
|
||||
XCTAssertEqual(sut.count, 2)
|
||||
XCTAssertTrue(sut.contains(where: { $0.name == "id" && $0.value == "123" }))
|
||||
XCTAssertTrue(sut.contains(where: { $0.name == "optionalFlag" && $0.value == "22" }))
|
||||
XCTAssertTrue(sut.contains(where: { $0.key == "id" }))
|
||||
XCTAssertTrue(sut.contains(where: { ($0.value as? String) == "123" }))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ extension URLRequestFacilitatorTests
|
|||
let sut = facilitator.prepareRequest(
|
||||
.get,
|
||||
relativePath: "user",
|
||||
parameterEncoding: URLEncoding.default,
|
||||
parameters: ["id": "123"]
|
||||
)
|
||||
|
||||
|
|
Loading…
Reference in New Issue