Skip to content
This repository was archived by the owner on Aug 20, 2018. It is now read-only.
Open
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
6 changes: 4 additions & 2 deletions Cartfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
github "mxcl/PromiseKit" ~> 6.3
#github "mxcl/PromiseKit" ~> 6.3
github "dougzilla32/PromiseKit" "CoreCancel"
github "mxcl/OMGHTTPURLRQ" ~> 3.2
github "PromiseKit/Foundation" ~> 3.1
#github "PromiseKit/Foundation" ~> 3.1
github "dougzilla32/Foundation" "CoreCancel"
4 changes: 2 additions & 2 deletions Cartfile.resolved
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
github "AliSoftware/OHHTTPStubs" "6.1.0"
github "PromiseKit/Foundation" "3.1.0"
github "dougzilla32/Foundation" "4b6d86210cf2f3a2010d37c44d7d63ccb20547b1"
github "dougzilla32/PromiseKit" "288f7fbabc0b33c558bf908a3a0770693223d4e0"
github "mxcl/OMGHTTPURLRQ" "3.2.5"
github "mxcl/PromiseKit" "6.3.3"
138 changes: 138 additions & 0 deletions Sources/NSURLSession+OMG+Promise.swift
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,141 @@ extension URLSession {
}
}
}

//////////////////////////////////////////////////////////// Cancellable wrappers

extension URLSession {
/**
Makes a cancellable **GET** request to the provided URL.

let p = URLSession.shared.GET("http://example.com", query: ["foo": "bar"])
p.then { data -> Void in
//…
}
p.asImage().then { image -> Void in
//…
}
p.asDictionary().then { json -> Void in
//…
}

- Parameter url: The URL to request.
- Parameter query: The parameters to be encoded as the query string for the GET request.
- Returns: A cancellable promise that represents the GET request.
*/
public func cancellableGET(_ url: String, query: [String: Any]? = nil) -> CancellablePromise<(data: Data, response: URLResponse)> {
return cancellable(GET(url, query: query))
}

/**
Makes a cancellable POST request to the provided URL passing form URL encoded
parameters.

Form URL-encoding is the standard way to POST on the Internet, so
probably this is what you want. If it doesn’t work, try the `+POST:JSON`
variant.

let url = "http://jsonplaceholder.typicode.com/posts"
let params = ["title": "foo", "body": "bar", "userId": 1]
URLSession.shared.POST(url, formData: params).asDictionary().then { json -> Void in
//…
}

- Parameter url: The URL to request.
- Parameter formData: The parameters to be form URL-encoded and passed as the POST body.
- Returns: A cancellable promise that represents the POST request.
*/
public func cancellablePOST(_ url: String, formData: [String: Any]? = nil) -> CancellablePromise<(data: Data, response: URLResponse)> {
return cancellable(POST(url, formData: formData))
}

/**
Makes a cancellable POST request to the provided URL passing multipart form-data.

let formData = OMGMultipartFormData()
let imgData = Data(contentsOfFile: "image.png")
formData.addFile(imgdata, parameterName: "file1", filename: "myimage1.png", contentType: "image/png")

URLSession.shared.POST(url, multipartFormData: formData).then { data in
//…
}

- Parameter url: The URL to request.
- Parameter multipartFormData: The parameters to be multipart form-data encoded and passed as the POST body.
- Returns: A cancellable promise that represents the POST request.
- SeeAlso: [https://github.com/mxcl/OMGHTTPURLRQ](OMGHTTPURLRQ)
*/
public func cancellablePOST(_ url: String, multipartFormData: OMGMultipartFormData) -> CancellablePromise<(data: Data, response: URLResponse)> {
return cancellable(POST(url, multipartFormData: multipartFormData))
}

/**
Makes a cancellable POST request to the provided URL passing JSON encoded
parameters.

Most web servers nowadays support POST with either JSON or form
URL-encoding. If in doubt try form URL-encoded parameters first.

let url = "http://jsonplaceholder.typicode.com/posts"
let params = ["title": "foo", "body": "bar", "userId": 1]
URLSession.shared.POST(url, json: params).asDictionary().then { json -> Void in
//…
}

- Parameter url: The URL to request.
- Parameter json: The parameters to be JSON-encoded and passed as the POST body.
- Returns: A cancellable promise that represents the POST request.
*/
public func cancellablePOST(_ url: String, json: [String: Any]? = nil) -> CancellablePromise<(data: Data, response: URLResponse)> {
return cancellable(POST(url, json: json))
}

/**
Makes a cancellable PUT request to the provided URL passing JSON encoded parameters.

let url = "http://jsonplaceholder.typicode.com/posts"
let params = ["title": "foo", "body": "bar", "userId": 1]
URLSession.shared.PUT(url, json: params).asDictionary().then { json -> Void in
//…
}

- Parameter url: The URL to request.
- Parameter json: The parameters to be JSON-encoded and passed as the PUT body.
- Returns: A cancellable promise that represents the PUT request.
*/
public func cancellablePUT(_ url: String, json: [String: Any]? = nil) -> CancellablePromise<(data: Data, response: URLResponse)> {
return cancellable(PUT(url, json: json))
}

/**
Makes a cancellable DELETE request to the provided URL passing form URL-encoded
parameters.

let url = "http://jsonplaceholder.typicode.com/posts/1"
URLSession.shared.DELETE(url).then.asDictionary() { json -> Void in
//…
}

- Parameter url: The URL to request.
- Returns: A cancellable promise that represents the PUT request.
*/
public func cancellableDELETE(_ url: String) -> CancellablePromise<(data: Data, response: URLResponse)> {
return cancellable(DELETE(url))
}

/**
Makes a cancellable PATCH request to the provided URL passing the provided JSON parameters.

let url = "http://jsonplaceholder.typicode.com/posts/1"
let params = ["foo": "bar"]
NSURLConnection.PATCH(url, json: params).asDictionary().then { json -> Void in
//…
}
- Parameter url: The URL to request.
- Parameter json: The JSON parameters to encode as the PATCH body.
- Returns: A cancellable promise that represents the PUT request.
*/
public func cancellablePATCH(_ url: String, json: [String: Any]? = nil) -> CancellablePromise<(data: Data, response: URLResponse)> {
return cancellable(PATCH(url, json: json))
}
}
78 changes: 78 additions & 0 deletions Tests/TestNSURLSession.swift
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,81 @@ class NSURLSessionTests: XCTestCase {
OHHTTPStubs.removeAllStubs()
}
}

//////////////////////////////////////////////////////////// Cancellation

extension NSURLSessionTests {
func testCancel1() {
let json: NSDictionary = ["key1": "value1", "key2": ["value2A", "value2B"]]

OHHTTPStubs.stubRequests(passingTest: { $0.url!.host == "example.com" }) { _ in
return OHHTTPStubsResponse(jsonObject: json, statusCode: 200, headers: nil)
}

let ex = expectation(description: "")
URLSession.shared.cancellableGET("http://example.com").compactMap {
XCTFail()
try JSONSerialization.jsonObject(with: $0.data)
}.done {
XCTAssertEqual(json, $0 as? NSDictionary)
XCTFail()
}.catch(policy: .allErrors) {
$0.isCancelled ? ex.fulfill() : XCTFail()
}.cancel()
waitForExpectations(timeout: 1)
}

func testCancel2() {

// test that Promise<Data> chains thens
// this test because I don’t trust the Swift compiler

let dummy = ("fred" as NSString).data(using: String.Encoding.utf8.rawValue)!

OHHTTPStubs.stubRequests(passingTest: { $0.url!.host == "example.com" }) { _ in
return OHHTTPStubsResponse(data: dummy, statusCode: 200, headers: [:])
}

let ex = expectation(description: "")

cancellable(after(seconds: 0.1)).then { () -> CancellablePromise<(data: Data, response: URLResponse)> in
let p = URLSession.shared.cancellableGET("http://example.com")
p.cancel()
return p
}.done {
XCTAssertEqual($0.data, dummy)
XCTFail()
}.catch(policy: .allErrors) {
$0.isCancelled ? ex.fulfill() : XCTFail()
}

waitForExpectations(timeout: 1)
}

func testCancelSyntax() {
let json: NSDictionary = ["key1": "value1", "key2": ["value2A", "value2B"]]

OHHTTPStubs.stubRequests(passingTest: {
$0.url!.host == "example.com"
}, withStubResponse: { _ in
OHHTTPStubsResponse(jsonObject: json, statusCode: 200, headers: nil)
})

let p = URLSession.shared.cancellableGET("http://example.com", query: [
"1": 1,
"2": 2
])

let ex = expectation(description: "")
p.compactMap {
p.cancel()
try JSONSerialization.jsonObject(with: $0.data)
}.done {
XCTAssertEqual(json, $0 as? NSDictionary)
XCTFail()
}.catch(policy: .allErrors) {
$0.isCancelled ? ex.fulfill() : XCTFail()
}
waitForExpectations(timeout: 1)
}
}