You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter in_app_purchase在iOS 18.3.1购后崩溃问题求助

iOS 18.3.1下Flutter in_app_purchase购买成功后崩溃的解决方案

问题分析

你遇到的崩溃是iOS 18.3.1特有的兼容性问题:-[NSNull length]: unrecognized selector sent to instance,本质是旧版本in_app_purchase插件未适配iOS 18 StoreKit返回的NSNull空值,导致原生层调用字符串方法时触发异常。

修复步骤

1. 升级in_app_purchase到最新稳定版

你的当前版本3.1.13发布时间较早,未覆盖iOS 18的兼容性修复。修改pubspec.yaml:

in_app_purchase: ^3.2.10 # 替换为pub.dev上的最新稳定版

执行flutter pub get更新依赖后重新编译测试。

2. 强制处理购买结果中的空字段

在监听购买状态更新的代码中(你当前的代码仅发起购买,未展示监听逻辑),必须对PurchaseDetails的关键字段做空值校验,避免原生层接收空值:

final Stream<List<PurchaseDetails>> purchaseStream = InAppPurchase.instance.purchaseStream;
_subscription = purchaseStream.listen((List<PurchaseDetails> purchaseDetailsList) {
  _listenToPurchaseUpdated(purchaseDetailsList);
}, onDone: () {
  _subscription?.cancel();
}, onError: (error) {
  // 处理错误
});

void _listenToPurchaseUpdated(List<PurchaseDetails> purchaseDetailsList) {
  for (final PurchaseDetails purchaseDetails in purchaseDetailsList) {
    if (purchaseDetails.status == PurchaseStatus.purchased) {
      // 关键:先校验所有可能为空的字段
      final receipt = purchaseDetails.verificationData.localVerificationData;
      if (receipt == null || receipt.isEmpty) {
        // 空值处理逻辑
        print("Receipt is null or empty");
      }
      // 必须调用completePurchase完成交易
      InAppPurchase.instance.completePurchase(purchaseDetails);
      // 其他业务逻辑
    }
  }
}

3. 确保调用completePurchase完成交易

iOS要求购买成功后必须调用completePurchase来结束交易流程,未调用会导致transaction残留,引发后续异常。你的当前代码仅发起购买,务必在收到PurchaseStatus.purchased状态时立即执行该方法。

4. 原生层临时异常捕获(可选)

如果升级插件后仍有问题,可在iOS原生代码中添加全局异常捕获,避免崩溃:
在AppDelegate.swift中添加:

import UIKit
import Flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    // 添加全局异常捕获
    NSSetUncaughtExceptionHandler { exception in
      print("Uncaught exception: \(exception)")
      print("Stack trace: \(exception.callStackSymbols)")
    }
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

关键说明

iOS 18的StoreKit API在某些场景下(比如沙盒环境的特定交易)会返回NSNull替代空字符串,旧版本插件未处理这种情况,直接调用length等字符串方法就会触发崩溃。升级插件是最根本的解决方式,同时完善空值校验和交易流程能避免类似问题复发。

内容的提问来源于stack exchange,提问作者Hindi Stories 686

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 14:14:53