-
Notifications
You must be signed in to change notification settings - Fork 0
/
InAppPurchaseStore.swift
136 lines (113 loc) · 3.76 KB
/
InAppPurchaseStore.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
//
// InAppPurchaseStore.swift
// ExpenseSheet
//
// Created by Bishal Aryal on 03/01/2021.
// Copyright © 2021 Bishal Aryal. All rights reserved.
//
import StoreKit
typealias FetchComplitionHandler = (([SKProduct]) -> Void)
typealias PurchaseomplitionHandler = ((SKPaymentTransaction?) -> Void)
class InAppPurchaseStore: NSObject, ObservableObject
{
private let allProductIdentifiers = Set(["biszaal.Expense.removeads"])
private var completedPurchases = [String]()
private var productRequests: SKProductsRequest?
private var fetchedProducts = [SKProduct]()
private var fetchComplitionHandler: FetchComplitionHandler?
private var purchaseComplitionHandler: PurchaseomplitionHandler?
override init()
{
super.init()
fetchProducts
{ (products) in
print(products)
}
}
private func startObservingPaymentQueue()
{
SKPaymentQueue.default().add(self)
}
private func fetchProducts(_ complition: @escaping FetchComplitionHandler)
{
guard self.productRequests == nil else { return }
fetchComplitionHandler = complition
productRequests = SKProductsRequest(productIdentifiers: allProductIdentifiers)
productRequests?.delegate = self
productRequests?.start()
}
private func buy(_ product: SKProduct, complition: @escaping PurchaseomplitionHandler)
{
purchaseComplitionHandler = complition
let payment = SKPayment(product: product)
SKPaymentQueue.default().add(payment)
}
}
extension InAppPurchaseStore
{
func purchaseProduct(_ product: SKProduct)
{
startObservingPaymentQueue()
buy(product)
{ _ in
// Empty
}
}
}
extension InAppPurchaseStore: SKPaymentTransactionObserver
{
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction])
{
for transaction in transactions
{
var shouldFinishTransaction = false
switch transaction.transactionState
{
case .purchased, .restored:
completedPurchases.append(transaction.payment.productIdentifier)
shouldFinishTransaction = true
case .failed:
shouldFinishTransaction = true
case .purchasing, .deferred:
break
@unknown default:
break
}
if shouldFinishTransaction
{
SKPaymentQueue.default().finishTransaction(transaction)
DispatchQueue.main.async
{
self.purchaseComplitionHandler?(transaction)
self.purchaseComplitionHandler = nil
}
}
}
}
}
extension InAppPurchaseStore: SKProductsRequestDelegate
{
func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse)
{
let loadedProducts = response.products
let invalidProducts = response.invalidProductIdentifiers
guard !loadedProducts.isEmpty else {
print("Could not load the purchase")
if !invalidProducts.isEmpty
{
print("Invalid purchase: \(invalidProducts)")
}
productRequests = nil
return
}
// Cache the fetched products
fetchedProducts = loadedProducts
// Notify anyone waiting on the product load
DispatchQueue.main.async
{
self.fetchComplitionHandler?(loadedProducts)
self.fetchComplitionHandler = nil
self.productRequests = nil
}
}
}