|
@@ -45,14 +45,14 @@ public class SwiftyStoreKit {
|
|
return productsInfoController.retrieveProductsInfo(productIds, completion: completion)
|
|
return productsInfoController.retrieveProductsInfo(productIds, completion: completion)
|
|
}
|
|
}
|
|
|
|
|
|
- func purchaseProduct(_ productId: String, atomically: Bool = true, applicationUsername: String = "", completion: @escaping ( PurchaseResult) -> Void) {
|
|
|
|
|
|
+ func purchaseProduct(_ productId: String, quantity: Int = 1, atomically: Bool = true, applicationUsername: String = "", completion: @escaping ( PurchaseResult) -> Void) {
|
|
|
|
|
|
if let product = productsInfoController.products[productId] {
|
|
if let product = productsInfoController.products[productId] {
|
|
- purchase(product: product, atomically: atomically, applicationUsername: applicationUsername, completion: completion)
|
|
|
|
|
|
+ purchase(product: product, quantity: quantity, atomically: atomically, applicationUsername: applicationUsername, completion: completion)
|
|
} else {
|
|
} else {
|
|
retrieveProductsInfo(Set([productId])) { result -> Void in
|
|
retrieveProductsInfo(Set([productId])) { result -> Void in
|
|
if let product = result.retrievedProducts.first {
|
|
if let product = result.retrievedProducts.first {
|
|
- self.purchase(product: product, atomically: atomically, applicationUsername: applicationUsername, completion: completion)
|
|
|
|
|
|
+ self.purchase(product: product, quantity: quantity, atomically: atomically, applicationUsername: applicationUsername, completion: completion)
|
|
} else if let error = result.error {
|
|
} else if let error = result.error {
|
|
completion(.error(error: SKError(_nsError: error as NSError)))
|
|
completion(.error(error: SKError(_nsError: error as NSError)))
|
|
} else if let invalidProductId = result.invalidProductIDs.first {
|
|
} else if let invalidProductId = result.invalidProductIDs.first {
|
|
@@ -73,7 +73,7 @@ public class SwiftyStoreKit {
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
|
|
- func completeTransactions(atomically: Bool = true, completion: @escaping ([Product]) -> Void) {
|
|
|
|
|
|
+ func completeTransactions(atomically: Bool = true, completion: @escaping ([Purchase]) -> Void) {
|
|
|
|
|
|
paymentQueueController.completeTransactions(CompleteTransactions(atomically: atomically, callback: completion))
|
|
paymentQueueController.completeTransactions(CompleteTransactions(atomically: atomically, callback: completion))
|
|
}
|
|
}
|
|
@@ -102,14 +102,14 @@ public class SwiftyStoreKit {
|
|
}
|
|
}
|
|
|
|
|
|
// MARK: private methods
|
|
// MARK: private methods
|
|
- private func purchase(product: SKProduct, atomically: Bool, applicationUsername: String = "", completion: @escaping (PurchaseResult) -> Void) {
|
|
|
|
|
|
+ private func purchase(product: SKProduct, quantity: Int, atomically: Bool, applicationUsername: String = "", completion: @escaping (PurchaseResult) -> Void) {
|
|
guard SwiftyStoreKit.canMakePayments else {
|
|
guard SwiftyStoreKit.canMakePayments else {
|
|
let error = NSError(domain: SKErrorDomain, code: SKError.paymentNotAllowed.rawValue, userInfo: nil)
|
|
let error = NSError(domain: SKErrorDomain, code: SKError.paymentNotAllowed.rawValue, userInfo: nil)
|
|
completion(.error(error: SKError(_nsError: error)))
|
|
completion(.error(error: SKError(_nsError: error)))
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
|
|
- paymentQueueController.startPayment(Payment(product: product, atomically: atomically, applicationUsername: applicationUsername) { result in
|
|
|
|
|
|
+ paymentQueueController.startPayment(Payment(product: product, quantity: quantity, atomically: atomically, applicationUsername: applicationUsername) { result in
|
|
|
|
|
|
completion(self.processPurchaseResult(result))
|
|
completion(self.processPurchaseResult(result))
|
|
})
|
|
})
|
|
@@ -117,30 +117,30 @@ public class SwiftyStoreKit {
|
|
|
|
|
|
private func processPurchaseResult(_ result: TransactionResult) -> PurchaseResult {
|
|
private func processPurchaseResult(_ result: TransactionResult) -> PurchaseResult {
|
|
switch result {
|
|
switch result {
|
|
- case .purchased(let product):
|
|
|
|
- return .success(product: product)
|
|
|
|
|
|
+ case .purchased(let purchase):
|
|
|
|
+ return .success(purchase: purchase)
|
|
case .failed(let error):
|
|
case .failed(let error):
|
|
return .error(error: error)
|
|
return .error(error: error)
|
|
- case .restored(let product):
|
|
|
|
- return .error(error: storeInternalError(description: "Cannot restore product \(product.productId) from purchase path"))
|
|
|
|
|
|
+ case .restored(let purchase):
|
|
|
|
+ return .error(error: storeInternalError(description: "Cannot restore product \(purchase.productId) from purchase path"))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private func processRestoreResults(_ results: [TransactionResult]) -> RestoreResults {
|
|
private func processRestoreResults(_ results: [TransactionResult]) -> RestoreResults {
|
|
- var restoredProducts: [Product] = []
|
|
|
|
- var restoreFailedProducts: [(SKError, String?)] = []
|
|
|
|
|
|
+ var restoredPurchases: [Purchase] = []
|
|
|
|
+ var restoreFailedPurchases: [(SKError, String?)] = []
|
|
for result in results {
|
|
for result in results {
|
|
switch result {
|
|
switch result {
|
|
- case .purchased(let product):
|
|
|
|
- let error = storeInternalError(description: "Cannot purchase product \(product.productId) from restore purchases path")
|
|
|
|
- restoreFailedProducts.append((error, product.productId))
|
|
|
|
|
|
+ case .purchased(let purchase):
|
|
|
|
+ let error = storeInternalError(description: "Cannot purchase product \(purchase.productId) from restore purchases path")
|
|
|
|
+ restoreFailedPurchases.append((error, purchase.productId))
|
|
case .failed(let error):
|
|
case .failed(let error):
|
|
- restoreFailedProducts.append((error, nil))
|
|
|
|
- case .restored(let product):
|
|
|
|
- restoredProducts.append(product)
|
|
|
|
|
|
+ restoreFailedPurchases.append((error, nil))
|
|
|
|
+ case .restored(let purchase):
|
|
|
|
+ restoredPurchases.append(purchase)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- return RestoreResults(restoredProducts: restoredProducts, restoreFailedProducts: restoreFailedProducts)
|
|
|
|
|
|
+ return RestoreResults(restoredPurchases: restoredPurchases, restoreFailedPurchases: restoreFailedPurchases)
|
|
}
|
|
}
|
|
|
|
|
|
private func storeInternalError(code: SKError.Code = SKError.unknown, description: String = "") -> SKError {
|
|
private func storeInternalError(code: SKError.Code = SKError.unknown, description: String = "") -> SKError {
|
|
@@ -167,13 +167,14 @@ extension SwiftyStoreKit {
|
|
/**
|
|
/**
|
|
* Purchase a product
|
|
* Purchase a product
|
|
* - Parameter productId: productId as specified in iTunes Connect
|
|
* - Parameter productId: productId as specified in iTunes Connect
|
|
|
|
+ * - Parameter quantity: quantity of the product to be purchased
|
|
* - Parameter atomically: whether the product is purchased atomically (e.g. finishTransaction is called immediately)
|
|
* - Parameter atomically: whether the product is purchased atomically (e.g. finishTransaction is called immediately)
|
|
* - Parameter applicationUsername: an opaque identifier for the user’s account on your system
|
|
* - Parameter applicationUsername: an opaque identifier for the user’s account on your system
|
|
* - Parameter completion: handler for result
|
|
* - Parameter completion: handler for result
|
|
*/
|
|
*/
|
|
- public class func purchaseProduct(_ productId: String, atomically: Bool = true, applicationUsername: String = "", completion: @escaping ( PurchaseResult) -> Void) {
|
|
|
|
|
|
+ public class func purchaseProduct(_ productId: String, quantity: Int = 1, atomically: Bool = true, applicationUsername: String = "", completion: @escaping ( PurchaseResult) -> Void) {
|
|
|
|
|
|
- sharedInstance.purchaseProduct(productId, atomically: atomically, applicationUsername: applicationUsername, completion: completion)
|
|
|
|
|
|
+ sharedInstance.purchaseProduct(productId, quantity: quantity, atomically: atomically, applicationUsername: applicationUsername, completion: completion)
|
|
}
|
|
}
|
|
|
|
|
|
public class func restorePurchases(atomically: Bool = true, applicationUsername: String = "", completion: @escaping (RestoreResults) -> Void) {
|
|
public class func restorePurchases(atomically: Bool = true, applicationUsername: String = "", completion: @escaping (RestoreResults) -> Void) {
|
|
@@ -181,7 +182,7 @@ extension SwiftyStoreKit {
|
|
sharedInstance.restorePurchases(atomically: atomically, applicationUsername: applicationUsername, completion: completion)
|
|
sharedInstance.restorePurchases(atomically: atomically, applicationUsername: applicationUsername, completion: completion)
|
|
}
|
|
}
|
|
|
|
|
|
- public class func completeTransactions(atomically: Bool = true, completion: @escaping ([Product]) -> Void) {
|
|
|
|
|
|
+ public class func completeTransactions(atomically: Bool = true, completion: @escaping ([Purchase]) -> Void) {
|
|
|
|
|
|
sharedInstance.completeTransactions(atomically: atomically, completion: completion)
|
|
sharedInstance.completeTransactions(atomically: atomically, completion: completion)
|
|
}
|
|
}
|