The following component functions nominally under Android. We thought we were cool.
But, the same code on iOS hangs when it tries to get subscriptions. The request doesn't succeed, doesn't fail, doesn't crash. The JS promise is seemingly never resolved or rejected.
Has anyone experienced this? Any ideas on what I should try next?
This is running on my 100% real iPhone logged into my Apple account tethered to my MacBook Pro. There don't appear to be any other issues regarding this phone's ability to make purchases.
Logs
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...
Component JSX
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;
Dependencies
"react": "17.0.2",
"react-native": "0.66.3",
"react-native-iap": "^8.0.0-rc.6",
GitHub
Also posted this to https://github.com/dooboolab/react-native-iap/issues/1708