mirror of
https://github.com/flutter/packages.git
synced 2025-07-01 23:51:55 +08:00
[in_app_purchase] Convert refreshReceipt(), startObservingPaymentQueue(), stopObservingPaymentQueue(), registerPaymentQueueDelegate(), removePaymentQueueDelegate(), showPriceConsentIfNeeded() to Pigeon (#6165)
Part 3 of https://github.com/flutter/flutter/issues/117910
This commit is contained in:
@ -1,3 +1,8 @@
|
|||||||
|
## 0.3.12
|
||||||
|
|
||||||
|
* Converts `refreshReceipt()`, `startObservingPaymentQueue()`, `stopObservingPaymentQueue()`,
|
||||||
|
`registerPaymentQueueDelegate()`, `removePaymentQueueDelegate()`, `showPriceConsentIfNeeded()` to pigeon.
|
||||||
|
|
||||||
## 0.3.11
|
## 0.3.11
|
||||||
|
|
||||||
* Fixes SKError.userInfo not being nullable.
|
* Fixes SKError.userInfo not being nullable.
|
||||||
|
@ -87,30 +87,6 @@
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
|
|
||||||
if ([@"-[InAppPurchasePlugin retrieveReceiptData:result:]" isEqualToString:call.method]) {
|
|
||||||
[self retrieveReceiptData:call result:result];
|
|
||||||
} else if ([@"-[InAppPurchasePlugin refreshReceipt:result:]" isEqualToString:call.method]) {
|
|
||||||
[self refreshReceipt:call result:result];
|
|
||||||
} else if ([@"-[SKPaymentQueue startObservingTransactionQueue]" isEqualToString:call.method]) {
|
|
||||||
[self startObservingPaymentQueue:result];
|
|
||||||
} else if ([@"-[SKPaymentQueue stopObservingTransactionQueue]" isEqualToString:call.method]) {
|
|
||||||
[self stopObservingPaymentQueue:result];
|
|
||||||
#if TARGET_OS_IOS
|
|
||||||
} else if ([@"-[SKPaymentQueue registerDelegate]" isEqualToString:call.method]) {
|
|
||||||
[self registerPaymentQueueDelegate:result];
|
|
||||||
#endif
|
|
||||||
} else if ([@"-[SKPaymentQueue removeDelegate]" isEqualToString:call.method]) {
|
|
||||||
[self removePaymentQueueDelegate:result];
|
|
||||||
#if TARGET_OS_IOS
|
|
||||||
} else if ([@"-[SKPaymentQueue showPriceConsentIfNeeded]" isEqualToString:call.method]) {
|
|
||||||
[self showPriceConsentIfNeeded:result];
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
result(FlutterMethodNotImplemented);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (nullable NSNumber *)canMakePaymentsWithError:
|
- (nullable NSNumber *)canMakePaymentsWithError:
|
||||||
(FlutterError *_Nullable __autoreleasing *_Nonnull)error {
|
(FlutterError *_Nullable __autoreleasing *_Nonnull)error {
|
||||||
return @([SKPaymentQueue canMakePayments]);
|
return @([SKPaymentQueue canMakePayments]);
|
||||||
@ -270,62 +246,61 @@
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)retrieveReceiptData:(FlutterMethodCall *)call result:(FlutterResult)result {
|
- (nullable NSString *)retrieveReceiptDataWithError:
|
||||||
FlutterError *error = nil;
|
(FlutterError *_Nullable __autoreleasing *_Nonnull)error {
|
||||||
NSString *receiptData = [self.receiptManager retrieveReceiptWithError:&error];
|
FlutterError *flutterError;
|
||||||
if (error) {
|
NSString *receiptData = [self.receiptManager retrieveReceiptWithError:&flutterError];
|
||||||
result(error);
|
if (flutterError) {
|
||||||
return;
|
*error = flutterError;
|
||||||
|
return nil;
|
||||||
}
|
}
|
||||||
result(receiptData);
|
return receiptData;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)refreshReceipt:(FlutterMethodCall *)call result:(FlutterResult)result {
|
- (void)refreshReceiptReceiptProperties:(nullable NSDictionary *)receiptProperties
|
||||||
NSDictionary *arguments = call.arguments;
|
completion:(nonnull void (^)(FlutterError *_Nullable))completion {
|
||||||
SKReceiptRefreshRequest *request;
|
SKReceiptRefreshRequest *request;
|
||||||
if (arguments) {
|
if (receiptProperties) {
|
||||||
if (![arguments isKindOfClass:[NSDictionary class]]) {
|
// if recieptProperties is not null, this call is for testing.
|
||||||
result([FlutterError errorWithCode:@"storekit_invalid_argument"
|
|
||||||
message:@"Argument type of startRequest is not array"
|
|
||||||
details:call.arguments]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
NSMutableDictionary *properties = [NSMutableDictionary new];
|
NSMutableDictionary *properties = [NSMutableDictionary new];
|
||||||
properties[SKReceiptPropertyIsExpired] = arguments[@"isExpired"];
|
properties[SKReceiptPropertyIsExpired] = receiptProperties[@"isExpired"];
|
||||||
properties[SKReceiptPropertyIsRevoked] = arguments[@"isRevoked"];
|
properties[SKReceiptPropertyIsRevoked] = receiptProperties[@"isRevoked"];
|
||||||
properties[SKReceiptPropertyIsVolumePurchase] = arguments[@"isVolumePurchase"];
|
properties[SKReceiptPropertyIsVolumePurchase] = receiptProperties[@"isVolumePurchase"];
|
||||||
request = [self getRefreshReceiptRequest:properties];
|
request = [self getRefreshReceiptRequest:properties];
|
||||||
} else {
|
} else {
|
||||||
request = [self getRefreshReceiptRequest:nil];
|
request = [self getRefreshReceiptRequest:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
FIAPRequestHandler *handler = [[FIAPRequestHandler alloc] initWithRequest:request];
|
FIAPRequestHandler *handler = [[FIAPRequestHandler alloc] initWithRequest:request];
|
||||||
[self.requestHandlers addObject:handler];
|
[self.requestHandlers addObject:handler];
|
||||||
__weak typeof(self) weakSelf = self;
|
__weak typeof(self) weakSelf = self;
|
||||||
[handler startProductRequestWithCompletionHandler:^(SKProductsResponse *_Nullable response,
|
[handler startProductRequestWithCompletionHandler:^(SKProductsResponse *_Nullable response,
|
||||||
NSError *_Nullable error) {
|
NSError *_Nullable error) {
|
||||||
|
FlutterError *requestError;
|
||||||
if (error) {
|
if (error) {
|
||||||
result([FlutterError errorWithCode:@"storekit_refreshreceiptrequest_platform_error"
|
requestError = [FlutterError errorWithCode:@"storekit_refreshreceiptrequest_platform_error"
|
||||||
message:error.localizedDescription
|
message:error.localizedDescription
|
||||||
details:error.description]);
|
details:error.description];
|
||||||
return;
|
completion(requestError);
|
||||||
}
|
}
|
||||||
result(nil);
|
completion(nil);
|
||||||
[weakSelf.requestHandlers removeObject:handler];
|
[weakSelf.requestHandlers removeObject:handler];
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)startObservingPaymentQueue:(FlutterResult)result {
|
- (void)startObservingPaymentQueueWithError:
|
||||||
|
(FlutterError *_Nullable __autoreleasing *_Nonnull)error {
|
||||||
[_paymentQueueHandler startObservingPaymentQueue];
|
[_paymentQueueHandler startObservingPaymentQueue];
|
||||||
result(nil);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)stopObservingPaymentQueue:(FlutterResult)result {
|
- (void)stopObservingPaymentQueueWithError:
|
||||||
|
(FlutterError *_Nullable __autoreleasing *_Nonnull)error {
|
||||||
[_paymentQueueHandler stopObservingPaymentQueue];
|
[_paymentQueueHandler stopObservingPaymentQueue];
|
||||||
result(nil);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)registerPaymentQueueDelegateWithError:
|
||||||
|
(FlutterError *_Nullable __autoreleasing *_Nonnull)error {
|
||||||
#if TARGET_OS_IOS
|
#if TARGET_OS_IOS
|
||||||
- (void)registerPaymentQueueDelegate:(FlutterResult)result {
|
|
||||||
if (@available(iOS 13.0, *)) {
|
if (@available(iOS 13.0, *)) {
|
||||||
_paymentQueueDelegateCallbackChannel = [FlutterMethodChannel
|
_paymentQueueDelegateCallbackChannel = [FlutterMethodChannel
|
||||||
methodChannelWithName:@"plugins.flutter.io/in_app_purchase_payment_queue_delegate"
|
methodChannelWithName:@"plugins.flutter.io/in_app_purchase_payment_queue_delegate"
|
||||||
@ -335,27 +310,25 @@
|
|||||||
initWithMethodChannel:_paymentQueueDelegateCallbackChannel];
|
initWithMethodChannel:_paymentQueueDelegateCallbackChannel];
|
||||||
_paymentQueueHandler.delegate = _paymentQueueDelegate;
|
_paymentQueueHandler.delegate = _paymentQueueDelegate;
|
||||||
}
|
}
|
||||||
result(nil);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
- (void)removePaymentQueueDelegate:(FlutterResult)result {
|
- (void)removePaymentQueueDelegateWithError:
|
||||||
|
(FlutterError *_Nullable __autoreleasing *_Nonnull)error {
|
||||||
if (@available(iOS 13.0, *)) {
|
if (@available(iOS 13.0, *)) {
|
||||||
_paymentQueueHandler.delegate = nil;
|
_paymentQueueHandler.delegate = nil;
|
||||||
}
|
}
|
||||||
_paymentQueueDelegate = nil;
|
_paymentQueueDelegate = nil;
|
||||||
_paymentQueueDelegateCallbackChannel = nil;
|
_paymentQueueDelegateCallbackChannel = nil;
|
||||||
result(nil);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)showPriceConsentIfNeededWithError:(FlutterError *_Nullable __autoreleasing *_Nonnull)error {
|
||||||
#if TARGET_OS_IOS
|
#if TARGET_OS_IOS
|
||||||
- (void)showPriceConsentIfNeeded:(FlutterResult)result {
|
|
||||||
if (@available(iOS 13.4, *)) {
|
if (@available(iOS 13.4, *)) {
|
||||||
[_paymentQueueHandler showPriceConsentIfNeeded];
|
[_paymentQueueHandler showPriceConsentIfNeeded];
|
||||||
}
|
}
|
||||||
result(nil);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
- (id)getNonNullValueFromDictionary:(NSDictionary *)dictionary forKey:(NSString *)key {
|
- (id)getNonNullValueFromDictionary:(NSDictionary *)dictionary forKey:(NSString *)key {
|
||||||
id value = dictionary[key];
|
id value = dictionary[key];
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
// Autogenerated from Pigeon (v16.0.4), do not edit directly.
|
// Autogenerated from Pigeon (v16.0.4), do not edit directly.
|
||||||
// See also: https://pub.dev/packages/pigeon
|
// See also: https://pub.dev/packages/pigeon
|
||||||
|
|
||||||
@ -271,6 +270,14 @@ NSObject<FlutterMessageCodec> *InAppPurchaseAPIGetCodec(void);
|
|||||||
- (void)restoreTransactionsApplicationUserName:(nullable NSString *)applicationUserName
|
- (void)restoreTransactionsApplicationUserName:(nullable NSString *)applicationUserName
|
||||||
error:(FlutterError *_Nullable *_Nonnull)error;
|
error:(FlutterError *_Nullable *_Nonnull)error;
|
||||||
- (void)presentCodeRedemptionSheetWithError:(FlutterError *_Nullable *_Nonnull)error;
|
- (void)presentCodeRedemptionSheetWithError:(FlutterError *_Nullable *_Nonnull)error;
|
||||||
|
- (nullable NSString *)retrieveReceiptDataWithError:(FlutterError *_Nullable *_Nonnull)error;
|
||||||
|
- (void)refreshReceiptReceiptProperties:(nullable NSDictionary<NSString *, id> *)receiptProperties
|
||||||
|
completion:(void (^)(FlutterError *_Nullable))completion;
|
||||||
|
- (void)startObservingPaymentQueueWithError:(FlutterError *_Nullable *_Nonnull)error;
|
||||||
|
- (void)stopObservingPaymentQueueWithError:(FlutterError *_Nullable *_Nonnull)error;
|
||||||
|
- (void)registerPaymentQueueDelegateWithError:(FlutterError *_Nullable *_Nonnull)error;
|
||||||
|
- (void)removePaymentQueueDelegateWithError:(FlutterError *_Nullable *_Nonnull)error;
|
||||||
|
- (void)showPriceConsentIfNeededWithError:(FlutterError *_Nullable *_Nonnull)error;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
extern void SetUpInAppPurchaseAPI(id<FlutterBinaryMessenger> binaryMessenger,
|
extern void SetUpInAppPurchaseAPI(id<FlutterBinaryMessenger> binaryMessenger,
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
// Autogenerated from Pigeon (v16.0.4), do not edit directly.
|
// Autogenerated from Pigeon (v16.0.4), do not edit directly.
|
||||||
// See also: https://pub.dev/packages/pigeon
|
// See also: https://pub.dev/packages/pigeon
|
||||||
|
|
||||||
@ -752,4 +751,147 @@ void SetUpInAppPurchaseAPI(id<FlutterBinaryMessenger> binaryMessenger,
|
|||||||
[channel setMessageHandler:nil];
|
[channel setMessageHandler:nil];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
|
||||||
|
initWithName:
|
||||||
|
@"dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.retrieveReceiptData"
|
||||||
|
binaryMessenger:binaryMessenger
|
||||||
|
codec:InAppPurchaseAPIGetCodec()];
|
||||||
|
if (api) {
|
||||||
|
NSCAssert(
|
||||||
|
[api respondsToSelector:@selector(retrieveReceiptDataWithError:)],
|
||||||
|
@"InAppPurchaseAPI api (%@) doesn't respond to @selector(retrieveReceiptDataWithError:)",
|
||||||
|
api);
|
||||||
|
[channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
|
||||||
|
FlutterError *error;
|
||||||
|
NSString *output = [api retrieveReceiptDataWithError:&error];
|
||||||
|
callback(wrapResult(output, error));
|
||||||
|
}];
|
||||||
|
} else {
|
||||||
|
[channel setMessageHandler:nil];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
|
||||||
|
initWithName:
|
||||||
|
@"dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.refreshReceipt"
|
||||||
|
binaryMessenger:binaryMessenger
|
||||||
|
codec:InAppPurchaseAPIGetCodec()];
|
||||||
|
if (api) {
|
||||||
|
NSCAssert([api respondsToSelector:@selector(refreshReceiptReceiptProperties:completion:)],
|
||||||
|
@"InAppPurchaseAPI api (%@) doesn't respond to "
|
||||||
|
@"@selector(refreshReceiptReceiptProperties:completion:)",
|
||||||
|
api);
|
||||||
|
[channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
|
||||||
|
NSArray *args = message;
|
||||||
|
NSDictionary<NSString *, id> *arg_receiptProperties = GetNullableObjectAtIndex(args, 0);
|
||||||
|
[api refreshReceiptReceiptProperties:arg_receiptProperties
|
||||||
|
completion:^(FlutterError *_Nullable error) {
|
||||||
|
callback(wrapResult(nil, error));
|
||||||
|
}];
|
||||||
|
}];
|
||||||
|
} else {
|
||||||
|
[channel setMessageHandler:nil];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
|
||||||
|
initWithName:@"dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI."
|
||||||
|
@"startObservingPaymentQueue"
|
||||||
|
binaryMessenger:binaryMessenger
|
||||||
|
codec:InAppPurchaseAPIGetCodec()];
|
||||||
|
if (api) {
|
||||||
|
NSCAssert([api respondsToSelector:@selector(startObservingPaymentQueueWithError:)],
|
||||||
|
@"InAppPurchaseAPI api (%@) doesn't respond to "
|
||||||
|
@"@selector(startObservingPaymentQueueWithError:)",
|
||||||
|
api);
|
||||||
|
[channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
|
||||||
|
FlutterError *error;
|
||||||
|
[api startObservingPaymentQueueWithError:&error];
|
||||||
|
callback(wrapResult(nil, error));
|
||||||
|
}];
|
||||||
|
} else {
|
||||||
|
[channel setMessageHandler:nil];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
|
||||||
|
initWithName:@"dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI."
|
||||||
|
@"stopObservingPaymentQueue"
|
||||||
|
binaryMessenger:binaryMessenger
|
||||||
|
codec:InAppPurchaseAPIGetCodec()];
|
||||||
|
if (api) {
|
||||||
|
NSCAssert([api respondsToSelector:@selector(stopObservingPaymentQueueWithError:)],
|
||||||
|
@"InAppPurchaseAPI api (%@) doesn't respond to "
|
||||||
|
@"@selector(stopObservingPaymentQueueWithError:)",
|
||||||
|
api);
|
||||||
|
[channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
|
||||||
|
FlutterError *error;
|
||||||
|
[api stopObservingPaymentQueueWithError:&error];
|
||||||
|
callback(wrapResult(nil, error));
|
||||||
|
}];
|
||||||
|
} else {
|
||||||
|
[channel setMessageHandler:nil];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
|
||||||
|
initWithName:@"dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI."
|
||||||
|
@"registerPaymentQueueDelegate"
|
||||||
|
binaryMessenger:binaryMessenger
|
||||||
|
codec:InAppPurchaseAPIGetCodec()];
|
||||||
|
if (api) {
|
||||||
|
NSCAssert([api respondsToSelector:@selector(registerPaymentQueueDelegateWithError:)],
|
||||||
|
@"InAppPurchaseAPI api (%@) doesn't respond to "
|
||||||
|
@"@selector(registerPaymentQueueDelegateWithError:)",
|
||||||
|
api);
|
||||||
|
[channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
|
||||||
|
FlutterError *error;
|
||||||
|
[api registerPaymentQueueDelegateWithError:&error];
|
||||||
|
callback(wrapResult(nil, error));
|
||||||
|
}];
|
||||||
|
} else {
|
||||||
|
[channel setMessageHandler:nil];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
|
||||||
|
initWithName:@"dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI."
|
||||||
|
@"removePaymentQueueDelegate"
|
||||||
|
binaryMessenger:binaryMessenger
|
||||||
|
codec:InAppPurchaseAPIGetCodec()];
|
||||||
|
if (api) {
|
||||||
|
NSCAssert([api respondsToSelector:@selector(removePaymentQueueDelegateWithError:)],
|
||||||
|
@"InAppPurchaseAPI api (%@) doesn't respond to "
|
||||||
|
@"@selector(removePaymentQueueDelegateWithError:)",
|
||||||
|
api);
|
||||||
|
[channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
|
||||||
|
FlutterError *error;
|
||||||
|
[api removePaymentQueueDelegateWithError:&error];
|
||||||
|
callback(wrapResult(nil, error));
|
||||||
|
}];
|
||||||
|
} else {
|
||||||
|
[channel setMessageHandler:nil];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
|
||||||
|
initWithName:@"dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI."
|
||||||
|
@"showPriceConsentIfNeeded"
|
||||||
|
binaryMessenger:binaryMessenger
|
||||||
|
codec:InAppPurchaseAPIGetCodec()];
|
||||||
|
if (api) {
|
||||||
|
NSCAssert([api respondsToSelector:@selector(showPriceConsentIfNeededWithError:)],
|
||||||
|
@"InAppPurchaseAPI api (%@) doesn't respond to "
|
||||||
|
@"@selector(showPriceConsentIfNeededWithError:)",
|
||||||
|
api);
|
||||||
|
[channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
|
||||||
|
FlutterError *error;
|
||||||
|
[api showPriceConsentIfNeededWithError:&error];
|
||||||
|
callback(wrapResult(nil, error));
|
||||||
|
}];
|
||||||
|
} else {
|
||||||
|
[channel setMessageHandler:nil];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,8 @@
|
|||||||
buildConfiguration = "Debug"
|
buildConfiguration = "Debug"
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
|
codeCoverageEnabled = "YES">
|
||||||
<MacroExpansion>
|
<MacroExpansion>
|
||||||
<BuildableReference
|
<BuildableReference
|
||||||
BuildableIdentifier = "primary"
|
BuildableIdentifier = "primary"
|
||||||
|
@ -26,20 +26,6 @@
|
|||||||
- (void)tearDown {
|
- (void)tearDown {
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)testInvalidMethodCall {
|
|
||||||
XCTestExpectation *expectation =
|
|
||||||
[self expectationWithDescription:@"expect result to be not implemented"];
|
|
||||||
FlutterMethodCall *call = [FlutterMethodCall methodCallWithMethodName:@"invalid" arguments:NULL];
|
|
||||||
__block id result;
|
|
||||||
[self.plugin handleMethodCall:call
|
|
||||||
result:^(id r) {
|
|
||||||
[expectation fulfill];
|
|
||||||
result = r;
|
|
||||||
}];
|
|
||||||
[self waitForExpectations:@[ expectation ] timeout:5];
|
|
||||||
XCTAssertEqual(result, FlutterMethodNotImplemented);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)testCanMakePayments {
|
- (void)testCanMakePayments {
|
||||||
FlutterError *error;
|
FlutterError *error;
|
||||||
NSNumber *result = [self.plugin canMakePaymentsWithError:&error];
|
NSNumber *result = [self.plugin canMakePaymentsWithError:&error];
|
||||||
@ -299,17 +285,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)testRetrieveReceiptDataSuccess {
|
- (void)testRetrieveReceiptDataSuccess {
|
||||||
XCTestExpectation *expectation = [self expectationWithDescription:@"receipt data retrieved"];
|
FlutterError *error;
|
||||||
FlutterMethodCall *call = [FlutterMethodCall
|
NSString *result = [self.plugin retrieveReceiptDataWithError:&error];
|
||||||
methodCallWithMethodName:@"-[InAppPurchasePlugin retrieveReceiptData:result:]"
|
|
||||||
arguments:nil];
|
|
||||||
__block NSDictionary *result;
|
|
||||||
[self.plugin handleMethodCall:call
|
|
||||||
result:^(id r) {
|
|
||||||
result = r;
|
|
||||||
[expectation fulfill];
|
|
||||||
}];
|
|
||||||
[self waitForExpectations:@[ expectation ] timeout:5];
|
|
||||||
XCTAssertNotNil(result);
|
XCTAssertNotNil(result);
|
||||||
XCTAssert([result isKindOfClass:[NSString class]]);
|
XCTAssert([result isKindOfClass:[NSString class]]);
|
||||||
}
|
}
|
||||||
@ -317,71 +294,47 @@
|
|||||||
- (void)testRetrieveReceiptDataNil {
|
- (void)testRetrieveReceiptDataNil {
|
||||||
NSBundle *mockBundle = OCMPartialMock([NSBundle mainBundle]);
|
NSBundle *mockBundle = OCMPartialMock([NSBundle mainBundle]);
|
||||||
OCMStub(mockBundle.appStoreReceiptURL).andReturn(nil);
|
OCMStub(mockBundle.appStoreReceiptURL).andReturn(nil);
|
||||||
XCTestExpectation *expectation = [self expectationWithDescription:@"nil receipt data retrieved"];
|
FlutterError *error;
|
||||||
FlutterMethodCall *call = [FlutterMethodCall
|
NSString *result = [self.plugin retrieveReceiptDataWithError:&error];
|
||||||
methodCallWithMethodName:@"-[InAppPurchasePlugin retrieveReceiptData:result:]"
|
|
||||||
arguments:nil];
|
|
||||||
__block NSDictionary *result;
|
|
||||||
[self.plugin handleMethodCall:call
|
|
||||||
result:^(id r) {
|
|
||||||
result = r;
|
|
||||||
[expectation fulfill];
|
|
||||||
}];
|
|
||||||
[self waitForExpectations:@[ expectation ] timeout:5];
|
|
||||||
XCTAssertNil(result);
|
XCTAssertNil(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)testRetrieveReceiptDataError {
|
- (void)testRetrieveReceiptDataError {
|
||||||
XCTestExpectation *expectation = [self expectationWithDescription:@"receipt data retrieved"];
|
|
||||||
FlutterMethodCall *call = [FlutterMethodCall
|
|
||||||
methodCallWithMethodName:@"-[InAppPurchasePlugin retrieveReceiptData:result:]"
|
|
||||||
arguments:nil];
|
|
||||||
__block NSDictionary *result;
|
|
||||||
self.receiptManagerStub.returnError = YES;
|
self.receiptManagerStub.returnError = YES;
|
||||||
[self.plugin handleMethodCall:call
|
|
||||||
result:^(id r) {
|
FlutterError *error;
|
||||||
result = r;
|
NSString *result = [self.plugin retrieveReceiptDataWithError:&error];
|
||||||
[expectation fulfill];
|
|
||||||
}];
|
XCTAssertNil(result);
|
||||||
[self waitForExpectations:@[ expectation ] timeout:5];
|
XCTAssertNotNil(error);
|
||||||
XCTAssertNotNil(result);
|
NSDictionary *details = error.details;
|
||||||
XCTAssert([result isKindOfClass:[FlutterError class]]);
|
|
||||||
NSDictionary *details = ((FlutterError *)result).details;
|
|
||||||
XCTAssertNotNil(details[@"error"]);
|
XCTAssertNotNil(details[@"error"]);
|
||||||
NSNumber *errorCode = (NSNumber *)details[@"error"][@"code"];
|
NSNumber *errorCode = (NSNumber *)details[@"error"][@"code"];
|
||||||
XCTAssertEqual(errorCode, [NSNumber numberWithInteger:99]);
|
XCTAssertEqual(errorCode, [NSNumber numberWithInteger:99]);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)testRefreshReceiptRequest {
|
- (void)testRefreshReceiptRequest {
|
||||||
XCTestExpectation *expectation = [self expectationWithDescription:@"expect success"];
|
XCTestExpectation *expectation =
|
||||||
FlutterMethodCall *call =
|
[self expectationWithDescription:@"completion handler successfully called"];
|
||||||
[FlutterMethodCall methodCallWithMethodName:@"-[InAppPurchasePlugin refreshReceipt:result:]"
|
[self.plugin refreshReceiptReceiptProperties:nil
|
||||||
arguments:nil];
|
completion:^(FlutterError *_Nullable error) {
|
||||||
__block BOOL result = NO;
|
[expectation fulfill];
|
||||||
[self.plugin handleMethodCall:call
|
}];
|
||||||
result:^(id r) {
|
|
||||||
result = YES;
|
|
||||||
[expectation fulfill];
|
|
||||||
}];
|
|
||||||
[self waitForExpectations:@[ expectation ] timeout:5];
|
[self waitForExpectations:@[ expectation ] timeout:5];
|
||||||
XCTAssertTrue(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// presentCodeRedemptionSheetWithError:error is only available on iOS
|
||||||
|
#if TARGET_OS_IOS
|
||||||
- (void)testPresentCodeRedemptionSheet {
|
- (void)testPresentCodeRedemptionSheet {
|
||||||
XCTestExpectation *expectation =
|
FIAPaymentQueueHandler *mockHandler = OCMClassMock([FIAPaymentQueueHandler class]);
|
||||||
[self expectationWithDescription:@"expect successfully present Code Redemption Sheet"];
|
self.plugin.paymentQueueHandler = mockHandler;
|
||||||
FlutterMethodCall *call = [FlutterMethodCall
|
|
||||||
methodCallWithMethodName:@"-[InAppPurchasePlugin presentCodeRedemptionSheet:result:]"
|
FlutterError *error;
|
||||||
arguments:nil];
|
[self.plugin presentCodeRedemptionSheetWithError:&error];
|
||||||
__block BOOL callbackInvoked = NO;
|
|
||||||
[self.plugin handleMethodCall:call
|
OCMVerify(times(1), [mockHandler presentCodeRedemptionSheet]);
|
||||||
result:^(id r) {
|
|
||||||
callbackInvoked = YES;
|
|
||||||
[expectation fulfill];
|
|
||||||
}];
|
|
||||||
[self waitForExpectations:@[ expectation ] timeout:5];
|
|
||||||
XCTAssertTrue(callbackInvoked);
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
- (void)testGetPendingTransactions {
|
- (void)testGetPendingTransactions {
|
||||||
SKPaymentQueue *mockQueue = OCMClassMock(SKPaymentQueue.class);
|
SKPaymentQueue *mockQueue = OCMClassMock(SKPaymentQueue.class);
|
||||||
@ -420,48 +373,28 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)testStartObservingPaymentQueue {
|
- (void)testStartObservingPaymentQueue {
|
||||||
XCTestExpectation *expectation =
|
|
||||||
[self expectationWithDescription:@"Should return success result"];
|
|
||||||
FlutterMethodCall *startCall = [FlutterMethodCall
|
|
||||||
methodCallWithMethodName:@"-[SKPaymentQueue startObservingTransactionQueue]"
|
|
||||||
arguments:nil];
|
|
||||||
FIAPaymentQueueHandler *mockHandler = OCMClassMock([FIAPaymentQueueHandler class]);
|
FIAPaymentQueueHandler *mockHandler = OCMClassMock([FIAPaymentQueueHandler class]);
|
||||||
self.plugin.paymentQueueHandler = mockHandler;
|
self.plugin.paymentQueueHandler = mockHandler;
|
||||||
[self.plugin handleMethodCall:startCall
|
|
||||||
result:^(id _Nullable result) {
|
|
||||||
XCTAssertNil(result);
|
|
||||||
[expectation fulfill];
|
|
||||||
}];
|
|
||||||
|
|
||||||
[self waitForExpectations:@[ expectation ] timeout:5];
|
FlutterError *error;
|
||||||
|
[self.plugin startObservingPaymentQueueWithError:&error];
|
||||||
|
|
||||||
OCMVerify(times(1), [mockHandler startObservingPaymentQueue]);
|
OCMVerify(times(1), [mockHandler startObservingPaymentQueue]);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)testStopObservingPaymentQueue {
|
- (void)testStopObservingPaymentQueue {
|
||||||
XCTestExpectation *expectation =
|
|
||||||
[self expectationWithDescription:@"Should return success result"];
|
|
||||||
FlutterMethodCall *stopCall =
|
|
||||||
[FlutterMethodCall methodCallWithMethodName:@"-[SKPaymentQueue stopObservingTransactionQueue]"
|
|
||||||
arguments:nil];
|
|
||||||
FIAPaymentQueueHandler *mockHandler = OCMClassMock([FIAPaymentQueueHandler class]);
|
FIAPaymentQueueHandler *mockHandler = OCMClassMock([FIAPaymentQueueHandler class]);
|
||||||
self.plugin.paymentQueueHandler = mockHandler;
|
self.plugin.paymentQueueHandler = mockHandler;
|
||||||
[self.plugin handleMethodCall:stopCall
|
|
||||||
result:^(id _Nullable result) {
|
|
||||||
XCTAssertNil(result);
|
|
||||||
[expectation fulfill];
|
|
||||||
}];
|
|
||||||
|
|
||||||
[self waitForExpectations:@[ expectation ] timeout:5];
|
FlutterError *error;
|
||||||
|
[self.plugin stopObservingPaymentQueueWithError:&error];
|
||||||
|
|
||||||
OCMVerify(times(1), [mockHandler stopObservingPaymentQueue]);
|
OCMVerify(times(1), [mockHandler stopObservingPaymentQueue]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if TARGET_OS_IOS
|
#if TARGET_OS_IOS
|
||||||
- (void)testRegisterPaymentQueueDelegate {
|
- (void)testRegisterPaymentQueueDelegate {
|
||||||
if (@available(iOS 13, *)) {
|
if (@available(iOS 13, *)) {
|
||||||
FlutterMethodCall *call =
|
|
||||||
[FlutterMethodCall methodCallWithMethodName:@"-[SKPaymentQueue registerDelegate]"
|
|
||||||
arguments:nil];
|
|
||||||
|
|
||||||
self.plugin.paymentQueueHandler =
|
self.plugin.paymentQueueHandler =
|
||||||
[[FIAPaymentQueueHandler alloc] initWithQueue:[SKPaymentQueueStub new]
|
[[FIAPaymentQueueHandler alloc] initWithQueue:[SKPaymentQueueStub new]
|
||||||
transactionsUpdated:nil
|
transactionsUpdated:nil
|
||||||
@ -475,9 +408,8 @@
|
|||||||
// Verify the delegate is nil before we register one.
|
// Verify the delegate is nil before we register one.
|
||||||
XCTAssertNil(self.plugin.paymentQueueHandler.delegate);
|
XCTAssertNil(self.plugin.paymentQueueHandler.delegate);
|
||||||
|
|
||||||
[self.plugin handleMethodCall:call
|
FlutterError *error;
|
||||||
result:^(id r){
|
[self.plugin registerPaymentQueueDelegateWithError:&error];
|
||||||
}];
|
|
||||||
|
|
||||||
// Verify the delegate is not nil after we registered one.
|
// Verify the delegate is not nil after we registered one.
|
||||||
XCTAssertNotNil(self.plugin.paymentQueueHandler.delegate);
|
XCTAssertNotNil(self.plugin.paymentQueueHandler.delegate);
|
||||||
@ -487,10 +419,6 @@
|
|||||||
|
|
||||||
- (void)testRemovePaymentQueueDelegate {
|
- (void)testRemovePaymentQueueDelegate {
|
||||||
if (@available(iOS 13, *)) {
|
if (@available(iOS 13, *)) {
|
||||||
FlutterMethodCall *call =
|
|
||||||
[FlutterMethodCall methodCallWithMethodName:@"-[SKPaymentQueue removeDelegate]"
|
|
||||||
arguments:nil];
|
|
||||||
|
|
||||||
self.plugin.paymentQueueHandler =
|
self.plugin.paymentQueueHandler =
|
||||||
[[FIAPaymentQueueHandler alloc] initWithQueue:[SKPaymentQueueStub new]
|
[[FIAPaymentQueueHandler alloc] initWithQueue:[SKPaymentQueueStub new]
|
||||||
transactionsUpdated:nil
|
transactionsUpdated:nil
|
||||||
@ -505,9 +433,8 @@
|
|||||||
// Verify the delegate is not nil before removing it.
|
// Verify the delegate is not nil before removing it.
|
||||||
XCTAssertNotNil(self.plugin.paymentQueueHandler.delegate);
|
XCTAssertNotNil(self.plugin.paymentQueueHandler.delegate);
|
||||||
|
|
||||||
[self.plugin handleMethodCall:call
|
FlutterError *error;
|
||||||
result:^(id r){
|
[self.plugin removePaymentQueueDelegateWithError:&error];
|
||||||
}];
|
|
||||||
|
|
||||||
// Verify the delegate is nill after removing it.
|
// Verify the delegate is nill after removing it.
|
||||||
XCTAssertNil(self.plugin.paymentQueueHandler.delegate);
|
XCTAssertNil(self.plugin.paymentQueueHandler.delegate);
|
||||||
@ -516,16 +443,11 @@
|
|||||||
|
|
||||||
#if TARGET_OS_IOS
|
#if TARGET_OS_IOS
|
||||||
- (void)testShowPriceConsentIfNeeded {
|
- (void)testShowPriceConsentIfNeeded {
|
||||||
FlutterMethodCall *call =
|
|
||||||
[FlutterMethodCall methodCallWithMethodName:@"-[SKPaymentQueue showPriceConsentIfNeeded]"
|
|
||||||
arguments:nil];
|
|
||||||
|
|
||||||
FIAPaymentQueueHandler *mockQueueHandler = OCMClassMock(FIAPaymentQueueHandler.class);
|
FIAPaymentQueueHandler *mockQueueHandler = OCMClassMock(FIAPaymentQueueHandler.class);
|
||||||
self.plugin.paymentQueueHandler = mockQueueHandler;
|
self.plugin.paymentQueueHandler = mockQueueHandler;
|
||||||
|
|
||||||
[self.plugin handleMethodCall:call
|
FlutterError *error;
|
||||||
result:^(id r){
|
[self.plugin showPriceConsentIfNeededWithError:&error];
|
||||||
}];
|
|
||||||
|
|
||||||
#pragma clang diagnostic push
|
#pragma clang diagnostic push
|
||||||
#pragma clang diagnostic ignored "-Wpartial-availability"
|
#pragma clang diagnostic ignored "-Wpartial-availability"
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
// Autogenerated from Pigeon (v16.0.4), do not edit directly.
|
// Autogenerated from Pigeon (v16.0.4), do not edit directly.
|
||||||
// See also: https://pub.dev/packages/pigeon
|
// See also: https://pub.dev/packages/pigeon
|
||||||
// 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
|
// 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
|
||||||
@ -788,4 +791,173 @@ class InAppPurchaseAPI {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<String?> retrieveReceiptData() async {
|
||||||
|
const String __pigeon_channelName =
|
||||||
|
'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.retrieveReceiptData';
|
||||||
|
final BasicMessageChannel<Object?> __pigeon_channel =
|
||||||
|
BasicMessageChannel<Object?>(
|
||||||
|
__pigeon_channelName,
|
||||||
|
pigeonChannelCodec,
|
||||||
|
binaryMessenger: __pigeon_binaryMessenger,
|
||||||
|
);
|
||||||
|
final List<Object?>? __pigeon_replyList =
|
||||||
|
await __pigeon_channel.send(null) as List<Object?>?;
|
||||||
|
if (__pigeon_replyList == null) {
|
||||||
|
throw _createConnectionError(__pigeon_channelName);
|
||||||
|
} else if (__pigeon_replyList.length > 1) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: __pigeon_replyList[0]! as String,
|
||||||
|
message: __pigeon_replyList[1] as String?,
|
||||||
|
details: __pigeon_replyList[2],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (__pigeon_replyList[0] as String?);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> refreshReceipt(
|
||||||
|
{Map<String?, Object?>? receiptProperties}) async {
|
||||||
|
const String __pigeon_channelName =
|
||||||
|
'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.refreshReceipt';
|
||||||
|
final BasicMessageChannel<Object?> __pigeon_channel =
|
||||||
|
BasicMessageChannel<Object?>(
|
||||||
|
__pigeon_channelName,
|
||||||
|
pigeonChannelCodec,
|
||||||
|
binaryMessenger: __pigeon_binaryMessenger,
|
||||||
|
);
|
||||||
|
final List<Object?>? __pigeon_replyList = await __pigeon_channel
|
||||||
|
.send(<Object?>[receiptProperties]) as List<Object?>?;
|
||||||
|
if (__pigeon_replyList == null) {
|
||||||
|
throw _createConnectionError(__pigeon_channelName);
|
||||||
|
} else if (__pigeon_replyList.length > 1) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: __pigeon_replyList[0]! as String,
|
||||||
|
message: __pigeon_replyList[1] as String?,
|
||||||
|
details: __pigeon_replyList[2],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> startObservingPaymentQueue() async {
|
||||||
|
const String __pigeon_channelName =
|
||||||
|
'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.startObservingPaymentQueue';
|
||||||
|
final BasicMessageChannel<Object?> __pigeon_channel =
|
||||||
|
BasicMessageChannel<Object?>(
|
||||||
|
__pigeon_channelName,
|
||||||
|
pigeonChannelCodec,
|
||||||
|
binaryMessenger: __pigeon_binaryMessenger,
|
||||||
|
);
|
||||||
|
final List<Object?>? __pigeon_replyList =
|
||||||
|
await __pigeon_channel.send(null) as List<Object?>?;
|
||||||
|
if (__pigeon_replyList == null) {
|
||||||
|
throw _createConnectionError(__pigeon_channelName);
|
||||||
|
} else if (__pigeon_replyList.length > 1) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: __pigeon_replyList[0]! as String,
|
||||||
|
message: __pigeon_replyList[1] as String?,
|
||||||
|
details: __pigeon_replyList[2],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> stopObservingPaymentQueue() async {
|
||||||
|
const String __pigeon_channelName =
|
||||||
|
'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.stopObservingPaymentQueue';
|
||||||
|
final BasicMessageChannel<Object?> __pigeon_channel =
|
||||||
|
BasicMessageChannel<Object?>(
|
||||||
|
__pigeon_channelName,
|
||||||
|
pigeonChannelCodec,
|
||||||
|
binaryMessenger: __pigeon_binaryMessenger,
|
||||||
|
);
|
||||||
|
final List<Object?>? __pigeon_replyList =
|
||||||
|
await __pigeon_channel.send(null) as List<Object?>?;
|
||||||
|
if (__pigeon_replyList == null) {
|
||||||
|
throw _createConnectionError(__pigeon_channelName);
|
||||||
|
} else if (__pigeon_replyList.length > 1) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: __pigeon_replyList[0]! as String,
|
||||||
|
message: __pigeon_replyList[1] as String?,
|
||||||
|
details: __pigeon_replyList[2],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> registerPaymentQueueDelegate() async {
|
||||||
|
const String __pigeon_channelName =
|
||||||
|
'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.registerPaymentQueueDelegate';
|
||||||
|
final BasicMessageChannel<Object?> __pigeon_channel =
|
||||||
|
BasicMessageChannel<Object?>(
|
||||||
|
__pigeon_channelName,
|
||||||
|
pigeonChannelCodec,
|
||||||
|
binaryMessenger: __pigeon_binaryMessenger,
|
||||||
|
);
|
||||||
|
final List<Object?>? __pigeon_replyList =
|
||||||
|
await __pigeon_channel.send(null) as List<Object?>?;
|
||||||
|
if (__pigeon_replyList == null) {
|
||||||
|
throw _createConnectionError(__pigeon_channelName);
|
||||||
|
} else if (__pigeon_replyList.length > 1) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: __pigeon_replyList[0]! as String,
|
||||||
|
message: __pigeon_replyList[1] as String?,
|
||||||
|
details: __pigeon_replyList[2],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> removePaymentQueueDelegate() async {
|
||||||
|
const String __pigeon_channelName =
|
||||||
|
'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.removePaymentQueueDelegate';
|
||||||
|
final BasicMessageChannel<Object?> __pigeon_channel =
|
||||||
|
BasicMessageChannel<Object?>(
|
||||||
|
__pigeon_channelName,
|
||||||
|
pigeonChannelCodec,
|
||||||
|
binaryMessenger: __pigeon_binaryMessenger,
|
||||||
|
);
|
||||||
|
final List<Object?>? __pigeon_replyList =
|
||||||
|
await __pigeon_channel.send(null) as List<Object?>?;
|
||||||
|
if (__pigeon_replyList == null) {
|
||||||
|
throw _createConnectionError(__pigeon_channelName);
|
||||||
|
} else if (__pigeon_replyList.length > 1) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: __pigeon_replyList[0]! as String,
|
||||||
|
message: __pigeon_replyList[1] as String?,
|
||||||
|
details: __pigeon_replyList[2],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> showPriceConsentIfNeeded() async {
|
||||||
|
const String __pigeon_channelName =
|
||||||
|
'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.showPriceConsentIfNeeded';
|
||||||
|
final BasicMessageChannel<Object?> __pigeon_channel =
|
||||||
|
BasicMessageChannel<Object?>(
|
||||||
|
__pigeon_channelName,
|
||||||
|
pigeonChannelCodec,
|
||||||
|
binaryMessenger: __pigeon_binaryMessenger,
|
||||||
|
);
|
||||||
|
final List<Object?>? __pigeon_replyList =
|
||||||
|
await __pigeon_channel.send(null) as List<Object?>?;
|
||||||
|
if (__pigeon_replyList == null) {
|
||||||
|
throw _createConnectionError(__pigeon_channelName);
|
||||||
|
} else if (__pigeon_replyList.length > 1) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: __pigeon_replyList[0]! as String,
|
||||||
|
message: __pigeon_replyList[1] as String?,
|
||||||
|
details: __pigeon_replyList[2],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,16 +86,16 @@ class SKPaymentQueueWrapper {
|
|||||||
///
|
///
|
||||||
/// Call this method when the first listener is subscribed to the
|
/// Call this method when the first listener is subscribed to the
|
||||||
/// [InAppPurchaseStoreKitPlatform.purchaseStream].
|
/// [InAppPurchaseStoreKitPlatform.purchaseStream].
|
||||||
Future<void> startObservingTransactionQueue() => channel
|
Future<void> startObservingTransactionQueue() =>
|
||||||
.invokeMethod<void>('-[SKPaymentQueue startObservingTransactionQueue]');
|
_hostApi.startObservingPaymentQueue();
|
||||||
|
|
||||||
/// Instructs the iOS implementation to remove the transaction observer and
|
/// Instructs the iOS implementation to remove the transaction observer and
|
||||||
/// stop listening to it.
|
/// stop listening to it.
|
||||||
///
|
///
|
||||||
/// Call this when there are no longer any listeners subscribed to the
|
/// Call this when there are no longer any listeners subscribed to the
|
||||||
/// [InAppPurchaseStoreKitPlatform.purchaseStream].
|
/// [InAppPurchaseStoreKitPlatform.purchaseStream].
|
||||||
Future<void> stopObservingTransactionQueue() => channel
|
Future<void> stopObservingTransactionQueue() =>
|
||||||
.invokeMethod<void>('-[SKPaymentQueue stopObservingTransactionQueue]');
|
_hostApi.stopObservingPaymentQueue();
|
||||||
|
|
||||||
/// Sets an implementation of the [SKPaymentQueueDelegateWrapper].
|
/// Sets an implementation of the [SKPaymentQueueDelegateWrapper].
|
||||||
///
|
///
|
||||||
@ -109,10 +109,10 @@ class SKPaymentQueueWrapper {
|
|||||||
/// default behaviour will apply (see [documentation](https://developer.apple.com/documentation/storekit/skpaymentqueue/3182429-delegate?language=objc)).
|
/// default behaviour will apply (see [documentation](https://developer.apple.com/documentation/storekit/skpaymentqueue/3182429-delegate?language=objc)).
|
||||||
Future<void> setDelegate(SKPaymentQueueDelegateWrapper? delegate) async {
|
Future<void> setDelegate(SKPaymentQueueDelegateWrapper? delegate) async {
|
||||||
if (delegate == null) {
|
if (delegate == null) {
|
||||||
await channel.invokeMethod<void>('-[SKPaymentQueue removeDelegate]');
|
await _hostApi.removePaymentQueueDelegate();
|
||||||
paymentQueueDelegateChannel.setMethodCallHandler(null);
|
paymentQueueDelegateChannel.setMethodCallHandler(null);
|
||||||
} else {
|
} else {
|
||||||
await channel.invokeMethod<void>('-[SKPaymentQueue registerDelegate]');
|
await _hostApi.registerPaymentQueueDelegate();
|
||||||
paymentQueueDelegateChannel
|
paymentQueueDelegateChannel
|
||||||
.setMethodCallHandler(handlePaymentQueueDelegateCallbacks);
|
.setMethodCallHandler(handlePaymentQueueDelegateCallbacks);
|
||||||
}
|
}
|
||||||
@ -207,8 +207,7 @@ class SKPaymentQueueWrapper {
|
|||||||
///
|
///
|
||||||
/// See documentation of StoreKit's [`-[SKPaymentQueue showPriceConsentIfNeeded]`](https://developer.apple.com/documentation/storekit/skpaymentqueue/3521327-showpriceconsentifneeded?language=objc).
|
/// See documentation of StoreKit's [`-[SKPaymentQueue showPriceConsentIfNeeded]`](https://developer.apple.com/documentation/storekit/skpaymentqueue/3521327-showpriceconsentifneeded?language=objc).
|
||||||
Future<void> showPriceConsentIfNeeded() async {
|
Future<void> showPriceConsentIfNeeded() async {
|
||||||
await channel
|
await _hostApi.showPriceConsentIfNeeded();
|
||||||
.invokeMethod<void>('-[SKPaymentQueue showPriceConsentIfNeeded]');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Triage a method channel call from the platform and triggers the correct observer method.
|
/// Triage a method channel call from the platform and triggers the correct observer method.
|
||||||
@ -354,7 +353,7 @@ class SKError {
|
|||||||
///
|
///
|
||||||
/// Any key of the map must be a valid [NSErrorUserInfoKey](https://developer.apple.com/documentation/foundation/nserroruserinfokey?language=objc).
|
/// Any key of the map must be a valid [NSErrorUserInfoKey](https://developer.apple.com/documentation/foundation/nserroruserinfokey?language=objc).
|
||||||
@JsonKey(defaultValue: <String, dynamic>{})
|
@JsonKey(defaultValue: <String, dynamic>{})
|
||||||
final Map<String?, Object?> userInfo;
|
final Map<String?, Object?>? userInfo;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
|
@ -4,7 +4,9 @@
|
|||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import '../channel.dart';
|
import '../messages.g.dart';
|
||||||
|
|
||||||
|
InAppPurchaseAPI _hostApi = InAppPurchaseAPI();
|
||||||
|
|
||||||
// ignore: avoid_classes_with_only_static_members
|
// ignore: avoid_classes_with_only_static_members
|
||||||
/// This class contains static methods to manage StoreKit receipts.
|
/// This class contains static methods to manage StoreKit receipts.
|
||||||
@ -17,8 +19,6 @@ class SKReceiptManager {
|
|||||||
/// For more details on how to validate the receipt data, you can refer to Apple's document about [`About Receipt Validation`](https://developer.apple.com/library/archive/releasenotes/General/ValidateAppStoreReceipt/Introduction.html#//apple_ref/doc/uid/TP40010573-CH105-SW1).
|
/// For more details on how to validate the receipt data, you can refer to Apple's document about [`About Receipt Validation`](https://developer.apple.com/library/archive/releasenotes/General/ValidateAppStoreReceipt/Introduction.html#//apple_ref/doc/uid/TP40010573-CH105-SW1).
|
||||||
/// If the receipt is invalid or missing, you can use [SKRequestMaker.startRefreshReceiptRequest] to request a new receipt.
|
/// If the receipt is invalid or missing, you can use [SKRequestMaker.startRefreshReceiptRequest] to request a new receipt.
|
||||||
static Future<String> retrieveReceiptData() async {
|
static Future<String> retrieveReceiptData() async {
|
||||||
return (await channel.invokeMethod<String>(
|
return (await _hostApi.retrieveReceiptData()) ?? '';
|
||||||
'-[InAppPurchasePlugin retrieveReceiptData:result:]')) ??
|
|
||||||
'';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import 'dart:async';
|
|||||||
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
import '../channel.dart';
|
|
||||||
import '../messages.g.dart';
|
import '../messages.g.dart';
|
||||||
import 'sk_product_wrapper.dart';
|
import 'sk_product_wrapper.dart';
|
||||||
|
|
||||||
@ -54,9 +53,6 @@ class SKRequestMaker {
|
|||||||
/// * isVolumePurchase: whether the receipt is a Volume Purchase Plan receipt.
|
/// * isVolumePurchase: whether the receipt is a Volume Purchase Plan receipt.
|
||||||
Future<void> startRefreshReceiptRequest(
|
Future<void> startRefreshReceiptRequest(
|
||||||
{Map<String, dynamic>? receiptProperties}) {
|
{Map<String, dynamic>? receiptProperties}) {
|
||||||
return channel.invokeMethod<void>(
|
return _hostApi.refreshReceipt(receiptProperties: receiptProperties);
|
||||||
'-[InAppPurchasePlugin refreshReceipt:result:]',
|
|
||||||
receiptProperties,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
Copyright 2013 The Flutter Authors. All rights reserved.
|
||||||
|
Use of this source code is governed by a BSD-style license that can be
|
||||||
|
found in the LICENSE file.
|
@ -243,4 +243,19 @@ abstract class InAppPurchaseAPI {
|
|||||||
void restoreTransactions(String? applicationUserName);
|
void restoreTransactions(String? applicationUserName);
|
||||||
|
|
||||||
void presentCodeRedemptionSheet();
|
void presentCodeRedemptionSheet();
|
||||||
|
|
||||||
|
String? retrieveReceiptData();
|
||||||
|
|
||||||
|
@async
|
||||||
|
void refreshReceipt({Map<String, Object?>? receiptProperties});
|
||||||
|
|
||||||
|
void startObservingPaymentQueue();
|
||||||
|
|
||||||
|
void stopObservingPaymentQueue();
|
||||||
|
|
||||||
|
void registerPaymentQueueDelegate();
|
||||||
|
|
||||||
|
void removePaymentQueueDelegate();
|
||||||
|
|
||||||
|
void showPriceConsentIfNeeded();
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ name: in_app_purchase_storekit
|
|||||||
description: An implementation for the iOS and macOS platforms of the Flutter `in_app_purchase` plugin. This uses the StoreKit Framework.
|
description: An implementation for the iOS and macOS platforms of the Flutter `in_app_purchase` plugin. This uses the StoreKit Framework.
|
||||||
repository: https://github.com/flutter/packages/tree/main/packages/in_app_purchase/in_app_purchase_storekit
|
repository: https://github.com/flutter/packages/tree/main/packages/in_app_purchase/in_app_purchase_storekit
|
||||||
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+in_app_purchase%22
|
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+in_app_purchase%22
|
||||||
version: 0.3.11
|
version: 0.3.12
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.2.3
|
sdk: ^3.2.3
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:in_app_purchase_storekit/in_app_purchase_storekit.dart';
|
import 'package:in_app_purchase_storekit/in_app_purchase_storekit.dart';
|
||||||
import 'package:in_app_purchase_storekit/src/channel.dart';
|
|
||||||
import 'package:in_app_purchase_storekit/src/messages.g.dart';
|
import 'package:in_app_purchase_storekit/src/messages.g.dart';
|
||||||
import 'package:in_app_purchase_storekit/store_kit_wrappers.dart';
|
import 'package:in_app_purchase_storekit/store_kit_wrappers.dart';
|
||||||
|
|
||||||
@ -13,11 +12,6 @@ import '../store_kit_wrappers/sk_test_stub_objects.dart';
|
|||||||
import '../test_api.g.dart';
|
import '../test_api.g.dart';
|
||||||
|
|
||||||
class FakeStoreKitPlatform implements TestInAppPurchaseApi {
|
class FakeStoreKitPlatform implements TestInAppPurchaseApi {
|
||||||
FakeStoreKitPlatform() {
|
|
||||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
|
||||||
.setMockMethodCallHandler(channel, onMethodCall);
|
|
||||||
}
|
|
||||||
|
|
||||||
// pre-configured store information
|
// pre-configured store information
|
||||||
String? receiptData;
|
String? receiptData;
|
||||||
late Set<String> validProductIDs;
|
late Set<String> validProductIDs;
|
||||||
@ -32,6 +26,7 @@ class FakeStoreKitPlatform implements TestInAppPurchaseApi {
|
|||||||
SKError? testRestoredError;
|
SKError? testRestoredError;
|
||||||
bool queueIsActive = false;
|
bool queueIsActive = false;
|
||||||
Map<String, dynamic> discountReceived = <String, dynamic>{};
|
Map<String, dynamic> discountReceived = <String, dynamic>{};
|
||||||
|
bool isPaymentQueueDelegateRegistered = false;
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
transactionList = <SKPaymentTransactionWrapper>[];
|
transactionList = <SKPaymentTransactionWrapper>[];
|
||||||
@ -57,6 +52,7 @@ class FakeStoreKitPlatform implements TestInAppPurchaseApi {
|
|||||||
testRestoredError = null;
|
testRestoredError = null;
|
||||||
queueIsActive = false;
|
queueIsActive = false;
|
||||||
discountReceived = <String, dynamic>{};
|
discountReceived = <String, dynamic>{};
|
||||||
|
isPaymentQueueDelegateRegistered = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SKPaymentTransactionWrapper createPendingTransaction(String id,
|
SKPaymentTransactionWrapper createPendingTransaction(String id,
|
||||||
@ -120,25 +116,6 @@ class FakeStoreKitPlatform implements TestInAppPurchaseApi {
|
|||||||
transactionIdentifier: transactionId);
|
transactionIdentifier: transactionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<dynamic> onMethodCall(MethodCall call) {
|
|
||||||
switch (call.method) {
|
|
||||||
case '-[InAppPurchasePlugin retrieveReceiptData:result:]':
|
|
||||||
if (receiptData != null) {
|
|
||||||
return Future<String>.value(receiptData!);
|
|
||||||
} else {
|
|
||||||
throw PlatformException(code: 'no_receipt_data');
|
|
||||||
}
|
|
||||||
case '-[InAppPurchasePlugin refreshReceipt:result:]':
|
|
||||||
receiptData = 'refreshed receipt data';
|
|
||||||
return Future<void>.sync(() {});
|
|
||||||
case '-[SKPaymentQueue startObservingTransactionQueue]':
|
|
||||||
queueIsActive = true;
|
|
||||||
case '-[SKPaymentQueue stopObservingTransactionQueue]':
|
|
||||||
queueIsActive = false;
|
|
||||||
}
|
|
||||||
return Future<void>.sync(() {});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool canMakePayments() {
|
bool canMakePayments() {
|
||||||
return true;
|
return true;
|
||||||
@ -246,4 +223,42 @@ class FakeStoreKitPlatform implements TestInAppPurchaseApi {
|
|||||||
return Future<SKProductsResponseMessage>.value(
|
return Future<SKProductsResponseMessage>.value(
|
||||||
SkProductResponseWrapper.convertToPigeon(response));
|
SkProductResponseWrapper.convertToPigeon(response));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> refreshReceipt({Map<String?, dynamic>? receiptProperties}) {
|
||||||
|
receiptData = 'refreshed receipt data';
|
||||||
|
return Future<void>.sync(() {});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void registerPaymentQueueDelegate() {
|
||||||
|
isPaymentQueueDelegateRegistered = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void removePaymentQueueDelegate() {
|
||||||
|
isPaymentQueueDelegateRegistered = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String retrieveReceiptData() {
|
||||||
|
if (receiptData != null) {
|
||||||
|
return receiptData!;
|
||||||
|
} else {
|
||||||
|
throw PlatformException(code: 'no_receipt_data');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void showPriceConsentIfNeeded() {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void startObservingPaymentQueue() {
|
||||||
|
queueIsActive = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void stopObservingPaymentQueue() {
|
||||||
|
queueIsActive = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:in_app_purchase_platform_interface/in_app_purchase_platform_interface.dart';
|
import 'package:in_app_purchase_platform_interface/in_app_purchase_platform_interface.dart';
|
||||||
import 'package:in_app_purchase_storekit/in_app_purchase_storekit.dart';
|
import 'package:in_app_purchase_storekit/in_app_purchase_storekit.dart';
|
||||||
@ -17,9 +16,6 @@ void main() {
|
|||||||
|
|
||||||
setUpAll(() {
|
setUpAll(() {
|
||||||
TestInAppPurchaseApi.setup(fakeStoreKitPlatform);
|
TestInAppPurchaseApi.setup(fakeStoreKitPlatform);
|
||||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
|
||||||
.setMockMethodCallHandler(
|
|
||||||
SystemChannels.platform, fakeStoreKitPlatform.onMethodCall);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
group('present code redemption sheet', () {
|
group('present code redemption sheet', () {
|
||||||
|
@ -23,9 +23,6 @@ void main() {
|
|||||||
|
|
||||||
setUpAll(() {
|
setUpAll(() {
|
||||||
TestInAppPurchaseApi.setup(fakeStoreKitPlatform);
|
TestInAppPurchaseApi.setup(fakeStoreKitPlatform);
|
||||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
|
||||||
.setMockMethodCallHandler(
|
|
||||||
SystemChannels.platform, fakeStoreKitPlatform.onMethodCall);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:in_app_purchase_storekit/src/channel.dart';
|
|
||||||
import 'package:in_app_purchase_storekit/src/messages.g.dart';
|
import 'package:in_app_purchase_storekit/src/messages.g.dart';
|
||||||
import 'package:in_app_purchase_storekit/store_kit_wrappers.dart';
|
import 'package:in_app_purchase_storekit/store_kit_wrappers.dart';
|
||||||
import '../test_api.g.dart';
|
import '../test_api.g.dart';
|
||||||
@ -17,9 +16,6 @@ void main() {
|
|||||||
|
|
||||||
setUpAll(() {
|
setUpAll(() {
|
||||||
TestInAppPurchaseApi.setup(fakeStoreKitPlatform);
|
TestInAppPurchaseApi.setup(fakeStoreKitPlatform);
|
||||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
|
||||||
.setMockMethodCallHandler(
|
|
||||||
SystemChannels.platform, fakeStoreKitPlatform.onMethodCall);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
setUp(() {});
|
setUp(() {});
|
||||||
@ -76,10 +72,10 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('refreshed receipt', () async {
|
test('refreshed receipt', () async {
|
||||||
final int receiptCountBefore = fakeStoreKitPlatform.refreshReceipt;
|
final int receiptCountBefore = fakeStoreKitPlatform.refreshReceiptCount;
|
||||||
await SKRequestMaker().startRefreshReceiptRequest(
|
await SKRequestMaker().startRefreshReceiptRequest(
|
||||||
receiptProperties: <String, dynamic>{'isExpired': true});
|
receiptProperties: <String, dynamic>{'isExpired': true});
|
||||||
expect(fakeStoreKitPlatform.refreshReceipt, receiptCountBefore + 1);
|
expect(fakeStoreKitPlatform.refreshReceiptCount, receiptCountBefore + 1);
|
||||||
expect(fakeStoreKitPlatform.refreshReceiptParam,
|
expect(fakeStoreKitPlatform.refreshReceiptParam,
|
||||||
<String, dynamic>{'isExpired': true});
|
<String, dynamic>{'isExpired': true});
|
||||||
});
|
});
|
||||||
@ -175,9 +171,9 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('showPriceConsentIfNeeded should call methodChannel', () async {
|
test('showPriceConsentIfNeeded should call methodChannel', () async {
|
||||||
expect(fakeStoreKitPlatform.showPriceConsentIfNeeded, false);
|
expect(fakeStoreKitPlatform.showPriceConsent, false);
|
||||||
await SKPaymentQueueWrapper().showPriceConsentIfNeeded();
|
await SKPaymentQueueWrapper().showPriceConsentIfNeeded();
|
||||||
expect(fakeStoreKitPlatform.showPriceConsentIfNeeded, true);
|
expect(fakeStoreKitPlatform.showPriceConsent, true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -192,10 +188,6 @@ void main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class FakeStoreKitPlatform implements TestInAppPurchaseApi {
|
class FakeStoreKitPlatform implements TestInAppPurchaseApi {
|
||||||
FakeStoreKitPlatform() {
|
|
||||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
|
||||||
.setMockMethodCallHandler(channel, onMethodCall);
|
|
||||||
}
|
|
||||||
// get product request
|
// get product request
|
||||||
List<dynamic> startProductRequestParam = <dynamic>[];
|
List<dynamic> startProductRequestParam = <dynamic>[];
|
||||||
bool getProductRequestFailTest = false;
|
bool getProductRequestFailTest = false;
|
||||||
@ -205,7 +197,7 @@ class FakeStoreKitPlatform implements TestInAppPurchaseApi {
|
|||||||
bool getReceiptFailTest = false;
|
bool getReceiptFailTest = false;
|
||||||
|
|
||||||
// refresh receipt request
|
// refresh receipt request
|
||||||
int refreshReceipt = 0;
|
int refreshReceiptCount = 0;
|
||||||
late Map<String, dynamic> refreshReceiptParam;
|
late Map<String, dynamic> refreshReceiptParam;
|
||||||
|
|
||||||
// payment queue
|
// payment queue
|
||||||
@ -217,7 +209,7 @@ class FakeStoreKitPlatform implements TestInAppPurchaseApi {
|
|||||||
bool presentCodeRedemption = false;
|
bool presentCodeRedemption = false;
|
||||||
|
|
||||||
// show price consent sheet
|
// show price consent sheet
|
||||||
bool showPriceConsentIfNeeded = false;
|
bool showPriceConsent = false;
|
||||||
|
|
||||||
// indicate if the payment queue delegate is registered
|
// indicate if the payment queue delegate is registered
|
||||||
bool isPaymentQueueDelegateRegistered = false;
|
bool isPaymentQueueDelegateRegistered = false;
|
||||||
@ -225,39 +217,6 @@ class FakeStoreKitPlatform implements TestInAppPurchaseApi {
|
|||||||
// Listen to purchase updates
|
// Listen to purchase updates
|
||||||
bool? queueIsActive;
|
bool? queueIsActive;
|
||||||
|
|
||||||
Future<dynamic> onMethodCall(MethodCall call) {
|
|
||||||
switch (call.method) {
|
|
||||||
// request makers
|
|
||||||
case '-[InAppPurchasePlugin refreshReceipt:result:]':
|
|
||||||
refreshReceipt++;
|
|
||||||
refreshReceiptParam = Map.castFrom<dynamic, dynamic, String, dynamic>(
|
|
||||||
call.arguments as Map<dynamic, dynamic>);
|
|
||||||
return Future<void>.sync(() {});
|
|
||||||
// receipt manager
|
|
||||||
case '-[InAppPurchasePlugin retrieveReceiptData:result:]':
|
|
||||||
if (getReceiptFailTest) {
|
|
||||||
throw Exception('some arbitrary error');
|
|
||||||
}
|
|
||||||
return Future<String>.value('receipt data');
|
|
||||||
case '-[SKPaymentQueue startObservingTransactionQueue]':
|
|
||||||
queueIsActive = true;
|
|
||||||
return Future<void>.sync(() {});
|
|
||||||
case '-[SKPaymentQueue stopObservingTransactionQueue]':
|
|
||||||
queueIsActive = false;
|
|
||||||
return Future<void>.sync(() {});
|
|
||||||
case '-[SKPaymentQueue registerDelegate]':
|
|
||||||
isPaymentQueueDelegateRegistered = true;
|
|
||||||
return Future<void>.sync(() {});
|
|
||||||
case '-[SKPaymentQueue removeDelegate]':
|
|
||||||
isPaymentQueueDelegateRegistered = false;
|
|
||||||
return Future<void>.sync(() {});
|
|
||||||
case '-[SKPaymentQueue showPriceConsentIfNeeded]':
|
|
||||||
showPriceConsentIfNeeded = true;
|
|
||||||
return Future<void>.sync(() {});
|
|
||||||
}
|
|
||||||
return Future<dynamic>.error('method not mocked');
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void addPayment(Map<String?, Object?> paymentMap) {
|
void addPayment(Map<String?, Object?> paymentMap) {
|
||||||
payments
|
payments
|
||||||
@ -304,6 +263,47 @@ class FakeStoreKitPlatform implements TestInAppPurchaseApi {
|
|||||||
}
|
}
|
||||||
return Future<SKProductsResponseMessage>.value(dummyProductResponseMessage);
|
return Future<SKProductsResponseMessage>.value(dummyProductResponseMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void registerPaymentQueueDelegate() {
|
||||||
|
isPaymentQueueDelegateRegistered = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void removePaymentQueueDelegate() {
|
||||||
|
isPaymentQueueDelegateRegistered = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void startObservingPaymentQueue() {
|
||||||
|
queueIsActive = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void stopObservingPaymentQueue() {
|
||||||
|
queueIsActive = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String retrieveReceiptData() {
|
||||||
|
if (getReceiptFailTest) {
|
||||||
|
throw Exception('some arbitrary error');
|
||||||
|
}
|
||||||
|
return 'receipt data';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> refreshReceipt({Map<String?, dynamic>? receiptProperties}) {
|
||||||
|
refreshReceiptCount++;
|
||||||
|
refreshReceiptParam =
|
||||||
|
Map.castFrom<dynamic, dynamic, String, dynamic>(receiptProperties!);
|
||||||
|
return Future<void>.sync(() {});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void showPriceConsentIfNeeded() {
|
||||||
|
showPriceConsent = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TestPaymentQueueDelegate extends SKPaymentQueueDelegateWrapper {}
|
class TestPaymentQueueDelegate extends SKPaymentQueueDelegateWrapper {}
|
||||||
|
@ -4,18 +4,18 @@
|
|||||||
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:in_app_purchase_storekit/src/channel.dart';
|
|
||||||
import 'package:in_app_purchase_storekit/store_kit_wrappers.dart';
|
import 'package:in_app_purchase_storekit/store_kit_wrappers.dart';
|
||||||
|
|
||||||
|
import '../fakes/fake_storekit_platform.dart';
|
||||||
|
import '../test_api.g.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
TestWidgetsFlutterBinding.ensureInitialized();
|
TestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
final FakeStoreKitPlatform fakeStoreKitPlatform = FakeStoreKitPlatform();
|
final FakeStoreKitPlatform fakeStoreKitPlatform = FakeStoreKitPlatform();
|
||||||
|
|
||||||
setUpAll(() {
|
setUpAll(() {
|
||||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
TestInAppPurchaseApi.setup(fakeStoreKitPlatform);
|
||||||
.setMockMethodCallHandler(
|
|
||||||
SystemChannels.platform, fakeStoreKitPlatform.onMethodCall);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test(
|
test(
|
||||||
@ -146,25 +146,3 @@ class TestPaymentQueueDelegate extends SKPaymentQueueDelegateWrapper {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class FakeStoreKitPlatform {
|
|
||||||
FakeStoreKitPlatform() {
|
|
||||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
|
||||||
.setMockMethodCallHandler(channel, onMethodCall);
|
|
||||||
}
|
|
||||||
|
|
||||||
// indicate if the payment queue delegate is registered
|
|
||||||
bool isPaymentQueueDelegateRegistered = false;
|
|
||||||
|
|
||||||
Future<dynamic> onMethodCall(MethodCall call) {
|
|
||||||
switch (call.method) {
|
|
||||||
case '-[SKPaymentQueue registerDelegate]':
|
|
||||||
isPaymentQueueDelegateRegistered = true;
|
|
||||||
return Future<void>.sync(() {});
|
|
||||||
case '-[SKPaymentQueue removeDelegate]':
|
|
||||||
isPaymentQueueDelegateRegistered = false;
|
|
||||||
return Future<void>.sync(() {});
|
|
||||||
}
|
|
||||||
return Future<dynamic>.error('method not mocked');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
// Autogenerated from Pigeon (v16.0.4), do not edit directly.
|
// Autogenerated from Pigeon (v16.0.4), do not edit directly.
|
||||||
// See also: https://pub.dev/packages/pigeon
|
// See also: https://pub.dev/packages/pigeon
|
||||||
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, unnecessary_import, no_leading_underscores_for_local_identifiers
|
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, unnecessary_import, no_leading_underscores_for_local_identifiers
|
||||||
@ -102,6 +105,20 @@ abstract class TestInAppPurchaseApi {
|
|||||||
|
|
||||||
void presentCodeRedemptionSheet();
|
void presentCodeRedemptionSheet();
|
||||||
|
|
||||||
|
String? retrieveReceiptData();
|
||||||
|
|
||||||
|
Future<void> refreshReceipt({Map<String?, Object?>? receiptProperties});
|
||||||
|
|
||||||
|
void startObservingPaymentQueue();
|
||||||
|
|
||||||
|
void stopObservingPaymentQueue();
|
||||||
|
|
||||||
|
void registerPaymentQueueDelegate();
|
||||||
|
|
||||||
|
void removePaymentQueueDelegate();
|
||||||
|
|
||||||
|
void showPriceConsentIfNeeded();
|
||||||
|
|
||||||
static void setup(TestInAppPurchaseApi? api,
|
static void setup(TestInAppPurchaseApi? api,
|
||||||
{BinaryMessenger? binaryMessenger}) {
|
{BinaryMessenger? binaryMessenger}) {
|
||||||
{
|
{
|
||||||
@ -331,5 +348,185 @@ abstract class TestInAppPurchaseApi {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<
|
||||||
|
Object?>(
|
||||||
|
'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.retrieveReceiptData',
|
||||||
|
pigeonChannelCodec,
|
||||||
|
binaryMessenger: binaryMessenger);
|
||||||
|
if (api == null) {
|
||||||
|
_testBinaryMessengerBinding!.defaultBinaryMessenger
|
||||||
|
.setMockDecodedMessageHandler<Object?>(__pigeon_channel, null);
|
||||||
|
} else {
|
||||||
|
_testBinaryMessengerBinding!.defaultBinaryMessenger
|
||||||
|
.setMockDecodedMessageHandler<Object?>(__pigeon_channel,
|
||||||
|
(Object? message) async {
|
||||||
|
try {
|
||||||
|
final String? output = api.retrieveReceiptData();
|
||||||
|
return <Object?>[output];
|
||||||
|
} on PlatformException catch (e) {
|
||||||
|
return wrapResponse(error: e);
|
||||||
|
} catch (e) {
|
||||||
|
return wrapResponse(
|
||||||
|
error: PlatformException(code: 'error', message: e.toString()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<
|
||||||
|
Object?>(
|
||||||
|
'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.refreshReceipt',
|
||||||
|
pigeonChannelCodec,
|
||||||
|
binaryMessenger: binaryMessenger);
|
||||||
|
if (api == null) {
|
||||||
|
_testBinaryMessengerBinding!.defaultBinaryMessenger
|
||||||
|
.setMockDecodedMessageHandler<Object?>(__pigeon_channel, null);
|
||||||
|
} else {
|
||||||
|
_testBinaryMessengerBinding!.defaultBinaryMessenger
|
||||||
|
.setMockDecodedMessageHandler<Object?>(__pigeon_channel,
|
||||||
|
(Object? message) async {
|
||||||
|
assert(message != null,
|
||||||
|
'Argument for dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.refreshReceipt was null.');
|
||||||
|
final List<Object?> args = (message as List<Object?>?)!;
|
||||||
|
final Map<String?, Object?>? arg_receiptProperties =
|
||||||
|
(args[0] as Map<Object?, Object?>?)?.cast<String?, Object?>();
|
||||||
|
try {
|
||||||
|
await api.refreshReceipt(receiptProperties: arg_receiptProperties);
|
||||||
|
return wrapResponse(empty: true);
|
||||||
|
} on PlatformException catch (e) {
|
||||||
|
return wrapResponse(error: e);
|
||||||
|
} catch (e) {
|
||||||
|
return wrapResponse(
|
||||||
|
error: PlatformException(code: 'error', message: e.toString()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<
|
||||||
|
Object?>(
|
||||||
|
'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.startObservingPaymentQueue',
|
||||||
|
pigeonChannelCodec,
|
||||||
|
binaryMessenger: binaryMessenger);
|
||||||
|
if (api == null) {
|
||||||
|
_testBinaryMessengerBinding!.defaultBinaryMessenger
|
||||||
|
.setMockDecodedMessageHandler<Object?>(__pigeon_channel, null);
|
||||||
|
} else {
|
||||||
|
_testBinaryMessengerBinding!.defaultBinaryMessenger
|
||||||
|
.setMockDecodedMessageHandler<Object?>(__pigeon_channel,
|
||||||
|
(Object? message) async {
|
||||||
|
try {
|
||||||
|
api.startObservingPaymentQueue();
|
||||||
|
return wrapResponse(empty: true);
|
||||||
|
} on PlatformException catch (e) {
|
||||||
|
return wrapResponse(error: e);
|
||||||
|
} catch (e) {
|
||||||
|
return wrapResponse(
|
||||||
|
error: PlatformException(code: 'error', message: e.toString()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<
|
||||||
|
Object?>(
|
||||||
|
'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.stopObservingPaymentQueue',
|
||||||
|
pigeonChannelCodec,
|
||||||
|
binaryMessenger: binaryMessenger);
|
||||||
|
if (api == null) {
|
||||||
|
_testBinaryMessengerBinding!.defaultBinaryMessenger
|
||||||
|
.setMockDecodedMessageHandler<Object?>(__pigeon_channel, null);
|
||||||
|
} else {
|
||||||
|
_testBinaryMessengerBinding!.defaultBinaryMessenger
|
||||||
|
.setMockDecodedMessageHandler<Object?>(__pigeon_channel,
|
||||||
|
(Object? message) async {
|
||||||
|
try {
|
||||||
|
api.stopObservingPaymentQueue();
|
||||||
|
return wrapResponse(empty: true);
|
||||||
|
} on PlatformException catch (e) {
|
||||||
|
return wrapResponse(error: e);
|
||||||
|
} catch (e) {
|
||||||
|
return wrapResponse(
|
||||||
|
error: PlatformException(code: 'error', message: e.toString()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<
|
||||||
|
Object?>(
|
||||||
|
'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.registerPaymentQueueDelegate',
|
||||||
|
pigeonChannelCodec,
|
||||||
|
binaryMessenger: binaryMessenger);
|
||||||
|
if (api == null) {
|
||||||
|
_testBinaryMessengerBinding!.defaultBinaryMessenger
|
||||||
|
.setMockDecodedMessageHandler<Object?>(__pigeon_channel, null);
|
||||||
|
} else {
|
||||||
|
_testBinaryMessengerBinding!.defaultBinaryMessenger
|
||||||
|
.setMockDecodedMessageHandler<Object?>(__pigeon_channel,
|
||||||
|
(Object? message) async {
|
||||||
|
try {
|
||||||
|
api.registerPaymentQueueDelegate();
|
||||||
|
return wrapResponse(empty: true);
|
||||||
|
} on PlatformException catch (e) {
|
||||||
|
return wrapResponse(error: e);
|
||||||
|
} catch (e) {
|
||||||
|
return wrapResponse(
|
||||||
|
error: PlatformException(code: 'error', message: e.toString()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<
|
||||||
|
Object?>(
|
||||||
|
'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.removePaymentQueueDelegate',
|
||||||
|
pigeonChannelCodec,
|
||||||
|
binaryMessenger: binaryMessenger);
|
||||||
|
if (api == null) {
|
||||||
|
_testBinaryMessengerBinding!.defaultBinaryMessenger
|
||||||
|
.setMockDecodedMessageHandler<Object?>(__pigeon_channel, null);
|
||||||
|
} else {
|
||||||
|
_testBinaryMessengerBinding!.defaultBinaryMessenger
|
||||||
|
.setMockDecodedMessageHandler<Object?>(__pigeon_channel,
|
||||||
|
(Object? message) async {
|
||||||
|
try {
|
||||||
|
api.removePaymentQueueDelegate();
|
||||||
|
return wrapResponse(empty: true);
|
||||||
|
} on PlatformException catch (e) {
|
||||||
|
return wrapResponse(error: e);
|
||||||
|
} catch (e) {
|
||||||
|
return wrapResponse(
|
||||||
|
error: PlatformException(code: 'error', message: e.toString()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<
|
||||||
|
Object?>(
|
||||||
|
'dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchaseAPI.showPriceConsentIfNeeded',
|
||||||
|
pigeonChannelCodec,
|
||||||
|
binaryMessenger: binaryMessenger);
|
||||||
|
if (api == null) {
|
||||||
|
_testBinaryMessengerBinding!.defaultBinaryMessenger
|
||||||
|
.setMockDecodedMessageHandler<Object?>(__pigeon_channel, null);
|
||||||
|
} else {
|
||||||
|
_testBinaryMessengerBinding!.defaultBinaryMessenger
|
||||||
|
.setMockDecodedMessageHandler<Object?>(__pigeon_channel,
|
||||||
|
(Object? message) async {
|
||||||
|
try {
|
||||||
|
api.showPriceConsentIfNeeded();
|
||||||
|
return wrapResponse(empty: true);
|
||||||
|
} on PlatformException catch (e) {
|
||||||
|
return wrapResponse(error: e);
|
||||||
|
} catch (e) {
|
||||||
|
return wrapResponse(
|
||||||
|
error: PlatformException(code: 'error', message: e.toString()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user