Files
eqn.ios/Sources/Earthquake Network/Controllers/InApp/SubscriptionDetailsViewController.swift
2025-03-07 09:42:26 +01:00

184 lines
6.7 KiB
Swift

//
// SubscriptionDetailsViewController.swift
// Earthquake Network
//
// Created by Andrea Busi on 18/06/24.
// Copyright © 2024 Earthquake Network. All rights reserved.
//
import UIKit
import StoreKit
import SafariServices
import Shogun
class SubscriptionDetailsViewController: UITableViewController {
/// Enable this allows shake to enable the current subscription
private static let ShakeToEnableSubscription = false
// MARK: - Internal
private let products: [EQNInAppProducts]
private var selectedProduct: EQNInAppProducts {
didSet {
onProductSelected()
}
}
private var priceFormatter: NumberFormatter = {
let formatter = NumberFormatter()
formatter.formatterBehavior = .behavior10_4
formatter.numberStyle = .currency
return formatter
}()
// MARK: - Init
init(
products: [EQNInAppProducts]
) {
self.products = products
self.selectedProduct = products.first(where: { $0.plan == .yearly }) ?? products.first!
super.init(style: .plain)
}
required init?(coder: NSCoder) {
fatalError("Please use init(products:) instead.")
}
// MARK: - View Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
configureUI()
addObservers()
}
private func addObservers() {
NotificationCenter.default.addObserver(self, selector: #selector(handlePurchaseNotification(_:)),
name: .EQNInAppPurchaseDidComplete,
object: nil)
}
private func configureUI() {
tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 2000.0
tableView.separatorStyle = .none
tableView.backgroundColor = .systemGroupedBackground
tableView.contentInset = EQNBaseContainerTableViewCell.EdgeInsets
tableView.registerCell(for: SubscriptionDetailsTableViewCell.self)
}
// MARK: - Notifications
@objc private func handlePurchaseNotification(_ notification: Notification) {
navigationController?.popViewController(animated: true)
}
// MARK: - Table view delegate & data source
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
1
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(cellIdentifiable: SubscriptionDetailsTableViewCell.self, for: indexPath)
cell.selectionStyle = .none
cell.productTitleLabel.text = selectedProduct.product.localizedTitle
cell.productImageView.image = selectedProduct.category.image
var purchaseRecapString = ""
var subscriptionDetailsString = ""
switch selectedProduct.productIdentifier {
case EQNInAppProducts.Identifier.Subscription10kMonthly,
EQNInAppProducts.Identifier.Subscription100kMonthly:
purchaseRecapString = "inapp_monthly_payment"
subscriptionDetailsString = "inapp_detail_description"
case EQNInAppProducts.Identifier.Subscription100kYearly,
EQNInAppProducts.Identifier.Subscription100kYearlyDiscounted,
EQNInAppProducts.Identifier.Subscription10kYearly,
EQNInAppProducts.Identifier.Subscription10kYearlyDiscounted:
purchaseRecapString = "inapp_yearly_payment"
subscriptionDetailsString = "inapp_detail_description"
case EQNInAppProducts.Identifier.Subscription10kPerpetual,
EQNInAppProducts.Identifier.Subscription100kPerpetual:
purchaseRecapString = "inapp_lifetime_payment"
subscriptionDetailsString = "inapp_lifetime_detail_description"
default:
break
}
cell.subscriptionDetailsLabel.text = NSLocalizedString(subscriptionDetailsString, comment: "")
cell.onTapPrivacy = { [weak self] in
self?.openExternalLink("\(EQNWebsiteAddress)/privacy/")
}
cell.onTapTerms = { [weak self] in
self?.openExternalLink("\(EQNWebsiteAddress)/terms-conditions/")
}
cell.onTapPurchase = { [weak self] in
self?.purchaseSelectedProduct()
}
cell.onChangePlan = { [weak self] type in
if let product = self?.productFromProductType(type) {
self?.selectedProduct = product
}
}
cell.planSegmentedControl.selectedSegmentIndex = selectedProduct.plan.index
cell.purchaseRecapLabel.text = "\(selectedProduct.product.localizedDescription), \(NSLocalizedString(purchaseRecapString, comment: ""))"
cell.productPriceLabel.text = priceFormatter.string(from: selectedProduct.product.price)
return cell
}
// MARK: - Private
private func onProductSelected() {
priceFormatter.locale = selectedProduct.product.priceLocale
tableView.reloadData()
}
private func openExternalLink(_ stringUrl: String) {
if let url = URL(string: stringUrl) {
let controller = SFSafariViewController(url: url)
present(controller, animated: true, completion: nil)
}
}
private func purchaseSelectedProduct() {
EQNInAppProducts.store.buyProduct(selectedProduct.product)
}
private func productFromProductType(_ type: EQNInAppProducts.Plan) -> EQNInAppProducts? {
let product: EQNInAppProducts?
switch type {
case .monthly:
product = products.first { $0.plan == .monthly }
case .yearly:
product = products.first { $0.plan == .yearly }
case .perpetual:
product = products.first { $0.plan == .perpetual }
}
return product
}
}
extension SubscriptionDetailsViewController {
override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
guard event?.subtype == .motionShake, Self.ShakeToEnableSubscription else {
return
}
let alert = UIAlertController(title: "🧑‍💻", message: "Please select an action", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Reset all purchases", style: .default) { action in
EQNPurchaseUtility.resetInAppPurchases()
})
alert.addAction(UIAlertAction(title: "Activate this subscription", style: .default) { action in
EQNPurchaseUtility.simulateProPurchase(identifier: self.selectedProduct.productIdentifier)
})
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
present(alert, animated: true, completion: nil)
}
}