内购
了解 EasyAppSwiftUI 应用内购买模块

内购模块
InAppPurchases 模块提供了完善的应用内购买解决方案,支持多种实现方式,包括 RevenueCat 和 StoreKit2 两套完整的订阅管理系统。
我们后续提供更多精美内购页面UI实现,敬请期待。
模块结构
InAppPurchases/
├── View/
│ ├── InAppPurchasesView.swift # 主入口页面
│ ├── CustomAPWithRevenueCatPaywallView.swift # RevenueCat完全自定义
│ ├── ASemiCustomWithRevenueCatPaywallView.swift # RevenueCat半自定义
│ └── CustomStoreKit2PaywallView.swift # StoreKit2完全自定义
└── TestPremium/
├── TestRequirePremium.swift # 测试Premium访问控制
└── TestActionGoPaywall.swift # 测试Paywall触发四种内购实现方案
1. 完全自定义 RevenueCat Paywall
使用 RevenueCat SDK API 实现完全自定义的付费墙界面:
核心特性:
- 自动计算订阅套餐间的节省金额
- 年度订阅显示月均价格
- 集中化的价格逻辑处理
struct CustomAPWithRevenueCatPaywallView: View {
@EnvironmentObject private var revenueCatManager: RevenueCatManager
@EnvironmentObject private var authManager: AuthManager
@State private var selectedPackage: Package?
var body: some View {
NavigationStack {
ScrollView {
VStack {
// 订阅信息显示
if let productTitle = authManager.storeProduct?.localizedTitle,
let entitlement = authManager.customerInfo?.entitlements[
Constants.RevenueCat.entitlementID], entitlement.isActive {
SubscriptionInfoView(
productTitle: productTitle,
expirationDate: entitlement.expirationDate
)
}
// 套餐选择界面
if let offerings = revenueCatManager.currentOfferings,
let currentOffering = offerings.current {
// 渲染套餐选择UI
}
}
}
}
}
}2. 半自定义 RevenueCat Paywall
使用 RevenueCat 的 .paywallFooter() API,允许自定义设计内容:
struct ASemiCustomWithRevenueCatPaywallView: View {
var body: some View {
// 自定义顶部内容
CustomPaywallContent()
.paywallFooter() // RevenueCat 提供的购买按钮逻辑
}
}3. 完全自定义 StoreKit2 Paywall
使用 StoreKit2 API 实现完全自定义的付费墙:
struct CustomStoreKit2PaywallView: View {
@EnvironmentObject private var storeKit2Manager: StoreKit2Manager
@EnvironmentObject private var authManager: AuthManager
@State private var selectedProduct: Product?
var body: some View {
NavigationStack {
ScrollView {
VStack {
// 当前订阅状态
if let productTitle = authManager.storeKitProduct?.displayName,
let transaction = authManager.storeKitTransaction {
SubscriptionInfoView(
productTitle: productTitle,
expirationDate: transaction.expirationDate
)
}
// 产品列表
ForEach(storeKit2Manager.products, id: \.id) { product in
ProductView(
product: product,
isSelected: selectedProduct?.id == product.id
) {
selectedProduct = product
}
}
}
}
}
}
}4. RevenueCatUI PaywallView
直接使用 RevenueCatUI 提供的标准付费墙组件:
.sheet(isPresented: $displayPaywall) {
PaywallView(
displayCloseButton: true,
performPurchase: { package in
print("Purchase started: \(package.identifier)")
HapticsEngine.impact()
paySuccessCount += 1
syncPurchases()
return (userCancelled: false, error: nil)
},
performRestore: {
print("Restore started")
HapticsEngine.impact()
paySuccessCount += 1
syncPurchases()
return (success: true, error: nil)
}
)
}Premium 访问控制
1. 声明式访问控制
使用 .requirePremium() 修饰符保护需要订阅的内容:
struct TestRequirePremium: View {
@EnvironmentObject private var authManager: AuthManager
var body: some View {
VStack {
Text("这是需要Premium访问的内容")
.requirePremium(
subscriptionType: .storeKit2,
sheetOrFullScreenCover: .fullScreenCover,
onCancelPaywall: {
print("用户取消了订阅")
},
onPaySuccess: {
print("订阅成功")
}
)
}
}
}2. 动作触发式访问控制
通过按钮点击等操作触发订阅检查:
struct TestActionGoPaywall: View {
@EnvironmentObject private var authManager: AuthManager
var body: some View {
VStack {
// RevenueCat 实现
Button("使用RevenueCat付费墙") {
authManager.actionGoPaywall(
subscriptionType: .revenueCat,
sheetOrFullScreenCover: .sheet
) {
// 用户有订阅权限时执行的操作
print("执行Premium功能")
}
}
// StoreKit2 实现
Button("使用StoreKit2付费墙") {
authManager.actionGoPaywall(
subscriptionType: .storeKit2,
sheetOrFullScreenCover: .fullScreenCover
) {
// 用户有订阅权限时执行的操作
print("执行Premium功能")
}
}
}
}
}核心功能特性
1. 双重订阅系统支持
- RevenueCat - 功能丰富的订阅管理平台
- StoreKit2 - Apple原生的订阅API
- 可以根据项目需求选择其中一种
2. 价格计算和显示
- 自动计算不同套餐间的节省金额
- 年度订阅显示月均价格
- 支持多币种和本地化价格显示
3. 订阅状态管理
- 实时显示当前订阅状态
- 支持恢复购买功能
4. 用户体验优化
- 庆祝动画(Confetti效果)
- 触觉反馈
- 加载状态指示
- 错误处理和重试机制
5. 灵活的展示方式
- Sheet 弹窗模式
- FullScreenCover 全屏模式
管理器集成
RevenueCat 管理器
@EnvironmentObject private var revenueCatManager: RevenueCatManager
// 获取订阅产品
let offerings = revenueCatManager.currentOfferings
let packages = offerings?.current?.availablePackages
// 购买处理
try await revenueCatManager.purchase(package: selectedPackage)StoreKit2 管理器
@EnvironmentObject private var storeKit2Manager: StoreKit2Manager
// 获取产品列表
let products = storeKit2Manager.products
// 购买处理
try await storeKit2Manager.purchase(product: selectedProduct)测试和调试
模块提供了完整的测试组件:
- 测试Premium访问 - 验证访问控制逻辑
- 测试Paywall触发 - 验证付费墙展示逻辑
- 模拟购买流程 - 沙盒测试
在开发阶段,内购都是在沙盒中进行测试的。进行购买时,不会真正扣费。
请使用真机进行测试,不要使用模拟器。
- 首先我们需要在 App Store Connect 的
Users and Access创建一个沙盒测试账号
如果您已经有测试账号按照如下图所示:

点击+按钮, 来创建一个沙盒测试账号,
如果您没有测试账号, 第一次创建,请按照如下图所示:

在后续弹窗中输入您的测试账号相关信息,然后点击Create按钮保存即可。

- 真机运行App,内购测试
如何实时查看订阅数据呢?
回到RevenueCat的Dashboard页面, 您可以看到您的所有订阅信息。
沙盒环境下,您需要打开Sandbox data 开关。

原生 StoreKit2 收入,需要到App Store Connect 查看。一般数据会有延迟,通常为 N+1 天。
本地化支持
- 多语言价格显示
- 本地化的错误消息
- 区域化的货币格式
通过 InAppPurchases 模块,您可以快速实现专业级的应用内购买功能,支持多种技术方案和展示方式,满足不同应用场景的需求。
更多学习资料,请参考:
Last updated on