|
@@ -58,6 +58,11 @@ final class SubscriptionManager: ObservableObject {
|
|
|
private var inFlightProductLoad: Task<Void, Never>?
|
|
private var inFlightProductLoad: Task<Void, Never>?
|
|
|
private var initialEntitlementTask: Task<Void, Never>?
|
|
private var initialEntitlementTask: Task<Void, Never>?
|
|
|
private var hasStarted = false
|
|
private var hasStarted = false
|
|
|
|
|
+ private var cancellables = Set<AnyCancellable>()
|
|
|
|
|
+
|
|
|
|
|
+ var isFirstTimeAppUser: Bool {
|
|
|
|
|
+ AppUsageManager.shared.isFirstTimeUser
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
init() {
|
|
init() {
|
|
|
hasPremiumAccess = UserDefaults.standard.bool(forKey: Self.cachedPremiumKey)
|
|
hasPremiumAccess = UserDefaults.standard.bool(forKey: Self.cachedPremiumKey)
|
|
@@ -71,6 +76,14 @@ final class SubscriptionManager: ObservableObject {
|
|
|
guard !hasStarted else { return }
|
|
guard !hasStarted else { return }
|
|
|
hasStarted = true
|
|
hasStarted = true
|
|
|
|
|
|
|
|
|
|
+ AppUsageManager.shared.start()
|
|
|
|
|
+
|
|
|
|
|
+ NotificationCenter.default.publisher(for: AppUsageManager.didCompleteFirstSession)
|
|
|
|
|
+ .sink { [weak self] _ in
|
|
|
|
|
+ self?.objectWillChange.send()
|
|
|
|
|
+ }
|
|
|
|
|
+ .store(in: &cancellables)
|
|
|
|
|
+
|
|
|
Task { await listenForTransactionUpdates() }
|
|
Task { await listenForTransactionUpdates() }
|
|
|
|
|
|
|
|
initialEntitlementTask = Task {
|
|
initialEntitlementTask = Task {
|
|
@@ -89,7 +102,8 @@ final class SubscriptionManager: ObservableObject {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
func eligibleIntroOffer(for product: Product) -> Product.SubscriptionOffer? {
|
|
func eligibleIntroOffer(for product: Product) -> Product.SubscriptionOffer? {
|
|
|
- guard introOfferEligibleByProductID[product.id] == true,
|
|
|
|
|
|
|
+ guard isFirstTimeAppUser,
|
|
|
|
|
+ introOfferEligibleByProductID[product.id] == true,
|
|
|
let offer = product.subscription?.introductoryOffer,
|
|
let offer = product.subscription?.introductoryOffer,
|
|
|
offer.paymentMode == .freeTrial else {
|
|
offer.paymentMode == .freeTrial else {
|
|
|
return nil
|
|
return nil
|
|
@@ -131,9 +145,11 @@ final class SubscriptionManager: ObservableObject {
|
|
|
return plan.fallbackBillingDescription(config: config)
|
|
return plan.fallbackBillingDescription(config: config)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if let subscription = product.subscription,
|
|
|
|
|
|
|
+ if isFirstTimeAppUser,
|
|
|
|
|
+ let subscription = product.subscription,
|
|
|
let intro = subscription.introductoryOffer,
|
|
let intro = subscription.introductoryOffer,
|
|
|
- intro.paymentMode == .freeTrial {
|
|
|
|
|
|
|
+ intro.paymentMode == .freeTrial,
|
|
|
|
|
+ introOfferEligibleByProductID[product.id] == true {
|
|
|
let trialPeriod = formattedPeriod(intro.period)
|
|
let trialPeriod = formattedPeriod(intro.period)
|
|
|
let billingPeriod = formattedSubscriptionPeriod(subscription.subscriptionPeriod)
|
|
let billingPeriod = formattedSubscriptionPeriod(subscription.subscriptionPeriod)
|
|
|
return "\(trialPeriod) Free Trial, then \(product.displayPrice) per \(billingPeriod)"
|
|
return "\(trialPeriod) Free Trial, then \(product.displayPrice) per \(billingPeriod)"
|