拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Folo 移动端 v0.4.0 发版技术解读:Apple 订阅、匿名阅读与发布质量体系升级

Folo 移动端 v0.4.0 发版技术解读Apple 订阅、匿名阅读与发布质量体系升级【免费下载链接】follow Folo is the AI RSS Reader项目地址: https://gitcode.com/GitHub_Trending/fol/follow本文围绕 FoloAI RSS Reader移动端版本更新文档 apps/mobile/changelog/0.4.0.md 展开逐一拆解 v0.4.0 的核心能力iOS 应用内订阅StoreKit/Apple IAP、免登录匿名时间线阅读、与桌面端对齐的升级引导、应用内评分提示、法语本地化以及围绕登录态与付费流程的稳定性和端到端E2E测试加固。读者将能理解这些发布点背后的实现位置与工作原理并能在仓库中自行定位、验证每一处改动。版本概览v0.4.0 是 Folo 移动端在订阅能力与账号体系上的一次集中升级。更新文档将内容划分为四类新增能力Shiny new things、体验改进Improvements、问题修复No longer broken与致谢Thanks对应的移动端源码位于 apps/mobile/src端到端测试流程位于 apps/mobile/e2e/flows。类别关键点新增iOS 端 Apple 订阅免登录匿名阅读时间线升级引导与桌面端订阅流程对齐应用内评分提示法语fr-FR本地化改进设置与发现页 UI 打磨iOS/Android订阅与套餐管理入口完善登录流程加固并扩大 E2E 覆盖翻译功能的角色门槛与实际用户角色对齐修复Discover 分类加载iOS 登录引导auth bootstrapiOS 订阅升级动作Android 弹窗头部重叠移动端登录态跨认证流程持久化iOS 端 Apple 订阅从 StoreKit 下单到服务端验签v0.4.0 最核心的增量是在 iOS 上正式接入 Apple 应用内订阅In-App Purchase。移动端没有引入第三方计费 SDK而是基于expo-iap直接对接 StoreKit并完整实现了「购买 → 验签 → 结算刷新」的闭环。计费能力提供方AppleIAPProvider源码 apps/mobile/src/providers/AppleIAPProvider.tsx 通过 React Contextuse(AppleIAPContext)向全 App 暴露一组类型化能力connected/subscriptionsStoreKit 连接状态与订阅商品ProductSubscription列表loadSubscriptions(skus)按 SKU 拉取 App Store 订阅商品对应fetchProducts({ skus, type: subs })requestSubscriptionPurchase({ sku, appAccountToken })发起订阅购买restoreSubscriptionPurchases()恢复购买RestoreisPurchasing/isProcessingPurchase/isRestoring购买中、验签处理中、恢复中的状态标志供界面展示加载态。值得注意的两个实现细节商品集合来自服务端配置而非硬编码Provider 会读取服务端配置PAYMENT_PLAN_LIST收集每个套餐的appleProductIdentifier月付与appleProductIdentifierAnnual年付构成已知订阅商品 ID 集合再用isKnownAppleSubscriptionPurchase过滤掉无关的 StoreKit 交易。购买完成不自动终结交易调用requestPurchase时显式传入andDangerouslyFinishTransactionAutomatically: false把交易终结finishTransaction推迟到服务端验签成功之后避免已扣款但权益未到账的中间态。客户端验签请求构造apps/mobile/src/providers/apple-iap-purchase.ts 封装了 Apple 交易的签名识别与验签报文构建isCompactJws判断字符串是否为三段式 Compact JWS形如header.payload.signature每段为[\w-]selectSignedTransactionInfo(...)从多个候选来源本地 Purchase Token、getTransactionJwsIOS(productId)、validateReceipt结果中挑出第一个合法的签名交易信息buildAppleVerificationRequest组装验签请求携带originalTransactionId、signedTransactionInfo、transactionId对应逻辑由单元测试 apps/mobile/src/providers/apple-iap-purchase.test.ts 覆盖例如 JWS 识别与请求字段拼装。验签动作最终 POST 到服务端接口/billing/apple/verify见 AppleIAPProvider.tsx只有服务端返回code 0才算验证通过随后才finishTransaction并触发结算状态刷新。结算刷新refreshBillingState会并行做三件事重新同步用户信息userSyncService.whoami()、使whoami查询失效、使billingSubscription查询失效从而让套餐页、头像角标等界面即时反映新权益。StoreKit 本地测试通道Provider 中还保留了一个仅供本地联调的StoreKitTestHelper原生模块入口AppleIAPProvider.tsx仅在 iOS 且 API 指向http://localhost时启用可调用prepareLocalSubscriptions()准备本地订阅商品、buyProduct(sku)模拟购买并返回jwsRepresentation用于在不依赖沙盒账户的本地环境验证订阅链路。恢复购买RestorerestoreSubscriptionPurchases先调用restorePurchases()随后在可用交易中筛选属于已知订阅的购买按expirationDateIOS过期时间倒序依次尝试验签并刷新结算状态成功后提示用户找不到订阅或全部验签失败时分别给出restore_not_found/restore_error文案。这套逻辑同时是修复 iOS 订阅升级动作问题项的底层基础。订阅与套餐管理界面PlanScreen升级文档中Refined upgrade prompts to match desktop subscription flows与Improved subscription and plan management surfaces都集中体现在套餐页 apps/mobile/src/modules/settings/routes/Plan.tsxPlanScreen套餐数据来源serverConfigs.PAYMENT_PLAN_LIST包含月付/年付价格、appleProductIdentifier/appleProductIdentifierAnnual、tier、权益限额limit、isComingSoon、isPopular等字段按tier升序渲染账期切换BillingToggle提供 monthly / yearly 分段切换并基于套餐价格计算年度订阅平均节省比例averageSavings显示在切换器上动作决策getPlanActionType根据当前角色、现有订阅/billing/subscription、账期与目标 tier 推导按钮类型——current当前套餐、upgrade升档、new新订阅、coming-soon即将上线双渠道下单iOS 且当前订阅非 Stripe 时走 Apple IAPrequestSubscriptionPurchase并携带whoami?.appleAppAccountToken作为appAccountToken关联用户否则走服务端authClient.subscription.upgrade生成 Stripe Checkout 链接再openURL跳转若命中ACTIVE_STRIPE_SUBSCRIPTION_EXISTS错误码则自动改开账单管理门户/billing/portal避免重复创建订阅——这与桌面端订阅管理流程保持一致价格展示iOS 上优先使用 StoreKit 返回的displayPrice真实地区定价否则以priceInDollars*配置折算同时展示划线原价与折扣标签权益列表按PLAN_FEATURE_ORDER顺序渲染plan.limit中的特性订阅数、列表数、AI 摘要/翻译/朗读额度、AI 模型档位、自备 Key、Boost、隐私订阅、安全图片代理、优先支持等布尔值显示为包含Number.MAX_SAFE_INTEGER显示为 Unlimited管理入口iOS 额外提供恢复购买Restore按钮当订阅来自 Stripe 且canManage为真时提供管理入口。当用户在订阅类操作上撞到付费墙时应用会弹出统一升级对话框 apps/mobile/src/modules/dialogs/UpgradeRequiredDialog.tsxshowUpgradeRequiredDialog(payload)在getIsPaymentEnabled()为真时展示标题/描述点击后跳转PlanScreen实现与桌面端升级引导 → 套餐页一致的用户路径。免登录匿名阅读时间线v0.4.0 支持未登录用户直接浏览时间线。从登录/会话相关代码看apps/mobile/src/lib/auth.ts 中明确提到queries can keep rendering anonymous cache under the new session——即查询层允许在新会话下继续渲染匿名缓存。结合 apps/mobile/src/initialize/index.ts 对whoami()的初始化判断可以推断v0.4.0 将必须有账号才能看到内容的强门槛弱化为匿名也可读、登录后无缝切换为用户数据。评分与弹窗类逻辑如 apps/mobile/src/modules/review-prompt/provider.tsx也都对userId为空做了短路处理说明整个应用层已把未登录当作一种被支持的状态来设计。应用内评分提示In-App Review新增的评分提示由 apps/mobile/src/modules/review-prompt/provider.tsx 统一驱动属于典型的主动采集时机 → 资格判定 → 系统原生评分弹窗架构触发信号采集通过全局 tracker 钩子监听打开文章NavigateEntry与新增订阅Subscribe两类行为并累计状态同时同步订阅总数feed list与付费转化Free → Pro/Plus静默窗口Quiet Window仅在 App 处于前台、无覆盖式路由、无业务弹窗、当前不在登录/引导/套餐页等阻塞路由时才允许触发isInQuietWindow/isBlockedRoute资格评分把已用天数、打开文章数、订阅数、是否付费、是否登录等汇总到reviewState调用getReviewPromptEligibility计算allowed与score单次会话内只尝试一次hasAttemptedInSessionRef且有REVIEW_PROMPT_QUIET_WINDOW_MS静默间隔触发方式符合条件的在空闲时InteractionManager.runAfterInteractions调用原生评分requestMobileNativeReview支持 App Store 原生评价未达到门槛的走 Debug/手动通道时仅记录跟踪事件。也就是说v0.4.0 不会在用户刚打开应用时就强推评分而是依据真实使用深度阅读、订阅、活跃天数按策略弹出。法语本地化v0.4.0 增加法语fr-FR支持本地化文案统一收口在仓库根目录 locales 下按用途拆分命名空间其中移动端默认文案位于 locales/mobile/default/fr-FR.json另有common、app、settings、errors、shortcuts、ai等命名空间的 fr-FR 版本与之配套。移动端界面通过react-i18next的useTranslation(namespace)引用对应键值如套餐页大量使用settings命名空间的subscription.*、plan.*键因此只需补齐 JSON 文案即可完成新语言适配无需改动 UI 结构。登录链路加固与 E2E 覆盖扩展发布说明中Hardened authentication flows and expanded end-to-end coverage在仓库中有明确落点移动端基于 Maestro 的 E2E 流程目录 apps/mobile/e2e/flows/ios 与 apps/mobile/e2e/flows/shared 中围绕账号体系沉淀了auth.yaml、login.yaml、register.yaml、sign-out.yaml等可复用的流程片段共享目录下还有open-auth.yaml等引导片段产物验证脚本 apps/mobile/scripts/e2e-prod-ios-auth-bootstrap.ts 对应了修复 iOS 登录引导auth bootstrap这一修复项用于为生产包准备可用的登录态会话持久化依赖服务端 token 与会话缓存机制初始化阶段对whoami()的状态判断见 apps/mobile/src/initialize/index.ts这与Stabilized sign-in persistence across mobile auth flows直接相关。修复项与平台打磨v0.4.0 修复的问题均能在当前目录结构中定位到对应模块Discover 分类加载发现页相关实现见 apps/mobile/src/modules/discover如Trending.tsx、Recommendations.tsx、search-tabs/*发布说明中的Fixed discover category loading针对的是分类入口首次加载失败的问题iOS 订阅升级动作由套餐页的升级分支与 AppleIAPProvider.tsx 的交易处理当前购买校验 → 验签 → 完成 → 刷新共同承载此前版本在 iOS 上点升级后可能卡在购买处理状态Android 弹窗头部重叠移动端跨平台的 PagerList / 时间线选择器相关代码apps/mobile/src/modules/screen/PagerList.tsx 与 iOS 变体PagerList.ios.tsx说明 Android 与 iOS 存在平台差异实现v0.4.0 修复了 Android 上 Modal 与头部导航重叠的布局问题iOS auth bootstrap与 apps/mobile/scripts/e2e-prod-ios-auth-bootstrap.ts 及 iOS 原生配置apps/mobile/ios/Folo相关。如何在仓库中进一步验证 v0.4.0 改动若希望按图索骥复核本版本内容建议按以下链路阅读先读 apps/mobile/changelog/0.4.0.md 掌握发布范围按计费 → 套餐 UI → 弹窗 → 评分 → 认证顺序阅读 apps/mobile/src/providers/AppleIAPProvider.tsx、apps/mobile/src/modules/settings/routes/Plan.tsx、apps/mobile/src/modules/dialogs/UpgradeRequiredDialog.tsx、apps/mobile/src/modules/review-prompt/provider.tsx关注 apps/mobile/src/providers/apple-iap-purchase.test.ts 等单元测试理解验签报文的构造约束在 apps/mobile/e2e/flows/ios 中查看auth.yaml/login.yaml/register.yaml理解登录 E2E 的覆盖程度需要接入法语文案时以 locales/mobile/default/fr-FR.json 为参照补齐其他命名空间。综上v0.4.0 标志着 Folo 移动端在商业化能力Apple 订阅 双渠道套餐管理与基础体验匿名阅读、评分策略、本地化两条线上同步成熟并将质量保障前移到 E2E 与单元测试层面这一版本所建立的 IAP 验签、结算刷新、角色门槛等基础设施也为此后版本的订阅与账号能力演进提供了可直接复用的骨架。【免费下载链接】follow Folo is the AI RSS Reader项目地址: https://gitcode.com/GitHub_Trending/fol/follow创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门