Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Data parser associated types #230

Merged
merged 2 commits into from
Mar 12, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,5 @@ Carthage/Build

fastlane/report.xml
fastlane/screenshots

.DS_Store
4 changes: 3 additions & 1 deletion Sources/APIKit/DataParser/DataParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import Foundation

/// `DataParser` protocol provides inteface to parse HTTP response body and to state Content-Type to accept.
public protocol DataParser {
associatedtype Parsed

/// Value for `Accept` header field of HTTP request.
var contentType: String? { get }

/// Return `Any` that expresses structure of response such as JSON and XML.
/// - Throws: `Error` when parser encountered invalid format data.
func parse(data: Data) throws -> Any
func parse(data: Data) throws -> Parsed
}
24 changes: 16 additions & 8 deletions Sources/APIKit/Request.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import Result
public protocol Request {
/// The response type associated with the request type.
associatedtype Response
associatedtype Parser: DataParser

/// The base URL.
var baseURL: URL { get }
Expand Down Expand Up @@ -41,7 +42,7 @@ public protocol Request {
var headerFields: [String: String] { get }

/// The parser object that states `Content-Type` to accept and parses response body.
var dataParser: DataParser { get }
var dataParser: Parser { get }

/// Intercepts `URLRequest` which is created by `Request.buildURLRequest()`. If an error is
/// thrown in this method, the result of `Session.send()` turns `.failure(.requestError(error))`.
Expand All @@ -53,15 +54,16 @@ public protocol Request {
/// The default implementation of this method is provided to throw `RequestError.unacceptableStatusCode`
/// if the HTTP status code is not in `200..<300`.
/// - Throws: `Error`
func intercept(object: Any, urlResponse: HTTPURLResponse) throws -> Any
func intercept(object: Parser.Parsed, urlResponse: HTTPURLResponse) throws -> Parser.Parsed

/// Build `Response` instance from raw response object. This method is called after
/// `intercept(object:urlResponse:)` if it does not throw any error.
/// - Throws: `Error`
func response(from object: Any, urlResponse: HTTPURLResponse) throws -> Response
func response(from object: Parser.Parsed, urlResponse: HTTPURLResponse) throws -> Response
}

public extension Request {

public var parameters: Any? {
return nil
}
Expand All @@ -86,15 +88,11 @@ public extension Request {
return [:]
}

public var dataParser: DataParser {
return JSONDataParser(readingOptions: [])
}

public func intercept(urlRequest: URLRequest) throws -> URLRequest {
return urlRequest
}

public func intercept(object: Any, urlResponse: HTTPURLResponse) throws -> Any {
public func intercept(object: Parser.Parsed, urlResponse: HTTPURLResponse) throws -> Parser.Parsed {
guard 200..<300 ~= urlResponse.statusCode else {
throw ResponseError.unacceptableStatusCode(urlResponse.statusCode)
}
Expand Down Expand Up @@ -146,3 +144,13 @@ public extension Request {
return try response(from: passedObject, urlResponse: urlResponse)
}
}

public protocol JSONRequest: Request {}

public extension JSONRequest {

public var dataParser: JSONDataParser {
return JSONDataParser(readingOptions: [])
}

}
2 changes: 1 addition & 1 deletion Tests/APIKitTests/SessionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ class SessionTests: XCTestCase {
waitForExpectations(timeout: 1.0, handler: nil)
}

struct AnotherTestRequest: Request {
struct AnotherTestRequest: JSONRequest {
typealias Response = Void

var baseURL: URL {
Expand Down
2 changes: 1 addition & 1 deletion Tests/APIKitTests/TestComponents/TestRequest.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Foundation
import APIKit

struct TestRequest: Request {
struct TestRequest: JSONRequest {
var absoluteURL: URL? {
let urlRequest = try? buildURLRequest()
return urlRequest?.url
Expand Down