diff options
| author | Andrej Mihajlov <and@mullvad.net> | 2020-07-15 17:25:00 +0200 |
|---|---|---|
| committer | Andrej Mihajlov <and@mullvad.net> | 2020-07-15 18:12:28 +0200 |
| commit | 13d929e64536cb54a2438ee28067e92234f898ef (patch) | |
| tree | 8bb092514866e7053bfca998479699c0eb747024 | |
| parent | a3f0653a7129316ccb9847ff6c6f6a334592e807 (diff) | |
| download | mullvadvpn-13d929e64536cb54a2438ee28067e92234f898ef.tar.xz mullvadvpn-13d929e64536cb54a2438ee28067e92234f898ef.zip | |
Remove the use of Combine in SelectLocationController
| -rw-r--r-- | ios/MullvadVPN/Base.lproj/Main.storyboard | 44 | ||||
| -rw-r--r-- | ios/MullvadVPN/SelectLocationController.swift | 111 |
2 files changed, 80 insertions, 75 deletions
diff --git a/ios/MullvadVPN/Base.lproj/Main.storyboard b/ios/MullvadVPN/Base.lproj/Main.storyboard index f1a8fcd7fb..31ea1456cb 100644 --- a/ios/MullvadVPN/Base.lproj/Main.storyboard +++ b/ios/MullvadVPN/Base.lproj/Main.storyboard @@ -44,7 +44,7 @@ </constraints> </view> <imageView clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.0" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="IconSuccess" translatesAutoresizingMaskIntoConstraints="NO" id="7ux-Tb-Fzq"> - <rect key="frame" x="127.5" y="137" width="120" height="120"/> + <rect key="frame" x="157.5" y="167" width="60" height="60"/> </imageView> <view contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" translatesAutoresizingMaskIntoConstraints="NO" id="V3j-Lb-fSQ" userLabel="Form"> <rect key="frame" x="0.0" y="251" width="375" height="125.5"/> @@ -292,7 +292,7 @@ <objects> <tableViewController id="SHd-a4-ewi" customClass="SettingsViewController" customModule="MullvadVPN" customModuleProvider="target" sceneMemberID="viewController"> <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="6Gz-UM-orK"> - <rect key="frame" x="0.0" y="0.0" width="375" height="647"/> + <rect key="frame" x="0.0" y="0.0" width="375" height="667"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <color key="backgroundColor" name="Secondary"/> <color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> @@ -430,11 +430,11 @@ <objects> <viewController id="vAK-MJ-h3c" customClass="WireguardKeysViewController" customModule="MullvadVPN" customModuleProvider="target" sceneMemberID="viewController"> <view key="view" contentMode="scaleToFill" id="NHk-FR-Mwy"> - <rect key="frame" x="0.0" y="0.0" width="375" height="647"/> + <rect key="frame" x="0.0" y="0.0" width="375" height="667"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fa2-zl-Fc4"> - <rect key="frame" x="0.0" y="0.0" width="375" height="647"/> + <rect key="frame" x="0.0" y="0.0" width="375" height="667"/> <subviews> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="5VO-oQ-4jM" userLabel="Container"> <rect key="frame" x="0.0" y="0.0" width="375" height="295.5"/> @@ -666,11 +666,11 @@ <objects> <viewController id="ruh-Q2-P39" customClass="AccountViewController" customModule="MullvadVPN" customModuleProvider="target" sceneMemberID="viewController"> <view key="view" contentMode="scaleToFill" id="Qpl-bL-ZGl"> - <rect key="frame" x="0.0" y="0.0" width="375" height="647"/> + <rect key="frame" x="0.0" y="0.0" width="375" height="667"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" translatesAutoresizingMaskIntoConstraints="NO" id="saE-dV-AgF"> - <rect key="frame" x="0.0" y="0.0" width="375" height="647"/> + <rect key="frame" x="0.0" y="0.0" width="375" height="667"/> <subviews> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="rkG-Xa-pEO" userLabel="Container"> <rect key="frame" x="0.0" y="0.0" width="375" height="349.5"/> @@ -896,10 +896,10 @@ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" translatesAutoresizingMaskIntoConstraints="NO" id="JYh-33-d0O"> - <rect key="frame" x="0.0" y="0.0" width="375" height="598"/> + <rect key="frame" x="0.0" y="0.0" width="375" height="597"/> <subviews> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="N9k-cQ-tlw" userLabel="Content view"> - <rect key="frame" x="0.0" y="0.0" width="375" height="568"/> + <rect key="frame" x="0.0" y="0.0" width="375" height="558"/> <subviews> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Wnl-L9-JqG" userLabel="Logo header"> <rect key="frame" x="0.0" y="0.0" width="375" height="100"/> @@ -935,7 +935,7 @@ <nil key="highlightedColor"/> </label> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="leading" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Cas-Tk-gcz" customClass="LinkButton" customModule="MullvadVPN" customModuleProvider="target"> - <rect key="frame" x="20" y="516" width="36" height="32"/> + <rect key="frame" x="20" y="516" width="128" height="22"/> <fontDescription key="fontDescription" name=".AppleSystemUIFont" family=".AppleSystemUIFont" pointSize="18"/> <color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <state key="normal" title="Privacy Policy" image="IconExtlink"/> @@ -971,10 +971,10 @@ </constraints> </scrollView> <view contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" translatesAutoresizingMaskIntoConstraints="NO" id="16P-Q0-ZO9" userLabel="Footer"> - <rect key="frame" x="0.0" y="598" width="375" height="69"/> + <rect key="frame" x="0.0" y="597" width="375" height="70"/> <subviews> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ttw-7B-1MM" customClass="AppButton" customModule="MullvadVPN" customModuleProvider="target"> - <rect key="frame" x="16" y="24" width="343" height="21"/> + <rect key="frame" x="16" y="24" width="343" height="22"/> <accessibility key="accessibilityConfiguration" identifier="AgreeButton"/> <state key="normal" title="Agree and continue" backgroundImage="DefaultButton"> <color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> @@ -1010,7 +1010,7 @@ </viewController> <placeholder placeholderIdentifier="IBFirstResponder" id="87X-aX-U9x" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/> </objects> - <point key="canvasLocation" x="-1207" y="27"/> + <point key="canvasLocation" x="-551" y="27"/> </scene> <!--Navigation Controller--> <scene sceneID="oT4-Ap-qrZ"> @@ -1063,31 +1063,31 @@ </view> <prototypes> <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="Cell" id="aFz-H5-sPu" customClass="SelectLocationCell" customModule="MullvadVPN" customModuleProvider="target"> - <rect key="frame" x="0.0" y="173" width="375" height="48.5"/> + <rect key="frame" x="0.0" y="173" width="375" height="43.5"/> <autoresizingMask key="autoresizingMask"/> <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="aFz-H5-sPu" id="6nQ-gT-vzf"> - <rect key="frame" x="0.0" y="0.0" width="375" height="48.5"/> + <rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/> <autoresizingMask key="autoresizingMask"/> <subviews> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="5ag-N4-pUg" customClass="RelayStatusIndicatorView" customModule="MullvadVPN" customModuleProvider="target"> - <rect key="frame" x="16" y="16.5" width="16" height="16"/> + <rect key="frame" x="16" y="14" width="16" height="16"/> <constraints> <constraint firstAttribute="height" constant="16" id="QWj-hh-I3P"/> <constraint firstAttribute="width" constant="16" id="TFV-yi-LXG"/> </constraints> </view> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="y7o-0b-MUV"> - <rect key="frame" x="44" y="11" width="42" height="26.5"/> + <rect key="frame" x="44" y="11" width="42" height="21.5"/> <fontDescription key="fontDescription" type="system" pointSize="17"/> <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <nil key="highlightedColor"/> </label> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="IconTick" translatesAutoresizingMaskIntoConstraints="NO" id="e1o-Bl-zd5"> - <rect key="frame" x="0.0" y="0.5" width="48" height="48"/> + <rect key="frame" x="12" y="10" width="24" height="24"/> <color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> </imageView> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="KaW-bN-I51"> - <rect key="frame" x="311" y="0.0" width="64" height="48.5"/> + <rect key="frame" x="311" y="0.0" width="64" height="43.5"/> <accessibility key="accessibilityConfiguration" identifier="ExpandButton"/> <constraints> <constraint firstAttribute="width" constant="64" id="UU3-Di-65E"/> @@ -1131,18 +1131,10 @@ </barButtonItem> </navigationItem> <connections> - <outlet property="activityIndicator" destination="Mdw-ey-b8l" id="w7b-yv-Q39"/> <segue destination="6Lc-ZQ-E4P" kind="unwind" identifier="ReturnToConnectWithNewRelay" unwindAction="unwindFromSelectLocationWithSegue:" id="SPT-Ay-Cy3"/> </connections> </tableViewController> <placeholder placeholderIdentifier="IBFirstResponder" id="EvX-LH-gOg" userLabel="First Responder" sceneMemberID="firstResponder"/> - <view contentMode="scaleToFill" id="Mdw-ey-b8l" customClass="SpinnerActivityIndicatorView" customModule="MullvadVPN" customModuleProvider="target"> - <rect key="frame" x="0.0" y="0.0" width="48" height="48"/> - <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> - <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> - <color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> - <viewLayoutGuide key="safeArea" id="gNQ-Ao-v6S"/> - </view> <exit id="6Lc-ZQ-E4P" userLabel="Exit" sceneMemberID="exit"/> </objects> <point key="canvasLocation" x="2649" y="841"/> diff --git a/ios/MullvadVPN/SelectLocationController.swift b/ios/MullvadVPN/SelectLocationController.swift index cbb06ac1a0..c1c8b7d938 100644 --- a/ios/MullvadVPN/SelectLocationController.swift +++ b/ios/MullvadVPN/SelectLocationController.swift @@ -6,28 +6,32 @@ // Copyright © 2019 Mullvad VPN AB. All rights reserved. // -import Combine import DiffableDataSources import UIKit import os private let kCellIdentifier = "Cell" -enum SelectLocationControllerError: Error { - case loadRelayList(RelayCacheError) - case getRelayConstraints(TunnelManagerError) -} +class SelectLocationController: UITableViewController, RelayCacheObserver { -class SelectLocationController: UITableViewController { + private enum Error: ChainedError { + case loadRelayList(RelayCacheError) + case getRelayConstraints(TunnelManager.Error) + + var errorDescription: String? { + switch self { + case .loadRelayList: + return "Failure to load a relay list" + case .getRelayConstraints: + return "Failure to get relay constraints" + } + } + } - private let relayCache = try! RelayCache.withDefaultLocationAndEphemeralSession().get() private var relayList: RelayList? private var relayConstraints: RelayConstraints? private var expandedItems = [RelayLocation]() private var dataSource: DataSource? - private var loadDataSubscriber: AnyCancellable? - - @IBOutlet var activityIndicator: SpinnerActivityIndicatorView! var selectedLocation: RelayLocation? @@ -59,7 +63,7 @@ class SelectLocationController: UITableViewController { tableView.dataSource = dataSource - addActivityIndicatorView() + RelayCache.shared.addObserver(self) loadData() } @@ -93,38 +97,62 @@ class SelectLocationController: UITableViewController { } } + // MARK: - RelayCacheObserver + + func relayCache(_ relayCache: RelayCache, didUpdateCachedRelayList cachedRelayList: CachedRelayList) { + self.didReceiveCachedRelays(cachedRelayList: cachedRelayList) { (result) in + DispatchQueue.main.async { + switch result { + case .success(let (cachedRelayList, relayConstraints)): + self.didReceive(relayList: cachedRelayList.relayList, relayConstraints: relayConstraints) + + case .failure(let error): + error.logChain() + } + } + } + } + // MARK: - Relay list handling private func loadData() { - loadDataSubscriber = relayCache.read() - .mapError { SelectLocationControllerError.loadRelayList($0) } - .map { $0.relayList.sorted() } - .flatMap({ (filteredRelayList) in - TunnelManager.shared.getRelayConstraints() - .mapError { SelectLocationControllerError.getRelayConstraints($0) } - .map { (filteredRelayList, $0) } - }) - .receive(on: DispatchQueue.main) - .handleEvents(receiveSubscription: { [weak self] _ in - self?.activityIndicator.startAnimating() - }, receiveCompletion: { [weak self] _ in - self?.activityIndicator.stopAnimating() - }, receiveCancel: { [weak self] () in - self?.activityIndicator.stopAnimating() - }) - .sink(receiveCompletion: { (completion) in - if case .failure(let error) = completion { - os_log(.error, "Failed to load the SelectLocation controller: %{public}s", error.localizedDescription) + fetchRelays { (result) in + DispatchQueue.main.async { + switch result { + case .success(let (cachedRelayList, relayConstraints)): + self.didReceive(relayList: cachedRelayList.relayList, relayConstraints: relayConstraints) + + case .failure(let error): + error.logChain() } - }) { [weak self] (result) in - let (relayList, constraints) = result + } + } + } + + private func fetchRelays(completionHandler: @escaping (Result<(CachedRelayList, RelayConstraints), Error>) -> Void) { + RelayCache.shared.read { (result) in + switch result { + case .success(let cachedRelayList): + self.didReceiveCachedRelays(cachedRelayList: cachedRelayList, completionHandler: completionHandler) - self?.didReceive(relayList: relayList, relayConstraints: constraints) + case .failure(let error): + completionHandler(.failure(.loadRelayList(error))) } + } + } + + private func didReceiveCachedRelays(cachedRelayList: CachedRelayList, completionHandler: @escaping (Result<(CachedRelayList, RelayConstraints), Error>) -> Void) { + TunnelManager.shared.getRelayConstraints { (result) in + let result = result + .map { (cachedRelayList, $0) } + .mapError { Error.getRelayConstraints($0) } + + completionHandler(result) + } } private func didReceive(relayList: RelayList, relayConstraints: RelayConstraints) { - self.relayList = relayList + self.relayList = relayList.sorted() self.relayConstraints = relayConstraints let relayLocation = relayConstraints.location.value @@ -215,21 +243,6 @@ class SelectLocationController: UITableViewController { tableView.tableHeaderView = header } } - - // MARK: - Activity indicator - - private func addActivityIndicatorView() { - view.addSubview(activityIndicator) - - activityIndicator.translatesAutoresizingMaskIntoConstraints = false - - NSLayoutConstraint.activate([ - activityIndicator.widthAnchor.constraint(equalToConstant: 48), - activityIndicator.heightAnchor.constraint(equalToConstant: 48), - activityIndicator.centerXAnchor.constraint(equalTo: view.centerXAnchor), - activityIndicator.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -60) - ]) - } } private extension RelayList { |
