I am learning Flutter and implemented the in_app_purchase
for for Android and iOS, however it works fine into both platforms but having the below issue into iOS 18.3.1 . The version I have
in_app_purchase: ^3.1.13
I face this issue
flutter: Purchase successful!
flutter: Purchase finally :
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSNull length]: unrecognized selector sent to instance 0x20c8db910'
*** First throw call stack:
(0x1a266a5fc 0x19fbe5244 0x1a27c3174 0x1a266d5c8 0x1a266cef0 0x1a125bbf0 0x1cfc08f64 0x1cfc066a8 0x1cfc05d18 0x1cfc052f4 0x1cfc07811 0x1cfc09a29 0x1cfbe2ddd 0x1cfbe2ddd 0x1cfbe2ddd 0x1cfbde2c5 0x1cfbde419 0x1cfbde2c5 0x1adf8fe39)
libc++abi: terminating due to uncaught exception of type NSException
My source code
Future<void> purchasePlan(BasePlans basePlan, BuildContext context) async {
try {
isLoading.value = true;
print("purchasePlan called : " + basePlan.id.toString());
print("purchasePlan called : " + basePlan.productDetails!.title);
if (basePlan.productDetails == null) {
error.value = "Product not available for purchase.";
print("Product not available for purchase");
isLoading.value = false;
return;
}
purchasePending.value = true;
late PurchaseParam purchaseParam;
if (Platform.isAndroid) {
// Check for existing subscriptions
final GooglePlayPurchaseDetails? oldSubscription =
_getOldSubscription(basePlan.productDetails!, purchases);
purchaseParam = GooglePlayPurchaseParam(
productDetails: basePlan.productDetails!,
changeSubscriptionParam: (oldSubscription != null)
? ChangeSubscriptionParam(
oldPurchaseDetails: oldSubscription,
replacementMode: ReplacementMode.withoutProration)
: null,
);
} else {
print("basePlan.productDetails id: " + basePlan.productDetails!.id);
print("basePlan.productDetails title : " +
basePlan.productDetails!.title);
print("basePlan.productDetails description : " +
basePlan.productDetails!.description);
print("basePlan.productDetails price : " +
basePlan.productDetails!.price);
print("basePlan.productDetails rawPrice: " +
basePlan.productDetails!.rawPrice.toString());
print("basePlan.productDetails currencyCode: " +
basePlan.productDetails!.currencyCode.toString());
print("basePlan.productDetails currencySymbol: " +
basePlan.productDetails!.currencySymbol.toString());
purchaseParam = PurchaseParam(
productDetails: basePlan.productDetails!,
);
print("basePlan.purchaseParam : " + purchaseParam.productDetails.id);
print("basePlan.applicationUserName : " +
purchaseParam.applicationUserName.toString());
}
try {
await _inAppPurchasePlatform.buyNonConsumable(
purchaseParam: purchaseParam);
print("Purchase successful!");
} catch (e, stacktrace) {
print("Purchase failed: $e");
print("Stacktrace: $stacktrace");
rethrow; // Preserve the crash for further debugging
}
} catch (e) {
print("Purchase error : $e");
error.value = "Purchase error: $e";
purchasePending.value = false;
isLoading.value = false;
String errorMessage = e.toString();
String displayMessage = '';
// Check if the error contains the specific message
if (errorMessage.contains('storekit_duplicate_product_object')) {
displayMessage =
'There is a pending transaction for the same product identifier. Please either wait for it to be finished or finish it manually using `completePurchase` to avoid edge cases.';
} else {
displayMessage = 'An unexpected purchase error occurred: $errorMessage';
}
Get.snackbar(
"Something went wrong!",
displayMessage,
snackPosition: SnackPosition.BOTTOM,
);
return;
} finally {
print("Purchase finally : ");
isPurchasing.value = false; // Set to false when purchase is done
// isLoading.value = false;
}
}
I am learning Flutter and implemented the in_app_purchase
for for Android and iOS, however it works fine into both platforms but having the below issue into iOS 18.3.1 . The version I have
in_app_purchase: ^3.1.13
I face this issue
flutter: Purchase successful!
flutter: Purchase finally :
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSNull length]: unrecognized selector sent to instance 0x20c8db910'
*** First throw call stack:
(0x1a266a5fc 0x19fbe5244 0x1a27c3174 0x1a266d5c8 0x1a266cef0 0x1a125bbf0 0x1cfc08f64 0x1cfc066a8 0x1cfc05d18 0x1cfc052f4 0x1cfc07811 0x1cfc09a29 0x1cfbe2ddd 0x1cfbe2ddd 0x1cfbe2ddd 0x1cfbde2c5 0x1cfbde419 0x1cfbde2c5 0x1adf8fe39)
libc++abi: terminating due to uncaught exception of type NSException
My source code
Future<void> purchasePlan(BasePlans basePlan, BuildContext context) async {
try {
isLoading.value = true;
print("purchasePlan called : " + basePlan.id.toString());
print("purchasePlan called : " + basePlan.productDetails!.title);
if (basePlan.productDetails == null) {
error.value = "Product not available for purchase.";
print("Product not available for purchase");
isLoading.value = false;
return;
}
purchasePending.value = true;
late PurchaseParam purchaseParam;
if (Platform.isAndroid) {
// Check for existing subscriptions
final GooglePlayPurchaseDetails? oldSubscription =
_getOldSubscription(basePlan.productDetails!, purchases);
purchaseParam = GooglePlayPurchaseParam(
productDetails: basePlan.productDetails!,
changeSubscriptionParam: (oldSubscription != null)
? ChangeSubscriptionParam(
oldPurchaseDetails: oldSubscription,
replacementMode: ReplacementMode.withoutProration)
: null,
);
} else {
print("basePlan.productDetails id: " + basePlan.productDetails!.id);
print("basePlan.productDetails title : " +
basePlan.productDetails!.title);
print("basePlan.productDetails description : " +
basePlan.productDetails!.description);
print("basePlan.productDetails price : " +
basePlan.productDetails!.price);
print("basePlan.productDetails rawPrice: " +
basePlan.productDetails!.rawPrice.toString());
print("basePlan.productDetails currencyCode: " +
basePlan.productDetails!.currencyCode.toString());
print("basePlan.productDetails currencySymbol: " +
basePlan.productDetails!.currencySymbol.toString());
purchaseParam = PurchaseParam(
productDetails: basePlan.productDetails!,
);
print("basePlan.purchaseParam : " + purchaseParam.productDetails.id);
print("basePlan.applicationUserName : " +
purchaseParam.applicationUserName.toString());
}
try {
await _inAppPurchasePlatform.buyNonConsumable(
purchaseParam: purchaseParam);
print("Purchase successful!");
} catch (e, stacktrace) {
print("Purchase failed: $e");
print("Stacktrace: $stacktrace");
rethrow; // Preserve the crash for further debugging
}
} catch (e) {
print("Purchase error : $e");
error.value = "Purchase error: $e";
purchasePending.value = false;
isLoading.value = false;
String errorMessage = e.toString();
String displayMessage = '';
// Check if the error contains the specific message
if (errorMessage.contains('storekit_duplicate_product_object')) {
displayMessage =
'There is a pending transaction for the same product identifier. Please either wait for it to be finished or finish it manually using `completePurchase` to avoid edge cases.';
} else {
displayMessage = 'An unexpected purchase error occurred: $errorMessage';
}
Get.snackbar(
"Something went wrong!",
displayMessage,
snackPosition: SnackPosition.BOTTOM,
);
return;
} finally {
print("Purchase finally : ");
isPurchasing.value = false; // Set to false when purchase is done
// isLoading.value = false;
}
}
Share
Improve this question
edited Mar 30 at 10:35
Vy Do
52.9k69 gold badges255 silver badges387 bronze badges
asked Mar 30 at 6:01
Hindi Stories 686Hindi Stories 686
1
2
|
1 Answer
Reset to default 1It usually occurs when you don't configure your product in your app store to connect correctly. The issue is due to multiple reasons, like your product has some missing info and it's still on pending for approval.
Check this:
The product exists in App Store Connect.
The product is correctly added in Xcode under App Store -> Subscriptions/In-App Purchases.
You are using the correct product identifier in your Flutter app.
The product is marked as "Ready to Submit".
You are logged into a sandbox account when testing purchases.
Also, try to update the package if you are using the old version.
flutter pub upgrade in_app_purchase
You can also handle the null check error in your app.
print("basePlan.productDetails id: " + (basePlan.productDetails?.id ?? "N/A")); print("basePlan.productDetails title: " + (basePlan.productDetails?.title ?? "N/A")); print("basePlan.productDetails description: " + (basePlan.productDetails?.description ?? "N/A")); print("basePlan.productDetails price: " + (basePlan.productDetails?.price ?? "N/A")); print("basePlan.productDetails rawPrice: " + (basePlan.productDetails?.rawPrice.toString() ?? "N/A")); print("basePlan.productDetails currencyCode: " + (basePlan.productDetails?.currencyCode ?? "N/A")); print("basePlan.productDetails currencySymbol: " + (basePlan.productDetails?.currencySymbol ?? "N/A"));
Length
method was invoked onNSNull
; most likely something that you think is a string, isn't. You need to symbolicate your stack trace or perhaps try running under the Xcode debugger – Paulw11 Commented Mar 30 at 8:06