Skip to content

Commit

Permalink
Merge branch 'feature/HTTP-headers'
Browse files Browse the repository at this point in the history
  • Loading branch information
ishkawa committed Feb 22, 2015
2 parents 3f62224 + 1a848e8 commit b9ac30a
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 26 deletions.
6 changes: 4 additions & 2 deletions APIKit/APIKit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ public class API {
}

public class func requestBodyBuilder() -> RequestBodyBuilder {
return .JSON(nil)
return .JSON(writingOptions: nil)
}

public class func responseBodyParser() -> ResponseBodyParser {
return .JSON(nil)
return .JSON(readingOptions: nil)
}

// build NSURLRequest
Expand All @@ -66,6 +66,8 @@ public class API {
components.path = (components.path ?? "").stringByAppendingPathComponent(path)
request.URL = components.URL
request.HTTPMethod = method.rawValue
request.setValue(requestBodyBuilder().contentTypeHeader, forHTTPHeaderField: "Content-Type")
request.setValue(responseBodyParser().acceptHeader, forHTTPHeaderField: "Accept")

return request
} else {
Expand Down
21 changes: 17 additions & 4 deletions APIKit/RequestBodyBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,22 @@ import LlamaKit
public let APIKitRequestBodyBuidlerErrorDomain = "APIKitRequestBodyBuidlerErrorDomain"

public enum RequestBodyBuilder {
case JSON(NSJSONWritingOptions)
case URL(NSStringEncoding)
case Custom(AnyObject -> Result<NSData, NSError>)
case JSON(writingOptions: NSJSONWritingOptions)
case URL(encoding: NSStringEncoding)
case Custom(contentTypeHeader: String, buildBodyFromObject: AnyObject -> Result<NSData, NSError>)

public var contentTypeHeader: String {
switch self {
case .JSON:
return "application/json"

case .URL:
return "application/x-www-form-urlencoded"

case .Custom(let (type, _)):
return type
}
}

public func buildBodyFromObject(object: AnyObject) -> Result<NSData, NSError> {
var result: Result<NSData, NSError>
Expand Down Expand Up @@ -38,7 +51,7 @@ public enum RequestBodyBuilder {
result = Result.Failure(Box(error!))
}

case .Custom(let buildBodyFromObject):
case .Custom(let (_, buildBodyFromObject)):
result = buildBodyFromObject(object)
}

Expand Down
23 changes: 19 additions & 4 deletions APIKit/ResponseBodyParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,22 @@ import LlamaKit
#endif

public enum ResponseBodyParser {
case JSON(NSJSONReadingOptions)
case URL(NSStringEncoding)
case Custom(NSData -> Result<AnyObject, NSError>)
case JSON(readingOptions: NSJSONReadingOptions)
case URL(encoding: NSStringEncoding)
case Custom(acceptHeader: String, parseData: NSData -> Result<AnyObject, NSError>)

public var acceptHeader: String {
switch self {
case .JSON:
return "application/json"

case .URL:
return "application/x-www-form-urlencoded"

case .Custom(let (type, _)):
return type
}
}

public func parseData(data: NSData) -> Result<AnyObject, NSError> {
var result: Result<AnyObject, NSError>
Expand All @@ -29,10 +42,12 @@ public enum ResponseBodyParser {
result = Result.Failure(Box(error!))
}

case .Custom(let parseData):
case .Custom(let (accept, parseData)):
result = parseData(data)
}

return result
}


}
25 changes: 20 additions & 5 deletions APIKitTests/RequestBodyBuilderTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@ import LlamaKit
import XCTest

class RequestBodyBuilderTests: XCTestCase {
func testJSONHeader() {
let builder = RequestBodyBuilder.JSON(writingOptions: nil)
XCTAssertEqual(builder.contentTypeHeader, "application/json")
}

func testJSONSuccess() {
let object = ["foo": 1, "bar": 2, "baz": 3]
let builder = RequestBodyBuilder.JSON(nil)
let builder = RequestBodyBuilder.JSON(writingOptions: nil)

switch builder.buildBodyFromObject(object) {
case .Success(let box):
Expand All @@ -22,7 +27,7 @@ class RequestBodyBuilderTests: XCTestCase {

func testJSONFailure() {
let object = NSObject()
let builder = RequestBodyBuilder.JSON(nil)
let builder = RequestBodyBuilder.JSON(writingOptions: nil)

switch builder.buildBodyFromObject(object) {
case .Success:
Expand All @@ -35,9 +40,14 @@ class RequestBodyBuilderTests: XCTestCase {
}
}

func testURLHeader() {
let builder = RequestBodyBuilder.URL(encoding: NSUTF8StringEncoding)
XCTAssertEqual(builder.contentTypeHeader, "application/x-www-form-urlencoded")
}

func testURLSuccess() {
let object = ["foo": 1, "bar": 2, "baz": 3]
let builder = RequestBodyBuilder.URL(NSUTF8StringEncoding)
let builder = RequestBodyBuilder.URL(encoding: NSUTF8StringEncoding)

switch builder.buildBodyFromObject(object) {
case .Success(let box):
Expand All @@ -49,10 +59,15 @@ class RequestBodyBuilderTests: XCTestCase {
}
}

func testCustomHeader() {
let builder = RequestBodyBuilder.Custom(contentTypeHeader: "foo", buildBodyFromObject: { o in Result.Success(Box(o as NSData)) })
XCTAssertEqual(builder.contentTypeHeader, "foo")
}

func testCustomSuccess() {
let string = "foo"
let expectedData = string.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
let builder = RequestBodyBuilder.Custom({ object in
let builder = RequestBodyBuilder.Custom(contentTypeHeader: "", buildBodyFromObject: { object in
return Result.Success(Box(expectedData))
})

Expand All @@ -68,7 +83,7 @@ class RequestBodyBuilderTests: XCTestCase {
func testCustomFailure() {
let string = "foo"
let expectedError = NSError()
let builder = RequestBodyBuilder.Custom({ object in
let builder = RequestBodyBuilder.Custom(contentTypeHeader: "", buildBodyFromObject: { object in
return Result.Failure(Box(expectedError))
})

Expand Down
25 changes: 20 additions & 5 deletions APIKitTests/ResponseBodyParserTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@ import LlamaKit
import XCTest

class ResponseBodyParserTests: XCTestCase {
func testJSONAcceptHeader() {
let parser = ResponseBodyParser.JSON(readingOptions: nil)
XCTAssertEqual(parser.acceptHeader, "application/json")
}

func testJSONSuccess() {
let string = "{\"foo\": 1, \"bar\": 2, \"baz\": 3}"
let data = string.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
let parser = ResponseBodyParser.JSON(nil)
let parser = ResponseBodyParser.JSON(readingOptions: nil)

switch parser.parseData(data) {
case .Success(let box):
Expand All @@ -24,7 +29,7 @@ class ResponseBodyParserTests: XCTestCase {
func testJSONFailure() {
let string = "{\"foo\": 1, \"bar\": 2, \" 3}"
let data = string.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
let parser = ResponseBodyParser.JSON(nil)
let parser = ResponseBodyParser.JSON(readingOptions: nil)

switch parser.parseData(data) {
case .Success:
Expand All @@ -37,10 +42,15 @@ class ResponseBodyParserTests: XCTestCase {
}
}

func testURLAcceptHeader() {
let parser = ResponseBodyParser.URL(encoding: NSUTF8StringEncoding)
XCTAssertEqual(parser.acceptHeader, "application/x-www-form-urlencoded")
}

func testURLSuccess() {
let string = "foo=1&bar=2&baz=3"
let data = string.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
let parser = ResponseBodyParser.URL(NSUTF8StringEncoding)
let parser = ResponseBodyParser.URL(encoding: NSUTF8StringEncoding)

switch parser.parseData(data) {
case .Success(let box):
Expand All @@ -53,11 +63,16 @@ class ResponseBodyParserTests: XCTestCase {
XCTFail()
}
}

func testCustomAcceptHeader() {
let parser = ResponseBodyParser.Custom(acceptHeader: "foo", parseData: { d in Result.Success(Box(d)) })
XCTAssertEqual(parser.acceptHeader, "foo")
}

func testCustomSuccess() {
let expectedDictionary = ["foo": 1]
let data = NSData()
let parser = ResponseBodyParser.Custom({ data in
let parser = ResponseBodyParser.Custom(acceptHeader: "", parseData: { data in
return Result.Success(Box(expectedDictionary))
})

Expand All @@ -74,7 +89,7 @@ class ResponseBodyParserTests: XCTestCase {
func testCustomFailure() {
let expectedError = NSError()
let data = NSData()
let parser = ResponseBodyParser.Custom({ data in
let parser = ResponseBodyParser.Custom(acceptHeader: "", parseData: { data in
return Result.Failure(Box(expectedError))
})

Expand Down
4 changes: 2 additions & 2 deletions DemoApp/GitHub.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ class GitHub: API {
}

override class func requestBodyBuilder() -> RequestBodyBuilder {
return .JSON(nil)
return .JSON(writingOptions: nil)
}

override class func responseBodyParser() -> ResponseBodyParser {
return .JSON(nil)
return .JSON(readingOptions: nil)
}

class Request {
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ You have 2 choices. If your app supports iOS 7.0, you can only choose copying so

## Usage

1. Create subclass of `APIKit.API` that represents target web API.
1. Create subclass of `API` that represents target web API.
2. Set base URL by overriding `baseURL()`.
3. Set encoding of request body by overriding `requestBodyBuilder()`.
4. Set encoding of response body by overriding `responseBodyParser()`.
5. Define request classes that conforms to `APIKit.Request` for each endpoints.
5. Define request classes that conforms to `Request` for each endpoints.

### Example

Expand All @@ -66,11 +66,11 @@ class GitHub: API {
}

override class func requestBodyBuilder() -> RequestBodyBuilder {
return .JSON(nil)
return .JSON(writingOptions: nil)
}

override class func responseBodyParser() -> ResponseBodyParser {
return .JSON(nil)
return .JSON(readingOptions: nil)
}

class Endpoint {
Expand Down

0 comments on commit b9ac30a

Please sign in to comment.