diff options
| author | Andrej Mihajlov <and@mullvad.net> | 2020-07-21 14:26:34 +0300 |
|---|---|---|
| committer | Andrej Mihajlov <and@mullvad.net> | 2020-07-22 18:35:43 +0300 |
| commit | 868f0bdf1d4bb05babbfeec817315027283cf2f1 (patch) | |
| tree | 766ad3cd2b0e4622dab2424cc83e66da0406e347 | |
| parent | 218756ae97e6e222572bd9bb68a5d25268b4a2ac (diff) | |
| download | mullvadvpn-868f0bdf1d4bb05babbfeec817315027283cf2f1.tar.xz mullvadvpn-868f0bdf1d4bb05babbfeec817315027283cf2f1.zip | |
Migrate AppStorePaymentManager to REST
| -rw-r--r-- | ios/MullvadVPN/Account.swift | 2 | ||||
| -rw-r--r-- | ios/MullvadVPN/AccountViewController.swift | 10 | ||||
| -rw-r--r-- | ios/MullvadVPN/AppStorePaymentManager.swift | 36 | ||||
| -rw-r--r-- | ios/MullvadVPN/MullvadRest.swift | 11 |
4 files changed, 37 insertions, 22 deletions
diff --git a/ios/MullvadVPN/Account.swift b/ios/MullvadVPN/Account.swift index 86865c10d7..eaf9b954c1 100644 --- a/ios/MullvadVPN/Account.swift +++ b/ios/MullvadVPN/Account.swift @@ -227,7 +227,7 @@ extension Account: AppStorePaymentObserver { // no-op } - func appStorePaymentManager(_ manager: AppStorePaymentManager, transaction: SKPaymentTransaction, accountToken: String, didFinishWithResponse response: SendAppStoreReceiptResponse) { + func appStorePaymentManager(_ manager: AppStorePaymentManager, transaction: SKPaymentTransaction, accountToken: String, didFinishWithResponse response: CreateApplePaymentResponse) { let newExpiry = response.newExpiry let operation = AsyncBlockOperation { (finish) in diff --git a/ios/MullvadVPN/AccountViewController.swift b/ios/MullvadVPN/AccountViewController.swift index d95adcf738..1c0ed4177c 100644 --- a/ios/MullvadVPN/AccountViewController.swift +++ b/ios/MullvadVPN/AccountViewController.swift @@ -176,8 +176,8 @@ class AccountViewController: UIViewController, AppStorePaymentObserver { } private func showTimeAddedConfirmationAlert( - with response: SendAppStoreReceiptResponse, - context: SendAppStoreReceiptResponse.Context) + with response: CreateApplePaymentResponse, + context: CreateApplePaymentResponse.Context) { let alertController = UIAlertController( title: response.alertTitle(context: context), @@ -282,7 +282,7 @@ class AccountViewController: UIViewController, AppStorePaymentObserver { } } - func appStorePaymentManager(_ manager: AppStorePaymentManager, transaction: SKPaymentTransaction, accountToken: String, didFinishWithResponse response: SendAppStoreReceiptResponse) { + func appStorePaymentManager(_ manager: AppStorePaymentManager, transaction: SKPaymentTransaction, accountToken: String, didFinishWithResponse response: CreateApplePaymentResponse) { DispatchQueue.main.async { self.showTimeAddedConfirmationAlert(with: response, context: .purchase) @@ -361,7 +361,7 @@ class AccountViewController: UIViewController, AppStorePaymentObserver { } -private extension SendAppStoreReceiptResponse { +private extension CreateApplePaymentResponse { enum Context { case purchase @@ -385,7 +385,7 @@ private extension SendAppStoreReceiptResponse { formattedTimeAdded ?? "" ) case .restoration: - return timeAdded.isZero + return timeAdded == 0 ? NSLocalizedString( "Your previous purchases have already been added to this account.", comment: "") diff --git a/ios/MullvadVPN/AppStorePaymentManager.swift b/ios/MullvadVPN/AppStorePaymentManager.swift index 55a22f8cae..688d2779af 100644 --- a/ios/MullvadVPN/AppStorePaymentManager.swift +++ b/ios/MullvadVPN/AppStorePaymentManager.swift @@ -45,7 +45,7 @@ protocol AppStorePaymentObserver: class { _ manager: AppStorePaymentManager, transaction: SKPaymentTransaction, accountToken: String, - didFinishWithResponse response: SendAppStoreReceiptResponse) + didFinishWithResponse response: CreateApplePaymentResponse) } /// A type-erasing weak container for `AppStorePaymentObserver` @@ -71,7 +71,7 @@ private class AnyAppStorePaymentObserver: WeakObserverBox, Equatable { func appStorePaymentManager(_ manager: AppStorePaymentManager, transaction: SKPaymentTransaction, accountToken: String, - didFinishWithResponse response: SendAppStoreReceiptResponse) + didFinishWithResponse response: CreateApplePaymentResponse) { self.inner?.appStorePaymentManager( manager, @@ -99,7 +99,7 @@ class AppStorePaymentManager: NSObject, SKPaymentTransactionObserver { case noAccountSet case storePayment(Swift.Error) case readReceipt(AppStoreReceipt.Error) - case sendReceipt(MullvadRpc.Error) + case sendReceipt(RestError) var errorDescription: String? { switch self { @@ -115,12 +115,18 @@ class AppStorePaymentManager: NSObject, SKPaymentTransactionObserver { } } + private enum ExlcusivityCategory { + case sendReceipt + } + /// A shared instance of `AppStorePaymentManager` static let shared = AppStorePaymentManager(queue: SKPaymentQueue.default()) private let operationQueue = OperationQueue() + private lazy var exclusivityController = ExclusivityController<ExlcusivityCategory>(operationQueue: operationQueue) + + private let rest = MullvadRest(session: URLSession(configuration: .ephemeral)) private let queue: SKPaymentQueue - private let rpc = MullvadRpc.withEphemeralURLSession() private var observerList = ObserverList<AnyAppStorePaymentObserver>() private let lock = NSRecursiveLock() @@ -225,7 +231,7 @@ class AppStorePaymentManager: NSObject, SKPaymentTransactionObserver { func restorePurchases( for accountToken: String, - completionHandler: @escaping (Result<SendAppStoreReceiptResponse, AppStorePaymentManager.Error>) -> Void) { + completionHandler: @escaping (Result<CreateApplePaymentResponse, AppStorePaymentManager.Error>) -> Void) { return sendAppStoreReceipt( accountToken: accountToken, forceRefresh: true, @@ -235,23 +241,21 @@ class AppStorePaymentManager: NSObject, SKPaymentTransactionObserver { // MARK: - Private methods - private func sendAppStoreReceipt(accountToken: String, forceRefresh: Bool, completionHandler: @escaping (Result<SendAppStoreReceiptResponse, Error>) -> Void) + private func sendAppStoreReceipt(accountToken: String, forceRefresh: Bool, completionHandler: @escaping (Result<CreateApplePaymentResponse, Error>) -> Void) { AppStoreReceipt.fetch(forceRefresh: forceRefresh) { (result) in switch result { case .success(let receiptData): - let request = self.rpc.sendAppStoreReceipt( - accountToken: accountToken, - receiptData: receiptData - ) + let payload = TokenPayload<CreateApplePaymentRequest>(token: accountToken, payload: CreateApplePaymentRequest(receiptString: receiptData)) + + let createApplePaymentOperation = self.rest.createApplePayment() + .operation(payload: payload) - request.start { (result) in + createApplePaymentOperation.addDidFinishBlockObserver { (operation, result) in switch result { case .success(let response): - os_log( - .info, - "AppStore Receipt was processed. Time added: %{public}.2f, New expiry: %{private}s", - response.timeAdded, "\(response.newExpiry)") + os_log(.info, "AppStore Receipt was processed. Time added: %{public}.2f, New expiry: %{private}s", + response.timeAdded, "\(response.newExpiry)") completionHandler(.success(response)) @@ -259,6 +263,8 @@ class AppStorePaymentManager: NSObject, SKPaymentTransactionObserver { completionHandler(.failure(.sendReceipt(error))) } } + + self.exclusivityController.addOperation(createApplePaymentOperation, categories: [.sendReceipt]) case .failure(let error): completionHandler(.failure(.readReceipt(error))) diff --git a/ios/MullvadVPN/MullvadRest.swift b/ios/MullvadVPN/MullvadRest.swift index 90cf44fc20..fd1b7d9c94 100644 --- a/ios/MullvadVPN/MullvadRest.swift +++ b/ios/MullvadVPN/MullvadRest.swift @@ -501,10 +501,19 @@ struct ReplaceWireguardKeyRequest: Encodable, RestPayload { } struct CreateApplePaymentRequest: Encodable, RestPayload { - let receiptString: String + let receiptString: Data } struct CreateApplePaymentResponse: Decodable, RestResponse { let timeAdded: Int let newExpiry: Date + + /// Returns a formatted string for the `timeAdded` interval, i.e "30 days" + var formattedTimeAdded: String? { + let formatter = DateComponentsFormatter() + formatter.allowedUnits = [.day, .hour] + formatter.unitsStyle = .full + + return formatter.string(from: TimeInterval(timeAdded)) + } } |
