Skip to content

Commit e95f6d8

Browse files
authored
[in_app_purchase_storekit] disallow ios versions lower than supported from enabling storekit (flutter#8110)
Fixes flutter#158894 Checks device version before enabling storekit 2.
1 parent fc80137 commit e95f6d8

File tree

14 files changed

+128
-9
lines changed

14 files changed

+128
-9
lines changed

packages/in_app_purchase/in_app_purchase_storekit/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.3.20+1
2+
3+
* Prevent devices below iOS 15 or macOS 15 from enabling StoreKit2.
4+
15
## 0.3.20
26

37
* Fixes manual invocation of `finishTransaction` causing a fatal crash.

packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,15 @@ public class InAppPurchasePlugin: NSObject, FlutterPlugin, FIAInAppPurchaseAPI {
420420
NSLog("Received an updatedDownloads callback, but downloads are not supported.")
421421
}
422422

423+
public func supportsStoreKit2WithError(_ error: AutoreleasingUnsafeMutablePointer<FlutterError?>)
424+
-> NSNumber?
425+
{
426+
if #available(iOS 15.0, macOS 12.0, *) {
427+
return true
428+
}
429+
return false
430+
}
431+
423432
// MARK: - Methods exposed for testing
424433
func getProduct(productID: String) -> SKProduct? {
425434
return self.productsCache[productID] as? SKProduct

packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/messages.g.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright 2013 The Flutter Authors. All rights reserved.
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
4-
// Autogenerated from Pigeon (v22.4.2), do not edit directly.
4+
// Autogenerated from Pigeon (v22.6.0), do not edit directly.
55
// See also: https://pub.dev/packages/pigeon
66

77
#import <Foundation/Foundation.h>
@@ -67,7 +67,8 @@ typedef NS_ENUM(NSUInteger, FIASKProductDiscountTypeMessage) {
6767
typedef NS_ENUM(NSUInteger, FIASKProductDiscountPaymentModeMessage) {
6868
/// Allows user to pay the discounted price at each payment period.
6969
FIASKProductDiscountPaymentModeMessagePayAsYouGo = 0,
70-
/// Allows user to pay the discounted price upfront and receive the product for the rest of time
70+
/// Allows user to pay the discounted price upfront and receive the product
71+
/// for the rest of time
7172
/// that was paid for.
7273
FIASKProductDiscountPaymentModeMessagePayUpFront = 1,
7374
/// User pays nothing during the discounted period.
@@ -278,6 +279,8 @@ NSObject<FlutterMessageCodec> *FIAGetMessagesCodec(void);
278279
- (void)registerPaymentQueueDelegateWithError:(FlutterError *_Nullable *_Nonnull)error;
279280
- (void)removePaymentQueueDelegateWithError:(FlutterError *_Nullable *_Nonnull)error;
280281
- (void)showPriceConsentIfNeededWithError:(FlutterError *_Nullable *_Nonnull)error;
282+
/// @return `nil` only when `error != nil`.
283+
- (nullable NSNumber *)supportsStoreKit2WithError:(FlutterError *_Nullable *_Nonnull)error;
281284
@end
282285

283286
extern void SetUpFIAInAppPurchaseAPI(id<FlutterBinaryMessenger> binaryMessenger,

packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/messages.g.m

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright 2013 The Flutter Authors. All rights reserved.
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
4-
// Autogenerated from Pigeon (v22.4.2), do not edit directly.
4+
// Autogenerated from Pigeon (v22.6.0), do not edit directly.
55
// See also: https://pub.dev/packages/pigeon
66

77
#import "messages.g.h"
@@ -978,4 +978,26 @@ void SetUpFIAInAppPurchaseAPIWithSuffix(id<FlutterBinaryMessenger> binaryMesseng
978978
[channel setMessageHandler:nil];
979979
}
980980
}
981+
{
982+
FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
983+
initWithName:[NSString stringWithFormat:@"%@%@",
984+
@"dev.flutter.pigeon.in_app_purchase_storekit."
985+
@"InAppPurchaseAPI.supportsStoreKit2",
986+
messageChannelSuffix]
987+
binaryMessenger:binaryMessenger
988+
codec:FIAGetMessagesCodec()];
989+
if (api) {
990+
NSCAssert(
991+
[api respondsToSelector:@selector(supportsStoreKit2WithError:)],
992+
@"FIAInAppPurchaseAPI api (%@) doesn't respond to @selector(supportsStoreKit2WithError:)",
993+
api);
994+
[channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
995+
FlutterError *error;
996+
NSNumber *output = [api supportsStoreKit2WithError:&error];
997+
callback(wrapResult(output, error));
998+
}];
999+
} else {
1000+
[channel setMessageHandler:nil];
1001+
}
1002+
}
9811003
}

packages/in_app_purchase/in_app_purchase_storekit/example/lib/main.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ void main() {
1717
// When using the Android plugin directly it is mandatory to register
1818
// the plugin as default instance as part of initializing the app.
1919
InAppPurchaseStoreKitPlatform.registerPlatform();
20+
InAppPurchaseStoreKitPlatform.enableStoreKit2();
2021

2122
runApp(_MyApp());
2223
}

packages/in_app_purchase/in_app_purchase_storekit/lib/src/in_app_purchase_storekit_platform.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,10 @@ class InAppPurchaseStoreKitPlatform extends InAppPurchasePlatform {
249249
Future<String?> getCountryCode() => countryCode();
250250

251251
/// Turns on StoreKit2. You cannot disable this after it is enabled.
252-
void enableStoreKit2() {
253-
_useStoreKit2 = true;
252+
/// This can only be enabled if your device supports StoreKit 2.
253+
static Future<bool> enableStoreKit2() async {
254+
_useStoreKit2 = await SKRequestMaker.supportsStoreKit2();
255+
return _useStoreKit2;
254256
}
255257
}
256258

packages/in_app_purchase/in_app_purchase_storekit/lib/src/messages.g.dart

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright 2013 The Flutter Authors. All rights reserved.
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
4-
// Autogenerated from Pigeon (v22.4.2), do not edit directly.
4+
// Autogenerated from Pigeon (v22.6.0), do not edit directly.
55
// See also: https://pub.dev/packages/pigeon
66
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers
77

@@ -984,4 +984,33 @@ class InAppPurchaseAPI {
984984
return;
985985
}
986986
}
987+
988+
Future<bool> supportsStoreKit2() async {
989+
final String pigeonVar_channelName =
990+
'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.supportsStoreKit2$pigeonVar_messageChannelSuffix';
991+
final BasicMessageChannel<Object?> pigeonVar_channel =
992+
BasicMessageChannel<Object?>(
993+
pigeonVar_channelName,
994+
pigeonChannelCodec,
995+
binaryMessenger: pigeonVar_binaryMessenger,
996+
);
997+
final List<Object?>? pigeonVar_replyList =
998+
await pigeonVar_channel.send(null) as List<Object?>?;
999+
if (pigeonVar_replyList == null) {
1000+
throw _createConnectionError(pigeonVar_channelName);
1001+
} else if (pigeonVar_replyList.length > 1) {
1002+
throw PlatformException(
1003+
code: pigeonVar_replyList[0]! as String,
1004+
message: pigeonVar_replyList[1] as String?,
1005+
details: pigeonVar_replyList[2],
1006+
);
1007+
} else if (pigeonVar_replyList[0] == null) {
1008+
throw PlatformException(
1009+
code: 'null-error',
1010+
message: 'Host platform returned null value for non-null return value.',
1011+
);
1012+
} else {
1013+
return (pigeonVar_replyList[0] as bool?)!;
1014+
}
1015+
}
9871016
}

packages/in_app_purchase/in_app_purchase_storekit/lib/src/store_kit_wrappers/sk_request_maker.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,9 @@ class SKRequestMaker {
5555
{Map<String, Object?>? receiptProperties}) {
5656
return _hostApi.refreshReceipt(receiptProperties: receiptProperties);
5757
}
58+
59+
/// Check if current device supports StoreKit 2.
60+
static Future<bool> supportsStoreKit2() async {
61+
return _hostApi.supportsStoreKit2();
62+
}
5863
}

packages/in_app_purchase/in_app_purchase_storekit/pigeons/messages.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,4 +264,6 @@ abstract class InAppPurchaseAPI {
264264
void removePaymentQueueDelegate();
265265

266266
void showPriceConsentIfNeeded();
267+
268+
bool supportsStoreKit2();
267269
}

packages/in_app_purchase/in_app_purchase_storekit/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: in_app_purchase_storekit
22
description: An implementation for the iOS and macOS platforms of the Flutter `in_app_purchase` plugin. This uses the StoreKit Framework.
33
repository: https://github.com/flutter/packages/tree/main/packages/in_app_purchase/in_app_purchase_storekit
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+in_app_purchase%22
5-
version: 0.3.20
5+
version: 0.3.20+1
66

77
environment:
88
sdk: ^3.3.0

0 commit comments

Comments
 (0)