React-native-iap: ์ œํ’ˆ / ๊ตฌ๋…์˜ ๋ฐฐ์—ด์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์— ๋งŒ๋“  2019๋…„ 08์›” 19์ผ  ยท  31์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: dooboolab/react-native-iap

react-native-iap ๋ฒ„์ „

3.3.9

๋ฐ˜์‘ ๋„ค์ดํ‹ฐ๋ธŒ ๋ฒ„์ „

0.59.9

์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ํ”Œ๋žซํผ (IOS ๋˜๋Š” Android ๋˜๋Š” ๋‘˜ ๋‹ค?)

iOS ๋ฐ Android

์˜ˆ์ƒ๋˜๋Š” ํ–‰๋™

Play Console๊ณผ Appstore์—์„œ ์ƒ์„ฑ ๋œ ๋‹ค์–‘ํ•œ ์ œํ’ˆ๊ณผ ๊ตฌ๋…์„ ์–ป์„ ์ˆ˜์žˆ์„ ๊ฒƒ์œผ๋กœ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค.

์‹ค์ œ ํ–‰๋™

RNIap.getProducts ๋ฐ RNIap.getSubscriptions ํ•จ์ˆ˜๋Š” ํ•ญ์ƒ ๋นˆ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

ํ…Œ์ŠคํŠธ ๋œ ํ™˜๊ฒฝ (์—๋ฎฌ๋ ˆ์ดํ„ฐ? ์‹ค์ œ ์žฅ์น˜?)

iOS ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ, Android ์—๋ฎฌ๋ ˆ์ดํ„ฐ ๋ฐ Android ์‹ค์ œ ์žฅ์น˜

ํ–‰๋™์„ ์žฌํ˜„ํ•˜๋Š” ๋‹จ๊ณ„

  1. Google Play Console ๋ฐ Apple Appstore Connect์— ์ œํ’ˆ ์ถ”๊ฐ€
  2. ์˜ˆ์ œ ํด๋”์˜ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.
  3. ์ œํ’ˆ / ๊ตฌ๋… ID๋ฅผ ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค.

24 ์‹œ๊ฐ„ ์ด์ƒ ๊ธฐ๋‹ค๋ ธ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ Google Play Console์—์„œ ๋‚ด๋ถ€ ๋ฐ ์•ŒํŒŒ ๋ฆด๋ฆฌ์Šค๋ฅผ ๋งŒ๋“ค์—ˆ์ง€ ๋งŒ ์—ฌ์ „ํžˆ ๋นˆ ๋ฐฐ์—ด ๋งŒ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

์ •ํ™•ํžˆ ์–ธ์ œ ์ž‘๋™์„ ์‹œ์ž‘ํ•ด์•ผํ•˜๋Š”์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‚ด ์•ŒํŒŒ ํ…Œ์ŠคํŠธ ์ถœ์‹œ๊ฐ€ Google Play Console์— ์•„์ง ๊ฒŒ์‹œ ๋ณด๋ฅ˜ ์ค‘์ด๋ผ๋ฉด react-native-iap ์ด ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์˜๋ฏธ์ธ๊ฐ€์š”? ์•ฑ์ด ๊ฒŒ์‹œ ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผํ•˜๋‚˜์š”?

๋˜ํ•œ ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ / ์—๋ฎฌ๋ ˆ์ดํ„ฐ์—์„œ ํ…Œ์ŠคํŠธ ๊ตฌ๋งค๋„ ํ•  ์ˆ˜ ์—†์ง€๋งŒ getProducts / getSubscriptions ๊ฐ€ ์—๋ฎฌ๋ ˆ์ดํ„ฐ์—์„œ ์ž‘๋™ํ•ด์•ผํ•ฉ๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด ์‹ค์ œ ์žฅ์น˜๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๊นŒ?

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

const itemSubs = Platform.select({
    ios: ['subscription_1'],
    android: ['subscription_1', 'subscription_2']
});

let purchaseUpdateSubscription;
let purchaseErrorSubscription;

class App extends Component {
    constructor(props) {
        super(props);

        this.state = {
            productList: [],
            receipt: '',
            availableItemsMessage: ''
        };
    }

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

        purchaseUpdateSubscription = purchaseUpdatedListener(async purchase => {
            console.log('purchaseUpdatedListener', purchase);
            if (purchase.purchaseStateAndroid === 1 && !purchase.isAcknowledgedAndroid) {
                try {
                    const ackResult = await acknowledgePurchaseAndroid(purchase.purchaseToken);
                    console.log('ackResult', ackResult);
                } catch (ackErr) {
                    console.warn('ackErr', ackErr);
                }
            }
            this.setState({ receipt: purchase.transactionReceipt }, () => this.goNext());
        });

        purchaseErrorSubscription = purchaseErrorListener(error => {
            console.log('purchaseErrorListener', error);
            Alert.alert('purchase error', JSON.stringify(error));
        });
    }

    componentWillMount() {
        if (purchaseUpdateSubscription) {
            purchaseUpdateSubscription.remove();
            purchaseUpdateSubscription = null;
        }
        if (purchaseErrorSubscription) {
            purchaseErrorSubscription.remove();
            purchaseErrorSubscription = null;
        }
    }

    goNext = () => {
        Alert.alert('Receipt', this.state.receipt);
    };

    getItems = async () => {
        try {
            const products = await RNIap.getProducts(itemSkus);            
            console.log('Products', products);
            this.setState({ productList: products });
        } catch (err) {
            console.warn(err.code, err.message);
        }
    };

    getSubscriptions = async () => {
        try {
            const products = 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);
        }
    };

    requestPurchase = async sku => {
        try {
            RNIap.requestPurchase(sku);
        } catch (err) {
            console.warn(err.code, err.message);
        }
    };

    requestSubscription = async sku => {
        try {
            RNIap.requestSubscription(sku);
        } catch (err) {
            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 }} />
                        <NativeButton
                            onPress={this.getAvailablePurchases}
                            activeOpacity={0.5}
                            style={styles.btn}
                            textStyle={styles.txt}
                        >
                            Get available purchases
                        </NativeButton>

                        <Text style={{ margin: 5, fontSize: 15, alignSelf: 'center' }}>
                            {availableItemsMessage}
                        </Text>

                        <Text style={{ margin: 5, fontSize: 9, alignSelf: 'center' }}>
                            {receipt100}
                        </Text>

                        <NativeButton
                            onPress={() => this.getItems()}
                            activeOpacity={0.5}
                            style={styles.btn}
                            textStyle={styles.txt}
                        >
                            Get Products ({productList.length})
                        </NativeButton>
                        {productList.map((product, i) => {
                            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>
                                    <NativeButton
                                        // onPress={() => this.requestPurchase(product.productId)}
                                        onPress={() => this.requestSubscription(product.productId)}
                                        // onPress={() => this.buyItem(product.productId)}
                                        // onPress={() => this.buySubscribeItem(product.productId)}
                                        activeOpacity={0.5}
                                        style={styles.btn}
                                        textStyle={styles.txt}
                                    >
                                        Request purchase for above product
                                    </NativeButton>
                                </View>
                            );
                        })}
                    </ScrollView>
                </View>
            </View>
        );
    }
}
๐Ÿ“ฑ iOS ๐Ÿ™ help wanted ๐Ÿšถ๐Ÿป stale ๐Ÿค– android

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

๋ฌผ๋ก . Google Play ์Šคํ† ์–ด์—์„œ ๊ฒŒ์‹œ ํ•œ ํ›„ ์—ฌ๊ธฐ์—์„œ ํ™•์ธํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ตœ์‹  ์ •๋ณด

๋‚ด ์•ฑ์ด Google Play ์Šคํ† ์–ด์— ๊ฒŒ์‹œ ๋œ ํ›„ ๊ตฌ๋งค๊ฐ€ ์ด๋ฃจ์–ด์ง€๊ณ  ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค. ์Šน์ธํ•˜๋Š” ๋ฐ 3 ์ผ์ด ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค. @jvandenaardweg ๋•๋ถ„์—

์—…๋ฐ์ดํŠธ 2

react-native-iap๋Š” ์—๋ฎฌ๋ ˆ์ดํ„ฐ๊ฐ€ Google Play ์Šคํ† ์–ด๋ฅผ ์ง€์›ํ•˜๋Š” ๊ฒฝ์šฐ android emulator์—์„œ ์ž‘๋™ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  31 ๋Œ“๊ธ€

๋‹น์‹ ์€ ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค real device ์˜ ํ…Œ์ŠคํŠธ์— ios ์— ๋Œ€ํ•ด getProducts / getSubscription ์—์„œ๊ฐ€ ์•„๋‹ˆ๋ผ android . android ๊ตฌ๋งคํ•˜๋ ค๋ฉด ์‹ค์ œ ๊ธฐ๊ธฐ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

Google์˜ ๊ฒฝ์šฐ ๋‚ด ๊ฐ€์ด๋“œ ๋ฅผ ๊ฒ€ํ† ํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์‹ญ์‹œ์˜ค.
์‹ค์ œ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด ์•ฑ์„ playstore์— ๊ฒŒ์‹œ ํ•  ํ•„์š”๋Š” ์—†์ง€๋งŒ ์„œ๋ช… ๋œ APK๋ฅผ ์—…๋กœ๋“œํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋˜ํ•œ์ด ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š”๋ฐ, ์ด๋ฏธ ์• ํ”Œ์—์„œ ์ œํ’ˆ์„ ๋งŒ๋“ค์—ˆ๊ณ  ์•ก์„ธ์Šค ํ•  ์ˆ˜์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

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

RNIap.getProducts(itemSkus).then((products) => {
      console.log(products);  //<< returns empty array
}).catch((error) => console.log(error))

์ œํ’ˆ์ด ๊ท€ํ•˜์˜ ๊ฒฝํ—˜์— ๋ฐ˜์˜๋˜๋Š” ๋ฐ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๋‚˜์š”?

๊ณ„์•ฝ, ์„ธ๊ธˆ ๋ฐ ์€ํ–‰ ์—…๋ฌด๊ฐ€ ๋ชจ๋‘ ํ™œ์„ฑํ™” ๋จ
"react-native-iap": "^ 3.4.0",
์ธ์•ฑ์€ ์ด๋ฏธ "์ œ์ถœ ์ค€๋น„ ์™„๋ฃŒ"์ƒํƒœ์ž…๋‹ˆ๋‹ค.

@nateblog ์–ด๋–ค ์ข…๋ฅ˜์˜ ์ œํ’ˆ์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๊นŒ? ๊ตฌ๋…์ด๋‚˜ ๋‹ค๋ฅธ ๊ฒƒ?

๋˜ํ•œ ์ œํ’ˆ / ๊ตฌ๋…์— ๋Œ€ํ•ด App Store Connect์— ํ˜„์ง€ํ™”๋ฅผ ์ถ”๊ฐ€ ํ–ˆ์Šต๋‹ˆ๊นŒ? ๊ทธ๋ ‡๋‹ค๋ฉด ์žฅ์น˜ ๋˜๋Š” ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ์—์„œ ํ™œ์„ฑํ™” ํ•œ ํ˜„์ง€ํ™”๋ฅผ ์ถ”๊ฐ€ํ•ด๋ณด์‹ญ์‹œ์˜ค. ์ด์ „์— ๋ช‡ ๊ฐ€์ง€ ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ๋˜ ๊ฒƒ์„ ๊ธฐ์–ตํ•ฉ๋‹ˆ๋‹ค. ๋‚ด ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ ๋ฐ ์žฅ์น˜ ๋กœ์ผ€์ผ์ด ์˜์–ด๋กœ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ๊ตฌ๋…์— ๋Œ€ํ•ด "์˜์–ด (๋ฏธ๊ตญ)"ํ˜„์ง€ํ™” ๋งŒ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

@jvandenaardweg- ์‘๋‹ต ํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ํ˜„์ง€ํ™”๋ฅผ ๊ฑด๋„ˆ ๋›ฐ๋ฉด ์ธ์•ฑ ์ƒํƒœ๊ฐ€ "์ œ์ถœ ์ค€๋น„ ์™„๋ฃŒ"๋กœ ์„ค์ •๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฏธ ํ˜„์ง€ํ™”๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ค‘์ธ ๊ธฐ๊ธฐ๊ฐ€ ์˜์–ด๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๊ณ  ์ œํ’ˆ์ด ๊ตฌ๋…์ด๋ฏ€๋กœ ํ˜„์ง€ํ™”๋ฅผ "์˜์–ด (๋ฏธ๊ตญ)"๋กœ ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ตœ์‹  ์ •๋ณด

์ด๋ฏธ ๊ธฐ๋Šฅ์—์„œ ์ธ์•ฑ์„ ํ™œ์„ฑํ™”ํ•˜๊ณ  ํŒจํ‚ค์ง€๋ฅผ 2.4.0์œผ๋กœ ๋‹ค์šด ๊ทธ๋ ˆ์ด๋“œํ–ˆ์ง€๋งŒ ์—ฌ์ „ํžˆ ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ์–ป์—ˆ๋Š”์ง€ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค. . ์ œํ’ˆ์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์—†์œผ๋ฉฐ ๋นˆ ๋ฐฐ์—ด ๋งŒ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ ๋‹ค๋ฅธ ๊ฒŒ์‹œ๋ฌผ์ด ๋ฐ˜์‘ ๋„ค์ดํ‹ฐ๋ธŒ ๋งํฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ๋ง๋ผ๊ณ  ์ œ์•ˆํ–ˆ์ง€๋งŒ ์—ฌ์ „ํžˆ ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ์ œ์•ˆํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ํŒจํ‚ค์ง€๋ฅผ ์ˆ˜๋™์œผ๋กœ ์—ฐ๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค. ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ์™€ ์‹ค์ œ ์žฅ์น˜๋ฅผ ๋ชจ๋‘ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ์ด์ œ ์ •๋ฆฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๋Š” xcode์˜ ๋ฒˆ๋“ค ID์˜€์Šต๋‹ˆ๋‹ค. ์ž˜๋ชป๋œ ๋ฒˆ๋“ค ID๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ๋ชจ๋‘ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

์ €๋„ ๋น„์Šทํ–ˆ๊ณ  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์—ฐ๊ฒฐ ๊ณผ์ •์„ ์ˆ˜๋™์œผ๋กœํ•ด์•ผํ–ˆ์Šต๋‹ˆ๋‹ค. (ios)

๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  Itunes Connect์—์„œ ์ œํ’ˆ์„๋กœ๋“œํ•˜์ง€ ์•Š๊ณ  ์–ด๋””์„œ ๋ฌธ์ œ๋ฅผ ์ฐพ์•„์•ผํ• ์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ์•ฑ์ด ์ด์ „ ๋ฒ„์ „์˜ RN : 0.43.4๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. RN-IAP ๋ฒ„์ „ 3.3.7 ๋ฐ 2.5.5๋ฅผ ์‚ฌ์šฉํ•ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์ด์ „ ๋ฒ„์ „์˜ React-Native๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด์ „ ๋ฒ„์ „์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•ฉ๋‹ˆ๊นŒ?

์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๊ฐ€์—†๊ณ  ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์–ด์„œ ํ•ด๊ฒฐํ•˜๊ธฐ ์–ด๋ ค์šด ๋ฌธ์ œ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ์ด์ œ ์ •๋ฆฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๋Š” xcode์˜ ๋ฒˆ๋“ค ID์˜€์Šต๋‹ˆ๋‹ค. ์ž˜๋ชป๋œ ๋ฒˆ๋“ค ID๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ๋ชจ๋‘ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š”, @nateblog! ๋น„์Šทํ•œ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ œํ’ˆ ๋ฐ ๊ตฌ๋…์— ๋Œ€ํ•œ ๋นˆ ๋ฐฐ์—ด์ด ํ‘œ์‹œ๋˜๊ณ  App Store Connect ๋‚ด์— 2 ๊ฐœ์˜ ๊ตฌ๋… ํ•ญ๋ชฉ์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ๋ฒˆ๋“ค ID์— ์–ด๋–ค ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ๋Š”์ง€ ์ž์„ธํžˆ ์„ค๋ช…ํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ์˜ฌ๋ฐ”๋ฅธ ์ƒํ’ˆ SKU๋ฅผ ์ œ์ถœ ํ•œ ๊ฒƒ ๊ฐ™์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์–ด๋–ป๊ฒŒ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋Š”์ง€ ๋˜๋Š” ๋ฌด์—‡์ธ์ง€์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— [Bundle Identifier]. [๊ตฌ๋งค ํ•ญ๋ชฉ์˜ ProductId] ๋˜๋Š” [ProductId]๋ฟ์ž…๋‹ˆ๋‹ค. ๊ตฌ๋งค ํ•ญ๋ชฉ]?

๋˜ํ•œ ๋ฆด๋ฆฌ์Šค ๋ฐ ๋””๋ฒ„๊ทธ ์ฒด๊ณ„์— ๋Œ€ํ•ด ์•ฝ๊ฐ„ ๋‹ค๋ฅธ ๋ฒˆ๋“ค ์‹๋ณ„์ž๊ฐ€ ์žˆ์Œ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

  • ์ถœ์‹œ- 'domain.appName';
  • ๋””๋ฒ„๊ทธ- 'domain.appName.dev';
    ๋‚ด๊ฐ€ ๋งŒ๋“  ์ธ์•ฑ ๊ตฌ๋งค ํ•ญ๋ชฉ์€ ์•ฑ์˜ ํ”„๋กœ๋•์…˜ (์ฆ‰ ์ถœ์‹œ) ๋ฒ„์ „๊ณผ ๊ด€๋ จ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์•ฑ์˜ ๊ฐœ๋ฐœ์ž ๋ฒ„์ „์—์„œ ํ•ด๋‹น ํ•ญ๋ชฉ์— ์•ก์„ธ์Šค ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๊นŒ?

์–ด๋–ค ์กฐ์–ธ์ด๋ผ๋„ ๋Œ€๋‹จํžˆ ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ €๋„ ๋น„์Šทํ–ˆ๊ณ  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์—ฐ๊ฒฐ ๊ณผ์ •์„ ์ˆ˜๋™์œผ๋กœํ•ด์•ผํ–ˆ์Šต๋‹ˆ๋‹ค. (ios)

๋‹น์‹ ์€ ๋‚ด ํ•˜๋ฃจ๋ฅผ ๊ตฌํ–ˆ์Šต๋‹ˆ๋‹ค!

react-native-iap์„ ํ†ตํ•ฉํ•˜๊ณ  ์„œ๋ช… ๋œ APK๋ฅผ Play ์Šคํ† ์–ด์˜ ๋ฒ ํƒ€ ๋ฆด๋ฆฌ์Šค์— ์—…๋กœ๋“œํ•˜๊ณ  ํ•˜๋‚˜์˜ ๊ตฌ๋… ํ”Œ๋žœ๋„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•ญ์ƒ ๋นˆ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋””๋ฒ„๊ทธ ๋ชจ๋“œ์—์„œ ๊ตฌ๋… ID๋กœ ๊ตฌ๋… ๋ชฉ๋ก์„ ๊ฐ€์ ธ ์˜ค๋ ค๊ณ ํ•ฉ๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ๋””๋ฒ„๊ทธ ๋ชจ๋“œ์—์„œ ๊ตฌ๋…์„ ํ…Œ์ŠคํŠธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

@ShridharCodewave ๋‚˜๋Š” ๊ฐ™์€ ๋ฌธ์ œ์— ์ง๋ฉดํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ๋ ค์ฃผ์‹ญ์‹œ์˜ค.

๋ฐ˜์‘ ๋„ค์ดํ‹ฐ๋ธŒ IAP : 3.3.2

Android Emulator์—์„œ ๋™์ผํ•œ ๋ฌธ์ œ์— ์ง๋ฉดํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฒ ํƒ€ ์ฑ„๋„์— Google Play ์Šคํ† ์–ด์— APK๋ฅผ ์—…๋กœ๋“œํ•˜๊ณ  ์ œํ’ˆ์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

image

๋จผ์ € ์—ฐ๊ฒฐ ์ดˆ๊ธฐํ™” ํ›„ ์ œํ’ˆ์„ ๊ฐ€์ ธ ์˜ค๋ ค๊ณ ํ•˜์ง€๋งŒ ์ฝ˜์†”์— ์•„๋ฌด๊ฒƒ๋„ ํ‘œ์‹œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
์—ฌ๊ธฐ์— ๊ฒฐ๊ณผ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
์—ฌ๊ธฐ์— ์˜ค๋ฅ˜ ์—†์Œ

@ismetsezer Android ์šฉ ์ธ์•ฑ ๊ฒฐ์ œ ์ „์ฒด๊ฐ€ ์—๋ฎฌ๋ ˆ์ดํ„ฐ์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์—๋ฎฌ๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Google Play ๊ฒฐ์ œ๋ฅผ ํ…Œ์ŠคํŠธ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. Google Play ๊ฒฐ์ œ๋ฅผ ํ…Œ์ŠคํŠธํ•˜๋ ค๋ฉด ๊ธฐ๊ธฐ์— ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์„ค์น˜ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.
https://developer.android.com/google/play/billing/billing_testing

์ด๋ฅผ ์œ„ํ•ด์„œ๋Š” ์‹ค์ œ ์žฅ์น˜๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

iOS์—์„œ๋Š” ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ์—์„œ ๊ตฌ๋… ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์‹ค์ œ ์žฅ์น˜๊ฐ€ ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ตฌ์ž…ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์œ„์˜ ๋‹ค๋ฅธ ์ฝ”๋ฉ˜ํŠธ : ๋˜ํ•œ ์ง€ ํ™•์ธํ•˜์„ธ์š” versionName ๋ฐ versionCode ์—์„œ android/app/build.gradle Google Play ์ฝ˜์†”์— ์—…๋กœ๋“œ ํ•œ ๊ฒƒ๊ณผ ๋™์ผํ•˜๊ฑฐ๋‚˜ ๋” ๋†’๋‹ค.

๋˜ํ•œ Android์˜ ์ƒˆ๋กœ์šด ๊ฒ€ํ†  ์ •์ฑ…์œผ๋กœ ์ธํ•ด ๋น„ ํ”„๋กœ๋•์…˜ ํŠธ๋ž™์— ํ™œ์„ฑ ๊ฒ€ํ†  ๋œ ์•ฑ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์ด์ „์—๋Š” ๊ฒŒ์‹œ๋˜์ง€ ์•Š์€ "์ดˆ์•ˆ"๋ฒ„์ „์„ ์—…๋กœ๋“œํ•˜์—ฌ ์•ฑ์„ ํ…Œ์ŠคํŠธ ํ•  ์ˆ˜์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์€ ๋” ์ด์ƒ ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  ๋น„๊ณต๊ฐœ ๋˜๋Š” ๊ณต๊ฐœ ํ…Œ์ŠคํŠธ ํŠธ๋ž™์— ์•ฑ์„ ๊ฒŒ์‹œํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์ดˆ์•ˆ ์•ฑ์ด ๋” ์ด์ƒ ์ง€์›๋˜์ง€ ์•Š์Œ์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.
https://developer.android.com/google/play/billing/billing_testing

๋น„๊ณต๊ฐœ / ๊ณต๊ฐœ ํ…Œ์ŠคํŠธ ํŠธ๋ž™์˜ '๊ฒŒ์‹œ'๋Š” Google Play์˜ ์ƒˆ๋กœ์šด ๊ฒ€ํ†  ํ”„๋กœ์„ธ์Šค๋ฅผ ๊ฑฐ์ณ์•ผ ํ•จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ƒˆ ์•ฑ์˜ ๊ฒฝ์šฐ ๋ฉฐ์น , ๊ธฐ์กด ์•ฑ์˜ ๊ฒฝ์šฐ ๋ช‡ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ํ•œ ์ •ํ™•ํ•œ ๋‹จ๊ณ„๋Š” ๋ชจ๋ฅด์ง€๋งŒ Android ๊ธฐ๊ธฐ์—์„œ ๋กœ์ปฌ๋กœ ์ž‘์—…ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์•„๋งˆ๋„ react-native-iap ํŒจํ‚ค์ง€ ๋ฌธ์ œ๊ฐ€ ์•„๋‹ˆ๋ผ ๊ตฌ์„ฑ ๋ฌธ์ œ ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ˆ„๊ตฐ๊ฐ€ ์œ„์˜ ๋‚ด์šฉ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด์ด ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋Œ€ํ•œ README๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ง€๋‚œ๋‹ฌ๋ถ€ํ„ฐ ์ƒˆ๋กœ์šด ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์‹ค์ œ ์žฅ์น˜๋กœ ์ „ํ™˜ํ–ˆ์„ ๋•Œ @jvandenaardweg ์—๊ฒŒ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ์˜ˆ ์ž‘๋™ํ•˜๊ณ  ์—ฐ๊ฒฐ์ด ์„ฑ๊ณตํ–ˆ์ง€๋งŒ

@ismetsezer ๋ฅผ ๋“ฃ๊ณ 

๋ฌผ๋ก . Google Play ์Šคํ† ์–ด์—์„œ ๊ฒŒ์‹œ ํ•œ ํ›„ ์—ฌ๊ธฐ์—์„œ ํ™•์ธํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ตœ์‹  ์ •๋ณด

๋‚ด ์•ฑ์ด Google Play ์Šคํ† ์–ด์— ๊ฒŒ์‹œ ๋œ ํ›„ ๊ตฌ๋งค๊ฐ€ ์ด๋ฃจ์–ด์ง€๊ณ  ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค. ์Šน์ธํ•˜๋Š” ๋ฐ 3 ์ผ์ด ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค. @jvandenaardweg ๋•๋ถ„์—

์—…๋ฐ์ดํŠธ 2

react-native-iap๋Š” ์—๋ฎฌ๋ ˆ์ดํ„ฐ๊ฐ€ Google Play ์Šคํ† ์–ด๋ฅผ ์ง€์›ํ•˜๋Š” ๊ฒฝ์šฐ android emulator์—์„œ ์ž‘๋™ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@kesepara Play ์Šคํ† ์–ด์— ์ƒˆ ๊ตฌ๋… ์š”๊ธˆ์ œ๋ฅผ ์ถ”๊ฐ€ ํ•œ ํ›„ ๊ธฐ๊ธฐ์— ํ‘œ์‹œ ๋˜๋ ค๋ฉด ๋ช‡ ์‹œ๊ฐ„์„ ๊ธฐ๋‹ค๋ ค์•ผํ–ˆ์Šต๋‹ˆ๋‹ค.

@ismetsezer ๋ฐ @kesepara ์•ˆ๋…•ํ•˜์„ธ์š”.
์•„์ง ๋ช…ํ™•ํ•˜์ง€ ์•Š์€ ๊ฒƒ์ด ์žˆ์œผ๋ฏ€๋กœ ๊ฐœ๋ฐœ ํ๋ฆ„์— ๋Œ€ํ•œ ๊ท€ํ•˜์˜ ์˜๊ฒฌ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.
iOS ์šฉ RN IAP๋ฅผ ์„ค์ •ํ–ˆ์œผ๋ฉฐ ์ด์ œ ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
์ง€๊ธˆ์€ ์•ˆ๋“œ๋กœ์ด๋“œ ๋ถ€๋ถ„์„ ์‹œ์ž‘ ํ–ˆ์–ด, ๋‚ด๊ฐ€ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค ์—ฌ๊ธฐ์— ์šฐ๋ฆฌ๊ฐ€ ์„œ๋ช… ํ•œ APK ํ…Œ์ŠคํŠธ ์ง€๋ถˆ ๊ธฐ๋Šฅ์„ ํ•  ์ˆ˜ ์žˆ๋„๋ก (์ ์–ด๋„) ๋‹ซํžŒ ๊ถค๋„์— ์—…๋กœ๋“œ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€์žˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ๊ท€ํ•˜์˜ ์˜๊ฒฌ์—์„œ Android ์—๋ฎฌ๋ ˆ์ดํ„ฐ์—์„œ ํ…Œ์ŠคํŠธ ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค๊ณ  ๋ง์”€ํ•˜์…จ์Šต๋‹ˆ๋‹ค. ๋งž์Šต๋‹ˆ๊นŒ?
๋˜ํ•œ ์Šคํ† ์–ด์—์„œ ์„œ๋ช… ๋œ APK๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ ์–ด๋–ป๊ฒŒ ๋””๋ฒ„๊น… ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?
๊ท€ํ•˜์˜ ๋„์›€์€ ๋Œ€๋‹จํžˆ ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š” @beeremy ๊ท€ํ•˜์˜ ์ข‹์€ ์˜๊ฒฌ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ์ œํ’ˆ์„ ๊ฐ€์ ธ ์˜ค๋ ค๋ฉด Google Play๋ฅผ ์ง€์›ํ•˜๋Š” ์‹ค์ œ ์žฅ์น˜ ๋˜๋Š” ์—๋ฎฌ๋ ˆ์ดํ„ฐ์—์„œ iap์„ ํ…Œ์ŠคํŠธํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. IAP๋Š” Google Play ์Šคํ† ์–ด์— ์•ฑ์„ ๊ฒŒ์‹œ ํ•œ ํ›„ ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ณ€๊ฒฝ ๋  ์ˆ˜ ์žˆ์ง€๋งŒ ์ ์–ด๋„์ด ๊ธฐ๋Šฅ์„ ํ…Œ์ŠคํŠธํ•˜๋ ค๋ฉด ์Šคํ† ์–ด์— ์ดˆ์•ˆ์„ ์—…๋กœ๋“œํ•˜๊ฑฐ๋‚˜ ์ œ๊ณตํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ผํ•˜๋Š” ๋ฐ 2 โ€‹โ€‹~ 3 ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š” @ismetsezer , ํ”ผ๋“œ๋ฐฑ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

์œ ์šฉ ํ•  ์ˆ˜์žˆ๋Š” ์‚ฌ๋žŒ์„ ์œ„ํ•ด https://stackoverflow.com/questions/36113347/is-it-possible-to-debug-locally-google-plays๋ฅผ ๋”ฐ๋ฅธ ํ›„ ๋””๋ฒ„๊ทธ ๊ตฌ์„ฑ์„ ์‹คํ–‰ํ•  ์ˆ˜์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

@ismetsezer ๋กœ ๊ตฌ๊ธ€ ํ”Œ๋ ˆ์ด ์ฝ˜์†”์— ์•ฑ์ด ๊ฒŒ์‹œ ๋œ ํ›„ ์•ˆ๋“œ๋กœ์ด๋“œ์—์„œ ๊ตฌ๋… ๋ฐ ์ œํ’ˆ์ด ์ž‘๋™ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•ฑ์ด ์•„์ง ๊ฒŒ์‹œ๋˜์ง€ ์•Š์€ ์ƒํƒœ์—์„œ ๊ตฌ๋… / ์ œํ’ˆ์„ ๋ฐ›์œผ๋ ค๋Š” ์‹œ๋„๋Š” Android์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

iOS์—์„œ ๊ตฌ๋… ๋ฐ ์ œํ’ˆ์€ ์•ฑ์„ ๊ฒŒ์‹œํ•˜์ง€ ์•Š๊ณ ๋„ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š”. ์ตœ๊ทผ์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ™œ๋™์ด์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ ๋˜์—ˆ์Šต๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด ์—ฌ์ „ํžˆ ์ปค๋ฎค๋‹ˆํ‹ฐ์˜์ฃผ์˜๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๊นŒ? ์ด ๋ฌธ์ œ๋Š” ๋” ์ด์ƒ ํ™œ๋™์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š์œผ๋ฉด ์ข…๊ฒฐ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ "ํ† ๋ก  ์šฉ"๋˜๋Š” "์ข‹์€ ์ฒซ ๋ฒˆ์งธ ๋ฌธ์ œ"๋กœ ํ‘œ์‹œ ํ•  ์ˆ˜๋„ ์žˆ์œผ๋ฉฐ ์—ด์–ด ๋‘๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ท€ํ•˜์˜ ๊ธฐ์—ฌ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ Android dev์˜ RN 0.59.1์ด๊ณ  iap ๋ฒ„์ „ 4.4.1์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚ด ๋นŒ๋“œ๋Š” ํ˜„์žฌ ์•ŒํŒŒ ํŠธ๋ž™์— ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ํ›„ , ๋””๋ฒ„๊ทธ ๋ชจ๋“œ๋กœ ๋‚ด ์ปดํ“จํ„ฐ์—์„œ ํ‰์†Œ์™€ ๊ฐ™์ด ๋‹ค์‹œ ๋นŒ๋“œํ–ˆ์Šต๋‹ˆ๋‹ค. Platform.select ({}) ๋‚ด์—์„œ Play Console์—์žˆ๋Š” ๊ตฌ๋… ID๋ฅผ ์ง€์ •ํ•˜๊ณ  getSubscriptions ()๋ฅผ ํ˜ธ์ถœํ–ˆ์ง€๋งŒ ๋นˆ ๋ฐฐ์—ด์ด ์ˆ˜์‹ ๋ฉ๋‹ˆ๋‹ค. ์•ŒํŒŒ์ด๊ธฐ ๋•Œ๋ฌธ์ธ๊ฐ€์š”? ์–ด๋–ค ์•„์ด๋””์–ด?

@edgaralienfoe Google Play Console์—์„œ ๊ตฌ๋…์„ ํ™œ์„ฑํ™”ํ•˜์…จ์Šต๋‹ˆ๊นŒ?

@acostalima ํ™œ์„ฑํ™”ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒํ•˜๋Š” ๋ฐ ๋ฉฐ์น ์ด ๊ฑธ๋ฆด ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์ง€๋งŒ ์—ฌ์ „ํžˆ ์šด์ด ์—†์Šต๋‹ˆ๋‹ค.

@edgaralienfoe Google Play Console์—์„œ ๊ตฌ๋…์„ ๋ช…์‹œ ์ ์œผ๋กœ ํ™œ์„ฑํ™”ํ•˜๋Š” ์˜ต์…˜์ด ์žˆ์œผ๋ฉฐ ํ™œ์„ฑํ™”๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ๊ตฌ๋…์ด ์•ฑ์— ํ‘œ์‹œ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๋ ‡๊ฒŒ ๋งํ•˜๋ฉด ๋‹ค๋ฅธ ๋ฌธ์ œ๊ฐ€์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@edgaralienfoe ํ•ด๊ฒฐ์ฑ…์„ ์ฐพ์•˜์Šต๋‹ˆ๊นŒ? ์•ฑ ๋ฒ„์ „์ด Alpha ํŠธ๋ž™์˜ ๋ฒ„์ „๋ณด๋‹ค ๋†’์•„์•ผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@edgaralienfoe ํ•ด๊ฒฐ์ฑ…์„ ์ฐพ์•˜์Šต๋‹ˆ๊นŒ? ์•ฑ ๋ฒ„์ „์ด Alpha ํŠธ๋ž™์˜ ๋ฒ„์ „๋ณด๋‹ค ๋†’์•„์•ผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•ŒํŒŒ ํŠธ๋ž™์€ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์ €๋Š” ๋ฌธ์ œ์—†์ด Alpha์— ๋ฐฐํฌ ๋œ ๋นŒ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฝค ์˜ค๋žซ๋™์•ˆ IAP๋ฅผ ํ…Œ์ŠคํŠธ ํ•ด ์™”์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด ๋‚ด๋ถ€ ํŠธ๋ž™์€ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜์žˆ๋Š” ๋ชจ๋“  ์‚ฌ๋žŒ๋“ค์„ ์œ„ํ•ด iOS์—์„œ ํŠธ๋ฆญ์€ @ Kuhne1์ด ์ œ์•ˆํ•œ๋Œ€๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ ์ˆ˜๋™์œผ๋กœ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒƒ์ด ์—ˆ์Šต๋‹ˆ๋‹ค. ๋นŒ๋“œ ํด๋”๋ฅผ ์ •๋ฆฌํ•˜๊ณ  Pod๋ฅผ ์ˆ˜๋™์œผ๋กœ ์„ค์น˜ ํ•œ ํ›„์—๋„ ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ˆ„๊ตฌ์—๊ฒŒ๋‚˜ ์œ ์šฉํ•˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค!

์•ˆ๋…•ํ•˜์„ธ์š”. ์ตœ๊ทผ์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ™œ๋™์ด์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ ๋˜์—ˆ์Šต๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด ์—ฌ์ „ํžˆ ์ปค๋ฎค๋‹ˆํ‹ฐ์˜์ฃผ์˜๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๊นŒ? ์ด ๋ฌธ์ œ๋Š” ๋” ์ด์ƒ ํ™œ๋™์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š์œผ๋ฉด ์ข…๊ฒฐ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ "ํ† ๋ก  ์šฉ"๋˜๋Š” "์ข‹์€ ์ฒซ ๋ฒˆ์งธ ๋ฌธ์ œ"๋กœ ํ‘œ์‹œ ํ•  ์ˆ˜๋„ ์žˆ์œผ๋ฉฐ ์—ด์–ด ๋‘๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ท€ํ•˜์˜ ๊ธฐ์—ฌ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

์žฅ๊ธฐ๊ฐ„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด์ด ๋ฌธ์ œ๋ฅผ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๊ฐ€ ์ตœ์‹  ๋ฆด๋ฆฌ์Šค์— ์—ฌ์ „ํžˆ ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ ์ตœ์‹  ์ •๋ณด๋กœ ์ƒˆ ๋ฌธ์ œ๋ฅผ ์ž์œ ๋กญ๊ฒŒ ์ž‘์„ฑํ•˜์‹ญ์‹œ์˜ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰