iOS 应用内购买与付费墙概述
0:02:00欢迎来到 RevenueCat 的 iOS SDK Codelab!
在本 Codelab 中,您将学习:
将 RevenueCat SDK 集成到您的 Xcode 项目中。 在您的 SwiftUI 应用程序中实现应用内购买。 学习如何区分付费用户和非付费用户。 使用 SwiftUI 构建付费墙界面,由 RevenueCat 的服务端配置驱动。
完成本 Codelab 后,您将能够在 iOS 应用中成功实现应用内购买,并使用 RevenueCat 的 iOS SDK 和 SwiftUI 显示动态付费墙。
导入 RevenueCat SDK
0:05:00首先,在实现应用内购买之前,您需要将 RevenueCat SDK 导入到您的项目中。最简单的方法是使用 Swift Package Manager。
在 Xcode 中,将以下内容添加到您的 Podfile 中:
pod 'RevenueCat'
pod 'RevenueCatUI'Xcode 将获取该软件包。请确保将 RevenueCat 添加到您应用的主目标中。
如果您还计划实现我们预构建的付费墙,可以同时添加 RevenueCatUI 库。
Getting Your API Key
Before you can initialize the SDK, you'll need your RevenueCat API key. Here's where to find it:
- Go to the RevenueCat dashboard
- Navigate to your project
- Click on API keys in the left sidebar
- Copy your Apple App Store API key (it should start with
appl_)
Initialize the SDK
接下来,使用以下代码在您的 App 的 init() 方法或 AppDelegate 中初始化 Purchases SDK:
import SwiftUI
import RevenueCat
@main
struct MyApp: App {
init() {
// 记录 SDK 的所有消息
Purchases.logLevel = .debug
// 使用您的 API 密钥配置 SDK
Purchases.configure(withAPIKey: <public_apple_api_key>, appUserID: <app_user_id>)
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
} 用户识别: 我们没有提供特定的 appUserID,因此 RevenueCat 将自动为用户生成和管理匿名 ID。如果您想正确使用恢复购买功能,请提供由您的后端提供的唯一标识符。 交易完成: 默认情况下,SDK 会自动处理与 App Store 的交易完成,因此您无需手动处理。
太棒了!您现在已经完成了 50% 的实现工作。
验证用户权益
0:03:00现在让我们继续验证用户权益。
权益(Entitlement)代表用户在购买后解锁的访问级别或功能。这对于确定是否显示广告横幅或授予高级访问权限等场景非常有用。
您可以使用 Swift 的现代 async/await 语法轻松检查用户是否拥有活跃的权益:
import SwiftUI
import RevenueCat
struct ContentView: View {
@State private var isSubscribed: Bool = false
let ENTITLEMENT_ID = "premium" // 您在 RevenueCat 控制台中的权益标识符
var body: some View {
VStack {
if isSubscribed {
PremiumContent()
} else {
Text("这是免费内容。")
// 您可以在这里显示横幅或付费墙
}
}
.task {
// 视图出现时检查权益
await checkEntitlement()
}
}
private func checkEntitlement() async {
do {
let customerInfo = try await Purchases.shared.customerInfo()
// 检查权益是否激活
if customerInfo.entitlements[ENTITLEMENT_ID]?.isActive == true {
self.isSubscribed = true
} else {
self.isSubscribed = false
}
} catch {
print("获取客户信息时出错: \(error)")
}
}
}一旦您检查了用户是否拥有特定权益,就可以决定如何继续。在这个 SwiftUI 示例中,我们更新了一个 @State 变量(isSubscribed),这会导致视图自动重新渲染,显示高级内容或免费版本。
实现应用内购买
0:04:00现在,让我们实现应用内购买以提供高级体验。首先,您需要获取在 RevenueCat 中配置的产品。这些数据将用于向用户展示购买选项。
您可以通过调用 Purchases.shared.products(productIdentifiers:) 来获取可用产品:
import RevenueCat
class PurchaseViewModel: ObservableObject {
func purchase(product: StoreProduct) async {
do {
let result = try await Purchases.shared.purchase(product: product)
// 检查用户现在是否有高级权益
if result.customerInfo.entitlements["premium"]?.isActive == true {
// 解锁高级内容
print("购买成功!")
}
} catch {
print("购买时出错: \(error)")
}
}
func fetchProducts() async -> [StoreProduct] {
do {
// 使用产品标识符获取产品
let products = try await Purchases.shared.products(["premium_monthly", "premium_yearly"])
return products
} catch {
print("获取产品时出错: \(error)")
return []
}
}
}一旦您获取了 StoreProduct 对象,就可以通过调用 Purchases.shared.purchase(product:) 来启动应用内购买流程。这将自动触发原生 App Store 购买弹窗,使用户能够在您的应用内安全地完成交易。
就这样,您只用几行代码就集成了一个完整功能的应用内购买流程——无需处理收据、StoreKit API 或手动购买验证的复杂性。
实现付费墙
0:07:00现在,是时候使用 SwiftUI 在您的 iOS 项目中实现付费墙了。
业务逻辑
首先,您需要从 RevenueCat 控制台获取当前的产品方案(Offering)。产品方案定义了在付费墙上向用户展示的可用套餐(月度、年度等)。使用 Purchases.shared.offerings() 可以轻松完成:
import Foundation
import RevenueCat
import SwiftUI
@MainActor // 确保对 @Published 属性的更改发生在主线程上
class PaywallViewModel: ObservableObject {
// 这将保存要在付费墙上显示的当前产品方案。
@Published var offering: Offering?
// 这将跟踪加载状态以在 UI 中显示指示器。
@Published var isLoading: Bool = false
init() {
// 您可以在 ViewModel 创建后立即获取产品方案。
Task {
await fetchOffering()
}
}
/**
* 从 RevenueCat 获取当前产品方案并更新 @Published 属性。
*/
func fetchOffering() async {
self.isLoading = true
do {
let offerings = try await Purchases.shared.offerings()
// 我们获取 'current' 产品方案,这是您在控制台上
// 为此位置配置的要显示的产品方案。
self.offering = offerings.current
} catch {
print("获取产品方案时出错: \(error.localizedDescription)")
// 您可能还想在 UI 中处理错误状态
}
self.isLoading = false
}
}RevenueCat iOS SDK 原生支持 Swift 的 async/await,使其与现代 SwiftUI 应用程序完美配合。通过使用 @Published 发布 offering,我们的 SwiftUI 视图可以响应式地观察变化。
使用 SwiftUI 构建付费墙 UI
此时,一切都已准备就绪。如果您添加了 RevenueCatUI 包,您可以使用 SwiftUI 轻松构建付费墙 UI。
RevenueCat 的 UI 库提供了一个内置的 SwiftUI 视图 PaywallView,允许您快速显示付费墙界面。此组件可以使用标准 SwiftUI 修饰符进行完全自定义。
以下示例展示了使用 SwiftUI 的 sheet 修饰符实现和显示付费墙是多么简单:
import SwiftUI
import RevenueCat
import RevenueCatUI
struct ContentView: View {
@State private var showPaywall = false
var body: some View {
Button("显示付费墙") {
showPaywall = true
}
.sheet(isPresented: $showPaywall) {
// 在 sheet 中显示付费墙
PaywallView()
}
}
}PaywallView 将自动获取当前产品方案,并使用您在 RevenueCat 控制台上配置的模板显示它。如果您已经获取了产品方案,也可以直接传入一个 Offering 对象:
import SwiftUI
import RevenueCat
import RevenueCatUI
struct ContentView: View {
// 这将触发付费墙 sheet 的展示。
@State private var showPaywall = false
// 为付费墙创建 ViewModel 实例。
// @StateObject 确保它与视图具有相同的生命周期。
@StateObject private var paywallViewModel = PaywallViewModel()
var body: some View {
VStack(spacing: 20) {
Text("欢迎使用本应用!")
Button("升级到高级版") {
// 当按钮被点击时,设置标志以显示 sheet。
showPaywall = true
}
}
.sheet(isPresented: $showPaywall) {
// 这是 sheet 的内容。
// 它将显示 PaywallView 并从我们的 ViewModel 传递产品方案。
// 我们可以在获取产品方案时显示加载指示器。
if paywallViewModel.isLoading {
ProgressView()
} else if let offering = paywallViewModel.offering {
// 一旦产品方案可用,将其传递给 PaywallView。
PaywallView(offering: offering)
} else {
// 可选:如果无法加载产品方案,显示错误或消息。
Text("抱歉,我们目前无法加载订阅选项。")
}
}
.onAppear {
// 您也可以在视图出现时刷新产品方案,
// 尽管 ViewModel 的 init 已经处理了第一次获取。
// Task {
// await paywallViewModel.fetchOffering()
// }
}
}
}您可以将一些修饰符附加到应用程序中的顶级视图,例如根视图。它会自动为您处理展示逻辑。
在 iPhone 上,RevenueCat 付费墙可以以 sheet 或全屏方式显示,您有多种选项可以在 SwiftUI 或 UIKit 中集成它们:
- 使用
presentPaywallIfNeeded基于权益自动展示 - 使用
presentPaywallIfNeeded自定义展示逻辑 - 使用 PaywallView 或
PaywallViewController手动集成
例如:
import SwiftUI
import RevenueCat
import RevenueCatUI
@main
struct MyApp: App {
// ... (init 代码) ...
var body: some Scene {
WindowGroup {
ContentView()
// 此修饰符将检查 "premium" 权益。
// 如果用户没有该权益,将展示付费墙 sheet。
.presentPaywallIfNeeded(
requiredEntitlementIdentifier: "premium",
purchaseCompleted: { customerInfo in
// 这是庆祝购买成功的好地方!
print("购买完成: \(customerInfo.entitlements)")
},
restoreCompleted: { customerInfo in
// 如果权益现在已激活,付费墙将自动关闭。
print("恢复完成: \(customerInfo.entitlements)")
}
)
}
}
}配置完成!现在,每当用户没有所需权益时,您就可以显示付费墙,使用的正是您在付费墙编辑器中配置的设计。
如您所见,付费墙系统建立在服务端驱动的 UI 之上。这意味着您可以直接从控制台动态更新付费墙的内容和设计,无需推送应用更新或经过 App Store 审核。
总结
在本 Codelab 中,您学习了如何集成 RevenueCat 的 iOS SDK、实现应用内购买以及在 SwiftUI 中构建付费墙。现在是时候发布您的应用并赚取更多收入了!
您还可以通过以下资源了解更多关于在 iOS 项目中使用 RevenueCat SDK 和 SwiftUI 的信息: