关于react-native:在React-Native应用中实现Android内购功能
<article class=“article fmt article-content”><blockquote>首发于公众号 <strong>前端混合开发</strong>,欢送关注。</blockquote><p>编者注:本文于2023年9月21日更新,移除了对现已弃用的 expo-in-app-purchases 库的提及。当初建议您应用 react-native-iap 或 react-native-purchases ,咱们在本文中都有探讨。</p><p>利用内购买(IAP)曾经扭转了挪动利用的盈利形式。它不仅为开发者和企业解锁了新的支出起源,还使开发者可能为用户发明更具吸引力和沉迷感的体验。</p><p>有许多基于 Google Play 计费库和苹果的 StoreKit 框架构建的 React Native IAP(利用内购买)包,能够让你轻松地将利用内购买集成到你的利用中。然而,咱们将通过一系列步骤来探讨如何将 react-native-iap 集成到你的 React Native 利用中,这波及构建一个简略的食谱应用程序;在这里找到 GitHub。</p><h2>概述:利用内购买</h2><p>利用内购买是用户能够间接在你的利用内购买的额定内容、性能、订阅或服务。换句话说,它是一种利用货币化模型,容许咱们收费或以较低成本提供你的应用程序,给予用户无需事后财务承诺就能应用利用的机会,并通过进行利用内购买解锁额定性能或内容的选项。</p><p>利用内购买是通过连贯到利用商店计费零碎的领取网关来实现的。计费和交易过程齐全由利用商店治理,使用户可能平安地进行交易。</p><p>IAP 提供了极大的灵活性。无论你是在开发电子商务平台、生产力利用还是媒体平台,都能够利用 IAP 来开释你利用的全副货币化后劲。一些常见的利用内购买示例包含:</p><ul><li>虚构产品:如虚构货币、扩大包、游戏晋升等虚构物品,用于加强用户体验</li><li>锁定性能:利用可能有一个收费的根底版本供普通用户应用,以及一个付费的业余版本,该版本提供了只能通过利用内购买解锁的额定性能,以吸引寻求更残缺体验的用户</li><li>订阅:为了定期取得对独家内容或服务的拜访权而收取的周期性费用,即费用是每月的,到了结算周期的开端,订阅费用会主动收取,以持续取得对产品或服务的拜访权。</li></ul><p>此外,IAP容许你依据各种条件(如购买历史)为选定的用户群体创立个性化的优惠,以最大化收益,并为你的用户提供更相干的体验。</p><h2>IAP 的类型</h2><p>在设置IAP之前,你应该了解有三大类的利用内购买:</p><ul><li>消耗品:这种类型的利用内购买是为一次性应用而设计的。因而,用户能够在物品用完后再次购买——例如,虚构货币、助推器和虚构礼物。</li><li>非消耗品:这些是只须要购买一次并且永恒关联到用户账户的物品 - 例如,广告移除,处分章节和自定义设置</li><li>订阅:如前所述,这种利用内购买形式容许用户定期领取反复费用,以获取高级性能或独家内容的拜访权限</li></ul><h2>对于咱们的食谱应用程序</h2><p>要顺利追随本文进行,你应该具备以下条件:</p><ul><li>React Native的常识</li><li>一个谷歌开发者账户</li><li>在你的开发机器上设置React Native环境</li><li>一个安卓设施</li></ul><p>为了演示如何将利用内购买集成到React Native利用中,咱们将开发一个食谱利用,该利用为收费用户显示无限的食谱列表,并提供利用内购买选项,通过高级订阅解锁所有食谱。</p><p>该应用程序由三个屏幕组成:</p><ul><li>首页:显示食谱列表,并蕴含一个按钮,该按钮会疏导用户到付费墙屏幕,在那里用户能够购买高级订阅</li><li>菜谱详情:这个界面展现了菜谱的具体概览,包含所需的食材和制作步骤</li><li>付费墙:这显示了用户能够购买的可用内购产品</li></ul><p>应用程序的初始我的项目在GitHub上可用。咱们将在其根底上开发应用程序内购买局部,这将贯通文章的其余部分。</p><p>运行以下命令来克隆启动我的项目:</p><pre><code>git clone -b start https://github.com/emmanuelhashy/RecipeApp.git –single-branch</code></pre><h2>创立咱们的IAP产品</h2><p>要将IAP集成到你的应用程序中,你首先须要在各自的商店中设置产品。这些商店作为一个核心,用于配置和治理在你的应用程序中向用户展现的产品。</p><p>在这个例子中,咱们将介绍如何在Google Play控制台为Android设施设置产品的步骤。为了在开发过程中无缝测试利用内购买,你须要将你的利用公布到内部测试轨道。</p><p>在Google Play控制台中,设置一个商户账户以在您的利用中承受付款。之后,在“All apps”页面的已公布利用列表中抉择您的利用。</p><p></p><p>在应用程序仪表板中,滚动到侧边栏的 <strong>创收</strong> 局部并抉择 <strong>商品</strong> 下拉按钮。能够依据您的IAP产品类型抉择 <strong>利用内产品</strong> 或 <strong>订阅</strong> 。在这个例子中,咱们将抉择“利用内产品”。</p><p></p><p>当初,在利用内产品页面上,点击创立产品按钮以创立新产品:</p><p></p><p>提供产品所需的属性,包含产品 ID、名称、形容和价格。之后,点击“保留”,而后点击“激活”以使产品可供购买。你会想复制产品的 ID,因为咱们稍后会在利用中应用它:</p><p></p><p>你当初应该能在产品概览页面看到你的产品。你能够在此页面创立尽可能多的产品。</p><h2>增加许可证测试员</h2><p>许可证测试员是一个账户,容许你在受控环境中与利用内购买进行交互。在开发过程中,你能够应用许可证测试员来测试和验证你的利用内购买是否失常工作,而无需进行理论领取。</p><p>在你的 Google Play 控制台中,导航至许可证测试页面,能够通过在搜寻栏中搜寻,或者从主控制台的仪表板侧边栏抉择许可证测试:</p><p></p><p>而后,点击“创立电子邮件列表”按钮,并为列表提供一个名称和测试账户的电子邮件地址。点击“保留更改”。</p><p></p><p>接下来,在应用程序仪表板的内部测试局部,点击测试人员选项卡,并增加您的测试人员列表:</p><p></p><p>抉择你之前创立的列表,而后点击保留:</p><p></p><p>接下来,点击页面底部的“复制链接”按钮,以复制给你的测试人员的邀请URL:</p><p></p><p>最初,在带有测试账户的设施上关上URL以承受邀请。</p><h2>装置 react-native-iap</h2><p>react-native-iap 库容许你在你的 React Native 利用中无缝实现利用内购买。它是围绕 Google Play 计费库和苹果 StoreKit 框架的封装。此外,通过这个库,你还能够集成来自亚马逊利用商店的 IAP 我的项目。</p><p>首先,在终端中运行以下命令来应用npm安装包:</p><pre><code>npm install react-native-iap</code></pre><p>装置后,须要进行一些额定的配置以实现包的设置。请返回 <code>android/build.gradle</code> ,并在 <code>buildscript.ext</code> 块中增加以下属性:</p><pre><code>androidXAnnotation = “1.1.0"androidXBrowser = “1.0.0"minSdkVersion = 24kotlinVersion = “1.6.0”</code></pre><p>而后,在依赖项块上面增加以下内容:</p><pre><code>classpath “org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion”</code></pre><p><code>react-native-iap</code> 容许你整合来自Google Play商店和Amazon Appstore的IAP产品。要启用Play商店的领取性能,请导航至 <code>android/app/build.gradle</code> ,而后在 <code>defaultConfig</code> 块下增加以下内容:</p><pre><code>missingDimensionStrategy “store”, “play”</code></pre><p>或者,你能够通过在Android块中增加以下属性来启用两个商店的领取性能:</p><pre><code> flavorDimensions “appstore” productFlavors { googlePlay { dimension “appstore” missingDimensionStrategy “store”, “play” } amazon { dimension “appstore” missingDimensionStrategy “store”, “amazon” } }</code></pre><h2>初始化连贯</h2><p><code>react-native-iap</code> 库的原生模块须要在应用程序生命周期的晚期进行初始化,即在进行任何与IAP相干的函数调用之前。这能够在应用程序的根组件中实现。</p><p>为了实现这个,将以下代码增加到你的 App 组件中:</p><pre><code>useEffect(() => { const init = async () => { try { await initConnection(); if (Platform.OS === ‘android’) { flushFailedPurchasesCachedAsPendingAndroid(); } } catch (error) { console.error(‘Error occurred during initilization’, error.message); } } init(); return () => { endConnection(); }}, [])</code></pre><p>在上述代码中,调用了 <code>initConnection</code> 函数来初始化包的原生模块。</p><p>另外,在文件中蕴含以下导入:</p><pre><code>import React, { useEffect } from ‘react’;import { Platform } from ‘react-native’;import { initConnection, endConnection, flushFailedPurchasesCachedAsPendingAndroid,} from ‘react-native-iap’;</code></pre><h2>定义产品SKU</h2><p>产品ID是集成利用内购买的要害组成部分。每一个都能惟一地标识一个可购买的产品。因为咱们的利用内购买产品的ID将在利用的不同中央应用,咱们须要在一个核心地位定义它。</p><p>在 <code>src/utils</code> 下创立一个名为 <code>constants.js</code> 的新文件,并增加以下代码:</p><pre><code>import { Platform } from “react-native"const productSkus = Platform.select({ android: [ ‘recipe_app_premium’ ]})export const constants = { productSkus};</code></pre><p>在这里,咱们定义了一个常量 <code>productSkus</code> ,借助 <code>Platform.select</code> 函数,正确地辨认出与设施操作系统对应的产品ID。咱们还提供了之前在 Google Play 控制台中创立的产品的产品ID。</p><h2>获取可用购买项</h2><p><code>react-native-iap</code> 提供了 <code>getAvailablePurchases</code> 性能,用于检查用户以后的购买状况。咱们能够应用这种办法来验证用户是否领有高级订阅,以解锁所有食谱的拜访权限。</p><p>关上 <code>src/screens/home.jsx</code> 并在 Home 组件中增加以下代码:</p><pre><code>useFocusEffect( useCallback(() => { setLoading(true); const getPurchase = async () => { try { const result = await getAvailablePurchases(); const hasPurchased = result.find((product) => product.productId === constants.productSkus[0]); setLoading(false); setPremiumUser(hasPurchased); } catch (error) { console.error(‘Error occurred while fetching purchases’, error); } } getPurchase(); }, []))</code></pre><p>在 <code>useFocusEffect</code> 钩子外部,咱们定义了一个 <code>getPurchase</code> 函数,该函数获取用户的可用购买并设置 <code>isPremiumUser</code> 状态为真,如果用户购买的产品的ID与咱们的高级产品的ID匹配。</p><p>另外,不要遗记蕴含以下的导入:</p><pre><code>import { getAvailablePurchases } from “react-native-iap”;import { constants } from “../utils/constants”;</code></pre><h2>增加内购产品</h2><p>目前,付费墙屏幕并未显示其前面的可用IAP产品。为了在这个屏幕上展现咱们的IAP产品,让咱们开始创立一个 ProductItem 组件来代表每一个IAP我的项目。</p><p>在 <code>src/components</code> 中创立一个名为 <code>productItem.js</code> 的文件。而后,增加以下代码:</p><pre><code>import React from “react”;import { View, StyleSheet, Text, Button } from “react-native”;const ProductItem = ({ title, onPress }) => { return ( <View style={styles.container}> <Text style={styles.title}>{title}</Text> <View style={styles.button}><Button title=‘Buy’ color=‘coral’ onPress={onPress}/></View> </View> )}export default ProductItem;</code></pre><p>该组件有两个属性 —— <code>title</code> ,是产品的名称,和 <code>onPress</code> ,一个启动购买的回调函数。</p><p>接下来,增加组件款式:</p><pre><code>const styles = StyleSheet.create({ container: { flexDirection: ‘row’, backgroundColor: ‘#fff’, height: 100, borderRadius: 10, elevation: 6, justifyContent: ‘space-between’, alignItems: ‘center’, padding: 10, marginTop: 30, marginHorizontal: 10 }, title: { color: ‘#000’, fontSize: 16, flex: 2.5, marginRight: 10 }, button: { flex: 1 }});</code></pre><p>而后,关上 src/screens/paywall.jsx 并在 Paywall 组件中增加以下内容:</p><pre><code>const [products, setProducts] = useState([]);const [isLoading, setLoading] = useState(true);useEffect(() => { const purchaseUpdateSubscription = purchaseUpdatedListener( async (purchase) => { const receipt = purchase.transactionReceipt; if (receipt) { try { await finishTransaction({ purchase, isConsumable: false }); } catch (error) { console.error(“An error occurred while completing transaction”, error); } notifySuccessfulPurchase(); } }); const purchaseErrorSubscription = purchaseErrorListener((error) => console.error(‘Purchase error’, error.message)); const fetchProducts = async () => { try { const result = await getProducts({ skus: constants.productSkus }); setProducts(result); setLoading(false); } catch (error) { Alert.alert(‘Error fetching products’) } } fetchProducts(); return () => { purchaseUpdateSubscription.remove(); purchaseErrorSubscription.remove(); } }, [])</code></pre><p>咱们合成下面的代码块是做什么的:</p><ul><li>首先,咱们定义两个状态 — <code>products</code> 和 <code>isLoading</code> — 用于存储IAP我的项目和正在获取的IAP我的项目的加载状态</li><li>在 <code>useEffect</code> 钩子中,咱们定义了两个监听器 — <code>purchaseUpdatedListener</code> 和 <code>purchaseError</code> — 来监听胜利的购买和在过程中可能产生的任何谬误。通常,你应该在启动任何购买事件之前注册这些监听器。</li><li>在 <code>purchaseUpdatedListener</code> 中,咱们定义了一些自定义逻辑来解决与咱们后端的收据验证</li></ul><p>在钩子中,咱们应用 <code>fetchProduct</code> 函数获取可用的产品,该函数围绕 <code>react-native-iap</code> 中的 getProducts 函数。而后,产品的状态会依据返回后果进行更新。</p><p>最初,咱们确保在组件卸载时移除监听器。</p><p>接下来,增加以下函数,该函数在购买实现时执行:</p><pre><code>const notifySuccessfulPurchase = () => { Alert.alert(“Success”, “Purchase successful”, [ { text: ‘Home’, onPress: () => navigation.navigate(‘Home’) } ])}</code></pre><p>而后,增加上面的代码来解决购买:</p><pre><code>const handlePurchase = async (productId) => { setPurchaseLoading(true) try { await requestPurchase({ skus: [productId] }); } catch (error) { Alert.alert(‘Error occurred while making purchase’) } finally { setLoading(false); }}</code></pre><p>上述函数通过提供正在购买的商品的产品ID来调用 <code>requestPurchase</code> 函数,以启动一个IAP。</p><h2>更新付费墙</h2><p>最初,将付费墙的JSX更新为以下内容:</p><pre><code><View style={styles.container}> { !isLoading ? <> <View style={styles.header}> <Image source={backgroundImage} style={styles.image} /> <View style={styles.heading}> <Text style={styles.text}>Unlock all Recipes</Text> <Text style={styles.subText}>Get unlimited access to 1000+ recipes</Text> </View> </View> {products.map((product, index) => ( <ProductItem key={index} title={product.title} onPress={() => handlePurchase(product.productId)} /> ))} </> : <View style={styles.indicator}> <ActivityIndicator size=‘large’ /> </View> }</View></code></pre><p>在文件中蕴含以下导入:</p><pre><code>import React, { useEffect, useState } from “react”;import { View, StyleSheet, Text, Image, Alert, ActivityIndicator } from “react-native”;import { constants } from “../utils/constants”;import { getProducts, //For fetching available products requestPurchase, //For initiating in-app purchases purchaseUpdatedListener, //For listening to purchase events purchaseErrorListener, //For listening to purchase errors finishTransaction //For acknowledging a purchase} from “react-native-iap”;import ProductItem from “../components/productItem”;</code></pre><h2>运行 React Native 利用</h2><p>当初你曾经实现了利用内购买的设置,是时候运行应用程序了。为了做到这一点,确保你的安卓设施已连贯到你的开发机器。尽管你能够应用模拟器来实现这一点,但咱们倡议你在实在设施上测试利用内购买。</p><p>当初,在你的终端运行以下命令:</p><pre><code>npx run react-native run-android</code></pre><p>你应该能看到与上面相似的输入,并可能发动利用内购买:</p><p></p><h2>总结</h2><p>在你的React Native应用程序中实现利用内购买能够解锁额定的支出起源,而且,如果实现切当,还能够晋升你的用户体验。</p><p>咱们曾经通过逐渐领导,介绍了如何应用 <code>react-native-iap</code> 库轻松地将利用内购买集成到您的React Native利用中。如果您想思考另一种办法,或者想在iOS利用中实现IAP,请查看咱们对于应用expo-in-app-purchases实现IAP的帖子。</p><h3>交换</h3><blockquote><p>首发于公众号 大迁世界,欢送关注。 每周一篇实用的前端文章 ️ 分享值得关注的开发工具 ❓ 有疑难?我来答复</p><p>本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试残缺考点、材料以及我的系列文章。</p></blockquote><p></p></article> ...