144 lines
5.8 KiB
Swift
144 lines
5.8 KiB
Swift
//
|
|
// StatusInfoView.swift
|
|
// Feels
|
|
//
|
|
// Created by Trey Tartt on 7/8/22.
|
|
//
|
|
|
|
import SwiftUI
|
|
import StoreKit
|
|
|
|
struct StatusInfoView: View {
|
|
@EnvironmentObject var iapManager: IAPManager
|
|
|
|
let product: Product
|
|
let status: Product.SubscriptionInfo.Status
|
|
|
|
var body: some View {
|
|
ScrollView {
|
|
Text(statusDescription())
|
|
.frame(maxWidth: .infinity, alignment: .center)
|
|
.font(.body)
|
|
}
|
|
.frame(maxWidth: .infinity)
|
|
.frame(height: 75)
|
|
}
|
|
|
|
//Build a string description of the subscription status to display to the user.
|
|
fileprivate func statusDescription() -> String {
|
|
guard case .verified(let renewalInfo) = status.renewalInfo,
|
|
case .verified(let transaction) = status.transaction else {
|
|
return "The App Store could not verify your subscription status."
|
|
}
|
|
|
|
var description = ""
|
|
|
|
switch status.state {
|
|
case .subscribed:
|
|
let renewToProduct: Product?
|
|
let renewalInfo: RenewalInfo?
|
|
|
|
renewalInfo = try? iapManager.checkVerified(status.renewalInfo)
|
|
renewToProduct = iapManager.subscriptions.first(where: {
|
|
$0.key.id == renewalInfo?.autoRenewPreference
|
|
})?.key
|
|
|
|
description = subscribedDescription(expirationDate: transaction.expirationDate,
|
|
willRenew: renewalInfo?.willAutoRenew ?? false,
|
|
willRenewTo: renewToProduct)
|
|
case .expired:
|
|
if let expirationDate = transaction.expirationDate,
|
|
let expirationReason = renewalInfo.expirationReason {
|
|
description = expirationDescription(expirationReason, expirationDate: expirationDate)
|
|
}
|
|
case .revoked:
|
|
if let revokedDate = transaction.revocationDate {
|
|
description = "The App Store refunded your subscription to \(product.displayName) on \(revokedDate.formattedDate())."
|
|
}
|
|
case .inGracePeriod:
|
|
description = gracePeriodDescription(renewalInfo)
|
|
case .inBillingRetryPeriod:
|
|
description = billingRetryDescription()
|
|
default:
|
|
break
|
|
}
|
|
return description
|
|
}
|
|
|
|
fileprivate func billingRetryDescription() -> String {
|
|
var description = "The App Store could not confirm your billing information for \(product.displayName)."
|
|
description += " Please verify your billing information to resume service."
|
|
return description
|
|
}
|
|
|
|
fileprivate func gracePeriodDescription(_ renewalInfo: RenewalInfo) -> String {
|
|
var description = "The App Store could not confirm your billing information for \(product.displayName)."
|
|
if let untilDate = renewalInfo.gracePeriodExpirationDate {
|
|
description += " Please verify your billing information to continue service after \(untilDate.formattedDate())"
|
|
}
|
|
|
|
return description
|
|
}
|
|
|
|
fileprivate func subscribedDescription(expirationDate: Date?, willRenew: Bool, willRenewTo: Product?) -> String {
|
|
var description = "You are currently subscribed to \(product.displayName)"
|
|
|
|
if let expirationDate = expirationDate {
|
|
description += ", which will expire on \(expirationDate.formattedDate()),"
|
|
}
|
|
|
|
if willRenew {
|
|
if let willRenewTo = willRenewTo {
|
|
if willRenewTo == product {
|
|
description += " and will auto renew."
|
|
} else {
|
|
description += " and will auto renew to \(willRenewTo.displayName) at \(willRenewTo.displayPrice)."
|
|
}
|
|
}
|
|
} else {
|
|
description += " and will NOT auto renew."
|
|
}
|
|
|
|
return description
|
|
}
|
|
|
|
fileprivate func renewalDescription(_ renewalInfo: RenewalInfo, _ expirationDate: Date) -> String {
|
|
var description = ""
|
|
|
|
if let newProductID = renewalInfo.autoRenewPreference {
|
|
if let newProduct = iapManager.subscriptions.first(where: { $0.key.id == newProductID }) {
|
|
description += "\nYour subscription to \(newProduct.key.displayName)"
|
|
description += " will begin when your current subscription expires on \(expirationDate.formattedDate())."
|
|
}
|
|
} else if renewalInfo.willAutoRenew {
|
|
description += "\nWill auto renew on: \(expirationDate.formattedDate())."
|
|
}
|
|
|
|
return description
|
|
}
|
|
|
|
//Build a string description of the `expirationReason` to display to the user.
|
|
fileprivate func expirationDescription(_ expirationReason: RenewalInfo.ExpirationReason, expirationDate: Date) -> String {
|
|
var description = ""
|
|
|
|
switch expirationReason {
|
|
case .autoRenewDisabled:
|
|
if expirationDate > Date() {
|
|
description += "Your subscription to \(product.displayName) will expire on \(expirationDate.formattedDate())."
|
|
} else {
|
|
description += "Your subscription to \(product.displayName) expired on \(expirationDate.formattedDate())."
|
|
}
|
|
case .billingError:
|
|
description = "Your subscription to \(product.displayName) was not renewed due to a billing error."
|
|
case .didNotConsentToPriceIncrease:
|
|
description = "Your subscription to \(product.displayName) was not renewed due to a price increase that you disapproved."
|
|
case .productUnavailable:
|
|
description = "Your subscription to \(product.displayName) was not renewed because the product is no longer available."
|
|
default:
|
|
description = "Your subscription to \(product.displayName) was not renewed."
|
|
}
|
|
|
|
return description
|
|
}
|
|
}
|