Kotlin Multiplatform 应用内购买与付费墙概述

0:02:00

欢迎来到 RevenueCat 的 KMP(Kotlin Multiplatform)SDK Codelab!

在本 Codelab 中,您将:

RevenueCat KMP SDK 集成到您的 Kotlin Multiplatform 项目中 在您的 KMP 应用中实现 应用内购买 学习如何 区分付费用户和非付费用户 构建一个基于 服务端驱动 UI 方法的 付费墙界面

完成本 Codelab 后,您将能够在 KMP 应用中成功实现应用内购买,并使用 RevenueCat 的 KMP SDK 显示动态付费墙。

overview

导入 RevenueCat SDK

0:04:00

首先,在实现应用内购买之前,您需要将 RevenueCat SDK 导入到您现有或新建的项目中。首先,将以下依赖项添加到您的 build.gradle.kts 文件中:

您可以在 GitHub 上查看最新发布版本

gradle
[versions]
purchases-kmp = "3.0.0"

[libraries]
purchases-core = { module = "com.revenuecat.purchases:purchases-kmp-core", version.ref = "purchases-kmp" }
purchases-ui = { module = "com.revenuecat.purchases:purchases-kmp-ui", version.ref = "purchases-kmp" }
要求(purchases-kmp 3.0.0+): Kotlin 2.3.20 及以上,Android 6.0 及以上(API 23),iOS 13.0 及以上。如果您从早期版本升级,请参阅 3.0.0 迁移指南

现在您可以在模块的 build.gradle.kts 的 commonMain 源集中添加依赖项。

gradle
kotlin {
    // ...
    sourceSets {
        // ...
        commonMain.dependencies {
            // 添加 purchases-kmp 依赖项。
            implementation(libs.purchases.core)
            implementation(libs.purchases.ui)
        }
    }
}

启用 ExperimentalForeignApi

由于 SDK 使用 Kotlin 生成的原生 iOS 代码绑定,您需要在 iOS 源集中启用 ExperimentalForeignApi。要启用此功能,请在模块的 build.gradle.kts 文件中添加以下配置:

kotlin
kotlin {
    // ...
    sourceSets {
        // ...
        named { it.lowercase().startsWith("ios") }.configureEach {
            languageSettings {
                optIn("kotlinx.cinterop.ExperimentalForeignApi")
            }
        }
    }
}

iOS 设置 — 无需 CocoaPods

从 purchases-kmp 3.0.0 开始,在 iOS 上集成 SDK 变得非常简单。您不再需要PurchasesHybridCommon(或 PurchasesHybridCommonUI)作为 CocoaPods 依赖项添加,也不再需要 kotlin-cocoapods Gradle 插件。原生 RevenueCat iOS SDK 现在直接捆绑在由共享模块生成的 Kotlin Multiplatform 框架中。

只需像处理其他任何 KMP 项目一样从共享模块生成常规的 iOS 框架即可。例如,在 composeApp/build.gradle.kts 中:

kotlin
kotlin {
    listOf(
        iosX64(),
        iosArm64(),
        iosSimulatorArm64()
    ).forEach { iosTarget ->
        iosTarget.binaries.framework {
            baseName = "ComposeApp"
            isStatic = true
        }
    }
    // ...
}
正在从 purchases-kmp 2.x 或更早版本迁移? 请从您的 Podfile 中删除 pod 'PurchasesHybridCommon' / pod 'PurchasesHybridCommonUI' 条目,从 build.gradle.kts 中删除 pod("PurchasesHybridCommon") { ... } 代码块,并从版本目录中删除相应的 purchases-common 版本。完整说明请参阅 3.0.0 迁移指南

您已成功导入 RevenueCat SDK。现在,让我们进入初始化步骤。

初始化

0:02:00

现在,是时候在您的项目中初始化 Purchases SDK 了。请确保仅使用您的 公共 API 密钥 配置 Purchases,该密钥可以在 项目设置 > 平台 下的应用设置中找到。

kotlin
import com.revenuecat.purchases.kmp.LogLevel
import com.revenuecat.purchases.kmp.Purchases
import com.revenuecat.purchases.kmp.configure

// 如果您有通用的初始化逻辑,请在那里调用 configure()。如果没有,
// 请在各自平台的应用生命周期早期调用它。
// 注意:确保为每个平台使用正确的 api key。您可以
// 使用 Kotlin Multiplatform 的 expect/actual 机制来实现这一点。

Purchases.logLevel = LogLevel.DEBUG
Purchases.configure(apiKey = "<google_or_apple_api_key>") {
    appUserId = "<app_user_id>"
    // 其他配置选项。
}

.configure 方法中的 app_user_id 字段用于 RevenueCat 识别您应用中的用户。您可以提供自定义用户标识符,或省略它让 RevenueCat 自动生成匿名 ID。有关更多详情,请参阅我们的 用户识别指南

太好了!您现在已完成 50% 的实现工作。

验证权益

0:03:00

现在让我们来验证用户权益。

如前所述,权益代表用户购买后解锁的访问级别或功能。这对于确定是否显示广告横幅或授予高级访问权限等非常有用。

您可以使用以下代码片段轻松检查用户是否拥有有效权益:

kotlin
val ENTITLEMENT_IDENTIFIER = ".." // 从您的 RevenueCat 仪表板获取特定权益标识符
val customerInfo = Purchases.sharedInstance.awaitCustomerInfo()
val isEntitled = customerInfo?.entitlements[ENTITLEMENT_IDENTIFIER]?.isActive == true

一旦您检查了用户是否拥有特定权益,就可以根据您应用的业务模式决定如何处理。

例如,如果您的应用是广告支持的,您可能会选择显示或隐藏 AdMob 横幅。或者,您可以选择显示付费墙或购买对话框,允许用户解锁高级功能或内容。

以下是您可能如何实现该逻辑的示例:

kotlin
@Composable
fun ContentScreen(isEntitled: Boolean) {
    if (isEntitled) {
      // 如果用户被授予此权益的访问权限,则不需要显示横幅。
    } else {
      // 在此显示横幅 UI 或显示付费墙
      ..
    }
}

实现应用内购买

0:04:00

现在,让我们实现应用内购买以提供无广告体验。首先,您需要从 RevenueCat 仪表板获取相关的产品信息。这些产品数据将用于向用户展示购买选项。

您可以通过调用 Purchases.sharedInstance.awaitGetProducts() 来检索可用产品,如下例所示:

kotlin
// 从 RevenueCat 服务器获取产品信息
val products = Purchases.sharedInstance.awaitGetProducts(
  productIds = listOf("paywall_tester.subs"),
)

// 进行应用内购买
val purchaseResult = Purchases.sharedInstance.awaitPurchase(
  storeProduct = products.first()
)

如果您提供多种产品变体,例如 paywall_tester.subs:weeklypaywall_tester.subs:monthlypaywall_tester.subs:yearly,您可以使用 基础产品标识符 paywall_tester.subs 作为 productIds 字段的值来简化产品检索。这告诉 RevenueCat 以列表形式获取 所有相关产品变体,以便您可以在付费墙 UI 中动态展示它们。

检索到产品数据后,您可以通过调用 Purchases.sharedInstance.awaitPurchase(product) 启动 应用内购买流程。这将自动触发 Google Play 购买对话框,使用户能够在您的应用中完成交易。

就这样,您只用几行代码就集成了一个功能完整的 应用内购买流程——无需处理收据、商店 API 或手动购买验证的复杂性。

实现付费墙

0:07:00

现在,是时候使用 Compose Multiplatform 在您的 KMP 项目中实现付费墙了。

业务逻辑

首先,您需要从 RevenueCat 仪表板 获取当前的 Offering。Offering 定义了向用户展示的可用购买选项,例如月度、年度或终身计划。这可以使用 Purchases.sharedInstance.awaitOfferings() 方法轻松完成,如下例所示。

kotlin
internal class DetailsRepositoryImpl : DetailsRepository {

  override fun fetchOffering(): Flow<ApiResponse<Offering>> = flow {
    try {
      val offerings = Purchases.sharedInstance.awaitOfferings()
      offerings.current?.let { currentOffering ->
        val response = ApiResponse.of { currentOffering }
        emit(response)
      }
    } catch (e: PurchasesException) {
      ApiResponse.exception(e)
    }
  }
}

RevenueCat KMP SDK 原生支持 Kotlin 协程,使其能够无缝适配使用协程架构的项目。当前的 Offering 也作为 Flow 公开,允许您响应式地观察变化并相应地更新 UI。

使用 Compose Multiplatform 构建付费墙 UI

此时,一切应该都准备就绪了。如果您已经添加了 com.revenuecat.purchases:purchases-kmp-ui SDK,您可以 轻松使用 Compose Multiplatform 构建付费墙 UI

RevenueCat 的 UI 库提供了内置组件,例如 PaywallDialog,允许您 快速显示付费墙屏幕或对话框。这些组件完全可定制,提供各种配置选项来调整外观和行为以匹配您的应用设计。

以下是一个示例,展示了使用 Compose Multiplatform 实现和自定义付费墙是多么简单:

kotlin
val currentOffering by viewModel.offering.collectAsState()

val options = remember {
    PaywallOptions(dismissRequest = { TODO("Handle dismiss") }) {
        offering = currentOffering
        shouldDisplayDismissButton = true
    }
}

Paywall(options)

配置完成!现在,当用户没有所需权益时,您将能够使用在 Paywall Editor 中配置的完全相同的设计来显示付费墙。

正如您在 Codelab: RevenueCat Google Play 集成(创建付费墙) 中所见,付费墙系统基于 服务端驱动 UI 构建。这意味着您可以直接从仪表板动态更新付费墙的内容和设计,无需推送应用更新或经过审核流程。

总结

在本 Codelab 中,您学习了如何集成 RevenueCat 的 KMP SDK、实现应用内购买以及在 Compose Multiplatform 中构建付费墙。现在是时候发布您的应用并赚取更多收入了!

您还可以通过以下资源了解更多关于使用 RevenueCat SDK 的信息:

  • 产品教程:帮助您入门并充分利用 RevenueCat 的视频教程。