Skip to content

Commit 39e0035

Browse files
authored
[in_app_purchase] Implement registerPlatform method for iOS implementation (flutter#3851)
1 parent d3b9711 commit 39e0035

File tree

3 files changed

+32
-42
lines changed

3 files changed

+32
-42
lines changed

packages/in_app_purchase/in_app_purchase_ios/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,7 @@ dependencies:
3131
...
3232
```
3333

34+
## TODO
35+
- [ ] Add an example application demonstrating the use of the [in_app_purchase_ios] package (see also issue [flutter/flutter#81695](https://github.com/flutter/flutter/issues/81695)).
36+
3437
[1]: ../in_app_purchase/in_app_purchase

packages/in_app_purchase/in_app_purchase_ios/lib/src/in_app_purchase_ios_platform.dart

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,6 @@ const String kIAPSource = 'app_store';
2323
/// This translates various `StoreKit` calls and responses into the
2424
/// generic plugin API.
2525
class InAppPurchaseIosPlatform extends InAppPurchasePlatform {
26-
/// Returns the singleton instance of the [InAppPurchaseIosPlatform] that should be
27-
/// used across the app.
28-
static InAppPurchaseIosPlatform get instance => _getOrCreateInstance();
29-
static InAppPurchaseIosPlatform? _instance;
3026
static late SKPaymentQueueWrapper _skPaymentQueueWrapper;
3127
static late _TransactionObserver _observer;
3228

@@ -44,22 +40,19 @@ class InAppPurchaseIosPlatform extends InAppPurchasePlatform {
4440
@visibleForTesting
4541
static SKTransactionObserverWrapper get observer => _observer;
4642

47-
static InAppPurchaseIosPlatform _getOrCreateInstance() {
48-
if (_instance != null) {
49-
return _instance!;
50-
}
51-
43+
/// Registers this class as the default instance of [InAppPurchasePlatform].
44+
static void registerPlatform() {
5245
// Register the [InAppPurchaseIosPlatformAddition] containing iOS
5346
// platform-specific functionality.
5447
InAppPurchasePlatformAddition.instance = InAppPurchaseIosPlatformAddition();
5548

5649
// Register the platform-specific implementation of the idiomatic
5750
// InAppPurchase API.
58-
_instance = InAppPurchaseIosPlatform();
51+
InAppPurchasePlatform.setInstance(InAppPurchaseIosPlatform());
52+
5953
_skPaymentQueueWrapper = SKPaymentQueueWrapper();
6054
_observer = _TransactionObserver(StreamController.broadcast());
6155
_skPaymentQueueWrapper.setTransactionObserver(observer);
62-
return _instance!;
6356
}
6457

6558
@override

packages/in_app_purchase/in_app_purchase_ios/test/in_app_purchase_ios_platform_test.dart

Lines changed: 25 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,24 @@ void main() {
1818
TestWidgetsFlutterBinding.ensureInitialized();
1919

2020
final FakeIOSPlatform fakeIOSPlatform = FakeIOSPlatform();
21+
late InAppPurchaseIosPlatform iapIosPlatform;
2122

2223
setUpAll(() {
2324
SystemChannels.platform
2425
.setMockMethodCallHandler(fakeIOSPlatform.onMethodCall);
2526
});
2627

27-
setUp(() => fakeIOSPlatform.reset());
28+
setUp(() {
29+
InAppPurchaseIosPlatform.registerPlatform();
30+
iapIosPlatform = InAppPurchasePlatform.instance as InAppPurchaseIosPlatform;
31+
fakeIOSPlatform.reset();
32+
});
2833

2934
tearDown(() => fakeIOSPlatform.reset());
3035

3136
group('isAvailable', () {
3237
test('true', () async {
33-
expect(await InAppPurchaseIosPlatform.instance.isAvailable(), isTrue);
38+
expect(await iapIosPlatform.isAvailable(), isTrue);
3439
});
3540
});
3641

@@ -69,8 +74,7 @@ void main() {
6974
group('restore purchases', () {
7075
test('should emit restored transactions on purchase stream', () async {
7176
Completer completer = Completer();
72-
Stream<List<PurchaseDetails>> stream =
73-
InAppPurchaseIosPlatform.instance.purchaseStream;
77+
Stream<List<PurchaseDetails>> stream = iapIosPlatform.purchaseStream;
7478

7579
late StreamSubscription subscription;
7680
subscription = stream.listen((purchaseDetailsList) {
@@ -80,7 +84,7 @@ void main() {
8084
}
8185
});
8286

83-
await InAppPurchaseIosPlatform.instance.restorePurchases();
87+
await iapIosPlatform.restorePurchases();
8488
List<PurchaseDetails> details = await completer.future;
8589

8690
expect(details.length, 2);
@@ -103,8 +107,7 @@ void main() {
103107
fakeIOSPlatform.transactions
104108
.insert(0, fakeIOSPlatform.createPurchasedTransaction('foo', 'bar'));
105109
Completer completer = Completer();
106-
Stream<List<PurchaseDetails>> stream =
107-
InAppPurchaseIosPlatform.instance.purchaseStream;
110+
Stream<List<PurchaseDetails>> stream = iapIosPlatform.purchaseStream;
108111

109112
late StreamSubscription subscription;
110113
subscription = stream.listen((purchaseDetailsList) {
@@ -113,7 +116,7 @@ void main() {
113116
subscription.cancel();
114117
}
115118
});
116-
await InAppPurchaseIosPlatform.instance.restorePurchases();
119+
await iapIosPlatform.restorePurchases();
117120
List<PurchaseDetails> details = await completer.future;
118121
expect(details.length, 3);
119122
for (int i = 0; i < fakeIOSPlatform.transactions.length; i++) {
@@ -139,8 +142,7 @@ void main() {
139142
() async {
140143
fakeIOSPlatform.receiptData = null;
141144
Completer completer = Completer();
142-
Stream<List<PurchaseDetails>> stream =
143-
InAppPurchaseIosPlatform.instance.purchaseStream;
145+
Stream<List<PurchaseDetails>> stream = iapIosPlatform.purchaseStream;
144146

145147
late StreamSubscription subscription;
146148
subscription = stream.listen((purchaseDetailsList) {
@@ -150,7 +152,7 @@ void main() {
150152
}
151153
});
152154

153-
await InAppPurchaseIosPlatform.instance.restorePurchases();
155+
await iapIosPlatform.restorePurchases();
154156
List<PurchaseDetails> details = await completer.future;
155157

156158
for (PurchaseDetails purchase in details) {
@@ -166,7 +168,7 @@ void main() {
166168
userInfo: {'message': 'errorMessage'});
167169

168170
expect(
169-
() => InAppPurchaseIosPlatform.instance.restorePurchases(),
171+
() => iapIosPlatform.restorePurchases(),
170172
throwsA(
171173
isA<SKError>()
172174
.having((error) => error.code, 'code', 123)
@@ -183,8 +185,7 @@ void main() {
183185
() async {
184186
List<PurchaseDetails> details = [];
185187
Completer completer = Completer();
186-
Stream<List<PurchaseDetails>> stream =
187-
InAppPurchaseIosPlatform.instance.purchaseStream;
188+
Stream<List<PurchaseDetails>> stream = iapIosPlatform.purchaseStream;
188189

189190
late StreamSubscription subscription;
190191
subscription = stream.listen((purchaseDetailsList) {
@@ -198,8 +199,7 @@ void main() {
198199
productDetails:
199200
AppStoreProductDetails.fromSKProduct(dummyProductWrapper),
200201
applicationUserName: 'appName');
201-
await InAppPurchaseIosPlatform.instance
202-
.buyNonConsumable(purchaseParam: purchaseParam);
202+
await iapIosPlatform.buyNonConsumable(purchaseParam: purchaseParam);
203203

204204
List<PurchaseDetails> result = await completer.future;
205205
expect(result.length, 2);
@@ -211,8 +211,7 @@ void main() {
211211
() async {
212212
List<PurchaseDetails> details = [];
213213
Completer completer = Completer();
214-
Stream<List<PurchaseDetails>> stream =
215-
InAppPurchaseIosPlatform.instance.purchaseStream;
214+
Stream<List<PurchaseDetails>> stream = iapIosPlatform.purchaseStream;
216215

217216
late StreamSubscription subscription;
218217
subscription = stream.listen((purchaseDetailsList) {
@@ -226,8 +225,7 @@ void main() {
226225
productDetails:
227226
AppStoreProductDetails.fromSKProduct(dummyProductWrapper),
228227
applicationUserName: 'appName');
229-
await InAppPurchaseIosPlatform.instance
230-
.buyConsumable(purchaseParam: purchaseParam);
228+
await iapIosPlatform.buyConsumable(purchaseParam: purchaseParam);
231229

232230
List<PurchaseDetails> result = await completer.future;
233231
expect(result.length, 2);
@@ -240,8 +238,8 @@ void main() {
240238
AppStoreProductDetails.fromSKProduct(dummyProductWrapper),
241239
applicationUserName: 'appName');
242240
expect(
243-
() => InAppPurchaseIosPlatform.instance
244-
.buyConsumable(purchaseParam: purchaseParam, autoConsume: false),
241+
() => iapIosPlatform.buyConsumable(
242+
purchaseParam: purchaseParam, autoConsume: false),
245243
throwsA(isInstanceOf<AssertionError>()));
246244
});
247245

@@ -251,8 +249,7 @@ void main() {
251249
Completer completer = Completer();
252250
late IAPError error;
253251

254-
Stream<List<PurchaseDetails>> stream =
255-
InAppPurchaseIosPlatform.instance.purchaseStream;
252+
Stream<List<PurchaseDetails>> stream = iapIosPlatform.purchaseStream;
256253
late StreamSubscription subscription;
257254
subscription = stream.listen((purchaseDetailsList) {
258255
details.addAll(purchaseDetailsList);
@@ -268,8 +265,7 @@ void main() {
268265
productDetails:
269266
AppStoreProductDetails.fromSKProduct(dummyProductWrapper),
270267
applicationUserName: 'appName');
271-
await InAppPurchaseIosPlatform.instance
272-
.buyNonConsumable(purchaseParam: purchaseParam);
268+
await iapIosPlatform.buyNonConsumable(purchaseParam: purchaseParam);
273269

274270
IAPError completerError = await completer.future;
275271
expect(completerError.code, 'purchase_error');
@@ -283,14 +279,13 @@ void main() {
283279
test('should complete purchase', () async {
284280
List<PurchaseDetails> details = [];
285281
Completer completer = Completer();
286-
Stream<List<PurchaseDetails>> stream =
287-
InAppPurchaseIosPlatform.instance.purchaseStream;
282+
Stream<List<PurchaseDetails>> stream = iapIosPlatform.purchaseStream;
288283
late StreamSubscription subscription;
289284
subscription = stream.listen((purchaseDetailsList) {
290285
details.addAll(purchaseDetailsList);
291286
purchaseDetailsList.forEach((purchaseDetails) {
292287
if (purchaseDetails.pendingCompletePurchase) {
293-
InAppPurchaseIosPlatform.instance.completePurchase(purchaseDetails);
288+
iapIosPlatform.completePurchase(purchaseDetails);
294289
completer.complete(details);
295290
subscription.cancel();
296291
}
@@ -300,8 +295,7 @@ void main() {
300295
productDetails:
301296
AppStoreProductDetails.fromSKProduct(dummyProductWrapper),
302297
applicationUserName: 'appName');
303-
await InAppPurchaseIosPlatform.instance
304-
.buyNonConsumable(purchaseParam: purchaseParam);
298+
await iapIosPlatform.buyNonConsumable(purchaseParam: purchaseParam);
305299
List<PurchaseDetails> result = await completer.future;
306300
expect(result.length, 2);
307301
expect(result.first.productID, dummyProductWrapper.productIdentifier);

0 commit comments

Comments
 (0)