Skip to content

Commit 7ca198c

Browse files
committed
Simplify code to create purchase action sheet
1 parent 1abac1b commit 7ca198c

File tree

6 files changed

+67
-96
lines changed

6 files changed

+67
-96
lines changed

ios/MullvadVPN.xcodeproj/project.pbxproj

+4
Original file line numberDiff line numberDiff line change
@@ -1055,6 +1055,7 @@
10551055
F0F56B092C0E058A009D676B /* ObserverList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58CC40EE24A601900019D96E /* ObserverList.swift */; };
10561056
F0FADDEA2BE90AAA000D0B02 /* LaunchArguments.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0F1EF8C2BE8FF0A00CED01D /* LaunchArguments.swift */; };
10571057
F0FADDEC2BE90AB0000D0B02 /* LaunchArguments.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0F1EF8C2BE8FF0A00CED01D /* LaunchArguments.swift */; };
1058+
F95C1C252D3E5E8E00EBE769 /* UIAlertController+InAppPurchase.swift in Sources */ = {isa = PBXBuildFile; fileRef = F95C1C242D3E5E7A00EBE769 /* UIAlertController+InAppPurchase.swift */; };
10581059
F998EFF82D359C4600D88D01 /* SKProduct+Formatting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58FD5BEF24238EB300112C88 /* SKProduct+Formatting.swift */; };
10591060
F998EFFA2D3656BA00D88D01 /* SKProduct+Sorting.swift in Sources */ = {isa = PBXBuildFile; fileRef = F998EFF92D3656B100D88D01 /* SKProduct+Sorting.swift */; };
10601061
/* End PBXBuildFile section */
@@ -2313,6 +2314,7 @@
23132314
F0F316182BF3572B0078DBCF /* RelaySelectorResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelaySelectorResult.swift; sourceTree = "<group>"; };
23142315
F0F3161A2BF358590078DBCF /* NoRelaysSatisfyingConstraintsError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NoRelaysSatisfyingConstraintsError.swift; sourceTree = "<group>"; };
23152316
F0FBD98E2C4A60CC00EE5323 /* KeyExchangingResultStub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyExchangingResultStub.swift; sourceTree = "<group>"; };
2317+
F95C1C242D3E5E7A00EBE769 /* UIAlertController+InAppPurchase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIAlertController+InAppPurchase.swift"; sourceTree = "<group>"; };
23162318
F998EFF92D3656B100D88D01 /* SKProduct+Sorting.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SKProduct+Sorting.swift"; sourceTree = "<group>"; };
23172319
/* End PBXFileReference section */
23182320

@@ -3160,6 +3162,7 @@
31603162
E158B35F285381C60002F069 /* String+AccountFormatting.swift */,
31613163
7A09C98029D99215000C2CAC /* String+FuzzyMatch.swift */,
31623164
5807E2BF2432038B00F5FF30 /* String+Helpers.swift */,
3165+
F95C1C242D3E5E7A00EBE769 /* UIAlertController+InAppPurchase.swift */,
31633166
58CEB2F82AFD136E00E6E088 /* UIBackgroundConfiguration+Extensions.swift */,
31643167
5891BF5025E66B1E006D6FB0 /* UIBarButtonItem+KeyboardNavigation.swift */,
31653168
587CBFE222807F530028DED3 /* UIColor+Helpers.swift */,
@@ -6183,6 +6186,7 @@
61836186
A9E034642ABB302000E59A5A /* UIEdgeInsets+Extensions.swift in Sources */,
61846187
58CEB2E92AFBBA4A00E6E088 /* AddAccessMethodCoordinator.swift in Sources */,
61856188
58DFF7D02B02560400F864E0 /* NSAttributedString+Extensions.swift in Sources */,
6189+
F95C1C252D3E5E8E00EBE769 /* UIAlertController+InAppPurchase.swift in Sources */,
61866190
58E0A98827C8F46300FE6BDD /* Tunnel.swift in Sources */,
61876191
7A12D0762B062D5C00E9602D /* URLSessionProtocol.swift in Sources */,
61886192
58ACF64F26567A7100ACE4B7 /* CustomSwitchContainer.swift in Sources */,

ios/MullvadVPN/Coordinators/AccountCoordinator.swift

+3-31
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ final class AccountCoordinator: Coordinator, Presentable, Presenting, @unchecked
7070
showRestorePurchasesInfo()
7171
case let .showPurchaseOptions(details):
7272
showPurchaseOptions(
73-
availableProducts: details.products,
73+
products: details.products,
7474
accountNumber: details.accountNumber,
7575
didRequestPurchase: details.didRequestPurchase
7676
)
@@ -80,39 +80,11 @@ final class AccountCoordinator: Coordinator, Presentable, Presenting, @unchecked
8080
}
8181

8282
func showPurchaseOptions(
83-
availableProducts: [SKProduct],
83+
products: [SKProduct],
8484
accountNumber: String,
8585
didRequestPurchase: @escaping (_ product: SKProduct) -> Void
8686
) {
87-
let localizedString = NSLocalizedString(
88-
"ADD_TIME",
89-
tableName: "Welcome",
90-
value: "Add Time",
91-
comment: ""
92-
)
93-
let alert = UIAlertController(title: localizedString, message: nil, preferredStyle: .actionSheet)
94-
availableProducts.sortedByPrice().forEach { product in
95-
guard let localizedTitle = product.customLocalizedTitle else {
96-
return
97-
}
98-
let action = UIAlertAction(title: localizedTitle, style: .default, handler: { _ in
99-
alert.dismiss(animated: true, completion: {
100-
didRequestPurchase(product)
101-
})
102-
})
103-
action
104-
.accessibilityIdentifier =
105-
"\(AccessibilityIdentifier.purchaseButton.asString)_\(product.productIdentifier)"
106-
alert.addAction(action)
107-
}
108-
let cancelAction = UIAlertAction(title: NSLocalizedString(
109-
"PRODUCT_LIST_CANCEL_BUTTON",
110-
tableName: "Welcome",
111-
value: "Cancel",
112-
comment: ""
113-
), style: .cancel)
114-
cancelAction.accessibilityIdentifier = AccessibilityIdentifier.cancelPurchaseListButton.asString
115-
alert.addAction(cancelAction)
87+
let alert = UIAlertController.showInAppPurchaseAlert(products: products, didRequestPurchase: didRequestPurchase)
11688
presentationContext.present(alert, animated: true)
11789
}
11890

ios/MullvadVPN/Coordinators/OutOfTimeCoordinator.swift

+1-29
Original file line numberDiff line numberDiff line change
@@ -89,35 +89,7 @@ class OutOfTimeCoordinator: Coordinator, Presenting, @preconcurrency OutOfTimeVi
8989
products: [SKProduct],
9090
didRequestPurchase: @escaping (SKProduct) -> Void
9191
) {
92-
let localizedString = NSLocalizedString(
93-
"ADD_TIME_BUTTON",
94-
tableName: "Welcome",
95-
value: "Add Time",
96-
comment: ""
97-
)
98-
let alert = UIAlertController(title: localizedString, message: nil, preferredStyle: .actionSheet)
99-
products.sortedByPrice().forEach { product in
100-
guard let localizedTitle = product.customLocalizedTitle else {
101-
return
102-
}
103-
let action = UIAlertAction(title: localizedTitle, style: .default, handler: { _ in
104-
alert.dismiss(animated: true, completion: {
105-
didRequestPurchase(product)
106-
})
107-
})
108-
action
109-
.accessibilityIdentifier =
110-
"\(AccessibilityIdentifier.purchaseButton.asString)_\(product.productIdentifier)"
111-
alert.addAction(action)
112-
}
113-
let cancelAction = UIAlertAction(title: NSLocalizedString(
114-
"PRODUCT_LIST_CANCEL_BUTTON",
115-
tableName: "Welcome",
116-
value: "Cancel",
117-
comment: ""
118-
), style: .cancel)
119-
cancelAction.accessibilityIdentifier = AccessibilityIdentifier.cancelPurchaseListButton.asString
120-
alert.addAction(cancelAction)
92+
let alert = UIAlertController.showInAppPurchaseAlert(products: products, didRequestPurchase: didRequestPurchase)
12193
presentationContext.present(alert, animated: true)
12294
}
12395

ios/MullvadVPN/Coordinators/WelcomeCoordinator.swift

+9-34
Original file line numberDiff line numberDiff line change
@@ -152,42 +152,17 @@ extension WelcomeCoordinator: @preconcurrency WelcomeViewControllerDelegate {
152152

153153
func didRequestToViewPurchaseOptions(
154154
controller: WelcomeViewController,
155-
availableProducts: [SKProduct],
155+
products: [SKProduct],
156156
accountNumber: String
157157
) {
158-
let localizedString = NSLocalizedString(
159-
"ADD_TIME_BUTTON",
160-
tableName: "Welcome",
161-
value: "Add Time",
162-
comment: ""
163-
)
164-
let alert = UIAlertController(title: localizedString, message: nil, preferredStyle: .actionSheet)
165-
availableProducts.sortedByPrice().forEach { product in
166-
guard let localizedTitle = product.customLocalizedTitle else {
167-
return
168-
}
169-
let action = UIAlertAction(title: localizedTitle, style: .default, handler: { _ in
170-
alert.dismiss(animated: true, completion: {
171-
self.didRequestToPurchaseCredit(
172-
controller: controller,
173-
accountNumber: accountNumber,
174-
product: product
175-
)
176-
})
177-
})
178-
action
179-
.accessibilityIdentifier =
180-
"\(AccessibilityIdentifier.purchaseButton.asString)_\(product.productIdentifier)"
181-
alert.addAction(action)
182-
}
183-
let cancelAction = UIAlertAction(title: NSLocalizedString(
184-
"PRODUCT_LIST_CANCEL_BUTTON",
185-
tableName: "Welcome",
186-
value: "Cancel",
187-
comment: ""
188-
), style: .cancel)
189-
cancelAction.accessibilityIdentifier = AccessibilityIdentifier.cancelPurchaseListButton.asString
190-
alert.addAction(cancelAction)
158+
let alert = UIAlertController.showInAppPurchaseAlert(products: products, didRequestPurchase: { product in
159+
self.didRequestToPurchaseCredit(
160+
controller: controller,
161+
accountNumber: accountNumber,
162+
product: product
163+
)
164+
})
165+
191166
presentationContext.present(alert, animated: true)
192167
}
193168

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//
2+
// UIAlertController+InAppPurchase.swift
3+
// MullvadVPN
4+
//
5+
// Created by Steffen Ernst on 2025-01-20.
6+
// Copyright © 2025 Mullvad VPN AB. All rights reserved.
7+
//
8+
9+
import StoreKit
10+
import UIKit
11+
12+
extension UIAlertController {
13+
public static func showInAppPurchaseAlert(
14+
products: [SKProduct],
15+
didRequestPurchase: @escaping (SKProduct) -> Void
16+
) -> UIAlertController {
17+
let localizedString = NSLocalizedString(
18+
"ADD_TIME_BUTTON",
19+
tableName: "Welcome",
20+
value: "Add Time",
21+
comment: ""
22+
)
23+
let alert = UIAlertController(title: localizedString, message: nil, preferredStyle: .actionSheet)
24+
products.sortedByPrice().forEach { product in
25+
guard let localizedTitle = product.customLocalizedTitle else {
26+
return
27+
}
28+
let action = UIAlertAction(title: localizedTitle, style: .default, handler: { _ in
29+
alert.dismiss(animated: true, completion: {
30+
didRequestPurchase(product)
31+
})
32+
})
33+
action
34+
.accessibilityIdentifier =
35+
"\(AccessibilityIdentifier.purchaseButton.asString)_\(product.productIdentifier)"
36+
alert.addAction(action)
37+
}
38+
let cancelAction = UIAlertAction(title: NSLocalizedString(
39+
"PRODUCT_LIST_CANCEL_BUTTON",
40+
tableName: "Welcome",
41+
value: "Cancel",
42+
comment: ""
43+
), style: .cancel)
44+
cancelAction.accessibilityIdentifier = AccessibilityIdentifier.cancelPurchaseListButton.asString
45+
alert.addAction(cancelAction)
46+
return alert
47+
}
48+
}

ios/MullvadVPN/View controllers/CreationAccount/Welcome/WelcomeViewController.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ protocol WelcomeViewControllerDelegate: AnyObject {
1414
func didRequestToShowInfo(controller: WelcomeViewController)
1515
func didRequestToViewPurchaseOptions(
1616
controller: WelcomeViewController,
17-
availableProducts: [SKProduct],
17+
products: [SKProduct],
1818
accountNumber: String
1919
)
2020
func didRequestToShowFailToFetchProducts(controller: WelcomeViewController)
@@ -100,7 +100,7 @@ extension WelcomeViewController: @preconcurrency WelcomeContentViewDelegate {
100100
if !products.isEmpty {
101101
delegate?.didRequestToViewPurchaseOptions(
102102
controller: self,
103-
availableProducts: products,
103+
products: products,
104104
accountNumber: interactor.accountNumber
105105
)
106106
} else {

0 commit comments

Comments
 (0)