Skip to content

Commit 2c55e45

Browse files
committed
'Cancel' for PromiseKit
1 parent de16bbe commit 2c55e45

File tree

4 files changed

+86
-2
lines changed

4 files changed

+86
-2
lines changed

Cartfile.resolved

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
github "mxcl/PromiseKit" "6.3.3"
1+
github "mxcl/PromiseKit" "6.3.4"

Sources/SKProductsRequest+Promise.swift

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,40 @@ fileprivate class SKDelegate: NSObject, SKProductsRequestDelegate {
5050
// return true
5151
// }
5252
//}
53+
54+
//////////////////////////////////////////////////////////// Cancellation
55+
56+
extension SKProductsRequest {
57+
/**
58+
Sends the request to the Apple App Store.
59+
60+
- Returns: A cancellable promise that fulfills if the request succeeds.
61+
*/
62+
public func startCC(_: PMKNamespacer) -> CancellablePromise<SKProductsResponse> {
63+
let proxy = SKDelegate()
64+
delegate = proxy
65+
proxy.retainCycle = proxy
66+
let cp = CancellablePromise(task: SKRequestTask(self, proxy), promise: proxy.promise, resolver: proxy.seal)
67+
68+
start()
69+
return cp
70+
}
71+
}
72+
73+
fileprivate class SKRequestTask: CancellableTask {
74+
let request: SKRequest
75+
let proxy: SKDelegate
76+
77+
init(_ request: SKRequest, _ proxy: SKDelegate) {
78+
self.request = request
79+
self.proxy = proxy
80+
}
81+
82+
var isCancelled = false
83+
84+
func cancel() {
85+
request.cancel()
86+
proxy.retainCycle = nil
87+
isCancelled = true
88+
}
89+
}

Sources/SKReceiptRefreshRequest+Promise.swift

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ extension SKReceiptRefreshRequest {
99
}
1010
}
1111

12-
private class ReceiptRefreshObserver: NSObject, SKRequestDelegate {
12+
private class ReceiptRefreshObserver: NSObject, SKRequestDelegate, CancellableTask {
1313
let (promise, seal) = Promise<SKReceiptRefreshRequest>.pending()
1414
let request: SKReceiptRefreshRequest
1515
var retainCycle: ReceiptRefreshObserver?
@@ -32,4 +32,21 @@ private class ReceiptRefreshObserver: NSObject, SKRequestDelegate {
3232
seal.reject(error)
3333
retainCycle = nil
3434
}
35+
36+
var isCancelled = false
37+
38+
func cancel() {
39+
request.cancel()
40+
retainCycle = nil
41+
isCancelled = true
42+
}
43+
}
44+
45+
//////////////////////////////////////////////////////////// Cancellation
46+
47+
extension SKReceiptRefreshRequest {
48+
public func promiseCC() -> CancellablePromise<SKReceiptRefreshRequest> {
49+
let rro = ReceiptRefreshObserver(request: self)
50+
return CancellablePromise(task: rro, promise: rro.promise, resolver: rro.seal)
51+
}
3552
}

Tests/TestStoreKit.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,33 @@ class SKProductsRequestTests: XCTestCase {
2020
waitForExpectations(timeout: 1, handler: nil)
2121
}
2222
}
23+
24+
//////////////////////////////////////////////////////////// Cancellation
25+
26+
extension SKProductsRequestTests {
27+
func testCancel() {
28+
class MockProductsRequest: SKProductsRequest {
29+
var isCancelled = false
30+
31+
override func start() {
32+
after(seconds: 0.1).done {
33+
if !self.isCancelled {
34+
self.delegate?.productsRequest(self, didReceive: SKProductsResponse())
35+
}
36+
}
37+
}
38+
}
39+
40+
let ex = expectation(description: "")
41+
42+
let request = MockProductsRequest()
43+
request.startCC(.promise).done { _ in
44+
XCTFail()
45+
}.catch(policy: .allErrors) {
46+
$0.isCancelled ? ex.fulfill() : XCTFail()
47+
}.cancel()
48+
request.isCancelled = true
49+
50+
waitForExpectations(timeout: 1, handler: nil)
51+
}
52+
}

0 commit comments

Comments
 (0)