diff options
| -rw-r--r-- | ios/MullvadVPN.xcodeproj/project.pbxproj | 12 | ||||
| -rw-r--r-- | ios/MullvadVPN/Account.swift | 4 | ||||
| -rw-r--r-- | ios/MullvadVPN/AccountViewController.swift | 9 | ||||
| -rw-r--r-- | ios/MullvadVPN/String+Split.swift | 22 | ||||
| -rw-r--r-- | ios/MullvadVPNTests/StringTests.swift | 29 |
5 files changed, 70 insertions, 6 deletions
diff --git a/ios/MullvadVPN.xcodeproj/project.pbxproj b/ios/MullvadVPN.xcodeproj/project.pbxproj index 9fb61664a7..643ba368b5 100644 --- a/ios/MullvadVPN.xcodeproj/project.pbxproj +++ b/ios/MullvadVPN.xcodeproj/project.pbxproj @@ -7,6 +7,9 @@ objects = { /* Begin PBXBuildFile section */ + 5807E2C02432038B00F5FF30 /* String+Split.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5807E2BF2432038B00F5FF30 /* String+Split.swift */; }; + 5807E2C2243203D000F5FF30 /* StringTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5807E2C1243203D000F5FF30 /* StringTests.swift */; }; + 5807E2C3243203E700F5FF30 /* String+Split.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5807E2BF2432038B00F5FF30 /* String+Split.swift */; }; 5811DE50239014550011EB53 /* NEVPNStatus+Debug.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5811DE4F239014550011EB53 /* NEVPNStatus+Debug.swift */; }; 581CBCE62296B97300727D7F /* ViewControllerIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 581CBCE52296B97300727D7F /* ViewControllerIdentifier.swift */; }; 581CBCEC2298041B00727D7F /* SettingsAppVersionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 581CBCEB2298041B00727D7F /* SettingsAppVersionCell.swift */; }; @@ -171,6 +174,8 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 5807E2BF2432038B00F5FF30 /* String+Split.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+Split.swift"; sourceTree = "<group>"; }; + 5807E2C1243203D000F5FF30 /* StringTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringTests.swift; sourceTree = "<group>"; }; 5811DE4F239014550011EB53 /* NEVPNStatus+Debug.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NEVPNStatus+Debug.swift"; sourceTree = "<group>"; }; 581CBCE52296B97300727D7F /* ViewControllerIdentifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewControllerIdentifier.swift; sourceTree = "<group>"; }; 581CBCEB2298041B00727D7F /* SettingsAppVersionCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsAppVersionCell.swift; sourceTree = "<group>"; }; @@ -323,8 +328,9 @@ 58B0A2A1238EE67E00BC001D /* MullvadVPNTests */ = { isa = PBXGroup; children = ( - 584B26F3237434D00073B10E /* RelaySelectorTests.swift */, 58B0A2A4238EE67E00BC001D /* Info.plist */, + 584B26F3237434D00073B10E /* RelaySelectorTests.swift */, + 5807E2C1243203D000F5FF30 /* StringTests.swift */, ); path = MullvadVPNTests; sourceTree = "<group>"; @@ -422,6 +428,7 @@ 58FD5BE82419406000112C88 /* SKRequestPublisher.swift */, 58F19E34228C15BA00C7710B /* SpinnerActivityIndicatorView.swift */, 581CBCED229826FD00727D7F /* StaticTableViewDataSource.swift */, + 5807E2BF2432038B00F5FF30 /* String+Split.swift */, 5862805322428EF100F5A6E1 /* TranslucentButtonBlurView.swift */, 587AD7C523421D7000E93A53 /* TunnelConfiguration.swift */, 58AEEF672344A40800C9BBD5 /* TunnelConfigurationCoder.swift */, @@ -715,12 +722,14 @@ buildActionMask = 2147483647; files = ( 58B0A2AA238EE6A900BC001D /* RelaySelector.swift in Sources */, + 5807E2C3243203E700F5FF30 /* String+Split.swift in Sources */, 58B0A2A8238EE68200BC001D /* RelaySelectorTests.swift in Sources */, 584E96BE240FD4DB00D3334F /* Location.swift in Sources */, 58B0A2AC238EE6D500BC001D /* IpAddress+Codable.swift in Sources */, 58B0A2AB238EE6BF00BC001D /* RelayList.swift in Sources */, 58B0A2AD238EE6EC00BC001D /* MullvadEndpoint.swift in Sources */, 58B0A2A9238EE6A100BC001D /* RelayConstraints.swift in Sources */, + 5807E2C2243203D000F5FF30 /* StringTests.swift in Sources */, 58A8BE81239FBE62006B74AC /* IPEndpoint.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -772,6 +781,7 @@ 587A01FC23F1F0BE00B68763 /* SimulatorTunnelProviderHost.swift in Sources */, 5862805422428EF100F5A6E1 /* TranslucentButtonBlurView.swift in Sources */, 5888AD83227B11080051EB06 /* SelectLocationCell.swift in Sources */, + 5807E2C02432038B00F5FF30 /* String+Split.swift in Sources */, 58CE5E66224146200008646E /* LoginViewController.swift in Sources */, 5877152E23981C5B001F8237 /* SettingsBasicCell.swift in Sources */, 58FD5BE724192A2C00112C88 /* AppStoreReceipt.swift in Sources */, diff --git a/ios/MullvadVPN/Account.swift b/ios/MullvadVPN/Account.swift index d05dea3cbd..cc1f10e8e6 100644 --- a/ios/MullvadVPN/Account.swift +++ b/ios/MullvadVPN/Account.swift @@ -97,6 +97,10 @@ class Account { return UserDefaults.standard.string(forKey: UserDefaultsKeys.accountToken.rawValue) } + var formattedToken: String? { + return token?.split(every: 4).joined(separator: " ") + } + /// Returns the account expiry for the currently used account token var expiry: Date? { return UserDefaults.standard.object(forKey: UserDefaultsKeys.accountExpiry.rawValue) as? Date diff --git a/ios/MullvadVPN/AccountViewController.swift b/ios/MullvadVPN/AccountViewController.swift index e7ed9b7ef3..dcd631d275 100644 --- a/ios/MullvadVPN/AccountViewController.swift +++ b/ios/MullvadVPN/AccountViewController.swift @@ -66,7 +66,7 @@ class AccountViewController: UIViewController { purchaseButton.titleLabel?.adjustsFontSizeToFitWidth = true purchaseButton.titleLabel?.baselineAdjustment = .alignCenters - accountTokenButton.setTitle(Account.shared.token, for: .normal) + accountTokenButton.setTitle(Account.shared.formattedToken, for: .normal) if let expiryDate = Account.shared.expiry { updateAccountExpiry(expiryDate: expiryDate) @@ -182,16 +182,15 @@ class AccountViewController: UIViewController { } @IBAction func copyAccountToken() { - let accountToken = Account.shared.token - - UIPasteboard.general.string = accountToken + UIPasteboard.general.string = Account.shared.token accountTokenButton.setTitle( NSLocalizedString("COPIED TO PASTEBOARD!", comment: ""), for: .normal) copyToPasteboardSubscriber = - Just(accountToken).cancellableDelay(for: .seconds(3), scheduler: DispatchQueue.main) + Just(Account.shared.formattedToken) + .cancellableDelay(for: .seconds(3), scheduler: DispatchQueue.main) .sink(receiveValue: { [weak self] (accountToken) in self?.accountTokenButton.setTitle(accountToken, for: .normal) }) diff --git a/ios/MullvadVPN/String+Split.swift b/ios/MullvadVPN/String+Split.swift new file mode 100644 index 0000000000..82352280fc --- /dev/null +++ b/ios/MullvadVPN/String+Split.swift @@ -0,0 +1,22 @@ +// +// String+Split.swift +// MullvadVPN +// +// Created by pronebird on 27/03/2020. +// Copyright © 2020 Mullvad VPN AB. All rights reserved. +// + +import Foundation + +extension String { + + /// Returns the array of the longest possible subsequences of the given length. + func split(every length: Int) -> [Substring] { + guard length > 0 else { return [prefix(upTo: endIndex)] } + + let resultCount = Int((Float(count) / Float(length)).rounded(.up)) + + return (0 ..< resultCount) + .map { dropFirst($0 * length).prefix(length) } + } +} diff --git a/ios/MullvadVPNTests/StringTests.swift b/ios/MullvadVPNTests/StringTests.swift new file mode 100644 index 0000000000..e5db3c096a --- /dev/null +++ b/ios/MullvadVPNTests/StringTests.swift @@ -0,0 +1,29 @@ +// +// StringTests.swift +// MullvadVPNTests +// +// Created by pronebird on 27/03/2020. +// Copyright © 2020 Mullvad VPN AB. All rights reserved. +// + +import XCTest + +class StringTests: XCTestCase { + + func testEmptyString() { + XCTAssertTrue("".split(every: 4).isEmpty) + } + + func testString() { + XCTAssertEqual("12345678".split(every: 4), ["1234", "5678"]) + } + + func testOddString() { + XCTAssertEqual("123456789".split(every: 4), ["1234", "5678", "9"]) + } + + func testStringShorterThanLength() { + XCTAssertEqual("1".split(every: 4), ["1"]) + } + +} |
