summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2020-07-15 17:25:00 +0200
committerAndrej Mihajlov <and@mullvad.net>2020-07-15 18:12:28 +0200
commit13d929e64536cb54a2438ee28067e92234f898ef (patch)
tree8bb092514866e7053bfca998479699c0eb747024
parenta3f0653a7129316ccb9847ff6c6f6a334592e807 (diff)
downloadmullvadvpn-13d929e64536cb54a2438ee28067e92234f898ef.tar.xz
mullvadvpn-13d929e64536cb54a2438ee28067e92234f898ef.zip
Remove the use of Combine in SelectLocationController
-rw-r--r--ios/MullvadVPN/Base.lproj/Main.storyboard44
-rw-r--r--ios/MullvadVPN/SelectLocationController.swift111
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 {