Various improvements

This commit is contained in:
Ilya Laktyushin
2023-01-21 15:56:57 +04:00
parent 9c99c04e64
commit 58c532b51e
44 changed files with 1270 additions and 358 deletions

View File

@@ -154,10 +154,12 @@ public final class InAppPurchaseManager: NSObject {
private final class PaymentTransactionContext {
var state: SKPaymentTransactionState?
var isUpgrade: Bool
var targetPeerId: PeerId?
let subscriber: (TransactionState) -> Void
init(targetPeerId: PeerId?, subscriber: @escaping (TransactionState) -> Void) {
init(isUpgrade: Bool, targetPeerId: PeerId?, subscriber: @escaping (TransactionState) -> Void) {
self.isUpgrade = isUpgrade
self.targetPeerId = targetPeerId
self.subscriber = subscriber
}
@@ -236,7 +238,7 @@ public final class InAppPurchaseManager: NSObject {
}
}
public func buyProduct(_ product: Product, targetPeerId: PeerId? = nil) -> Signal<PurchaseState, PurchaseError> {
public func buyProduct(_ product: Product, isUpgrade: Bool = false, targetPeerId: PeerId? = nil) -> Signal<PurchaseState, PurchaseError> {
if !self.canMakePayments {
return .fail(.cantMakePayments)
}
@@ -258,7 +260,7 @@ public final class InAppPurchaseManager: NSObject {
let disposable = MetaDisposable()
self.stateQueue.async {
let paymentContext = PaymentTransactionContext(targetPeerId: targetPeerId, subscriber: { state in
let paymentContext = PaymentTransactionContext(isUpgrade: isUpgrade, targetPeerId: targetPeerId, subscriber: { state in
switch state {
case let .purchased(transactionId), let .restored(transactionId):
if let transactionId = transactionId {
@@ -305,6 +307,13 @@ public final class InAppPurchaseManager: NSObject {
}
return signal
}
public func getValidTransactionIds() -> [String] {
guard let data = getReceiptData(), let receipt = parseReceipt(data) else {
return []
}
return receipt.purchases.map { $0.transactionId }
}
}
extension InAppPurchaseManager: SKProductsRequestDelegate {
@@ -370,6 +379,7 @@ extension InAppPurchaseManager: SKPaymentTransactionObserver {
productId: transaction.payment.productIdentifier,
content: PendingInAppPurchaseState(
productId: transaction.payment.productIdentifier,
isUpgrade: paymentContext.isUpgrade,
targetPeerId: paymentContext.targetPeerId
)
).start()
@@ -431,7 +441,23 @@ extension InAppPurchaseManager: SKPaymentTransactionObserver {
}
}
} else {
purpose = .single(.subscription)
let isUpgrade: Signal<Bool, NoError>
if let isUpgradeValue = paymentContexts[productIdentifier]?.isUpgrade {
isUpgrade = .single(isUpgradeValue)
} else {
isUpgrade = pendingInAppPurchaseState(engine: self.engine, productId: productIdentifier)
|> mapToSignal { state -> Signal<Bool, NoError> in
if let state = state {
return .single(state.isUpgrade)
} else {
return .single(false)
}
}
}
purpose = isUpgrade
|> map { isUpgrade in
return isUpgrade ? .upgrade : .subscription
}
}
let receiptData = getReceiptData() ?? Data()
@@ -508,10 +534,12 @@ extension InAppPurchaseManager: SKPaymentTransactionObserver {
private final class PendingInAppPurchaseState: Codable {
public let productId: String
public let isUpgrade: Bool
public let targetPeerId: PeerId?
public init(productId: String, targetPeerId: PeerId?) {
public init(productId: String, isUpgrade: Bool, targetPeerId: PeerId?) {
self.productId = productId
self.isUpgrade = isUpgrade
self.targetPeerId = targetPeerId
}
@@ -519,6 +547,7 @@ private final class PendingInAppPurchaseState: Codable {
let container = try decoder.container(keyedBy: StringCodingKey.self)
self.productId = try container.decode(String.self, forKey: "productId")
self.isUpgrade = try container.decodeIfPresent(Bool.self, forKey: "isUpgrade") ?? false
self.targetPeerId = (try container.decodeIfPresent(Int64.self, forKey: "targetPeerId")).flatMap { PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value($0)) }
}
@@ -526,6 +555,7 @@ private final class PendingInAppPurchaseState: Codable {
var container = encoder.container(keyedBy: StringCodingKey.self)
try container.encode(self.productId, forKey: "productId")
try container.encode(self.isUpgrade, forKey: "isUpgrade")
if let targetPeerId = self.targetPeerId {
try container.encode(targetPeerId.id._internalGetInt64Value(), forKey: "targetPeerId")
}