Skip to content

Commit ca6c5fd

Browse files
authored
Merge pull request #1 from mpsnp/master
Added SKPayment and SKProductsRequest wrappers
2 parents 525750d + 7d942b5 commit ca6c5fd

File tree

4 files changed

+94
-6
lines changed

4 files changed

+94
-6
lines changed

PMKStoreKit.xcodeproj/project.pbxproj

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@
99
/* Begin PBXBuildFile section */
1010
637B4A6C1D5D5F9B00E1BC6C /* SKRequest+AnyPromise.h in Headers */ = {isa = PBXBuildFile; fileRef = 637B4A691D5D5F9B00E1BC6C /* SKRequest+AnyPromise.h */; settings = {ATTRIBUTES = (Public, ); }; };
1111
637B4A6D1D5D5F9B00E1BC6C /* SKRequest+AnyPromise.m in Sources */ = {isa = PBXBuildFile; fileRef = 637B4A6A1D5D5F9B00E1BC6C /* SKRequest+AnyPromise.m */; };
12-
637B4A6E1D5D5F9B00E1BC6C /* SKRequest+Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = 637B4A6B1D5D5F9B00E1BC6C /* SKRequest+Promise.swift */; };
12+
637B4A6E1D5D5F9B00E1BC6C /* SKProductsRequest+Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = 637B4A6B1D5D5F9B00E1BC6C /* SKProductsRequest+Promise.swift */; };
1313
637B4A711D5D5FA400E1BC6C /* TestStoreKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 637B4A6F1D5D5FA400E1BC6C /* TestStoreKit.m */; };
1414
637B4A721D5D5FA400E1BC6C /* TestStoreKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 637B4A701D5D5FA400E1BC6C /* TestStoreKit.swift */; };
1515
637B4A741D5D5FC600E1BC6C /* PMKStoreKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 637B4A731D5D5FC600E1BC6C /* PMKStoreKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
1616
63C7FFF71D5C020D003BAE60 /* PMKStoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63C7FFA71D5BEE09003BAE60 /* PMKStoreKit.framework */; };
17+
D3F6DBF31EA245750013E242 /* SKPayment+Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3F6DBF21EA245750013E242 /* SKPayment+Promise.swift */; };
18+
D3F6DBF51EA246340013E242 /* SKReceiptRefreshRequest+Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3F6DBF41EA246340013E242 /* SKReceiptRefreshRequest+Promise.swift */; };
1719
/* End PBXBuildFile section */
1820

1921
/* Begin PBXContainerItemProxy section */
@@ -29,7 +31,7 @@
2931
/* Begin PBXFileReference section */
3032
637B4A691D5D5F9B00E1BC6C /* SKRequest+AnyPromise.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "SKRequest+AnyPromise.h"; path = "Sources/SKRequest+AnyPromise.h"; sourceTree = SOURCE_ROOT; };
3133
637B4A6A1D5D5F9B00E1BC6C /* SKRequest+AnyPromise.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "SKRequest+AnyPromise.m"; path = "Sources/SKRequest+AnyPromise.m"; sourceTree = SOURCE_ROOT; };
32-
637B4A6B1D5D5F9B00E1BC6C /* SKRequest+Promise.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "SKRequest+Promise.swift"; path = "Sources/SKRequest+Promise.swift"; sourceTree = SOURCE_ROOT; };
34+
637B4A6B1D5D5F9B00E1BC6C /* SKProductsRequest+Promise.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "SKProductsRequest+Promise.swift"; path = "Sources/SKProductsRequest+Promise.swift"; sourceTree = SOURCE_ROOT; };
3335
637B4A6F1D5D5FA400E1BC6C /* TestStoreKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TestStoreKit.m; path = Tests/TestStoreKit.m; sourceTree = SOURCE_ROOT; };
3436
637B4A701D5D5FA400E1BC6C /* TestStoreKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TestStoreKit.swift; path = Tests/TestStoreKit.swift; sourceTree = SOURCE_ROOT; };
3537
637B4A731D5D5FC600E1BC6C /* PMKStoreKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PMKStoreKit.h; path = Sources/PMKStoreKit.h; sourceTree = SOURCE_ROOT; };
@@ -38,6 +40,8 @@
3840
63C7FFF21D5C020D003BAE60 /* PMKSKTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PMKSKTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
3941
63CCF8121D5C0C4E00503216 /* Cartfile */ = {isa = PBXFileReference; lastKnownFileType = text; path = Cartfile; sourceTree = "<group>"; };
4042
63CCF8171D5C11B500503216 /* Carthage.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Carthage.xcconfig; sourceTree = "<group>"; };
43+
D3F6DBF21EA245750013E242 /* SKPayment+Promise.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "SKPayment+Promise.swift"; path = "Sources/SKPayment+Promise.swift"; sourceTree = SOURCE_ROOT; };
44+
D3F6DBF41EA246340013E242 /* SKReceiptRefreshRequest+Promise.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "SKReceiptRefreshRequest+Promise.swift"; path = "Sources/SKReceiptRefreshRequest+Promise.swift"; sourceTree = SOURCE_ROOT; };
4145
/* End PBXFileReference section */
4246

4347
/* Begin PBXFrameworksBuildPhase section */
@@ -86,7 +90,9 @@
8690
637B4A731D5D5FC600E1BC6C /* PMKStoreKit.h */,
8791
637B4A691D5D5F9B00E1BC6C /* SKRequest+AnyPromise.h */,
8892
637B4A6A1D5D5F9B00E1BC6C /* SKRequest+AnyPromise.m */,
89-
637B4A6B1D5D5F9B00E1BC6C /* SKRequest+Promise.swift */,
93+
637B4A6B1D5D5F9B00E1BC6C /* SKProductsRequest+Promise.swift */,
94+
D3F6DBF21EA245750013E242 /* SKPayment+Promise.swift */,
95+
D3F6DBF41EA246340013E242 /* SKReceiptRefreshRequest+Promise.swift */,
9096
);
9197
name = Sources;
9298
path = "PMK+UIKit";
@@ -215,8 +221,10 @@
215221
isa = PBXSourcesBuildPhase;
216222
buildActionMask = 2147483647;
217223
files = (
224+
D3F6DBF51EA246340013E242 /* SKReceiptRefreshRequest+Promise.swift in Sources */,
218225
637B4A6D1D5D5F9B00E1BC6C /* SKRequest+AnyPromise.m in Sources */,
219-
637B4A6E1D5D5F9B00E1BC6C /* SKRequest+Promise.swift in Sources */,
226+
637B4A6E1D5D5F9B00E1BC6C /* SKProductsRequest+Promise.swift in Sources */,
227+
D3F6DBF31EA245750013E242 /* SKPayment+Promise.swift in Sources */,
220228
);
221229
runOnlyForDeploymentPostprocessing = 0;
222230
};

Sources/SKPayment+Promise.swift

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import StoreKit
2+
#if !COCOAPODS
3+
import PromiseKit
4+
#endif
5+
6+
extension SKPayment {
7+
public func promise() -> Promise<SKPaymentTransaction> {
8+
return PaymentObserver(payment: self).promise
9+
}
10+
}
11+
12+
fileprivate class PaymentObserver: NSObject, SKPaymentTransactionObserver {
13+
let (promise, fulfill, reject) = Promise<SKPaymentTransaction>.pending()
14+
let payment: SKPayment
15+
var retainCycle: PaymentObserver?
16+
17+
init(payment: SKPayment) {
18+
self.payment = payment
19+
super.init()
20+
SKPaymentQueue.default().add(self)
21+
SKPaymentQueue.default().add(payment)
22+
retainCycle = self
23+
}
24+
25+
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
26+
guard let transaction = transactions.first(where: { $0.payment == payment }) else {
27+
return
28+
}
29+
switch transaction.transactionState {
30+
case .purchased:
31+
queue.finishTransaction(transaction)
32+
fulfill(transaction)
33+
queue.remove(self)
34+
retainCycle = nil
35+
case .failed:
36+
let error = transaction.error ?? NSError.cancelledError()
37+
queue.finishTransaction(transaction)
38+
reject(error)
39+
queue.remove(self)
40+
retainCycle = nil
41+
default:
42+
break
43+
}
44+
}
45+
}

Sources/SKRequest+Promise.swift renamed to Sources/SKProductsRequest+Promise.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import PromiseKit
1313

1414
import PromiseKit
1515
*/
16-
extension SKRequest {
16+
extension SKProductsRequest {
1717
/**
1818
Sends the request to the Apple App Store.
1919

@@ -29,7 +29,7 @@ extension SKRequest {
2929
}
3030

3131

32-
private class SKDelegate: NSObject, SKProductsRequestDelegate {
32+
fileprivate class SKDelegate: NSObject, SKProductsRequestDelegate {
3333
let (promise, fulfill, reject) = Promise<SKProductsResponse>.pending()
3434
var retainCycle: SKDelegate?
3535

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import StoreKit
2+
#if !COCOAPODS
3+
import PromiseKit
4+
#endif
5+
6+
extension SKReceiptRefreshRequest {
7+
public func promise() -> Promise<SKReceiptRefreshRequest> {
8+
return ReceiptRefreshObserver(request: self).promise
9+
}
10+
}
11+
12+
fileprivate class ReceiptRefreshObserver: NSObject, SKRequestDelegate {
13+
let (promise, fulfill, reject) = Promise<SKReceiptRefreshRequest>.pending()
14+
let request: SKReceiptRefreshRequest
15+
var retainCycle: ReceiptRefreshObserver?
16+
17+
init(request: SKReceiptRefreshRequest) {
18+
self.request = request
19+
super.init()
20+
request.delegate = self
21+
request.start()
22+
retainCycle = self
23+
}
24+
25+
26+
func requestDidFinish(_ request: SKRequest) {
27+
fulfill(self.request)
28+
retainCycle = nil
29+
}
30+
31+
func request(_ request: SKRequest, didFailWithError error: Error) {
32+
reject(error)
33+
retainCycle = nil
34+
}
35+
}

0 commit comments

Comments
 (0)