React-native-iap: RNIap.getProductsがiOSでpromiseを返さない

作成日 2018年12月19日  ·  24コメント  ·  ソース: dooboolab/react-native-iap

react-native-iapのバージョン

"react-native-iap": "^ 2.3.25"

react-nativeのバージョン

"react-native": "0.57.4"、

エラーに直面したプラットフォーム(IOSまたはAndroid、あるいはその両方?)

IOS

予想される行動

BuyProductはpromiseを返す必要があります(.then()は呼び出されません)、

実際の動作

BuyProductは約束を返しません。Androidでは正常に動作し、 .then()は正常に呼び出しますが、iOSではそうではありません。

テストされた環境(エミュレーター?実デバイス?)

実デバイス

動作を再現する手順

onBuyNowPress() {
    this.setState({ loading: true });
    RNIap.getProducts(['product_id']).then(success => { 
       RNIap.buyProduct('product_id').then(purchase => { 
        console.log("Purchase >>", purchase)
        this.setState({
          loading: false,
          receipt: purchase.transactionReceipt, 
        });
        Alert.alert('Purchase Successful!');
        this.props.getPurchase();
       }).catch(err => { 
         console.log(err.code, err.message);
          this.setState({ loading: false });
          Alert.alert(err.message);
          if(err.message === "You already own this item.") {
            this.props.getPurchase();
          }
        }) 
      }).catch(error => { 
        alert(error); 
        this.setState({ loading: false });
      })
  }

iOSではすでに製品を購入しているので、今すぐ購入を押すと、あなたがすでにこの製品を購入しているようにポップアップが表示されます。 しかし、 .then()または.catch()は呼び出されません。

getAvailablePurchases()メソッドも試しましたが、常に[]を返し

📱 iOS 🙏 help wanted

最も参考になるコメント

2.4.0-beta4を試していただけませんか?

全てのコメント24件

@ LinusU @ JJMoon正しかったと思います。 すべてのasyncを削除しましたが、問題が再び発生します。 どう思いますか? @ ZeroCool00今のところ2.3.24にダウングレードしますか?

@ ZeroCool00実は、 2.3.26を試してみませんか?

@hyochanすぐにテストします。そして、あなたに知らせて、そして迅速な返事をありがとう。

@hyochan 2.3.26で試しましたが、機能しませんか? 解決策はありますか?

@ ZeroCool00それなら、それはリンクの問題であるに違いありません。 unlinkを試して、もう一度linkやり直す必要があります。

@hyochan試してみましたが、リンクを解除してアンインストールしてから再インストールしてから、もう一度リンクしました。 しかし、それはまだ機能していません

@ ZeroCool00ウィンドウ内にいる場合、react-nativeリンクスクリプトはさらに不安定です。 手動で試しましたか? また、 2.3.24もお試しください。 設定の問題に直面していると思います。

@hyochan im on mac、そして私はリンクを解除してからアンインストールしてから2.3.24をインストールし、手動セットアップを行い、各手順に従います。Androidで動作しますが、iOSではまだ表示されません。 プロセスは正常に機能しています。 ポップアップが表示され、製品も購入されますが、約束は返されません。

iOS用の他の構成はありますか? 私はここで立ち往生しています、私がすでに購入していることを取得する他の方法はありますか?

@JJMoon @ ZeroCool00を手伝って

@ ZeroCool00また、 Alertを削除し、代わりにconsoleを使用してテストしてみてください。 iosは、購入の処理中にネイティブAlert ios自動的に生成するため、コードが中断される可能性があります。

@hyochanPlzはこれを再開します..私はすべてを試しました..私もアラートを削除します。 デバッグを停止して確認しても、機能しません。 アプリを公開したかったのですが、ここで立ち往生しています。 私もこのlibを試しましたhttps://github.com/chirag04/react-native-in-app-utils

このライブラリにも同じ問題があります。購入プロセスは正常に機能していますが、約束はありません。

イベントコールバックを取得するライフサイクルメソッドはありますか? サーバーAPIを呼び出すことができるイベントコールバックが必要です。

@ ZeroCool00 asyncawaitも使ってみませんか? 私もこれをアプリで使用していますが、この問題は発生していません。

@hyochanデモを提供していただけませんか..どのように使用していますか..それは大きな助けになるでしょう。

async forIOS() {
    let purchase =  await RNIap.buyProduct('product_id');
    console.log("BannerPurchase >>",purchase);  **<--- THIS IS NOT GETTING CALL**
    if(purchase) {
      console.log("Purchase >>", purchase)
      this.props.getPurchase();
      this.setState({
        loading: false,
        receipt: purchase.transactionReceipt, 
      });
      console.log('Purchase succesfully')
    }
  }

@hyochan私はあなたの言うことに従います、このプロセスは無限であり、何も返さないようです。 私もログを取得しません。

最近、他の多くの人が私たちのモジュールを使用しているので、あなたのケースはかなり奇妙に見えます。 あなたの完全に機能するコードがない限り、私たちが理解するのは難しいでしょう。

@hyochan @ ZeroCool00と同じ問題があります
2.3.26から2.4.0-beta3にアップグレードしたばかりです(リンク解除とリンクを作成しました)、同じ話です。
これをデバイスからログに記録します。 実際のiPhoneを使用して、xCode(有線接続)を介して開発を構築します。

[IAPInfoManager]: Update operation failed, error: Error Domain=SSErrorDomain Code=109 "Cannot connect to iTunes Store" UserInfo={NSLocalizedDescription=Cannot connect to iTunes Store, SSErrorHTTPStatusCodeKey=401}

しかし、購入したポップアップがサクセスストーリーとともに表示されます。 しかし、Javascriptスレッドでは何の反応もありません:(
iOSモジュールでPromiseが解決または拒否されません。

try {
      let purchase = false;

      console.log('BEFORE BUY');
      if (Platform.OS === 'ios') {
        purchase = await RNIap.buyProduct(selected);
      } else {
        purchase = await RNIap.buySubscription(selected);
      }
      console.log('AFTER BUY');

      await RNIap.finishTransaction();
      console.info('purchase >', purchase);
      setSubscription({type: selected, purchaseData: purchase});
    } catch (err) {
      console.log(err); // TODO add something went wrong
    }

AFTER BUY
現れさえしないでください。 .then約束を解決して、非同期/待機なしの同じ話。

この問題を引き起こす可能性のあるアイデアはありますか?

2.4.0-beta4を試していただけませんか?

@hyochanどうもありがとう👍
私の側で問題が解決しました。

@IsaevTimurどうやってそれを解決しましたか? それはまだ機能していません。

@hyochanこれが私のアプリ内購入モジュールの完全なコードです

import React, { Component } from 'react';
import { View, ImageBackground, TouchableOpacity, Image, Alert, 
  ActivityIndicator, Platform } from 'react-native';
import {inapp, btnBuy, purple} from '../helper/constants';
import ImageResizeMode from 'react-native/Libraries/Image/ImageResizeMode'
import { connect } from 'react-redux';
import { Icon } from 'native-base';
import { Actions } from 'react-native-router-flux';
import * as RNIap from 'react-native-iap';
import { getItems, getPurchase, fetchCategory } from '../action';

const itemSkus = Platform.select({
  ios: [
    'max_asl_unlimited_access'
  ],
  android: [
    'max_asl_unlimited_access'
  ]
});

class Banner extends Component {

  constructor(props){
    super(props);
    this.onBuyNowPress = this.onBuyNowPress.bind(this);
    this.forAndroid = this.forAndroid.bind(this);
    this.forIOS = this.forIOS.bind(this);
  }

  state = {
    loading: false,
  }

  async componentDidMount() {
    try {
      const result = await RNIap.initConnection();
      console.log('result', result);
      this.props.getItems();
    } catch (err) {
      console.warn(err.code, err.message);
    }
}

  componentDidUpdate(prevProps) {
    if(prevProps.purchase !== this.props.purchase) {
      this.props.fetchCategory();
    } 
  }

  onBuyNowPress() {
    this.setState({ loading: true });
    RNIap.getProducts(itemSkus).then(success => { 
      if(Platform.OS == "ios") {
        this.forIOS()
      } else {
        this.forAndroid()
      }
    }).catch(error => { 
      alert(error); 
      this.setState({ loading: false });
    })
  }

  async forIOS() {
    console.log('BannerCall');
    try {
      const purchase = await RNIap.buyProduct('max_asl_unlimited_access');
      console.log("BannerPurchase >>",purchase);
      if(purchase) {
        this.props.getPurchase();
        this.setState({
          loading: false,
        });
        console.log('Purchase succesfully')
      }
    } catch (err) {
      console.log("BannerError >> ", err);
    }
  }

  forAndroid() {
    RNIap.buyProduct('max_asl_unlimited_access').then(purchase => { 
      this.props.getPurchase();
      this.setState({
        loading: false,
        receipt: purchase.transactionReceipt, 
      });
      console.log('Purchase succesfully')
      Alert.alert("Purchase succesfully")
     }).catch(err => { 
       console.log(err.code, err.message);
        this.setState({ loading: false });
        if(err.message === "You already own this item.") {
          this.props.getPurchase();
          Alert.alert("You already own this product, we are restoring your purchase.")
        }
      }) 
  }

  componentWillUnmount() {
    RNIap.endConnection();
  }

  renderSpinner() {
    if(this.state.loading) {
      return (
        <ActivityIndicator size="large" color="#F7CD52" />
      )
    }
    return null
}

  render() {
    const { container, bannerStyle, btnContainer, iconClose } = styles;
    return (
      <View style={container}>
          <ImageBackground source={inapp} style={bannerStyle} resizeMode={ImageResizeMode.contain}>
              <Icon name="close" style={iconClose} type="FontAwesome" onPress={() => {Actions.pop()}}/>
              <View style={btnContainer}>
                {this.renderSpinner()}
                <TouchableOpacity onPress={() => this.onBuyNowPress()}>
                    <Image source={btnBuy}  />
                </TouchableOpacity>
              </View>
          </ImageBackground>
      </View>
    );
  }
}


const styles = {
  container: {
    flex: 1,  
  },
  iconClose: {
    color: '#FFF',
    fontSize: 30,
    alignSelf: 'flex-end',
    margin: 20,
    fontWeight: 'bold',
  },
  bannerStyle: {
    flex: 1,
    width: '100%',
    height: '100%',
    backgroundColor: purple
  }, 
  btnBuy: {
    marginRight: 20,
    marginTop: 160,
    height: 85,
    width: 215,
  },
  btnContainer: {
    flex: 1,
    marginTop: 50,
    justifyContent: 'center',
    alignItems: 'center'
  }
};

function mapStateToProps({ purchase }) {
    return { purchase };
}

export default connect(mapStateToProps, { getItems, getPurchase, fetchCategory })(Banner);

@ ZeroCool00

-2.4.0-beta4を使用していることを確認してください。

また、SANDBOXユーザー(開発中)を使用していることを確認してください。 これはiTunesConnectで設定できます。 これらのユーザーはここで作成されました-https://appstoreconnect.apple.com/access/users 、サンドボックスセクションの下。

それが役に立てば幸い :)

@IsaevTimur
しかし、私のアプリストアの購入プロセスは正常に機能しています。つまり、すべてが構成されており、2.4.0-beta4を使用しています。

これがpackage.jsonファイルの私のエントリです

"react-native-iap": "^2.4.0-beta4",

@hyochan私はついに問題を解決しました..問題は、最初にテストしたときに、.then()メソッドでこの行await RNIap.finishTransaction();記述しなかったことです。 後で追加しました。 それが問題でした。解決策は、トランザクション( await RNIap.clearTransaction(); )をクリアする必要があり、それが機能することです。

この素晴らしいライブラリをサポートしていただき、ありがとうございます。

@ ZeroCool00成功

このページは役に立ちましたか?
0 / 5 - 0 評価