98 lines
2.8 KiB
Swift
98 lines
2.8 KiB
Swift
//
|
|
// TransactionObserver.swift
|
|
// Toki Trainer
|
|
//
|
|
// Created by Madeline Pace on 12/18/23.
|
|
//
|
|
|
|
import CoreData
|
|
import StoreKit
|
|
|
|
@MainActor
|
|
final class TransactionObserver: ObservableObject {
|
|
|
|
var updates: Task<Void, Never>? = nil
|
|
|
|
@Published var donationHearts: Int = 0
|
|
@Published var hasDonated = false
|
|
|
|
|
|
init() {
|
|
updates = newTransactionListenerTask()
|
|
donationHearts = UserDefaults.standard.integer(forKey: K.UserDefaults.donationHearts)
|
|
hasDonated = UserDefaults.standard.bool(forKey: K.UserDefaults.hasDonated)
|
|
}
|
|
|
|
deinit {
|
|
updates?.cancel()
|
|
}
|
|
|
|
func addDonationHearts(_ amount: Int) {
|
|
if hasDonated == false {
|
|
hasDonated = true
|
|
UserDefaults.standard.set(hasDonated, forKey: K.UserDefaults.hasDonated)
|
|
}
|
|
|
|
DispatchQueue.main.async {
|
|
self.donationHearts += amount
|
|
}
|
|
UserDefaults.standard.set(donationHearts, forKey: K.UserDefaults.donationHearts)
|
|
}
|
|
|
|
private func newTransactionListenerTask() -> Task<Void, Never> {
|
|
Task(priority: .background) {
|
|
for await verificationResult in Transaction.updates {
|
|
await self.handle(updatedTransaction: verificationResult)
|
|
}
|
|
}
|
|
}
|
|
|
|
private func handle(updatedTransaction verificationResult: VerificationResult<Transaction>) async {
|
|
guard case .verified(let transaction) = verificationResult else {
|
|
return
|
|
}
|
|
|
|
switch transaction.productType {
|
|
case Product.ProductType.consumable:
|
|
processConsumable(transaction.productID)
|
|
case Product.ProductType.nonRenewable, Product.ProductType.autoRenewable:
|
|
processSubscription(transaction.productID)
|
|
default:
|
|
return
|
|
}
|
|
|
|
print("Finishing transaction")
|
|
await transaction.finish()
|
|
}
|
|
|
|
func processConsumable(_ productID: String) {
|
|
print("Consumable ID: \(productID)")
|
|
switch productID {
|
|
case K.ConsumableTransactions.TierOne:
|
|
self.addDonationHearts(100)
|
|
case K.ConsumableTransactions.TierTwo:
|
|
self.addDonationHearts(500)
|
|
case K.ConsumableTransactions.TierThree:
|
|
self.addDonationHearts(1000)
|
|
case K.ConsumableTransactions.TierFour:
|
|
self.addDonationHearts(2000)
|
|
default:
|
|
return
|
|
}
|
|
}
|
|
|
|
func processSubscription(_ productID: String) {
|
|
print("Subscription ID: \(productID)")
|
|
switch productID {
|
|
case K.MonthlyTransactions.TierOne:
|
|
self.addDonationHearts(100)
|
|
case K.MonthlyTransactions.TierTwo:
|
|
self.addDonationHearts(500)
|
|
case K.MonthlyTransactions.TierThree:
|
|
self.addDonationHearts(1000)
|
|
default:
|
|
return
|
|
}
|
|
}
|
|
}
|