我可以检查Superwall和RevenueCat中"PaywallDelegate"扩展中的用户订阅变量Bool吗?



我正在Swift中整合Superwall和RevenueCat。我已经决定使用Superwall,因为它易于配置和设置,但我实际上很难有条件地只向未订阅该平台的用户呈现付费墙。是否有专业的方法来检查(isusersubscriptions),如果用户是正确订阅?

extension PaywallService: PaywallDelegate {


// 1
func purchase(product: SKProduct) {
Task {
do {
let result = try await Purchases.shared.purchase(product: StoreProduct(sk1Product: product))
// React to the purchase here

print(result)
} catch {
// Handle purchase error here
}
}
}
// 2
func restorePurchases(completion: @escaping (Bool) -> Void) {
Task {
do {
let purchaserInfo = try await Purchases.shared.restorePurchases()

// check purchaserInfo to see if subscription "MyEntitlement" is now active
let restored = purchaserInfo.entitlements.all["subPlan"]?.isActive == true

completion(restored)
} catch {
completion(false)
}
}
}



// 3
func **isUserSubscribed**()  -> Bool {
// TODO: I need to check here if the user is correctly subscribed, but this first run always gives false and the user is ALWAYS getting the paywall. 


var isSub:Bool = false
Purchases.shared.getCustomerInfo  { purchaserInfo, error in
// access latest purchaserInfo

if (purchaserInfo?.entitlements.all["subPlan"]?.isActive == true) {
isSub = purchaserInfo?.entitlements.all["subPlan"]?.isActive == true

} else {
isSub = false
}

}

return isSub


}
}

多谢!

我的第一次运行总是返回false,用户总是获得付费墙。

你得到的问题是,Purchases.shared.getCustomerInfo有一个异步的完成块。这意味着在完成块有机会更新isSub之前,立即返回isSub的值,这就是为什么它总是将false

为了同时管理RevenueCat和Superwall,我们建议创建一个类来处理这一切,称为PaywallManager.swift(记住替换您的API密钥):

import Paywall
import RevenueCat
import StoreKit
final class PaywallManager: NSObject {
static let shared = PaywallManager()
var isSubscribed = false
#warning("Replace these with your API keys:")
private static let revenueCatApiKey = "YOUR_REVENUECAT_PUBLIC_API_KEY"
private static let superwallApiKey = "YOUR_SUPERWALL_PUBLIC_API_KEY"
private let proEntitlement = "subPlan"
/// Configures both the RevenueCat and Superwall SDKs.
///
/// Call this on `application(_:didFinishLaunchingWithOptions:)`
static func configure() {
Purchases.configure(withAPIKey: revenueCatApiKey)
Purchases.shared.delegate = shared
Paywall.configure(
apiKey: superwallApiKey,
delegate: shared
)
}
/// Logs the user in to both RevenueCat and Superwall with the specified `userId`.
///
/// Call this when you retrieve a userId.
static func logIn(userId: String) async {
do {
let (customerInfo, _) = try await Purchases.shared.logIn(userId)
shared.updateSubscriptionStatus(using: customerInfo)
Paywall.identify(userId: userId)
} catch {
print("A RevenueCat error occurred", error)
}
}
/// Logs the user out of RevenueCat and Superwall.
///
/// Call this when your user logs out.
func logOut() async {
do {
let customerInfo = try await Purchases.shared.logOut()
updateSubscriptionStatus(using: customerInfo)
Paywall.reset()
} catch {
print("A RevenueCat error occurred", error)
}
}
/// Handles a deep link to open a paywall preview.
///
/// [See here](https://docs.superwall.com/docs/in-app-paywall-previews#handling-deep-links)
/// for information on how to call this function in your app.
static func handleDeepLink(_ url: URL) {
Paywall.handleDeepLink(url)
}
}
// MARK: - Purchases Delegate
extension PaywallManager: PurchasesDelegate {
/// Handles updated CustomerInfo received from RevenueCat.
func purchases(_ purchases: Purchases, receivedUpdated customerInfo: CustomerInfo) {
updateSubscriptionStatus(using: customerInfo)
}
/// Updates the subscription status in response to customer info received from RevenueCat.
private func updateSubscriptionStatus(using customerInfo: CustomerInfo) {
isSubscribed = customerInfo.entitlements.active[proEntitlement] != nil
}
/// Restores purchases and updates subscription status.
///
/// - Returns: A boolean indicating whether the user restored a purchase or not.
private func restore() async -> Bool {
do {
let customerInfo = try await Purchases.shared.restorePurchases()
updateSubscriptionStatus(using: customerInfo)
return customerInfo.entitlements.active[proEntitlement] != nil
} catch {
return false
}
}
/// Purchases a product with RevenueCat.
///
/// - Returns: A boolean indicating whether the user cancelled or not.
private func purchase(_ product: SKProduct) async {
let storeProduct = StoreProduct(sk1Product: product)
do {
let (_, customerInfo, _) = try await Purchases.shared.purchase(product: storeProduct)
updateSubscriptionStatus(using: customerInfo)
} catch {
print("An error occurred purchasing", error)
}
}
}
// MARK: - Paywall Delegate
extension PaywallManager: PaywallDelegate {
/// Purchase a product from a paywall.
func purchase(product: SKProduct) {
Task {
await purchase(product)
}
}
func restorePurchases(completion: @escaping (Bool) -> Void) {
Task {
let isRestored = await restore()
completion(isRestored)
}
}
/// Lets Superwall know whether the user is subscribed or not.
func isUserSubscribed() -> Bool {
return isSubscribed
}
}

在AppDelegate中调用:

func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
PaywallManager.configure()
}

它的作用是在配置Paywall之前先配置和设置Purchases的委托。当它这样做时,委托函数purchases(_:,receivedUpdated:)接收到一个带有最新CustomerInfo的回调。在调用isUserSubscribed()之前,它确定并存储用户的订阅状态。

请注意,对于你的应用程序的新安装,如果你有一个session_start触发器,isUserSubscribed()仍然会被调用之前RevenueCat有机会更新订阅状态,因为RevenueCat正在检索客户信息从网上。对于后续的应用程序打开,用户订阅状态将是正确的。我们将在我们的应用程序的下一个主要更新中修复这个问题,但是,除非有订阅的用户重新下载应用程序,否则你应该没事。

最新更新