news 2026/9/11 13:43:28

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用 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/expo

expo-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 中声明仅支持appleandroid两个平台。

安装指南

托管工作流(managed)

对于托管 Expo 项目,直接在项目根目录执行:

npx expo install expo-store-review

npx 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-install

iOS 侧依赖 ExpoStoreReview.podspec 声明的最小 iOS 版本为16.4(Swift 5.9),低于该版本的工程需要先升级部署目标。

API 详解(源码级)

模块对外暴露四个 API,全部实现在 src/StoreReview.ts 中,Web 平台使用 src/ExpoStoreReview.ts 的空实现。

isAvailableAsync()

判断当前平台是否具备原生评分能力:

import * as StoreReview from 'expo-store-review'; export async function isAvailableAsync(): Promise<boolean> { return StoreReview.isAvailableAsync?.() ?? false; }

各平台返回值(与源码注释及原生实现一一对应):

平台返回值依据
iOStrue(经 TestFlight 分发除外)StoreReviewModule.swift 中isRunningFromTestFlight()判定
Android设备已安装 Play Store 时为trueStoreReviewModule.kt 中isPlayStoreInstalled()检查
Webfalse空实现,无原生能力

requestReview()

理想情况下会弹出系统原生弹窗,让用户在不离开应用的情况下完成星级评分:

export async function requestReview(): Promise<void> { if (StoreReview?.requestReview) { return StoreReview.requestReview(); } // 原生能力不可用时,回退为打开商店链接 const url = storeUrl(); ... }

两个值得注意的降级分支(StoreReview.ts):

  1. 原生模块缺失时:尝试通过Linking.openURL打开商店页;若设备不支持打开该链接,会输出Can't open store url警告。
  2. 连商店 URL 都没有配置时:输出警告,提示在app.json中填写android.playStoreUrlios.appStoreUrl字段。

在 Android 5.0 以下设备上,由于系统不支持 In-App Review API,模块同样会走链接跳转的降级路径。

storeUrl() 与 app.json 配置

storeUrl()是评分流程的兜底依赖,它通过expo-constants读取应用配置(StoreReview.ts):

export 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?id=com.example.myapp" } } }
  • 在 iOS 上返回ios.appStoreUrl,在 Android 上返回android.playStoreUrl
  • 在 Web 上恒返回null

hasAction()

评分流程“是否有事可做”的统一判定,推荐在调用requestReview()前先检查(StoreReview.ts):

export async function hasAction(): Promise<boolean> { return !!storeUrl() || (await isAvailableAsync()); }

只要配置了商店 URL原生评分能力可用,返回值即为true。官方推荐的用法:

import * as StoreReview from 'expo-store-review'; if (await StoreReview.hasAction()) { // 可以安全调用 requestReview() await StoreReview.requestReview(); }

平台差异与底层实现

iOS:StoreKit 与 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()屏蔽。

Android:Google Play In-App Review

StoreReviewModule.kt 完整走一遍 Google Play Core 的 ReviewManager 流程:

AsyncFunction("requestReview") { promise: Promise -> requestReview(promise) }

实现上依次执行ReviewManagerFactory.create(context)manager.requestReviewFlow()获取ReviewInfomanager.launchReviewFlow(activity, reviewInfo)拉起系统评分界面,并通过addOnCompleteListener区分成功与失败。异常统一映射为 StoreReviewExceptions.kt 中的RMTaskException/RMUnsuccessfulTaskExceptionCodedException子类)。

值得注意的工程细节:Google 官方限制每个用户每年最多弹出约 4 次系统评分框(配额由系统管理),因此模块本身不提供频率控制,业务侧应根据用户行为合理决定触发时机。

Web:明确不支持

Web 端通过 src/ExpoStoreReview.ts 的空对象实现,isAvailableAsync返回falserequestReview不存在,JS 层会自动降级为商店链接跳转,应用不会报错。

错误处理与最佳实践

结合上述源码行为,落地时建议遵循以下模式:

  1. 调用前先判断:用hasAction()(或isAvailableAsync())做守卫,避免无意义的原生调用;
  2. 补齐商店 URL:无论原生评分是否可用,都应在app.json中配置ios.appStoreUrl/android.playStoreUrl,这是降级路径的唯一出口;
  3. 选择恰当的触发时机:在用户完成关键操作、获得正向体验之后(如完成一次购买、通关关卡、使用一周)再请求评分,避免在启动或高频操作路径中打扰用户;
  4. 留意平台限制:TestFlight 包、无 Play Store 的设备、Web 端均无法弹出原生评分框,会走链接跳转或直接不执行,不要将其作为业务关键路径的依赖;
  5. 注意场景上下文(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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/11 13:37:24

Agilent E4417A功率计的VISA控制与SCPI编程指南

1. Agilent E4417A功率计控制基础Agilent E4417A作为一款经典的高精度功率计&#xff0c;在射频测试领域已经服役超过20年。我手头这台设备虽然出厂于2003年&#xff0c;但配合现代计算机通过VISA控制&#xff0c;依然能完美胜任5G基站功率校准任务。不同于现在主流的USB接口设…

作者头像 李华