-
Notifications
You must be signed in to change notification settings - Fork 326
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use SK2 RenewalInfo to get renewal prices & currency #4608
Changes from all commits
1f608ee
4d0342f
1fc7513
b8aaec4
c6e7d9f
78d03c5
3aeb44f
b15755d
d26883d
31501b9
9c452eb
0725da8
a3a26a7
524bd07
52479a1
4154ddf
a2dcd7a
5635d08
38264d5
61c699d
73ee192
716f6a4
2445eb1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
// | ||
// Copyright RevenueCat Inc. All Rights Reserved. | ||
// | ||
// Licensed under the MIT License (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// https://opensource.org/licenses/MIT | ||
// | ||
// CustomerCenterStoreKitUtilities.swift | ||
// | ||
// Created by Will Taylor on 12/18/24. | ||
|
||
import Foundation | ||
import StoreKit | ||
|
||
import RevenueCat | ||
|
||
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, visionOS 1.0, *) | ||
class CustomerCenterStoreKitUtilities: CustomerCenterStoreKitUtilitiesType { | ||
|
||
func renewalPriceFromRenewalInfo(for product: StoreProduct) async -> (price: Decimal, currencyCode: String)? { | ||
|
||
#if compiler(>=6.0) | ||
guard let renewalInfo = await renewalInfo(for: product) else { return nil } | ||
guard let renewalPrice = renewalInfo.renewalPrice else { return nil } | ||
guard let currencyCode = currencyCode(fromRenewalInfo: renewalInfo) else { return nil } | ||
|
||
return (renewalPrice, currencyCode) | ||
#else | ||
return nil | ||
#endif | ||
} | ||
|
||
private func currencyCode( | ||
fromRenewalInfo renewalInfo: Product.SubscriptionInfo.RenewalInfo, | ||
locale: Locale = Locale.current | ||
) -> String? { | ||
if #available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, watchOSApplicationExtension 9.0, *) { | ||
|
||
// renewalInfo.currency was introduced in iOS 18.0 and backdeployed through iOS 16.0 | ||
// However, Xcode versions <15.0 don't have the symbols, so we need to check the compiler version | ||
// to make sure that this is being built with an Xcode version >=15.0. | ||
#if compiler(>=6.0) | ||
guard let currency = renewalInfo.currency else { return nil } | ||
if currency.isISOCurrency { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. interesting, what's the other option if it's not ISO? just curious There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm honestly not sure, but |
||
return currency.identifier | ||
} else { | ||
return nil | ||
} | ||
#else | ||
return nil | ||
#endif | ||
} else { | ||
#if os(visionOS) || compiler(<6.0) | ||
return nil | ||
#else | ||
return renewalInfo.currencyCode | ||
#endif | ||
} | ||
} | ||
|
||
private func renewalInfo( | ||
for product: RevenueCat.StoreProduct | ||
) async -> Product.SubscriptionInfo.RenewalInfo? { | ||
guard let statuses = try? await product.sk2Product?.subscription?.status, !statuses.isEmpty else { | ||
// If StoreKit.Product.subscription is nil, then the product isn't a subscription | ||
// If statuses is empty, the subscriber was never subscribed to a product in the subscription group. | ||
return nil | ||
} | ||
|
||
guard let purchaseSubscriptionStatus = statuses.first(where: { | ||
do { | ||
return try $0.transaction.payloadValue.ownershipType == .purchased | ||
} catch { | ||
return false | ||
} | ||
}) else { | ||
return nil | ||
} | ||
|
||
switch purchaseSubscriptionStatus.renewalInfo { | ||
case .unverified: | ||
return nil | ||
case .verified(let renewalInfo): | ||
return renewalInfo | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// | ||
// Copyright RevenueCat Inc. All Rights Reserved. | ||
// | ||
// Licensed under the MIT License (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// https://opensource.org/licenses/MIT | ||
// | ||
// CustomerCenterStoreKitUtilitiesType.swift | ||
// | ||
// Created by Will Taylor on 12/18/24. | ||
|
||
import Foundation | ||
import StoreKit | ||
|
||
import RevenueCat | ||
|
||
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, visionOS 1.0, *) | ||
protocol CustomerCenterStoreKitUtilitiesType { | ||
|
||
func renewalPriceFromRenewalInfo(for product: StoreProduct) async -> (price: Decimal, currencyCode: String)? | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fall back to our old calculation method if the RenewalInfo method failed for some reason