Skip to content

Commit

Permalink
Merge pull request #1 from mpsnp/master
Browse files Browse the repository at this point in the history
Added SKPayment and SKProductsRequest wrappers
  • Loading branch information
mxcl authored Apr 15, 2017
2 parents 525750d + 7d942b5 commit ca6c5fd
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 6 deletions.
16 changes: 12 additions & 4 deletions PMKStoreKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
/* Begin PBXBuildFile section */
637B4A6C1D5D5F9B00E1BC6C /* SKRequest+AnyPromise.h in Headers */ = {isa = PBXBuildFile; fileRef = 637B4A691D5D5F9B00E1BC6C /* SKRequest+AnyPromise.h */; settings = {ATTRIBUTES = (Public, ); }; };
637B4A6D1D5D5F9B00E1BC6C /* SKRequest+AnyPromise.m in Sources */ = {isa = PBXBuildFile; fileRef = 637B4A6A1D5D5F9B00E1BC6C /* SKRequest+AnyPromise.m */; };
637B4A6E1D5D5F9B00E1BC6C /* SKRequest+Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = 637B4A6B1D5D5F9B00E1BC6C /* SKRequest+Promise.swift */; };
637B4A6E1D5D5F9B00E1BC6C /* SKProductsRequest+Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = 637B4A6B1D5D5F9B00E1BC6C /* SKProductsRequest+Promise.swift */; };
637B4A711D5D5FA400E1BC6C /* TestStoreKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 637B4A6F1D5D5FA400E1BC6C /* TestStoreKit.m */; };
637B4A721D5D5FA400E1BC6C /* TestStoreKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 637B4A701D5D5FA400E1BC6C /* TestStoreKit.swift */; };
637B4A741D5D5FC600E1BC6C /* PMKStoreKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 637B4A731D5D5FC600E1BC6C /* PMKStoreKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
63C7FFF71D5C020D003BAE60 /* PMKStoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63C7FFA71D5BEE09003BAE60 /* PMKStoreKit.framework */; };
D3F6DBF31EA245750013E242 /* SKPayment+Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3F6DBF21EA245750013E242 /* SKPayment+Promise.swift */; };
D3F6DBF51EA246340013E242 /* SKReceiptRefreshRequest+Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3F6DBF41EA246340013E242 /* SKReceiptRefreshRequest+Promise.swift */; };
/* End PBXBuildFile section */

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

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -86,7 +90,9 @@
637B4A731D5D5FC600E1BC6C /* PMKStoreKit.h */,
637B4A691D5D5F9B00E1BC6C /* SKRequest+AnyPromise.h */,
637B4A6A1D5D5F9B00E1BC6C /* SKRequest+AnyPromise.m */,
637B4A6B1D5D5F9B00E1BC6C /* SKRequest+Promise.swift */,
637B4A6B1D5D5F9B00E1BC6C /* SKProductsRequest+Promise.swift */,
D3F6DBF21EA245750013E242 /* SKPayment+Promise.swift */,
D3F6DBF41EA246340013E242 /* SKReceiptRefreshRequest+Promise.swift */,
);
name = Sources;
path = "PMK+UIKit";
Expand Down Expand Up @@ -215,8 +221,10 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
D3F6DBF51EA246340013E242 /* SKReceiptRefreshRequest+Promise.swift in Sources */,
637B4A6D1D5D5F9B00E1BC6C /* SKRequest+AnyPromise.m in Sources */,
637B4A6E1D5D5F9B00E1BC6C /* SKRequest+Promise.swift in Sources */,
637B4A6E1D5D5F9B00E1BC6C /* SKProductsRequest+Promise.swift in Sources */,
D3F6DBF31EA245750013E242 /* SKPayment+Promise.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
45 changes: 45 additions & 0 deletions Sources/SKPayment+Promise.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import StoreKit
#if !COCOAPODS
import PromiseKit
#endif

extension SKPayment {
public func promise() -> Promise<SKPaymentTransaction> {
return PaymentObserver(payment: self).promise
}
}

fileprivate class PaymentObserver: NSObject, SKPaymentTransactionObserver {
let (promise, fulfill, reject) = Promise<SKPaymentTransaction>.pending()
let payment: SKPayment
var retainCycle: PaymentObserver?

init(payment: SKPayment) {
self.payment = payment
super.init()
SKPaymentQueue.default().add(self)
SKPaymentQueue.default().add(payment)
retainCycle = self
}

func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
guard let transaction = transactions.first(where: { $0.payment == payment }) else {
return
}
switch transaction.transactionState {
case .purchased:
queue.finishTransaction(transaction)
fulfill(transaction)
queue.remove(self)
retainCycle = nil
case .failed:
let error = transaction.error ?? NSError.cancelledError()
queue.finishTransaction(transaction)
reject(error)
queue.remove(self)
retainCycle = nil
default:
break
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import PromiseKit

import PromiseKit
*/
extension SKRequest {
extension SKProductsRequest {
/**
Sends the request to the Apple App Store.

Expand All @@ -29,7 +29,7 @@ extension SKRequest {
}


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

Expand Down
35 changes: 35 additions & 0 deletions Sources/SKReceiptRefreshRequest+Promise.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import StoreKit
#if !COCOAPODS
import PromiseKit
#endif

extension SKReceiptRefreshRequest {
public func promise() -> Promise<SKReceiptRefreshRequest> {
return ReceiptRefreshObserver(request: self).promise
}
}

fileprivate class ReceiptRefreshObserver: NSObject, SKRequestDelegate {
let (promise, fulfill, reject) = Promise<SKReceiptRefreshRequest>.pending()
let request: SKReceiptRefreshRequest
var retainCycle: ReceiptRefreshObserver?

init(request: SKReceiptRefreshRequest) {
self.request = request
super.init()
request.delegate = self
request.start()
retainCycle = self
}


func requestDidFinish(_ request: SKRequest) {
fulfill(self.request)
retainCycle = nil
}

func request(_ request: SKRequest, didFailWithError error: Error) {
reject(error)
retainCycle = nil
}
}

0 comments on commit ca6c5fd

Please sign in to comment.