尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

用 expo-store-review 为 Expo 应用接入应用内评分(In-App Review)

用 expo-store-review 为 Expo 应用接入应用内评分(In-App Review) 用 expo-store-review 为 Expo 应用接入应用内评分In-App Review【免费下载链接】expoAn open-source framework for making universal native apps with React. Expo runs on Android, iOS, and the web.项目地址: https://gitcode.com/GitHub_Trending/ex/expoexpo-store-review是 Expo 官方提供的原生模块允许用户在 App Store 与 Google Play Store 中直接为你的应用打分评价而无需离开应用。本文以仓库中的 README 为骨架结合 TypeScript 封装层 与 Android / iOS 原生实现系统讲解该模块的安装步骤、全部 API 用法、平台差异与底层原理读完即可在托管或裸工作流中落地一套完整的应用内评分方案。模块概览与工作原理从 package.json 的描述看该模块的核心职责是“Provides access to native APIs for in-app reviews”即暴露系统级的应用内评分能力在 iOS 上调用 StoreKit 的原生评分弹窗在 Android 上通过 Google Play In-App Review API 拉起系统评分流程在 Web 上不提供任何能力相关调用会优雅降级为跳转应用商店链接。模块按 Expo Modules API 组织JS 层通过 src/ExpoStoreReview.native.ts 中的requireNativeModule(ExpoStoreReview)获取原生模块原生侧在 android/.../StoreReviewModule.kt 与 ios/StoreReviewModule.swift 中注册同名模块并在 expo-module.config.json 中声明仅支持apple与android两个平台。安装指南托管工作流managed对于托管 Expo 项目直接在项目根目录执行npx expo install expo-store-reviewnpx expo install会自动选取与当前 SDK 版本兼容的模块版本当前仓库内模块版本为 57.0.1见 package.json无需手动配置原生工程。裸工作流bare裸 React Native 项目在安装前必须确保已安装并配置好expo包本体然后再添加模块依赖npx expo install expo-store-review平台配置差异Android无需额外配置。从 AndroidManifest.xml 可以看到该模块的 manifest 是空的Google Play 的 In-App Review 能力由模块运行时通过ReviewManagerFactory动态获取不要求声明权限或 Activity。iOS安装 npm 包后执行一次 CocoaPods 安装。npx pod-installiOS 侧依赖 ExpoStoreReview.podspec 声明的最小 iOS 版本为16.4Swift 5.9低于该版本的工程需要先升级部署目标。API 详解源码级模块对外暴露四个 API全部实现在 src/StoreReview.ts 中Web 平台使用 src/ExpoStoreReview.ts 的空实现。isAvailableAsync()判断当前平台是否具备原生评分能力import * as StoreReview from expo-store-review; export async function isAvailableAsync(): Promiseboolean { return StoreReview.isAvailableAsync?.() ?? false; }各平台返回值与源码注释及原生实现一一对应平台返回值依据iOStrue经 TestFlight 分发除外StoreReviewModule.swift 中isRunningFromTestFlight()判定Android设备已安装 Play Store 时为trueStoreReviewModule.kt 中isPlayStoreInstalled()检查Webfalse空实现无原生能力requestReview()理想情况下会弹出系统原生弹窗让用户在不离开应用的情况下完成星级评分export async function requestReview(): Promisevoid { if (StoreReview?.requestReview) { return StoreReview.requestReview(); } // 原生能力不可用时回退为打开商店链接 const url storeUrl(); ... }两个值得注意的降级分支StoreReview.ts原生模块缺失时尝试通过Linking.openURL打开商店页若设备不支持打开该链接会输出Cant open store url警告。连商店 URL 都没有配置时输出警告提示在app.json中填写android.playStoreUrl与ios.appStoreUrl字段。在 Android 5.0 以下设备上由于系统不支持 In-App Review API模块同样会走链接跳转的降级路径。storeUrl() 与 app.json 配置storeUrl()是评分流程的兜底依赖它通过expo-constants读取应用配置StoreReview.tsexport function storeUrl(): string | null { const expoConfig Constants.expoConfig; if (Platform.OS ios expoConfig?.ios) { return expoConfig.ios.appStoreUrl ?? null; } else if (Platform.OS android expoConfig?.android) { return expoConfig.android.playStoreUrl ?? null; } return null; }对应在app.json中需要配置{ expo: { ios: { bundleIdentifier: com.example.myapp, appStoreUrl: https://apps.apple.com/app/id123456789 }, android: { package: com.example.myapp, playStoreUrl: https://play.google.com/store/apps/details?idcom.example.myapp } } }在 iOS 上返回ios.appStoreUrl在 Android 上返回android.playStoreUrl在 Web 上恒返回null。hasAction()评分流程“是否有事可做”的统一判定推荐在调用requestReview()前先检查StoreReview.tsexport async function hasAction(): Promiseboolean { return !!storeUrl() || (await isAvailableAsync()); }只要配置了商店 URL或原生评分能力可用返回值即为true。官方推荐的用法import * as StoreReview from expo-store-review; if (await StoreReview.hasAction()) { // 可以安全调用 requestReview() await StoreReview.requestReview(); }平台差异与底层实现iOSStoreKit 与 TestFlight 检测StoreReviewModule.swift 的核心逻辑AsyncFunction(requestReview) { MainActor () async throws in guard let currentScene getForegroundActiveScene() else { throw MissingCurrentWindowSceneException() } if #available(iOS 16.0, *) { AppStore.requestReview(in: currentScene) } else { SKStoreReviewController.requestReview(in: currentScene) } }iOS 16使用新的AppStore.requestReview(in:)旧版本回退到SKStoreReviewController弹窗必须依附于前台活跃的UIWindowScene若应用处于后台或找不到合适场景会抛出 StoreReviewExceptions.swift 中定义的MissingCurrentWindowSceneException提示“无法确定展示评分弹窗的当前窗口场景”TestFlight 判定通过检查 receipt 文件名是否为sandboxReceipt且不存在内嵌的 provisioning profile 来识别沙箱/TestFlight 环境模拟器环境直接放行返回false。也就是说TestFlight 分发下的评分入口会被isAvailableAsync()屏蔽。AndroidGoogle Play In-App ReviewStoreReviewModule.kt 完整走一遍 Google Play Core 的 ReviewManager 流程AsyncFunction(requestReview) { promise: Promise - requestReview(promise) }实现上依次执行ReviewManagerFactory.create(context)→manager.requestReviewFlow()获取ReviewInfo→manager.launchReviewFlow(activity, reviewInfo)拉起系统评分界面并通过addOnCompleteListener区分成功与失败。异常统一映射为 StoreReviewExceptions.kt 中的RMTaskException/RMUnsuccessfulTaskExceptionCodedException子类。值得注意的工程细节Google 官方限制每个用户每年最多弹出约 4 次系统评分框配额由系统管理因此模块本身不提供频率控制业务侧应根据用户行为合理决定触发时机。Web明确不支持Web 端通过 src/ExpoStoreReview.ts 的空对象实现isAvailableAsync返回false、requestReview不存在JS 层会自动降级为商店链接跳转应用不会报错。错误处理与最佳实践结合上述源码行为落地时建议遵循以下模式调用前先判断用hasAction()或isAvailableAsync()做守卫避免无意义的原生调用补齐商店 URL无论原生评分是否可用都应在app.json中配置ios.appStoreUrl/android.playStoreUrl这是降级路径的唯一出口选择恰当的触发时机在用户完成关键操作、获得正向体验之后如完成一次购买、通关关卡、使用一周再请求评分避免在启动或高频操作路径中打扰用户留意平台限制TestFlight 包、无 Play Store 的设备、Web 端均无法弹出原生评分框会走链接跳转或直接不执行不要将其作为业务关键路径的依赖注意场景上下文iOS确保调用发生在应用处于前台活跃状态否则会收到MissingCurrentWindowSceneException。小结expo-store-review用极小的接入成本让 Expo 应用同时获得 App Store 与 Google Play 两套系统级应用内评分能力并在 Web、旧系统、TestFlight 等受限场景下自动降级为商店链接跳转。核心 API 仅四个isAvailableAsync/requestReview/storeUrl/hasAction配合app.json中的商店 URL 配置即可快速集成深入阅读 TypeScript 封装、Android 实现 与 iOS 实现还能进一步掌握其平台检测与异常处理细节。【免费下载链接】expoAn open-source framework for making universal native apps with React. Expo runs on Android, iOS, and the web.项目地址: https://gitcode.com/GitHub_Trending/ex/expo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表