Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // IAPManager.swift
- // InAppPurchase
- //
- // Created by Caleb Manley on 1/10/16.
- // Copyright © 2016 Caleb Manley. All rights reserved.
- //
- import StoreKit
- public typealias ProductIdentifier = String
- public typealias ProductsRequestCompletionHandler = (_ success: Bool, _ products: [SKProduct]?) -> ()
- class IAPManager: NSObject {
- static let IAPManagerPurchaseNotification = "IAPManagerPurchaseNotification"
- fileprivate var productIdentifiers: Set<ProductIdentifier> = []
- fileprivate var purchasedProductIdentifiers = Set<ProductIdentifier>()
- fileprivate var productsRequest: SKProductsRequest?
- fileprivate var productsRequestCompletionHandler: ProductsRequestCompletionHandler?
- fileprivate let keychain = KeychainSwift()
- private override init() { super.init() }
- public convenience init(_ productIDs: Set<ProductIdentifier>) {
- self.init()
- productIdentifiers = productIDs
- for productIdentifier in productIDs {
- let purchased: Bool = keychain.getBool(productIdentifier) ?? false
- if purchased {
- purchasedProductIdentifiers.insert(productIdentifier)
- print("Previously purchased: \(productIdentifier)")
- } else {
- print("Not purchased: \(productIdentifier)")
- }
- }
- SKPaymentQueue.default().add(self)
- }
- }
- extension IAPManager {
- public func requestProducts(completionHandler: @escaping ProductsRequestCompletionHandler) {
- productsRequest?.cancel()
- productsRequestCompletionHandler = completionHandler
- productsRequest = SKProductsRequest(productIdentifiers: productIdentifiers)
- productsRequest!.delegate = self
- productsRequest!.start()
- }
- public func buyProduct(_ product: SKProduct) {
- print("Buying \(product.productIdentifier)...")
- let payment = SKPayment(product: product)
- SKPaymentQueue.default().add(payment)
- }
- public func isProductPurchased(_ productIdentifier: ProductIdentifier) -> Bool {
- return purchasedProductIdentifiers.contains(productIdentifier)
- }
- public class func canMakePayments() -> Bool {
- return SKPaymentQueue.canMakePayments()
- }
- public func restorePurchases() {
- if SKPaymentQueue.canMakePayments() {
- SKPaymentQueue.default().restoreCompletedTransactions()
- } else {
- print("Cannot restore purchases...")
- }
- }
- }
- extension IAPManager: SKProductsRequestDelegate {
- public func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
- let products = response.products
- print("Loaded list of products...")
- productsRequestCompletionHandler?(true, products)
- clearRequestAndHandler()
- for p in products {
- print("Found product: \(p.productIdentifier) \(p.localizedTitle) \(p.price.floatValue)")
- }
- }
- public func request(_ request: SKRequest, didFailWithError error: Error) {
- print("Failed to load list of products.")
- print("Error: \(error.localizedDescription)")
- productsRequestCompletionHandler?(false, nil)
- clearRequestAndHandler()
- }
- private func clearRequestAndHandler() {
- productsRequest = nil
- productsRequestCompletionHandler = nil
- }
- }
- extension IAPManager: SKPaymentTransactionObserver {
- public func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
- for transaction in transactions {
- switch (transaction.transactionState) {
- case .purchased:
- complete(transaction: transaction)
- break
- case .failed:
- fail(transaction: transaction)
- break
- case .restored:
- restore(transaction: transaction)
- break
- case .deferred:
- break
- case .purchasing:
- break
- }
- }
- }
- private func complete(transaction: SKPaymentTransaction) {
- print("complete...")
- deliverPurchaseNotificationFor(identifier: transaction.payment.productIdentifier)
- SKPaymentQueue.default().finishTransaction(transaction)
- }
- private func restore(transaction: SKPaymentTransaction) {
- guard let productIdentifier = transaction.original?.payment.productIdentifier else { return }
- keychain.set(false, forKey: productIdentifier)
- print("restore... \(productIdentifier)")
- deliverPurchaseNotificationFor(identifier: productIdentifier)
- SKPaymentQueue.default().finishTransaction(transaction)
- }
- private func fail(transaction: SKPaymentTransaction) {
- print("fail...")
- if let transactionError = transaction.error as? NSError {
- if transactionError.code != SKError.paymentCancelled.rawValue {
- print("Transaction Error: \(transaction.error?.localizedDescription)")
- }
- }
- SKPaymentQueue.default().finishTransaction(transaction)
- }
- private func deliverPurchaseNotificationFor(identifier: String?) {
- guard let identifier = identifier else { return }
- purchasedProductIdentifiers.insert(identifier)
- keychain.set(true, forKey: identifier)
- NotificationCenter.default.post(name: NSNotification.Name(rawValue: IAPManager.IAPManagerPurchaseNotification), object: identifier)
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement