diff options
| author | Steffen Ernst <steffen.ernst@mullvad.net> | 2025-01-20 11:42:40 +0100 |
|---|---|---|
| committer | Steffen Ernst <steffen.ernst@mullvad.net> | 2025-01-20 15:54:12 +0100 |
| commit | 91cb3e5038e635b9a33e7f1db275a2311956b03d (patch) | |
| tree | 90cfc7875ae8b537e079a5835422427883be7f32 | |
| parent | 9916d4009ef75f0d4c98b6869e3e0c8e34c2945e (diff) | |
| download | mullvadvpn-91cb3e5038e635b9a33e7f1db275a2311956b03d.tar.xz mullvadvpn-91cb3e5038e635b9a33e7f1db275a2311956b03d.zip | |
Simplify code to create purchase action sheet
6 files changed, 67 insertions, 96 deletions
diff --git a/ios/MullvadVPN.xcodeproj/project.pbxproj b/ios/MullvadVPN.xcodeproj/project.pbxproj index 32abb7f779..5025450b41 100644 --- a/ios/MullvadVPN.xcodeproj/project.pbxproj +++ b/ios/MullvadVPN.xcodeproj/project.pbxproj @@ -1054,6 +1054,7 @@ F0F56B092C0E058A009D676B /* ObserverList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58CC40EE24A601900019D96E /* ObserverList.swift */; }; F0FADDEA2BE90AAA000D0B02 /* LaunchArguments.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0F1EF8C2BE8FF0A00CED01D /* LaunchArguments.swift */; }; F0FADDEC2BE90AB0000D0B02 /* LaunchArguments.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0F1EF8C2BE8FF0A00CED01D /* LaunchArguments.swift */; }; + F95C1C252D3E5E8E00EBE769 /* UIAlertController+InAppPurchase.swift in Sources */ = {isa = PBXBuildFile; fileRef = F95C1C242D3E5E7A00EBE769 /* UIAlertController+InAppPurchase.swift */; }; F998EFF82D359C4600D88D01 /* SKProduct+Formatting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58FD5BEF24238EB300112C88 /* SKProduct+Formatting.swift */; }; F998EFFA2D3656BA00D88D01 /* SKProduct+Sorting.swift in Sources */ = {isa = PBXBuildFile; fileRef = F998EFF92D3656B100D88D01 /* SKProduct+Sorting.swift */; }; /* End PBXBuildFile section */ @@ -2311,6 +2312,7 @@ F0F316182BF3572B0078DBCF /* RelaySelectorResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelaySelectorResult.swift; sourceTree = "<group>"; }; F0F3161A2BF358590078DBCF /* NoRelaysSatisfyingConstraintsError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NoRelaysSatisfyingConstraintsError.swift; sourceTree = "<group>"; }; F0FBD98E2C4A60CC00EE5323 /* KeyExchangingResultStub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyExchangingResultStub.swift; sourceTree = "<group>"; }; + F95C1C242D3E5E7A00EBE769 /* UIAlertController+InAppPurchase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIAlertController+InAppPurchase.swift"; sourceTree = "<group>"; }; F998EFF92D3656B100D88D01 /* SKProduct+Sorting.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SKProduct+Sorting.swift"; sourceTree = "<group>"; }; /* End PBXFileReference section */ @@ -3157,6 +3159,7 @@ E158B35F285381C60002F069 /* String+AccountFormatting.swift */, 7A09C98029D99215000C2CAC /* String+FuzzyMatch.swift */, 5807E2BF2432038B00F5FF30 /* String+Helpers.swift */, + F95C1C242D3E5E7A00EBE769 /* UIAlertController+InAppPurchase.swift */, 58CEB2F82AFD136E00E6E088 /* UIBackgroundConfiguration+Extensions.swift */, 5891BF5025E66B1E006D6FB0 /* UIBarButtonItem+KeyboardNavigation.swift */, 587CBFE222807F530028DED3 /* UIColor+Helpers.swift */, @@ -6179,6 +6182,7 @@ A9E034642ABB302000E59A5A /* UIEdgeInsets+Extensions.swift in Sources */, 58CEB2E92AFBBA4A00E6E088 /* AddAccessMethodCoordinator.swift in Sources */, 58DFF7D02B02560400F864E0 /* NSAttributedString+Extensions.swift in Sources */, + F95C1C252D3E5E8E00EBE769 /* UIAlertController+InAppPurchase.swift in Sources */, 58E0A98827C8F46300FE6BDD /* Tunnel.swift in Sources */, 7A12D0762B062D5C00E9602D /* URLSessionProtocol.swift in Sources */, 58ACF64F26567A7100ACE4B7 /* CustomSwitchContainer.swift in Sources */, diff --git a/ios/MullvadVPN/Coordinators/AccountCoordinator.swift b/ios/MullvadVPN/Coordinators/AccountCoordinator.swift index 7b238e53b4..e8f87401ec 100644 --- a/ios/MullvadVPN/Coordinators/AccountCoordinator.swift +++ b/ios/MullvadVPN/Coordinators/AccountCoordinator.swift @@ -70,7 +70,7 @@ final class AccountCoordinator: Coordinator, Presentable, Presenting, @unchecked showRestorePurchasesInfo() case let .showPurchaseOptions(details): showPurchaseOptions( - availableProducts: details.products, + products: details.products, accountNumber: details.accountNumber, didRequestPurchase: details.didRequestPurchase ) @@ -80,39 +80,11 @@ final class AccountCoordinator: Coordinator, Presentable, Presenting, @unchecked } func showPurchaseOptions( - availableProducts: [SKProduct], + products: [SKProduct], accountNumber: String, didRequestPurchase: @escaping (_ product: SKProduct) -> Void ) { - let localizedString = NSLocalizedString( - "ADD_TIME", - tableName: "Welcome", - value: "Add Time", - comment: "" - ) - let alert = UIAlertController(title: localizedString, message: nil, preferredStyle: .actionSheet) - availableProducts.sortedByPrice().forEach { product in - guard let localizedTitle = product.customLocalizedTitle else { - return - } - let action = UIAlertAction(title: localizedTitle, style: .default, handler: { _ in - alert.dismiss(animated: true, completion: { - didRequestPurchase(product) - }) - }) - action - .accessibilityIdentifier = - "\(AccessibilityIdentifier.purchaseButton.asString)_\(product.productIdentifier)" - alert.addAction(action) - } - let cancelAction = UIAlertAction(title: NSLocalizedString( - "PRODUCT_LIST_CANCEL_BUTTON", - tableName: "Welcome", - value: "Cancel", - comment: "" - ), style: .cancel) - cancelAction.accessibilityIdentifier = AccessibilityIdentifier.cancelPurchaseListButton.asString - alert.addAction(cancelAction) + let alert = UIAlertController.showInAppPurchaseAlert(products: products, didRequestPurchase: didRequestPurchase) presentationContext.present(alert, animated: true) } diff --git a/ios/MullvadVPN/Coordinators/OutOfTimeCoordinator.swift b/ios/MullvadVPN/Coordinators/OutOfTimeCoordinator.swift index ccf8e442c0..003d88d2cc 100644 --- a/ios/MullvadVPN/Coordinators/OutOfTimeCoordinator.swift +++ b/ios/MullvadVPN/Coordinators/OutOfTimeCoordinator.swift @@ -89,35 +89,7 @@ class OutOfTimeCoordinator: Coordinator, Presenting, @preconcurrency OutOfTimeVi products: [SKProduct], didRequestPurchase: @escaping (SKProduct) -> Void ) { - let localizedString = NSLocalizedString( - "ADD_TIME_BUTTON", - tableName: "Welcome", - value: "Add Time", - comment: "" - ) - let alert = UIAlertController(title: localizedString, message: nil, preferredStyle: .actionSheet) - products.sortedByPrice().forEach { product in - guard let localizedTitle = product.customLocalizedTitle else { - return - } - let action = UIAlertAction(title: localizedTitle, style: .default, handler: { _ in - alert.dismiss(animated: true, completion: { - didRequestPurchase(product) - }) - }) - action - .accessibilityIdentifier = - "\(AccessibilityIdentifier.purchaseButton.asString)_\(product.productIdentifier)" - alert.addAction(action) - } - let cancelAction = UIAlertAction(title: NSLocalizedString( - "PRODUCT_LIST_CANCEL_BUTTON", - tableName: "Welcome", - value: "Cancel", - comment: "" - ), style: .cancel) - cancelAction.accessibilityIdentifier = AccessibilityIdentifier.cancelPurchaseListButton.asString - alert.addAction(cancelAction) + let alert = UIAlertController.showInAppPurchaseAlert(products: products, didRequestPurchase: didRequestPurchase) presentationContext.present(alert, animated: true) } diff --git a/ios/MullvadVPN/Coordinators/WelcomeCoordinator.swift b/ios/MullvadVPN/Coordinators/WelcomeCoordinator.swift index 0c1fc7c9df..b7af509df5 100644 --- a/ios/MullvadVPN/Coordinators/WelcomeCoordinator.swift +++ b/ios/MullvadVPN/Coordinators/WelcomeCoordinator.swift @@ -152,42 +152,17 @@ extension WelcomeCoordinator: @preconcurrency WelcomeViewControllerDelegate { func didRequestToViewPurchaseOptions( controller: WelcomeViewController, - availableProducts: [SKProduct], + products: [SKProduct], accountNumber: String ) { - let localizedString = NSLocalizedString( - "ADD_TIME_BUTTON", - tableName: "Welcome", - value: "Add Time", - comment: "" - ) - let alert = UIAlertController(title: localizedString, message: nil, preferredStyle: .actionSheet) - availableProducts.sortedByPrice().forEach { product in - guard let localizedTitle = product.customLocalizedTitle else { - return - } - let action = UIAlertAction(title: localizedTitle, style: .default, handler: { _ in - alert.dismiss(animated: true, completion: { - self.didRequestToPurchaseCredit( - controller: controller, - accountNumber: accountNumber, - product: product - ) - }) - }) - action - .accessibilityIdentifier = - "\(AccessibilityIdentifier.purchaseButton.asString)_\(product.productIdentifier)" - alert.addAction(action) - } - let cancelAction = UIAlertAction(title: NSLocalizedString( - "PRODUCT_LIST_CANCEL_BUTTON", - tableName: "Welcome", - value: "Cancel", - comment: "" - ), style: .cancel) - cancelAction.accessibilityIdentifier = AccessibilityIdentifier.cancelPurchaseListButton.asString - alert.addAction(cancelAction) + let alert = UIAlertController.showInAppPurchaseAlert(products: products, didRequestPurchase: { product in + self.didRequestToPurchaseCredit( + controller: controller, + accountNumber: accountNumber, + product: product + ) + }) + presentationContext.present(alert, animated: true) } diff --git a/ios/MullvadVPN/Extensions/UIAlertController+InAppPurchase.swift b/ios/MullvadVPN/Extensions/UIAlertController+InAppPurchase.swift new file mode 100644 index 0000000000..b94b457b5a --- /dev/null +++ b/ios/MullvadVPN/Extensions/UIAlertController+InAppPurchase.swift @@ -0,0 +1,48 @@ +// +// UIAlertController+InAppPurchase.swift +// MullvadVPN +// +// Created by Steffen Ernst on 2025-01-20. +// Copyright © 2025 Mullvad VPN AB. All rights reserved. +// + +import StoreKit +import UIKit + +extension UIAlertController { + public static func showInAppPurchaseAlert( + products: [SKProduct], + didRequestPurchase: @escaping (SKProduct) -> Void + ) -> UIAlertController { + let localizedString = NSLocalizedString( + "ADD_TIME_BUTTON", + tableName: "Welcome", + value: "Add Time", + comment: "" + ) + let alert = UIAlertController(title: localizedString, message: nil, preferredStyle: .actionSheet) + products.sortedByPrice().forEach { product in + guard let localizedTitle = product.customLocalizedTitle else { + return + } + let action = UIAlertAction(title: localizedTitle, style: .default, handler: { _ in + alert.dismiss(animated: true, completion: { + didRequestPurchase(product) + }) + }) + action + .accessibilityIdentifier = + "\(AccessibilityIdentifier.purchaseButton.asString)_\(product.productIdentifier)" + alert.addAction(action) + } + let cancelAction = UIAlertAction(title: NSLocalizedString( + "PRODUCT_LIST_CANCEL_BUTTON", + tableName: "Welcome", + value: "Cancel", + comment: "" + ), style: .cancel) + cancelAction.accessibilityIdentifier = AccessibilityIdentifier.cancelPurchaseListButton.asString + alert.addAction(cancelAction) + return alert + } +} diff --git a/ios/MullvadVPN/View controllers/CreationAccount/Welcome/WelcomeViewController.swift b/ios/MullvadVPN/View controllers/CreationAccount/Welcome/WelcomeViewController.swift index 5b19fb073e..70911810e0 100644 --- a/ios/MullvadVPN/View controllers/CreationAccount/Welcome/WelcomeViewController.swift +++ b/ios/MullvadVPN/View controllers/CreationAccount/Welcome/WelcomeViewController.swift @@ -14,7 +14,7 @@ protocol WelcomeViewControllerDelegate: AnyObject { func didRequestToShowInfo(controller: WelcomeViewController) func didRequestToViewPurchaseOptions( controller: WelcomeViewController, - availableProducts: [SKProduct], + products: [SKProduct], accountNumber: String ) func didRequestToShowFailToFetchProducts(controller: WelcomeViewController) @@ -100,7 +100,7 @@ extension WelcomeViewController: @preconcurrency WelcomeContentViewDelegate { if !products.isEmpty { delegate?.didRequestToViewPurchaseOptions( controller: self, - availableProducts: products, + products: products, accountNumber: interactor.accountNumber ) } else { |
