4
4
5
5
@available ( iOS 15 . 0 , macOS 12 . 0 , * )
6
6
extension InAppPurchasePlugin : InAppPurchase2API {
7
-
8
7
// MARK: - Pigeon Functions
9
8
10
- /// Wrapper method around StoreKit2's canMakePayments() method
11
- /// https://developer.apple.com/documentation/storekit/appstore/3822277-canmakepayments
9
+ // Wrapper method around StoreKit2's canMakePayments() method
10
+ // https://developer.apple.com/documentation/storekit/appstore/3822277-canmakepayments
12
11
func canMakePayments( ) throws -> Bool {
13
12
return AppStore . canMakePayments
14
13
}
15
14
16
- /// Wrapper method around StoreKit2's products() method
17
- /// https://developer.apple.com/documentation/storekit/product/3851116-products
15
+ // Wrapper method around StoreKit2's products() method
16
+ // https://developer.apple.com/documentation/storekit/product/3851116-products
18
17
func products(
19
18
identifiers: [ String ] , completion: @escaping ( Result < [ SK2ProductMessage ] , Error > ) -> Void
20
19
) {
@@ -35,144 +34,4 @@ extension InAppPurchasePlugin: InAppPurchase2API {
35
34
}
36
35
}
37
36
}
38
-
39
- /// Gets the appropriate product, then calls purchase on it.
40
- /// https://developer.apple.com/documentation/storekit/product/3791971-purchase
41
- func purchase(
42
- id: String , options: SK2ProductPurchaseOptionsMessage ? ,
43
- completion: @escaping ( Result < SK2ProductPurchaseResultMessage , Error > ) -> Void
44
- ) {
45
- Task { @MainActor in
46
- do {
47
- guard let product = try await Product . products ( for: [ id] ) . first else {
48
- let error = PigeonError (
49
- code: " storekit2_failed_to_fetch_product " ,
50
- message: " Storekit has failed to fetch this product. " ,
51
- details: " Product ID : \( id) " )
52
- return completion ( . failure( error) )
53
- }
54
-
55
- let result = try await product. purchase ( options: [ ] )
56
-
57
- switch result {
58
- case . success( let verification) :
59
- switch verification {
60
- case . verified( let transaction) :
61
- self . sendTransactionUpdate ( transaction: transaction)
62
- completion ( . success( result. convertToPigeon ( ) ) )
63
- case . unverified( _, let error) :
64
- completion ( . failure( error) )
65
- }
66
- case . pending:
67
- completion (
68
- . failure(
69
- PigeonError (
70
- code: " storekit2_purchase_pending " ,
71
- message:
72
- " This transaction is still pending and but may complete in the future. If it completes, it will be delivered via `purchaseStream` " ,
73
- details: " Product ID : \( id) " ) ) )
74
- case . userCancelled:
75
- completion (
76
- . failure(
77
- PigeonError (
78
- code: " storekit2_purchase_cancelled " ,
79
- message: " This transaction has been cancelled by the user. " ,
80
- details: " Product ID : \( id) " ) ) )
81
- @unknown default :
82
- fatalError ( " An unknown StoreKit PurchaseResult has been encountered. " )
83
- }
84
- } catch {
85
- completion ( . failure( error) )
86
- }
87
- }
88
- }
89
-
90
- /// Wrapper method around StoreKit2's transactions() method
91
- /// https://developer.apple.com/documentation/storekit/product/3851116-products
92
- func transactions(
93
- completion: @escaping ( Result < [ SK2TransactionMessage ] , Error > ) -> Void
94
- ) {
95
- Task {
96
- @MainActor in
97
- do {
98
- let transactionsMsgs = await rawTransactions ( ) . map {
99
- $0. convertToPigeon ( )
100
- }
101
- completion ( . success( transactionsMsgs) )
102
- }
103
- }
104
- }
105
-
106
- /// Wrapper method around StoreKit2's finish() method https://developer.apple.com/documentation/storekit/transaction/3749694-finish
107
- func finish( id: Int64 , completion: @escaping ( Result < Void , Error > ) -> Void ) {
108
- Task {
109
- let transaction = try await fetchTransaction ( by: UInt64 ( id) )
110
- if let transaction = transaction {
111
- await transaction. finish ( )
112
- }
113
- }
114
- }
115
-
116
- /// This Task listens to Transation.updates as shown here
117
- /// https://developer.apple.com/documentation/storekit/transaction/3851206-updates
118
- /// This function should be called as soon as the app starts to avoid missing any Transactions done outside of the app.
119
- func startListeningToTransactions( ) throws {
120
- self . setListenerTaskAsTask (
121
- task: Task { [ weak self] in
122
- for await verificationResult in Transaction . updates {
123
- switch verificationResult {
124
- case . verified( let transaction) :
125
- self ? . sendTransactionUpdate ( transaction: transaction)
126
- case . unverified:
127
- break
128
- }
129
- }
130
- } )
131
- }
132
-
133
- /// Stop subscribing to Transaction.updates
134
- func stopListeningToTransactions( ) throws {
135
- getListenerTaskAsTask. cancel ( )
136
- }
137
-
138
- /// Sends an transaction back to Dart. Access these transactions with `purchaseStream`
139
- func sendTransactionUpdate( transaction: Transaction ) {
140
- let transactionMessage = transaction. convertToPigeon ( )
141
- transactionCallbackAPI? . onTransactionsUpdated ( newTransaction: transactionMessage) { result in
142
- switch result {
143
- case . success: break
144
- case . failure( let error) :
145
- print ( " Failed to send transaction updates: \( error) " )
146
- }
147
- }
148
- }
149
-
150
- /// Helper function that fetches and unwraps all verified transactions
151
- private func rawTransactions( ) async -> [ Transaction ] {
152
- var transactions : [ Transaction ] = [ ]
153
- for await verificationResult in Transaction . all {
154
- switch verificationResult {
155
- case . verified( let transaction) :
156
- transactions. append ( transaction)
157
- case . unverified:
158
- break
159
- }
160
- }
161
- return transactions
162
- }
163
-
164
- /// Helper function to fetch specific transaction
165
- private func fetchTransaction( by id: UInt64 ) async throws -> Transaction ? {
166
- for await result in Transaction . all {
167
- switch result {
168
- case . verified( let transaction) :
169
- if transaction. id == id {
170
- return transaction
171
- }
172
- case . unverified:
173
- continue
174
- }
175
- }
176
- return nil
177
- }
178
37
}
0 commit comments