Skip to content

Commit

Permalink
Fix brave/brave-ios#7875: VPN Restore Infinite Loading (brave/brave-i…
Browse files Browse the repository at this point in the history
…os#7951)

- Handling restore completed empty restorations and timer for action
  • Loading branch information
soner-yuksel authored Aug 25, 2023
1 parent 4999560 commit 94469ee
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 1 deletion.
35 changes: 34 additions & 1 deletion Sources/BraveVPN/BuyVPNViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import DesignSystem
class BuyVPNViewController: VPNSetupLoadingController {

let iapObserver: IAPObserver

private var iapRestoreTimer: Timer?

var activeSubcriptionChoice: SubscriptionType = .yearly {
didSet {
buyVPNView.activeSubcriptionChoice = activeSubcriptionChoice
Expand Down Expand Up @@ -134,6 +135,19 @@ class BuyVPNViewController: VPNSetupLoadingController {
@objc func restorePurchasesAction() {
isLoading = true
SKPaymentQueue.default().restoreCompletedTransactions()

if iapRestoreTimer != nil {
iapRestoreTimer?.invalidate()
iapRestoreTimer = nil
}

// Adding 1 minute timer for restore
iapRestoreTimer = Timer.scheduledTimer(
timeInterval: 1.minutes,
target: self,
selector: #selector(handleRestoreTimeoutFailure),
userInfo: nil,
repeats: false)
}

@objc func startSubscriptionAction() {
Expand Down Expand Up @@ -182,6 +196,25 @@ extension BuyVPNViewController: IAPObserverDelegate {
}

func purchaseFailed(error: IAPObserver.PurchaseError) {
// Handle Transaction or Restore error
guard isLoading else {
return
}

handleTransactionError(error: error)
}

@objc func handleRestoreTimeoutFailure() {
// Handle Restore error from timeout
guard isLoading else {
return
}

let errorRestore = SKError(SKError.unknown, userInfo: ["detail": "time-out"])
handleTransactionError(error: .transactionError(error: errorRestore))
}

private func handleTransactionError(error: IAPObserver.PurchaseError) {
DispatchQueue.main.async {
self.isLoading = false

Expand Down
10 changes: 10 additions & 0 deletions Sources/BraveVPN/IAPObserver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,14 @@ public class IAPObserver: NSObject, SKPaymentTransactionObserver {
Logger.module.debug("Restoring transaction failed")
self.delegate?.purchaseFailed(error: .transactionError(error: error as? SKError))
}

// Used to handle restoring transaction error for users never purchased but trying to restore
public func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {
if queue.transactions.isEmpty {
Logger.module.debug("Restoring transaction failed - Nothing to restore - Account never bought this product")

let errorRestore = SKError(SKError.unknown, userInfo: ["detail": "not-purchased"])
delegate?.purchaseFailed(error: .transactionError(error: errorRestore))
}
}
}

0 comments on commit 94469ee

Please sign in to comment.