summaryrefslogtreecommitdiffhomepage
path: root/ios
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2022-10-27 09:51:27 +0200
committerAndrej Mihajlov <and@mullvad.net>2022-10-31 10:25:09 +0100
commit29234543ce8a68bd6e78f5bbb745e54bf81b2f28 (patch)
tree63cc8e4bda436642da0260a589bda8926f94d364 /ios
parent96526fe223025af0fcb4cc9092e963c5b87f5f20 (diff)
downloadmullvadvpn-29234543ce8a68bd6e78f5bbb745e54bf81b2f28.tar.xz
mullvadvpn-29234543ce8a68bd6e78f5bbb745e54bf81b2f28.zip
Introduce StorePaymentEvent to pass payment related data.
Remove App prefix from AppStore related classes
Diffstat (limited to 'ios')
-rw-r--r--ios/MullvadVPN.xcodeproj/project.pbxproj70
-rw-r--r--ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentManagerError.swift61
-rw-r--r--ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentObserver.swift28
-rw-r--r--ios/MullvadVPN/StorePaymentManager/SendStoreReceiptOperation.swift (renamed from ios/MullvadVPN/AppStorePaymentManager/SendAppStoreReceiptOperation.swift)21
-rw-r--r--ios/MullvadVPN/StorePaymentManager/StorePaymentBlockObserver.swift26
-rw-r--r--ios/MullvadVPN/StorePaymentManager/StorePaymentEvent.swift38
-rw-r--r--ios/MullvadVPN/StorePaymentManager/StorePaymentManager.swift (renamed from ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentManager.swift)148
-rw-r--r--ios/MullvadVPN/StorePaymentManager/StorePaymentManagerDelegate.swift (renamed from ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentManagerDelegate.swift)10
-rw-r--r--ios/MullvadVPN/StorePaymentManager/StorePaymentManagerError.swift59
-rw-r--r--ios/MullvadVPN/StorePaymentManager/StorePaymentObserver.swift16
-rw-r--r--ios/MullvadVPN/StorePaymentManager/StoreReceipt.swift (renamed from ios/MullvadVPN/AppStoreReceipt.swift)14
-rw-r--r--ios/MullvadVPN/StorePaymentManager/StoreSubscription.swift (renamed from ios/MullvadVPN/AppStorePaymentManager/AppStoreSubscription.swift)16
12 files changed, 293 insertions, 214 deletions
diff --git a/ios/MullvadVPN.xcodeproj/project.pbxproj b/ios/MullvadVPN.xcodeproj/project.pbxproj
index bf46a635ec..dc134a6eb4 100644
--- a/ios/MullvadVPN.xcodeproj/project.pbxproj
+++ b/ios/MullvadVPN.xcodeproj/project.pbxproj
@@ -116,9 +116,9 @@
58421032282E42B000F24E46 /* UpdateDeviceDataOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58421031282E42B000F24E46 /* UpdateDeviceDataOperation.swift */; };
58421034282E4B1500F24E46 /* TunnelSettingsV2+REST.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58421033282E4B1500F24E46 /* TunnelSettingsV2+REST.swift */; };
584592612639B4A200EF967F /* TermsOfServiceContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 584592602639B4A200EF967F /* TermsOfServiceContentView.swift */; };
- 5846227126E229F20035F7C2 /* AppStoreSubscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5846227026E229F20035F7C2 /* AppStoreSubscription.swift */; };
- 5846227326E22A160035F7C2 /* AppStorePaymentObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5846227226E22A160035F7C2 /* AppStorePaymentObserver.swift */; };
- 5846227726E22A7C0035F7C2 /* AppStorePaymentManagerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5846227626E22A7C0035F7C2 /* AppStorePaymentManagerDelegate.swift */; };
+ 5846227126E229F20035F7C2 /* StoreSubscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5846227026E229F20035F7C2 /* StoreSubscription.swift */; };
+ 5846227326E22A160035F7C2 /* StorePaymentObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5846227226E22A160035F7C2 /* StorePaymentObserver.swift */; };
+ 5846227726E22A7C0035F7C2 /* StorePaymentManagerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5846227626E22A7C0035F7C2 /* StorePaymentManagerDelegate.swift */; };
584B17AB27637DE40057F3B8 /* ReconnectTunnelOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 584B17AA27637DE40057F3B8 /* ReconnectTunnelOperation.swift */; };
584D26C2270C8542004EA533 /* SettingsStaticTextFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 584D26C1270C8542004EA533 /* SettingsStaticTextFooterView.swift */; };
584D26C4270C855B004EA533 /* PreferencesDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 584D26C3270C855A004EA533 /* PreferencesDataSource.swift */; };
@@ -133,7 +133,7 @@
585B4B8726D9098900555C4C /* TunnelStatusNotificationProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58A94AE326CFD945001CB97C /* TunnelStatusNotificationProvider.swift */; };
585C6F4C28F80745005196BE /* Logging in Frameworks */ = {isa = PBXBuildFile; productRef = 585C6F4B28F80745005196BE /* Logging */; };
585CA70F25F8C44600B47C62 /* UIMetrics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 585CA70E25F8C44600B47C62 /* UIMetrics.swift */; };
- 585E820327F3285E00939F0E /* SendAppStoreReceiptOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 585E820227F3285E00939F0E /* SendAppStoreReceiptOperation.swift */; };
+ 585E820327F3285E00939F0E /* SendStoreReceiptOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 585E820227F3285E00939F0E /* SendStoreReceiptOperation.swift */; };
5862805422428EF100F5A6E1 /* TranslucentButtonBlurView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5862805322428EF100F5A6E1 /* TranslucentButtonBlurView.swift */; };
5868585524054096000B8131 /* AppButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5868585424054096000B8131 /* AppButton.swift */; };
5868BD33261DCD2600E6027F /* CustomSplitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5868BD32261DCD2600E6027F /* CustomSplitViewController.swift */; };
@@ -155,6 +155,8 @@
587425C12299833500CA2045 /* RootContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587425C02299833500CA2045 /* RootContainerViewController.swift */; };
5875960A26F371FC00BF6711 /* Tunnel+Messaging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5875960926F371FC00BF6711 /* Tunnel+Messaging.swift */; };
5877D70F282137E8002FCFC7 /* SettingsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58FF2C02281BDE02009EF542 /* SettingsManager.swift */; };
+ 5878A27529093A310096FC88 /* StorePaymentEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5878A27429093A310096FC88 /* StorePaymentEvent.swift */; };
+ 5878A27729093A4F0096FC88 /* StorePaymentBlockObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5878A27629093A4F0096FC88 /* StorePaymentBlockObserver.swift */; };
587988C728A2A01F00E3DF54 /* AccountDataThrottling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587988C628A2A01F00E3DF54 /* AccountDataThrottling.swift */; };
587A01FC23F1F0BE00B68763 /* SimulatorTunnelProviderHost.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587A01FB23F1F0BE00B68763 /* SimulatorTunnelProviderHost.swift */; };
587AD7C623421D7000E93A53 /* TunnelSettingsV1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587AD7C523421D7000E93A53 /* TunnelSettingsV1.swift */; };
@@ -263,7 +265,7 @@
58D889C828DDF53500583FA8 /* ResultOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58F7D26427EB50A300E4D821 /* ResultOperation.swift */; };
58D889C928DDF53500583FA8 /* InputOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58DF5B732851FF3F00E92647 /* InputOperation.swift */; };
58D889CA28DDF53500583FA8 /* ResultOperation+Output.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58059DDF2846823E002B1049 /* ResultOperation+Output.swift */; };
- 58DF28A52417CB4B00E836B0 /* AppStorePaymentManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58DF28A42417CB4B00E836B0 /* AppStorePaymentManager.swift */; };
+ 58DF28A52417CB4B00E836B0 /* StorePaymentManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58DF28A42417CB4B00E836B0 /* StorePaymentManager.swift */; };
58E0729D28814AAE008902F8 /* PacketTunnelConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58E0729C28814AAE008902F8 /* PacketTunnelConfiguration.swift */; };
58E0729F28814ACC008902F8 /* WireGuardLogLevel+Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58E0729E28814ACC008902F8 /* WireGuardLogLevel+Logging.swift */; };
58E072A128814B0E008902F8 /* MullvadEndpoint+WgEndpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58E072A028814B0E008902F8 /* MullvadEndpoint+WgEndpoint.swift */; };
@@ -286,10 +288,10 @@
58F3C0A4249CB069003E76BE /* HeaderBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58F3C0A3249CB069003E76BE /* HeaderBarView.swift */; };
58F7CA882692E34000FC59FD /* WireguardKeysContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58F7CA872692E34000FC59FD /* WireguardKeysContentView.swift */; };
58F8AC0E25D3F8CE002BE0ED /* ProblemReportReviewViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58F8AC0D25D3F8CE002BE0ED /* ProblemReportReviewViewController.swift */; };
- 58FB865526E8BF3100F188BC /* AppStorePaymentManagerError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58FB865426E8BF3100F188BC /* AppStorePaymentManagerError.swift */; };
+ 58FB865526E8BF3100F188BC /* StorePaymentManagerError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58FB865426E8BF3100F188BC /* StorePaymentManagerError.swift */; };
58FB865A26EA214400F188BC /* RelayCacheTrackerObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58FB865926EA214400F188BC /* RelayCacheTrackerObserver.swift */; };
58FC040A27B3EE03001C21F0 /* TunnelMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58FC040927B3EE03001C21F0 /* TunnelMonitor.swift */; };
- 58FD5BE724192A2C00112C88 /* AppStoreReceipt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58FD5BE624192A2B00112C88 /* AppStoreReceipt.swift */; };
+ 58FD5BE724192A2C00112C88 /* StoreReceipt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58FD5BE624192A2B00112C88 /* StoreReceipt.swift */; };
58FD5BF024238EB300112C88 /* SKProduct+Formatting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58FD5BEF24238EB300112C88 /* SKProduct+Formatting.swift */; };
58FD5BF42428C67600112C88 /* InAppPurchaseButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58FD5BF32428C67600112C88 /* InAppPurchaseButton.swift */; };
58FEEB46260A028D00A621A8 /* GeoJSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58FEEB45260A028D00A621A8 /* GeoJSON.swift */; };
@@ -593,9 +595,9 @@
58421033282E4B1500F24E46 /* TunnelSettingsV2+REST.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TunnelSettingsV2+REST.swift"; sourceTree = "<group>"; };
584592602639B4A200EF967F /* TermsOfServiceContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TermsOfServiceContentView.swift; sourceTree = "<group>"; };
5846226426E0D9630035F7C2 /* ProductsRequestOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductsRequestOperation.swift; sourceTree = "<group>"; };
- 5846227026E229F20035F7C2 /* AppStoreSubscription.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppStoreSubscription.swift; sourceTree = "<group>"; };
- 5846227226E22A160035F7C2 /* AppStorePaymentObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppStorePaymentObserver.swift; sourceTree = "<group>"; };
- 5846227626E22A7C0035F7C2 /* AppStorePaymentManagerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppStorePaymentManagerDelegate.swift; sourceTree = "<group>"; };
+ 5846227026E229F20035F7C2 /* StoreSubscription.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoreSubscription.swift; sourceTree = "<group>"; };
+ 5846227226E22A160035F7C2 /* StorePaymentObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorePaymentObserver.swift; sourceTree = "<group>"; };
+ 5846227626E22A7C0035F7C2 /* StorePaymentManagerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorePaymentManagerDelegate.swift; sourceTree = "<group>"; };
584B17AA27637DE40057F3B8 /* ReconnectTunnelOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReconnectTunnelOperation.swift; sourceTree = "<group>"; };
584B26F3237434D00073B10E /* RelaySelectorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelaySelectorTests.swift; sourceTree = "<group>"; };
584D26BE270C550B004EA533 /* AnyIPAddress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyIPAddress.swift; sourceTree = "<group>"; };
@@ -610,7 +612,7 @@
585DA87626B024A600B8C587 /* CachedRelays.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CachedRelays.swift; sourceTree = "<group>"; };
585DA89226B0323E00B8C587 /* TunnelProviderMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelProviderMessage.swift; sourceTree = "<group>"; };
585DA89826B0329200B8C587 /* PacketTunnelStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PacketTunnelStatus.swift; sourceTree = "<group>"; };
- 585E820227F3285E00939F0E /* SendAppStoreReceiptOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendAppStoreReceiptOperation.swift; sourceTree = "<group>"; };
+ 585E820227F3285E00939F0E /* SendStoreReceiptOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendStoreReceiptOperation.swift; sourceTree = "<group>"; };
5862805322428EF100F5A6E1 /* TranslucentButtonBlurView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TranslucentButtonBlurView.swift; sourceTree = "<group>"; };
5866F39B2243B82D00168AE5 /* MullvadVPN.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MullvadVPN.entitlements; sourceTree = "<group>"; };
5868585424054096000B8131 /* AppButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppButton.swift; sourceTree = "<group>"; };
@@ -628,6 +630,8 @@
5875960926F371FC00BF6711 /* Tunnel+Messaging.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Tunnel+Messaging.swift"; sourceTree = "<group>"; };
58781CC822AE7CA8009B9D8E /* RelayConstraints.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayConstraints.swift; sourceTree = "<group>"; };
58781CD422AFBA39009B9D8E /* RelaySelector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelaySelector.swift; sourceTree = "<group>"; };
+ 5878A27429093A310096FC88 /* StorePaymentEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorePaymentEvent.swift; sourceTree = "<group>"; };
+ 5878A27629093A4F0096FC88 /* StorePaymentBlockObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorePaymentBlockObserver.swift; sourceTree = "<group>"; };
587988C628A2A01F00E3DF54 /* AccountDataThrottling.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountDataThrottling.swift; sourceTree = "<group>"; };
587A01FB23F1F0BE00B68763 /* SimulatorTunnelProviderHost.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimulatorTunnelProviderHost.swift; sourceTree = "<group>"; };
587AD7C523421D7000E93A53 /* TunnelSettingsV1.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TunnelSettingsV1.swift; sourceTree = "<group>"; };
@@ -716,7 +720,7 @@
58D0C79D23F1CEBA00FE9BA7 /* SnapshotHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SnapshotHelper.swift; sourceTree = "<group>"; };
58D0C79F23F1CECF00FE9BA7 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
58D0C7A023F1CECF00FE9BA7 /* MullvadVPNScreenshots.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MullvadVPNScreenshots.swift; sourceTree = "<group>"; };
- 58DF28A42417CB4B00E836B0 /* AppStorePaymentManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppStorePaymentManager.swift; sourceTree = "<group>"; };
+ 58DF28A42417CB4B00E836B0 /* StorePaymentManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorePaymentManager.swift; sourceTree = "<group>"; };
58DF5B732851FF3F00E92647 /* InputOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputOperation.swift; sourceTree = "<group>"; };
58DF5B752852108E00E92647 /* InputInjectionBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputInjectionBuilder.swift; sourceTree = "<group>"; };
58DF5B772852178600E92647 /* OperationInputInjectionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OperationInputInjectionTests.swift; sourceTree = "<group>"; };
@@ -752,10 +756,10 @@
58F7CA872692E34000FC59FD /* WireguardKeysContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WireguardKeysContentView.swift; sourceTree = "<group>"; };
58F7D26427EB50A300E4D821 /* ResultOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultOperation.swift; sourceTree = "<group>"; };
58F8AC0D25D3F8CE002BE0ED /* ProblemReportReviewViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProblemReportReviewViewController.swift; sourceTree = "<group>"; };
- 58FB865426E8BF3100F188BC /* AppStorePaymentManagerError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppStorePaymentManagerError.swift; sourceTree = "<group>"; };
+ 58FB865426E8BF3100F188BC /* StorePaymentManagerError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorePaymentManagerError.swift; sourceTree = "<group>"; };
58FB865926EA214400F188BC /* RelayCacheTrackerObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayCacheTrackerObserver.swift; sourceTree = "<group>"; };
58FC040927B3EE03001C21F0 /* TunnelMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelMonitor.swift; sourceTree = "<group>"; };
- 58FD5BE624192A2B00112C88 /* AppStoreReceipt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppStoreReceipt.swift; sourceTree = "<group>"; };
+ 58FD5BE624192A2B00112C88 /* StoreReceipt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoreReceipt.swift; sourceTree = "<group>"; };
58FD5BEF24238EB300112C88 /* SKProduct+Formatting.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SKProduct+Formatting.swift"; sourceTree = "<group>"; };
58FD5BF32428C67600112C88 /* InAppPurchaseButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InAppPurchaseButton.swift; sourceTree = "<group>"; };
58FEEB45260A028D00A621A8 /* GeoJSON.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeoJSON.swift; sourceTree = "<group>"; };
@@ -1036,17 +1040,20 @@
path = MullvadVPN;
sourceTree = "<group>";
};
- 5846226F26E229CD0035F7C2 /* AppStorePaymentManager */ = {
+ 5846226F26E229CD0035F7C2 /* StorePaymentManager */ = {
isa = PBXGroup;
children = (
- 58DF28A42417CB4B00E836B0 /* AppStorePaymentManager.swift */,
- 5846227626E22A7C0035F7C2 /* AppStorePaymentManagerDelegate.swift */,
- 58FB865426E8BF3100F188BC /* AppStorePaymentManagerError.swift */,
- 5846227226E22A160035F7C2 /* AppStorePaymentObserver.swift */,
- 5846227026E229F20035F7C2 /* AppStoreSubscription.swift */,
- 585E820227F3285E00939F0E /* SendAppStoreReceiptOperation.swift */,
+ 5878A27629093A4F0096FC88 /* StorePaymentBlockObserver.swift */,
+ 585E820227F3285E00939F0E /* SendStoreReceiptOperation.swift */,
+ 5878A27429093A310096FC88 /* StorePaymentEvent.swift */,
+ 58DF28A42417CB4B00E836B0 /* StorePaymentManager.swift */,
+ 5846227626E22A7C0035F7C2 /* StorePaymentManagerDelegate.swift */,
+ 58FB865426E8BF3100F188BC /* StorePaymentManagerError.swift */,
+ 5846227226E22A160035F7C2 /* StorePaymentObserver.swift */,
+ 58FD5BE624192A2B00112C88 /* StoreReceipt.swift */,
+ 5846227026E229F20035F7C2 /* StoreSubscription.swift */,
);
- path = AppStorePaymentManager;
+ path = StorePaymentManager;
sourceTree = "<group>";
};
584F991F2902CBDD001F858D /* Frameworks */ = {
@@ -1201,8 +1208,7 @@
58CCA01722426713004F3011 /* AccountViewController.swift */,
5868585424054096000B8131 /* AppButton.swift */,
58CE5E63224146200008646E /* AppDelegate.swift */,
- 5846226F26E229CD0035F7C2 /* AppStorePaymentManager */,
- 58FD5BE624192A2B00112C88 /* AppStoreReceipt.swift */,
+ 5846226F26E229CD0035F7C2 /* StorePaymentManager */,
58CE5E6A224146210008646E /* Assets.xcassets */,
58FEEB57260B662E00A621A8 /* AutomaticKeyboardResponder.swift */,
5891BF1B25E3E3EB006D6FB0 /* Bundle+ProductVersion.swift */,
@@ -2029,7 +2035,7 @@
587D96742886D87C00CD8F1C /* DeviceManagementContentView.swift in Sources */,
589A454C28DDF5E100565204 /* Swizzle.swift in Sources */,
5857F24724C882D700CF6F47 /* SelectLocationNavigationController.swift in Sources */,
- 5846227126E229F20035F7C2 /* AppStoreSubscription.swift in Sources */,
+ 5846227126E229F20035F7C2 /* StoreSubscription.swift in Sources */,
58421030282D8A3C00F24E46 /* UpdateAccountDataOperation.swift in Sources */,
58FF2C03281BDE02009EF542 /* SettingsManager.swift in Sources */,
587EB672271451E300123C75 /* PreferencesViewModel.swift in Sources */,
@@ -2039,6 +2045,7 @@
58BA693123EADA6A009DC256 /* SimulatorTunnelProvider.swift in Sources */,
587B753B2666467500DEF7E9 /* NotificationBannerView.swift in Sources */,
58B993B12608A34500BA7811 /* LoginContentView.swift in Sources */,
+ 5878A27529093A310096FC88 /* StorePaymentEvent.swift in Sources */,
58E6771F24ADFE7800AA26E7 /* SettingsNavigationController.swift in Sources */,
58A1AA8C23F5584C009F7EA6 /* ConnectionPanelView.swift in Sources */,
582BB1B3229574F40055B6EF /* SettingsAccountCell.swift in Sources */,
@@ -2065,14 +2072,14 @@
58F2E14C276A61C000A79513 /* RotateKeyOperation.swift in Sources */,
5871FB96254ADE4E0051A0A4 /* ConsolidatedApplicationLog.swift in Sources */,
58FEEB58260B662E00A621A8 /* AutomaticKeyboardResponder.swift in Sources */,
- 5846227326E22A160035F7C2 /* AppStorePaymentObserver.swift in Sources */,
+ 5846227326E22A160035F7C2 /* StorePaymentObserver.swift in Sources */,
58F2E146276A2C9900A79513 /* StopTunnelOperation.swift in Sources */,
E1187ABC289BBB850024E748 /* OutOfTimeViewController.swift in Sources */,
58293FB125124117005D0BB5 /* CustomTextField.swift in Sources */,
582AE3102440A6CA00E6733A /* AccountTokenInput.swift in Sources */,
5820EDAB288FF0D2006BF4E4 /* DeviceRowView.swift in Sources */,
75FD0C2128B108570021E33E /* ShortcutsDataSource.swift in Sources */,
- 5846227726E22A7C0035F7C2 /* AppStorePaymentManagerDelegate.swift in Sources */,
+ 5846227726E22A7C0035F7C2 /* StorePaymentManagerDelegate.swift in Sources */,
58EF581125D69DB400AEBA94 /* StatusImageView.swift in Sources */,
58907D9524D17B4E00CFC3F5 /* DisconnectSplitButton.swift in Sources */,
58EE2E3B272FF814003BFF93 /* SettingsDataSourceDelegate.swift in Sources */,
@@ -2092,14 +2099,15 @@
75FD0C2528B117D30021E33E /* ShortcutsViewController.swift in Sources */,
5871FBA0254C26C00051A0A4 /* NSRegularExpression+IPAddress.swift in Sources */,
58F7CA882692E34000FC59FD /* WireguardKeysContentView.swift in Sources */,
+ 5878A27729093A4F0096FC88 /* StorePaymentBlockObserver.swift in Sources */,
5868585524054096000B8131 /* AppButton.swift in Sources */,
58E25F812837BBBB002CFB2C /* SceneDelegate.swift in Sources */,
- 585E820327F3285E00939F0E /* SendAppStoreReceiptOperation.swift in Sources */,
+ 585E820327F3285E00939F0E /* SendStoreReceiptOperation.swift in Sources */,
584B17AB27637DE40057F3B8 /* ReconnectTunnelOperation.swift in Sources */,
5820676426E771DB00655B05 /* TunnelManagerErrors.swift in Sources */,
585B4B8726D9098900555C4C /* TunnelStatusNotificationProvider.swift in Sources */,
063F026628FFE11C001FA09F /* RESTCreateApplePaymentResponse+Localization.swift in Sources */,
- 58DF28A52417CB4B00E836B0 /* AppStorePaymentManager.swift in Sources */,
+ 58DF28A52417CB4B00E836B0 /* StorePaymentManager.swift in Sources */,
583DA21425FA4B5C00318683 /* LocationDataSource.swift in Sources */,
587EB6742714520600123C75 /* PreferencesDataSourceDelegate.swift in Sources */,
582BB1AF229566420055B6EF /* SettingsCell.swift in Sources */,
@@ -2113,7 +2121,7 @@
5807E2C02432038B00F5FF30 /* String+Split.swift in Sources */,
58CE5E66224146200008646E /* LoginViewController.swift in Sources */,
58EF580B25D69D7A00AEBA94 /* ProblemReportSubmissionOverlayView.swift in Sources */,
- 58FD5BE724192A2C00112C88 /* AppStoreReceipt.swift in Sources */,
+ 58FD5BE724192A2C00112C88 /* StoreReceipt.swift in Sources */,
5892A45E265FABFF00890742 /* EmptyTableViewHeaderFooterView.swift in Sources */,
580909D32876D09A0078138D /* RevokedDeviceViewController.swift in Sources */,
5835B7CC233B76CB0096D79F /* TunnelManager.swift in Sources */,
@@ -2131,7 +2139,7 @@
5872631D283F755900E14ADF /* IntentHandlers.swift in Sources */,
58CCA01222424D11004F3011 /* SettingsViewController.swift in Sources */,
580F8B8628197958002E0998 /* DNSSettings.swift in Sources */,
- 58FB865526E8BF3100F188BC /* AppStorePaymentManagerError.swift in Sources */,
+ 58FB865526E8BF3100F188BC /* StorePaymentManagerError.swift in Sources */,
58FD5BF42428C67600112C88 /* InAppPurchaseButton.swift in Sources */,
587D9676288989DB00CD8F1C /* NSLayoutConstraint+Helpers.swift in Sources */,
58293FAE2510CA58005D0BB5 /* ProblemReportViewController.swift in Sources */,
diff --git a/ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentManagerError.swift b/ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentManagerError.swift
deleted file mode 100644
index a57306aba9..0000000000
--- a/ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentManagerError.swift
+++ /dev/null
@@ -1,61 +0,0 @@
-//
-// AppStorePaymentManagerError.swift
-// AppStorePaymentManagerError
-//
-// Created by pronebird on 08/09/2021.
-// Copyright © 2021 Mullvad VPN AB. All rights reserved.
-//
-
-import Foundation
-import MullvadREST
-import MullvadTypes
-
-extension AppStorePaymentManager {
- /// An error type emitted by `AppStorePaymentManager`.
- enum Error: LocalizedError, WrappingError {
- /// Failure to find the account token associated with the transaction.
- case noAccountSet
-
- /// Failure to validate the account token.
- case validateAccount(REST.Error)
-
- /// Failure to handle payment transaction. Contains error returned by StoreKit.
- case storePayment(Swift.Error)
-
- /// Failure to read the AppStore receipt.
- case readReceipt(Swift.Error)
-
- /// Failure to send the AppStore receipt to backend.
- case sendReceipt(REST.Error)
-
- var errorDescription: String? {
- switch self {
- case .noAccountSet:
- return "Account is not set."
- case .validateAccount:
- return "Account validation error."
- case .storePayment:
- return "Store payment error."
- case .readReceipt:
- return "Read recept error."
- case .sendReceipt:
- return "Send receipt error."
- }
- }
-
- var underlyingError: Swift.Error? {
- switch self {
- case .noAccountSet:
- return nil
- case let .sendReceipt(error):
- return error
- case let .validateAccount(error):
- return error
- case let .readReceipt(error):
- return error
- case let .storePayment(error):
- return error
- }
- }
- }
-}
diff --git a/ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentObserver.swift b/ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentObserver.swift
deleted file mode 100644
index 306f5b3bef..0000000000
--- a/ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentObserver.swift
+++ /dev/null
@@ -1,28 +0,0 @@
-//
-// AppStorePaymentObserver.swift
-// AppStorePaymentObserver
-//
-// Created by pronebird on 03/09/2021.
-// Copyright © 2021 Mullvad VPN AB. All rights reserved.
-//
-
-import Foundation
-import MullvadREST
-import StoreKit
-
-protocol AppStorePaymentObserver: AnyObject {
- func appStorePaymentManager(
- _ manager: AppStorePaymentManager,
- transaction: SKPaymentTransaction?,
- payment: SKPayment,
- accountToken: String?,
- didFailWithError error: AppStorePaymentManager.Error
- )
-
- func appStorePaymentManager(
- _ manager: AppStorePaymentManager,
- transaction: SKPaymentTransaction,
- accountToken: String,
- didFinishWithResponse response: REST.CreateApplePaymentResponse
- )
-}
diff --git a/ios/MullvadVPN/AppStorePaymentManager/SendAppStoreReceiptOperation.swift b/ios/MullvadVPN/StorePaymentManager/SendStoreReceiptOperation.swift
index 860111e6f0..0b360a7184 100644
--- a/ios/MullvadVPN/AppStorePaymentManager/SendAppStoreReceiptOperation.swift
+++ b/ios/MullvadVPN/StorePaymentManager/SendStoreReceiptOperation.swift
@@ -1,5 +1,5 @@
//
-// SendAppStoreReceiptOperation.swift
+// SendStoreReceiptOperation.swift
// MullvadVPN
//
// Created by pronebird on 29/03/2022.
@@ -12,9 +12,9 @@ import MullvadREST
import MullvadTypes
import Operations
-class SendAppStoreReceiptOperation: ResultOperation<
+class SendStoreReceiptOperation: ResultOperation<
REST.CreateApplePaymentResponse,
- AppStorePaymentManager.Error
+ StorePaymentManagerError
> {
private let apiProxy: REST.APIProxy
private let accountToken: String
@@ -23,7 +23,7 @@ class SendAppStoreReceiptOperation: ResultOperation<
private var fetchReceiptTask: Cancellable?
private var submitReceiptTask: Cancellable?
- private let logger = Logger(label: "SendAppStoreReceiptOperation")
+ private let logger = Logger(label: "SendStoreReceiptOperation")
init(
apiProxy: REST.APIProxy,
@@ -53,7 +53,7 @@ class SendAppStoreReceiptOperation: ResultOperation<
}
override func main() {
- fetchReceiptTask = AppStoreReceipt.fetch(
+ fetchReceiptTask = StoreReceipt.fetch(
forceRefresh: forceRefresh,
receiptProperties: receiptProperties
) { completion in
@@ -82,10 +82,13 @@ class SendAppStoreReceiptOperation: ResultOperation<
) { result in
switch result {
case let .success(response):
- self.logger
- .info(
- "AppStore receipt was processed. Time added: \(response.timeAdded), New expiry: \(response.newExpiry.logFormatDate())"
- )
+ self.logger.info(
+ """
+ AppStore receipt was processed. \
+ Time added: \(response.timeAdded), \
+ New expiry: \(response.newExpiry.logFormatDate())
+ """
+ )
self.finish(completion: .success(response))
case let .failure(error):
diff --git a/ios/MullvadVPN/StorePaymentManager/StorePaymentBlockObserver.swift b/ios/MullvadVPN/StorePaymentManager/StorePaymentBlockObserver.swift
new file mode 100644
index 0000000000..ce3fd61915
--- /dev/null
+++ b/ios/MullvadVPN/StorePaymentManager/StorePaymentBlockObserver.swift
@@ -0,0 +1,26 @@
+//
+// StorePaymentBlockObserver.swift
+// MullvadVPN
+//
+// Created by pronebird on 26/10/2022.
+// Copyright © 2022 Mullvad VPN AB. All rights reserved.
+//
+
+import Foundation
+
+final class StorePaymentBlockObserver: StorePaymentObserver {
+ typealias BlockHandler = (StorePaymentManager, StorePaymentEvent) -> Void
+
+ private let blockHandler: BlockHandler
+
+ init(_ blockHandler: @escaping BlockHandler) {
+ self.blockHandler = blockHandler
+ }
+
+ func storePaymentManager(
+ _ manager: StorePaymentManager,
+ didReceiveEvent event: StorePaymentEvent
+ ) {
+ blockHandler(manager, event)
+ }
+}
diff --git a/ios/MullvadVPN/StorePaymentManager/StorePaymentEvent.swift b/ios/MullvadVPN/StorePaymentManager/StorePaymentEvent.swift
new file mode 100644
index 0000000000..ed03a59121
--- /dev/null
+++ b/ios/MullvadVPN/StorePaymentManager/StorePaymentEvent.swift
@@ -0,0 +1,38 @@
+//
+// StorePaymentEvent.swift
+// MullvadVPN
+//
+// Created by pronebird on 26/10/2022.
+// Copyright © 2022 Mullvad VPN AB. All rights reserved.
+//
+
+import Foundation
+import MullvadREST
+import StoreKit
+
+enum StorePaymentEvent {
+ case finished(StorePaymentCompletion)
+ case failure(StorePaymentFailure)
+
+ var payment: SKPayment {
+ switch self {
+ case let .finished(completion):
+ return completion.transaction.payment
+ case let .failure(failure):
+ return failure.payment
+ }
+ }
+}
+
+struct StorePaymentCompletion {
+ let transaction: SKPaymentTransaction
+ let accountNumber: String
+ let serverResponse: REST.CreateApplePaymentResponse
+}
+
+struct StorePaymentFailure {
+ let transaction: SKPaymentTransaction?
+ let payment: SKPayment
+ let accountNumber: String?
+ let error: StorePaymentManagerError
+}
diff --git a/ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentManager.swift b/ios/MullvadVPN/StorePaymentManager/StorePaymentManager.swift
index fcd41595df..53394d5eb1 100644
--- a/ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentManager.swift
+++ b/ios/MullvadVPN/StorePaymentManager/StorePaymentManager.swift
@@ -1,5 +1,5 @@
//
-// AppStorePaymentManager.swift
+// StorePaymentManager.swift
// MullvadVPN
//
// Created by pronebird on 10/03/2020.
@@ -13,31 +13,27 @@ import MullvadTypes
import Operations
import StoreKit
-class AppStorePaymentManager: NSObject, SKPaymentTransactionObserver {
+class StorePaymentManager: NSObject, SKPaymentTransactionObserver {
private enum OperationCategory {
- static let sendAppStoreReceipt = "AppStorePaymentManager.sendAppStoreReceipt"
- static let productsRequest = "AppStorePaymentManager.productsRequest"
+ static let sendStoreReceipt = "StorePaymentManager.sendStoreReceipt"
+ static let productsRequest = "StorePaymentManager.productsRequest"
}
- /// A shared instance of `AppStorePaymentManager`
- static let shared = AppStorePaymentManager(queue: SKPaymentQueue.default())
-
- private let logger = Logger(label: "AppStorePaymentManager")
+ private let logger = Logger(label: "StorePaymentManager")
private let operationQueue: OperationQueue = {
let queue = AsyncOperationQueue()
- queue.name = "AppStorePaymentManagerQueue"
+ queue.name = "StorePaymentManagerQueue"
return queue
}()
- private let apiProxy = REST.ProxyFactory.shared.createAPIProxy()
- private let accountsProxy = REST.ProxyFactory.shared.createAccountsProxy()
-
private let paymentQueue: SKPaymentQueue
- private var observerList = ObserverList<AppStorePaymentObserver>()
+ private let apiProxy: REST.APIProxy
+ private let accountsProxy: REST.AccountsProxy
+ private var observerList = ObserverList<StorePaymentObserver>()
- private weak var classDelegate: AppStorePaymentManagerDelegate?
- weak var delegate: AppStorePaymentManagerDelegate? {
+ private weak var classDelegate: StorePaymentManagerDelegate?
+ weak var delegate: StorePaymentManagerDelegate? {
get {
if Thread.isMainThread {
return classDelegate
@@ -66,8 +62,10 @@ class AppStorePaymentManager: NSObject, SKPaymentTransactionObserver {
return SKPaymentQueue.canMakePayments()
}
- init(queue: SKPaymentQueue) {
+ init(queue: SKPaymentQueue, apiProxy: REST.APIProxy, accountsProxy: REST.AccountsProxy) {
paymentQueue = queue
+ self.apiProxy = apiProxy
+ self.accountsProxy = accountsProxy
}
func startPaymentQueueMonitoring() {
@@ -93,18 +91,18 @@ class AppStorePaymentManager: NSObject, SKPaymentTransactionObserver {
// MARK: - Payment observation
- func addPaymentObserver(_ observer: AppStorePaymentObserver) {
+ func addPaymentObserver(_ observer: StorePaymentObserver) {
observerList.append(observer)
}
- func removePaymentObserver(_ observer: AppStorePaymentObserver) {
+ func removePaymentObserver(_ observer: StorePaymentObserver) {
observerList.remove(observer)
}
// MARK: - Products and payments
func requestProducts(
- with productIdentifiers: Set<AppStoreSubscription>,
+ with productIdentifiers: Set<StoreSubscription>,
completionHandler: @escaping (OperationCompletion<SKProductsResponse, Swift.Error>) -> Void
) -> Cancellable {
let productIdentifiers = productIdentifiers.productIdentifiersSet
@@ -139,25 +137,31 @@ class AppStorePaymentManager: NSObject, SKPaymentTransactionObserver {
self.paymentQueue.add(payment)
case let .failure(error):
- self.observerList.forEach { observer in
- observer.appStorePaymentManager(
- self,
+ let event = StorePaymentEvent.failure(
+ StorePaymentFailure(
transaction: nil,
payment: payment,
- accountToken: accountToken,
- didFailWithError: .validateAccount(error)
+ accountNumber: accountToken,
+ error: .validateAccount(error)
)
+ )
+
+ self.observerList.forEach { observer in
+ observer.storePaymentManager(self, didReceiveEvent: event)
}
case .cancelled:
- self.observerList.forEach { observer in
- observer.appStorePaymentManager(
- self,
+ let event = StorePaymentEvent.failure(
+ StorePaymentFailure(
transaction: nil,
payment: payment,
- accountToken: accountToken,
- didFailWithError: .validateAccount(.network(URLError(.cancelled)))
+ accountNumber: accountToken,
+ error: .validateAccount(.network(URLError(.cancelled)))
)
+ )
+
+ self.observerList.forEach { observer in
+ observer.storePaymentManager(self, didReceiveEvent: event)
}
}
@@ -169,10 +173,10 @@ class AppStorePaymentManager: NSObject, SKPaymentTransactionObserver {
for accountToken: String,
completionHandler: @escaping (OperationCompletion<
REST.CreateApplePaymentResponse,
- AppStorePaymentManager.Error
+ StorePaymentManagerError
>) -> Void
) -> Cancellable {
- return sendAppStoreReceipt(
+ return sendStoreReceipt(
accountToken: accountToken,
forceRefresh: true,
completionHandler: completionHandler
@@ -194,17 +198,20 @@ class AppStorePaymentManager: NSObject, SKPaymentTransactionObserver {
paymentToAccountToken.removeValue(forKey: payment)
return accountToken
} else {
- return classDelegate?.appStorePaymentManager(self, didRequestAccountTokenFor: payment)
+ return classDelegate?.storePaymentManager(self, didRequestAccountTokenFor: payment)
}
}
- private func sendAppStoreReceipt(
+ private func sendStoreReceipt(
accountToken: String,
forceRefresh: Bool,
- completionHandler: @escaping (OperationCompletion<REST.CreateApplePaymentResponse, Error>)
+ completionHandler: @escaping (OperationCompletion<
+ REST.CreateApplePaymentResponse,
+ StorePaymentManagerError
+ >)
-> Void
) -> Cancellable {
- let operation = SendAppStoreReceiptOperation(
+ let operation = SendStoreReceiptOperation(
apiProxy: apiProxy,
accountToken: accountToken,
forceRefresh: forceRefresh,
@@ -221,7 +228,7 @@ class AppStorePaymentManager: NSObject, SKPaymentTransactionObserver {
)
operation.addCondition(
- MutuallyExclusive(category: OperationCategory.sendAppStoreReceipt)
+ MutuallyExclusive(category: OperationCategory.sendStoreReceipt)
)
operationQueue.addOperation(operation)
@@ -270,65 +277,76 @@ class AppStorePaymentManager: NSObject, SKPaymentTransactionObserver {
paymentQueue.finishTransaction(transaction)
if let accountToken = deassociateAccountToken(transaction.payment) {
- observerList.forEach { observer in
- observer.appStorePaymentManager(
- self,
+ let event = StorePaymentEvent.failure(
+ StorePaymentFailure(
transaction: transaction,
payment: transaction.payment,
- accountToken: accountToken,
- didFailWithError: .storePayment(transaction.error!)
+ accountNumber: accountToken,
+ error: .storePayment(transaction.error!)
)
+ )
+
+ observerList.forEach { observer in
+ observer.storePaymentManager(self, didReceiveEvent: event)
}
} else {
- observerList.forEach { observer in
- observer.appStorePaymentManager(
- self,
+ let event = StorePaymentEvent.failure(
+ StorePaymentFailure(
transaction: transaction,
payment: transaction.payment,
- accountToken: nil,
- didFailWithError: .noAccountSet
+ accountNumber: nil,
+ error: .noAccountSet
)
+ )
+
+ observerList.forEach { observer in
+ observer.storePaymentManager(self, didReceiveEvent: event)
}
}
}
private func didFinishOrRestorePurchase(transaction: SKPaymentTransaction) {
guard let accountToken = deassociateAccountToken(transaction.payment) else {
- observerList.forEach { observer in
- observer.appStorePaymentManager(
- self,
+ let event = StorePaymentEvent.failure(
+ StorePaymentFailure(
transaction: transaction,
payment: transaction.payment,
- accountToken: nil,
- didFailWithError: .noAccountSet
+ accountNumber: nil,
+ error: .noAccountSet
)
+ )
+
+ observerList.forEach { observer in
+ observer.storePaymentManager(self, didReceiveEvent: event)
}
return
}
- _ = sendAppStoreReceipt(accountToken: accountToken, forceRefresh: false) { completion in
+ _ = sendStoreReceipt(accountToken: accountToken, forceRefresh: false) { completion in
switch completion {
case let .success(response):
self.paymentQueue.finishTransaction(transaction)
+ let event = StorePaymentEvent.finished(StorePaymentCompletion(
+ transaction: transaction,
+ accountNumber: accountToken,
+ serverResponse: response
+ ))
+
self.observerList.forEach { observer in
- observer.appStorePaymentManager(
- self,
- transaction: transaction,
- accountToken: accountToken,
- didFinishWithResponse: response
- )
+ observer.storePaymentManager(self, didReceiveEvent: event)
}
case let .failure(error):
+ let event = StorePaymentEvent.failure(StorePaymentFailure(
+ transaction: transaction,
+ payment: transaction.payment,
+ accountNumber: accountToken,
+ error: error
+ ))
+
self.observerList.forEach { observer in
- observer.appStorePaymentManager(
- self,
- transaction: transaction,
- payment: transaction.payment,
- accountToken: accountToken,
- didFailWithError: error
- )
+ observer.storePaymentManager(self, didReceiveEvent: event)
}
case .cancelled:
diff --git a/ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentManagerDelegate.swift b/ios/MullvadVPN/StorePaymentManager/StorePaymentManagerDelegate.swift
index 8dc848c854..a98a37e8da 100644
--- a/ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentManagerDelegate.swift
+++ b/ios/MullvadVPN/StorePaymentManager/StorePaymentManagerDelegate.swift
@@ -1,6 +1,6 @@
//
-// AppStorePaymentManagerDelegate.swift
-// AppStorePaymentManagerDelegate
+// StorePaymentManagerDelegate.swift
+// MullvadVPN
//
// Created by pronebird on 03/09/2021.
// Copyright © 2021 Mullvad VPN AB. All rights reserved.
@@ -9,11 +9,11 @@
import Foundation
import StoreKit
-protocol AppStorePaymentManagerDelegate: AnyObject {
+protocol StorePaymentManagerDelegate: AnyObject {
/// Return the account token associated with the payment.
/// Usually called for unfinished transactions coming back after the app was restarted.
- func appStorePaymentManager(
- _ manager: AppStorePaymentManager,
+ func storePaymentManager(
+ _ manager: StorePaymentManager,
didRequestAccountTokenFor payment: SKPayment
) -> String?
}
diff --git a/ios/MullvadVPN/StorePaymentManager/StorePaymentManagerError.swift b/ios/MullvadVPN/StorePaymentManager/StorePaymentManagerError.swift
new file mode 100644
index 0000000000..83a5508e77
--- /dev/null
+++ b/ios/MullvadVPN/StorePaymentManager/StorePaymentManagerError.swift
@@ -0,0 +1,59 @@
+//
+// StorePaymentManagerError.swift
+// MullvadVPN
+//
+// Created by pronebird on 08/09/2021.
+// Copyright © 2021 Mullvad VPN AB. All rights reserved.
+//
+
+import Foundation
+import MullvadREST
+import MullvadTypes
+
+/// An error type emitted by `StorePaymentManager`.
+enum StorePaymentManagerError: LocalizedError, WrappingError {
+ /// Failure to find the account token associated with the transaction.
+ case noAccountSet
+
+ /// Failure to validate the account token.
+ case validateAccount(REST.Error)
+
+ /// Failure to handle payment transaction. Contains error returned by StoreKit.
+ case storePayment(Swift.Error)
+
+ /// Failure to read the AppStore receipt.
+ case readReceipt(Swift.Error)
+
+ /// Failure to send the AppStore receipt to backend.
+ case sendReceipt(REST.Error)
+
+ var errorDescription: String? {
+ switch self {
+ case .noAccountSet:
+ return "Account is not set."
+ case .validateAccount:
+ return "Account validation error."
+ case .storePayment:
+ return "Store payment error."
+ case .readReceipt:
+ return "Read recept error."
+ case .sendReceipt:
+ return "Send receipt error."
+ }
+ }
+
+ var underlyingError: Swift.Error? {
+ switch self {
+ case .noAccountSet:
+ return nil
+ case let .sendReceipt(error):
+ return error
+ case let .validateAccount(error):
+ return error
+ case let .readReceipt(error):
+ return error
+ case let .storePayment(error):
+ return error
+ }
+ }
+}
diff --git a/ios/MullvadVPN/StorePaymentManager/StorePaymentObserver.swift b/ios/MullvadVPN/StorePaymentManager/StorePaymentObserver.swift
new file mode 100644
index 0000000000..0d6e3584fc
--- /dev/null
+++ b/ios/MullvadVPN/StorePaymentManager/StorePaymentObserver.swift
@@ -0,0 +1,16 @@
+//
+// StorePaymentObserver.swift
+// MullvadVPN
+//
+// Created by pronebird on 03/09/2021.
+// Copyright © 2021 Mullvad VPN AB. All rights reserved.
+//
+
+import Foundation
+
+protocol StorePaymentObserver: AnyObject {
+ func storePaymentManager(
+ _ manager: StorePaymentManager,
+ didReceiveEvent event: StorePaymentEvent
+ )
+}
diff --git a/ios/MullvadVPN/AppStoreReceipt.swift b/ios/MullvadVPN/StorePaymentManager/StoreReceipt.swift
index edc20573d8..93731ba7f9 100644
--- a/ios/MullvadVPN/AppStoreReceipt.swift
+++ b/ios/MullvadVPN/StorePaymentManager/StoreReceipt.swift
@@ -1,5 +1,5 @@
//
-// AppStoreReceipt.swift
+// StoreReceipt.swift
// MullvadVPN
//
// Created by pronebird on 11/03/2020.
@@ -12,17 +12,17 @@ import MullvadTypes
import Operations
import StoreKit
-struct AppStoreReceiptNotFound: LocalizedError {
+struct StoreReceiptNotFound: LocalizedError {
var errorDescription: String? {
return "AppStore receipt file does not exist on disk."
}
}
-enum AppStoreReceipt {
+enum StoreReceipt {
/// Internal operation queue.
private static let operationQueue: OperationQueue = {
let queue = AsyncOperationQueue()
- queue.name = "AppStoreReceiptQueue"
+ queue.name = "StoreReceiptQueue"
queue.maxConcurrentOperationCount = 1
return queue
}()
@@ -86,7 +86,7 @@ private class FetchAppStoreReceiptOperation: ResultOperation<Data, Error>, SKReq
let data = try readReceiptFromDisk()
finish(completion: .success(data))
- } catch is AppStoreReceiptNotFound {
+ } catch is StoreReceiptNotFound {
// Pull receipt from AppStore if it's not cached locally.
startRefreshRequest()
} catch {
@@ -139,7 +139,7 @@ private class FetchAppStoreReceiptOperation: ResultOperation<Data, Error>, SKReq
private func readReceiptFromDisk() throws -> Data {
guard let appStoreReceiptURL = Bundle.main.appStoreReceiptURL else {
- throw AppStoreReceiptNotFound()
+ throw StoreReceiptNotFound()
}
do {
@@ -147,7 +147,7 @@ private class FetchAppStoreReceiptOperation: ResultOperation<Data, Error>, SKReq
} catch let error as CocoaError
where error.code == .fileReadNoSuchFile || error.code == .fileNoSuchFile
{
- throw AppStoreReceiptNotFound()
+ throw StoreReceiptNotFound()
} catch {
throw error
}
diff --git a/ios/MullvadVPN/AppStorePaymentManager/AppStoreSubscription.swift b/ios/MullvadVPN/StorePaymentManager/StoreSubscription.swift
index 37fa3342cb..105ae4425f 100644
--- a/ios/MullvadVPN/AppStorePaymentManager/AppStoreSubscription.swift
+++ b/ios/MullvadVPN/StorePaymentManager/StoreSubscription.swift
@@ -1,6 +1,6 @@
//
-// AppStoreSubscription.swift
-// AppStoreSubscription
+// StoreSubscription.swift
+// MullvadVPN
//
// Created by pronebird on 03/09/2021.
// Copyright © 2021 Mullvad VPN AB. All rights reserved.
@@ -9,7 +9,7 @@
import Foundation
import StoreKit
-enum AppStoreSubscription: String {
+enum StoreSubscription: String {
/// Thirty days non-renewable subscription
case thirtyDays = "net.mullvad.MullvadVPN.subscription.30days"
@@ -17,8 +17,8 @@ enum AppStoreSubscription: String {
switch self {
case .thirtyDays:
return NSLocalizedString(
- "APPSTORE_SUBSCRIPTION_TITLE_ADD_30_DAYS",
- tableName: "AppStoreSubscriptions",
+ "STORE_SUBSCRIPTION_TITLE_ADD_30_DAYS",
+ tableName: "StoreSubscriptions",
value: "Add 30 days time",
comment: ""
)
@@ -28,12 +28,12 @@ enum AppStoreSubscription: String {
extension SKProduct {
var customLocalizedTitle: String? {
- return AppStoreSubscription(rawValue: productIdentifier)?.localizedTitle
+ return StoreSubscription(rawValue: productIdentifier)?.localizedTitle
}
}
-extension Set where Element == AppStoreSubscription {
+extension Set where Element == StoreSubscription {
var productIdentifiersSet: Set<String> {
- Set<String>(map { $0.rawValue })
+ return Set<String>(map { $0.rawValue })
}
}