React-native-iap: RNIap.getProducts не возвращает обещание на ios

Созданный на 19 дек. 2018  ·  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 должен вернуть обещание (.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 Если вы находитесь в окне, скрипт ссылки на реакцию будет еще более нестабильным. Вручную пробовали? Также попробуйте 2.3.24 . Я думаю, вы столкнулись с проблемой конфигурации.

@hyochan im на Mac, и я отключаю, а затем удаляю, а затем устанавливаю 2.3.24 и выполняю ручную настройку, следуйте каждому шагу, он работает с Android, в ios он все еще не отображается. процесс работает нормально. Я получаю всплывающее окно, и продукт также получает покупку, но не обещает возврата?

есть ли другая конфигурация для ios? Я застрял здесь, есть ли другой способ получить то, что я уже покупаю.

@JJMoon Не могли бы вы помочь @ ZeroCool00 ?

@ ZeroCool00 Также попробуйте удалить Alert и вместо этого используйте console для тестирования. Поскольку ios автоматически генерирует нативный Alert когда покупка обрабатывается, что может прервать ваш код.

@hyochan Plz, снова удаляю оповещение. даже я прекращаю отладку и проверяю .. это просто не работает. Я хотел опубликовать свое приложение, но застрял здесь. я даже пробовал эту библиотеку https://github.com/chirag04/react-native-in-app-utils

эта библиотека также имеет ту же проблему ... процесс покупки работает нормально, но не дает никаких обещаний.

есть ли какой-либо метод жизненного цикла, при котором я получаю обратный вызов события. Мне просто нужен обратный вызов события, где я могу вызвать сервер API.

@ ZeroCool00 Не могли бы вы также попробовать использовать async и await ? Я также использую это в нашем приложении, и мы не сталкиваемся с этой проблемой.

@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 (сделал unlink и линк), та же история.
Получение этого в журналах с устройства. Используя настоящий 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.

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
Даже не появляется. Та же история без async / await, с разрешением .then prom.

Есть идеи, что может вызвать эту проблему?

Не могли бы вы попробовать 2.4.0-beta4 ?

@hyochan Большое спасибо 👍
Вопрос решен на моей стороне.

@IsaevTimur, как ты это решил? все еще не работает.

@hyochan Вот полный код моего модуля покупки inapp

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 (в стадии разработки). Что можно настроить в iTunes Connect. Эти пользователи созданы здесь - https://appstoreconnect.apple.com/access/users , в разделе Sandbox.

Надеюсь, это поможет :)

@IsaevTimur
но мой процесс покупки в магазине приложений работает нормально, это означает, что все настроено, и да, я использую 2.4.0-beta4.

вот моя запись в файле package.json

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

@hyochan, я наконец решил проблему ... проблема в том, что когда я впервые тестировал, я не писал эту строку await RNIap.finishTransaction(); в методе .then (). я добавил это позже. это была проблема, решение: мне нужно очистить транзакцию ( await RNIap.clearTransaction(); ), и она сработает.

Еще раз спасибо за вашу поддержку этой замечательной библиотеки.

@ ZeroCool00 Поздравляю с успехом !! Да, проблемы такого рода следует лучше решать с вашей стороны, потому что нам нужно некоторое внимание к тому, что вы сделали неправильно. Спасибо, что вернулись снова для тех, кто, возможно, страдает от того же.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги