3.0.0-rc.1
0.59.9
iOS
Tidak ada kesalahan tipe
Argument of type '(purchase: ProductPurchase) => Promise<void>' is not assignable to parameter of type 'ProductPurchase'.
Type '(purchase: ProductPurchase) => Promise<void>' is missing the following properties from type 'ProductPurchase': productId, transactionId, transactionDate, transactionReceipt
Perangkat Nyata
import * as RNIap from 'react-native-iap';
export class Sample extends React.PureComponent {
purchaseUpdateSubscription: any = null;
componentDidMount() {
this.purchaseUpdateSubscription = RNIap.purchaseUpdatedListener(async (purchase: RNIap.ProductPurchase) => { })
}
}
Saya tidak begitu memahami kesalahan ini, karena jenis TS yang dikeluhkan tampaknya ada:
// RNIap.ProductPurchase
export interface ProductPurchase {
productId: string;
transactionId: string;
transactionDate: number;
transactionReceipt: string;
signatureAndroid?: string;
dataAndroid?: string;
purchaseToken?: string;
}
Dan definisi purchaseUpdatedListener
menggunakan antarmuka ProductPurchase
.
Saya tersesat 🤔
Apa yang terjadi jika Anda menyatakan seperti di bawah ini?
purchaseUpdateSubscription = purchaseUpdatedListener((purchase: ProductPurchase | SubscriptionPurchase) => {
console.log('purchaseUpdatedListener', purchase);
this.setState({ receipt: purchase.transactionReceipt }, () => this.goNext());
});
Sama...
Argument of type '(purchase: ProductPurchase | SubscriptionPurchase) => Promise<void>' is not assignable to parameter of type 'ProductPurchase'.
Type '(purchase: ProductPurchase | SubscriptionPurchase) => Promise<void>' is missing the following properties from type 'ProductPurchase': productId, transactionId, transactionDate, transactionReceipt
@jvandenaweg Heya! Maaf atas types
. Saya mengalami kesalahan kecil dan ini diperbaiki di `[email protected] '.
Juga di bawah ini adalah smaple dari App.tsx
untuk pengguna ketikan.
import React, { Component } from 'react';
import {
View,
Text,
Alert,
Platform,
ScrollView,
StyleSheet,
Button,
} from 'react-native';
import RNIap, {
Product,
ProductPurchase,
Subscription,
SubscriptionPurchase,
purchaseUpdatedListener,
} from 'react-native-iap';
// App Bundle > com.dooboolab.test
const itemSkus = Platform.select({
ios: [
'com.cooni.point1000', 'com.cooni.point5000', // dooboolab
],
android: [
'android.test.purchased', 'android.test.canceled', 'android.test.refunded', 'android.test.item_unavailable',
// 'point_1000', '5000_point', // dooboolab
],
});
const itemSubs = Platform.select({
ios: [
'com.cooni.point1000', 'com.cooni.point5000', // dooboolab
],
android: [
'test.sub1', // subscription
],
});
let purchaseUpdateSubscription: any;
interface IProps { };
interface IState {
productList: Product<string>[] | Subscription<string>[] | any;
receipt: string;
availableItemsMessage: string;
};
class Page extends Component<IProps, IState> {
constructor(props: IProps) {
super(props);
this.state = {
productList: [],
receipt: '',
availableItemsMessage: '',
};
}
async componentDidMount() {
try {
const result = await RNIap.initConnection();
await RNIap.consumeAllItemsAndroid();
console.log('result', result);
} catch (err) {
console.warn(err.code, err.message);
}
purchaseUpdateSubscription = purchaseUpdatedListener((purchase: ProductPurchase) => {
console.log('purchaseUpdatedListener', purchase);
this.setState({ receipt: purchase.transactionReceipt }, () => this.goNext());
});
}
componentWillMount() {
if (purchaseUpdateSubscription) {
purchaseUpdateSubscription.remove();
purchaseUpdateSubscription = null;
}
}
goNext = () => {
Alert.alert('Receipt', this.state.receipt);
}
getItems = async() => {
try {
const products: Product<string>[] = await RNIap.getProducts(itemSkus);
// const products = await RNIap.getSubscriptions(itemSkus);
console.log('Products', products);
this.setState({ productList: products });
} catch (err) {
console.warn(err.code, err.message);
}
}
getSubscriptions = async() => {
try {
const products: Subscription<string>[] = await RNIap.getSubscriptions(itemSubs);
console.log('Products', products);
this.setState({ productList: products });
} catch (err) {
console.warn(err.code, err.message);
}
}
getAvailablePurchases = async() => {
try {
console.info('Get available purchases (non-consumable or unconsumed consumable)');
const purchases = await RNIap.getAvailablePurchases();
console.info('Available purchases :: ', purchases);
if (purchases && purchases.length > 0) {
this.setState({
availableItemsMessage: `Got ${purchases.length} items.`,
receipt: purchases[0].transactionReceipt,
});
}
} catch (err) {
console.warn(err.code, err.message);
Alert.alert(err.message);
}
}
// Version 3 apis
requestPurchase = async(sku: string) => {
try {
RNIap.requestPurchase(sku);
} catch (err) {
console.warn(err.code, err.message);
}
}
requestSubscription = async(sku: string) => {
try {
RNIap.requestSubscription(sku);
} catch (err) {
Alert.alert(err.message);
}
}
// Deprecated apis
buyItem = async(sku: string) => {
console.info('buyItem', sku);
// const purchase = await RNIap.buyProduct(sku);
// const products = await RNIap.buySubscription(sku);
// const purchase = await RNIap.buyProductWithoutFinishTransaction(sku);
try {
const purchase: ProductPurchase = await RNIap.buyProduct(sku);
// console.log('purchase', purchase);
// await RNIap.consumePurchaseAndroid(purchase.purchaseToken);
this.setState({ receipt: purchase.transactionReceipt }, () => this.goNext());
} catch (err) {
console.warn(err.code, err.message);
const subscription = RNIap.addAdditionalSuccessPurchaseListenerIOS(async(purchase: ProductPurchase) => {
this.setState({ receipt: purchase.transactionReceipt }, () => this.goNext());
subscription.remove();
});
}
}
buySubscribeItem = async(sku: string) => {
try {
console.log('buySubscribeItem: ' + sku);
const purchase = await RNIap.buySubscription(sku);
console.info(purchase);
this.setState({ receipt: purchase.transactionReceipt }, () => this.goNext());
} catch (err) {
console.warn(err.code, err.message);
Alert.alert(err.message);
}
}
render() {
const { productList, receipt, availableItemsMessage } = this.state;
const receipt100 = receipt.substring(0, 100);
return (
<View style={ styles.container }>
<View style={ styles.header }>
<Text style={ styles.headerTxt} >react-native-iap V3</Text>
</View>
<View style={ styles.content }>
<ScrollView
style={{ alignSelf: 'stretch' }}
>
<View style={{ height: 50 }} />
<Button
onPress={this.getAvailablePurchases}
color='blue'
title='Get available purchases'
/>
<Text style={{ margin: 5, fontSize: 15, alignSelf: 'center' }} >{availableItemsMessage}</Text>
<Text style={{ margin: 5, fontSize: 9, alignSelf: 'center' }} >{receipt100}</Text>
<Button
onPress={() => this.getItems()}
color='green'
title={`Get Products ({productList.length})`}
/>
{
productList.map((product: Product<string> | Subscription<string>, i: number) => {
return (
<View key={i} style={{
flexDirection: 'column',
}}>
<Text style={{
marginTop: 20,
fontSize: 12,
color: 'black',
minHeight: 100,
alignSelf: 'center',
paddingHorizontal: 20,
}} >{JSON.stringify(product)}</Text>
<Button
onPress={() => this.requestPurchase(product.productId)}
// onPress={() => this.requestSubscription(product.productId)}
// onPress={() => this.buyItem(product.productId)}
// onPress={() => this.buySubscribeItem(product.productId)}
color='green'
title='Request purchase for above product'
/>
</View>
);
})
}
</ScrollView>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
marginTop: Platform.select({
ios: 0,
android: 24,
}),
paddingTop: Platform.select({
ios: 0,
android: 24,
}),
backgroundColor: 'white',
},
header: {
flex: 20,
flexDirection: 'row',
alignSelf: 'stretch',
justifyContent: 'center',
alignItems: 'center',
},
headerTxt: {
fontSize: 26,
color: 'green',
},
content: {
flex: 80,
flexDirection: 'column',
justifyContent: 'center',
alignSelf: 'stretch',
alignItems: 'center',
},
title: {
fontSize: 24,
fontWeight: 'bold',
},
btn: {
height: 48,
width: 240,
alignSelf: 'center',
backgroundColor: '#00c40f',
borderRadius: 0,
borderWidth: 0,
},
txt: {
fontSize: 16,
color: 'white',
},
});
export default Page;
Terima kasih @hyochan untuk perbaikan cepatnya, berhasil! :-)
Komentar yang paling membantu
@jvandenaweg Heya! Maaf atas
types
. Saya mengalami kesalahan kecil dan ini diperbaiki di `[email protected] '.Juga di bawah ini adalah smaple dari
App.tsx
untuk pengguna ketikan.