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

react-native-iap iOS端getSubscriptions获取订阅挂起无响应

问题描述

下述组件在Android端可正常运行,原本判定功能已调试完成,但相同代码在iOS端尝试获取订阅时会出现挂起问题:请求既不返回成功、也不抛出失败、不会触发崩溃,对应的JS Promise始终不会被决议(既不resolve也不reject)。
本次测试运行在登录了本人Apple账号的正版真机iPhone上,设备连接MacBook Pro调试,该设备本身的应用内购买功能无任何异常。

运行日志
LOG  [Subscription] Will init connection
 LOG  [Subscription] Did init connection
 LOG  [Subscription] Will clear transaction ios
 LOG  [Subscription] Did clear transaction ios
 LOG  [Subscription] Will get subscription
 ...then nothing, I've waited over 5 minutes...
组件代码
import React, { Component } from "react";
import { Platform, Text, TouchableOpacity } from "react-native";
import * as Sentry from "@sentry/react-native";
import * as RNIap from "react-native-iap";
import { Subscription, SubscriptionPurchase } from "react-native-iap/src/types";
import { SUBSCRIPTION_ID } from "../env";

class SubscriptionScreen extends Component {
  state = {
    subscription: undefined,
    available: undefined,
  };

  constructor(props) {
    super(props);
  }

  async componentDidMount() {
    try {
      console.log('[Subscription]','Will init connection');
      await RNIap.initConnection();
      console.log('[Subscription]','Did init connection');
      if (Platform.OS === 'ios') {
        console.log('[Subscription]','Will clear transaction ios');
        await RNIap.clearTransactionIOS();
        console.log('[Subscription]','Did clear transaction ios');
      }
      console.log('[Subscription]','Will get subscription');
      const subscription: Subscription = (await RNIap.getSubscriptions([SUBSCRIPTION_ID])).find(s => s.productId === SUBSCRIPTION_ID);
      console.log('[Subscription]','Did get subscription', subscription);
      console.log('[Subscription]','Will get available');
      const available: SubscriptionPurchase = (await RNIap.getAvailablePurchases([SUBSCRIPTION_ID])).find(p => p.productId === SUBSCRIPTION_ID);
      console.log('[Subscription]','Did get available', available);
      this.setState({subscription, available});

    } catch (err) {
      console.error('Failed to get subscriptions!', err.code, err.message);
      Sentry.captureException(err);
    }
  }

  async componentWillUnmount() {
    console.log('[Subscription]','Will close connection');
    await RNIap.endConnection();
    console.log('[Subscription]','Did close connection');
  }

  async purchaseSubscription() {
    try {
      await RNIap.requestSubscription(SUBSCRIPTION_ID);
    } catch (err) {
      console.error('Failed to purchase subscriptions!', err.code, err.message);
      Sentry.captureException(err);
    }
  }

  render() {
    if (this.state.available)
      return (
        <Text>You're a subscriber!</Text>
      )
    else
      return (
        <TouchableOpacity onPress={this.purchaseSubscription} >
          <Text>Subscribe</Text>
        </TouchableOpacity>
      )
  }
}

export default SubscriptionScreen;
依赖版本
"react": "17.0.2",
"react-native": "0.66.3",
"react-native-iap": "^8.0.0-rc.6",
可尝试的排查方向
  • 先确认iOS端内购配置完整性:检查App Store Connect中对应订阅商品的状态是否为准备提交/已批准,确保商品ID、订阅组配置、税务银行协议全部生效,iOS端商品查询请求对未完成配置的商品不会返回错误,只会直接挂起无响应。
  • 替换依赖版本:当前使用的react-native-iap@8.0.0-rc.6属于预览版本,存在已知的iOS端SKProductsRequest回调未正确桥接的问题,直接升级到v8.0.0及以上的正式稳定版即可修复该类Promise挂起问题,不要使用rc预览版本处理支付相关逻辑。
  • 调整初始化调用顺序:不要在initConnection完成后立即调用clearTransactionIOS,该方法会清空当前交易队列并中断商品请求监听,可将该方法调用移到购买流程结束后,或暂时注释该步骤验证是否能正常拿到商品列表。
  • 查看原生端系统日志:打开Xcode运行项目,在控制台筛选StoreKit相关日志,确认是否有无法连接App Store、商品ID无效类的系统级报错,JS层未做桥接捕获的原生端报错不会触发Promise reject,只会导致请求永久挂起。
  • 修正测试账号配置:不要使用登录了正式Apple ID的设备测试开发包内购,需要在iOS设置的「App Store-沙盒账户」入口单独登录沙盒测试账号,正式账号在调试包环境下发起StoreKit请求会被系统拦截且无任何回调。
  • 检查全局监听冲突:确认项目中没有其他模块在当前组件挂载前调用过endConnection方法,StoreKit全局只存在一个交易监听实例,被提前释放后所有后续内购请求都会无响应。

内容的提问来源于stack exchange,提问作者Nick Charney Kaye

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 00:21:39