diff --git a/packages/in_app_purchase/CHANGELOG.md b/packages/in_app_purchase/CHANGELOG.md index a071e1153c6e..f1b728b5387a 100644 --- a/packages/in_app_purchase/CHANGELOG.md +++ b/packages/in_app_purchase/CHANGELOG.md @@ -1,4 +1,8 @@ +## 0.3.4+11 + +* [iOS] Fixed: crash when sending null for simulatesAskToBuyInSandbox parameter. + ## 0.3.4+10 * Fixed typo 'verity' for 'verify'. diff --git a/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.m b/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.m index 156ce0c33e8f..6bcd58e73b96 100644 --- a/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.m +++ b/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.m @@ -179,8 +179,10 @@ - (void)addPayment:(FlutterMethodCall *)call result:(FlutterResult)result { NSNumber *quantity = [paymentMap objectForKey:@"quantity"]; payment.quantity = (quantity != nil) ? quantity.integerValue : 1; if (@available(iOS 8.3, *)) { - payment.simulatesAskToBuyInSandbox = - [[paymentMap objectForKey:@"simulatesAskToBuyInSandbox"] boolValue]; + NSNumber *simulatesAskToBuyInSandbox = [paymentMap objectForKey:@"simulatesAskToBuyInSandbox"]; + payment.simulatesAskToBuyInSandbox = (id)simulatesAskToBuyInSandbox == (id)[NSNull null] + ? NO + : [simulatesAskToBuyInSandbox boolValue]; } if (![self.paymentQueueHandler addPayment:payment]) { diff --git a/packages/in_app_purchase/ios/Tests/InAppPurchasePluginTest.m b/packages/in_app_purchase/ios/Tests/InAppPurchasePluginTest.m index 369e0ead0ba7..4025e9270fa9 100644 --- a/packages/in_app_purchase/ios/Tests/InAppPurchasePluginTest.m +++ b/packages/in_app_purchase/ios/Tests/InAppPurchasePluginTest.m @@ -146,6 +146,51 @@ - (void)testAddPaymentSuccessWithMockQueue { XCTAssertEqual(transactionForUpdateBlock.transactionState, SKPaymentTransactionStatePurchased); } +- (void)testAddPaymentWithNullSandboxArgument { + XCTestExpectation* expectation = + [self expectationWithDescription:@"result should return success state"]; + XCTestExpectation* simulatesAskToBuyInSandboxExpectation = + [self expectationWithDescription:@"payment isn't simulatesAskToBuyInSandbox"]; + FlutterMethodCall* call = + [FlutterMethodCall methodCallWithMethodName:@"-[InAppPurchasePlugin addPayment:result:]" + arguments:@{ + @"productIdentifier" : @"123", + @"quantity" : @(1), + @"simulatesAskToBuyInSandbox" : [NSNull null], + }]; + SKPaymentQueueStub* queue = [SKPaymentQueueStub new]; + queue.testState = SKPaymentTransactionStatePurchased; + __block SKPaymentTransaction* transactionForUpdateBlock; + self.plugin.paymentQueueHandler = [[FIAPaymentQueueHandler alloc] initWithQueue:queue + transactionsUpdated:^(NSArray* _Nonnull transactions) { + SKPaymentTransaction* transaction = transactions[0]; + if (transaction.transactionState == SKPaymentTransactionStatePurchased) { + transactionForUpdateBlock = transaction; + [expectation fulfill]; + } + if (@available(iOS 8.3, *)) { + if (!transaction.payment.simulatesAskToBuyInSandbox) { + [simulatesAskToBuyInSandboxExpectation fulfill]; + } + } else { + [simulatesAskToBuyInSandboxExpectation fulfill]; + } + } + transactionRemoved:nil + restoreTransactionFailed:nil + restoreCompletedTransactionsFinished:nil + shouldAddStorePayment:^BOOL(SKPayment* _Nonnull payment, SKProduct* _Nonnull product) { + return YES; + } + updatedDownloads:nil]; + [queue addTransactionObserver:self.plugin.paymentQueueHandler]; + [self.plugin handleMethodCall:call + result:^(id r){ + }]; + [self waitForExpectations:@[ expectation, simulatesAskToBuyInSandboxExpectation ] timeout:5]; + XCTAssertEqual(transactionForUpdateBlock.transactionState, SKPaymentTransactionStatePurchased); +} + - (void)testRestoreTransactions { XCTestExpectation* expectation = [self expectationWithDescription:@"result successfully restore transactions"]; diff --git a/packages/in_app_purchase/pubspec.yaml b/packages/in_app_purchase/pubspec.yaml index 6b1ddf9d08f8..a9bed88f1f65 100644 --- a/packages/in_app_purchase/pubspec.yaml +++ b/packages/in_app_purchase/pubspec.yaml @@ -1,7 +1,7 @@ name: in_app_purchase description: A Flutter plugin for in-app purchases. Exposes APIs for making in-app purchases through the App Store and Google Play. homepage: https://github.com/flutter/plugins/tree/master/packages/in_app_purchase -version: 0.3.4+10 +version: 0.3.4+11 dependencies: async: ^2.0.8