Files
Reflect/Shared/views/StatusInfoView.swift
2022-07-17 10:26:00 -05:00

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
}
}