summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2020-07-21 14:26:34 +0300
committerAndrej Mihajlov <and@mullvad.net>2020-07-22 18:35:43 +0300
commit868f0bdf1d4bb05babbfeec817315027283cf2f1 (patch)
tree766ad3cd2b0e4622dab2424cc83e66da0406e347
parent218756ae97e6e222572bd9bb68a5d25268b4a2ac (diff)
downloadmullvadvpn-868f0bdf1d4bb05babbfeec817315027283cf2f1.tar.xz
mullvadvpn-868f0bdf1d4bb05babbfeec817315027283cf2f1.zip
Migrate AppStorePaymentManager to REST
-rw-r--r--ios/MullvadVPN/Account.swift2
-rw-r--r--ios/MullvadVPN/AccountViewController.swift10
-rw-r--r--ios/MullvadVPN/AppStorePaymentManager.swift36
-rw-r--r--ios/MullvadVPN/MullvadRest.swift11
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))
+ }
}