Cache pool models, do not rebuild each time
Invalidate on new infrastructure.
This commit is contained in:
parent
d264c0089d
commit
cf8f0984a3
|
@ -26,36 +26,6 @@
|
||||||
import UIKit
|
import UIKit
|
||||||
import Passepartout_Core
|
import Passepartout_Core
|
||||||
|
|
||||||
private class PoolModel {
|
|
||||||
let title: String
|
|
||||||
|
|
||||||
var poolsByGroup: [PoolGroup: [Pool]] = [:]
|
|
||||||
|
|
||||||
private(set) var sortedGroups: [PoolGroup] = []
|
|
||||||
|
|
||||||
var isEmpty: Bool {
|
|
||||||
return sortedGroups.isEmpty
|
|
||||||
}
|
|
||||||
|
|
||||||
init(title: String) {
|
|
||||||
self.title = title
|
|
||||||
}
|
|
||||||
|
|
||||||
func addPool(_ p: Pool) {
|
|
||||||
let group = p.group()
|
|
||||||
if var existingPools = poolsByGroup[group] {
|
|
||||||
existingPools.append(p)
|
|
||||||
poolsByGroup[group] = existingPools
|
|
||||||
} else {
|
|
||||||
poolsByGroup[group] = [p]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func sort() {
|
|
||||||
sortedGroups = poolsByGroup.keys.sorted()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protocol ProviderPoolViewControllerDelegate: class {
|
protocol ProviderPoolViewControllerDelegate: class {
|
||||||
func providerPoolController(_: ProviderPoolViewController, didSelectPool pool: Pool)
|
func providerPoolController(_: ProviderPoolViewController, didSelectPool pool: Pool)
|
||||||
}
|
}
|
||||||
|
@ -69,28 +39,19 @@ class ProviderPoolViewController: UIViewController {
|
||||||
|
|
||||||
weak var delegate: ProviderPoolViewControllerDelegate?
|
weak var delegate: ProviderPoolViewControllerDelegate?
|
||||||
|
|
||||||
func setPools(_ pools: [Pool], currentPoolId: String?) {
|
func setModels(_ models: [PoolModel], currentPoolId: String?) {
|
||||||
let freeModel = PoolModel(title: L10n.Provider.Pool.Sections.Free.header)
|
self.models = models
|
||||||
let paidModel = PoolModel(title: L10n.Provider.Pool.Sections.Paid.header)
|
|
||||||
for p in pools {
|
|
||||||
if p.isFree ?? false {
|
|
||||||
freeModel.addPool(p)
|
|
||||||
} else {
|
|
||||||
paidModel.addPool(p)
|
|
||||||
}
|
|
||||||
if p.id == currentPoolId {
|
|
||||||
currentPool = p
|
|
||||||
}
|
|
||||||
}
|
|
||||||
freeModel.sort()
|
|
||||||
paidModel.sort()
|
|
||||||
|
|
||||||
models = []
|
// XXX: uglyyy
|
||||||
if !freeModel.isEmpty {
|
for m in models {
|
||||||
models.append(freeModel)
|
for pools in m.poolsByGroup.values {
|
||||||
}
|
for p in pools {
|
||||||
if !paidModel.isEmpty {
|
if p.id == currentPoolId {
|
||||||
models.append(paidModel)
|
currentPool = p
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,7 +101,7 @@ extension ProviderPoolViewController: UITableViewDataSource, UITableViewDelegate
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
let model = models[section]
|
let model = models[section]
|
||||||
return model.title
|
return model.isFree ? L10n.Provider.Pool.Sections.Free.header : L10n.Provider.Pool.Sections.Paid.header
|
||||||
}
|
}
|
||||||
|
|
||||||
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||||
|
|
|
@ -152,7 +152,7 @@ class ServiceViewController: UIViewController, TableModelHost {
|
||||||
|
|
||||||
case .providerPoolSegueIdentifier:
|
case .providerPoolSegueIdentifier:
|
||||||
let vc = destination as? ProviderPoolViewController
|
let vc = destination as? ProviderPoolViewController
|
||||||
vc?.setPools(uncheckedProviderProfile.pools(), currentPoolId: uncheckedProviderProfile.poolId)
|
vc?.setModels(InfrastructureCache.shared.poolModels(for: uncheckedProviderProfile), currentPoolId: uncheckedProviderProfile.poolId)
|
||||||
vc?.delegate = self
|
vc?.delegate = self
|
||||||
|
|
||||||
case .endpointSegueIdentifier:
|
case .endpointSegueIdentifier:
|
||||||
|
@ -289,14 +289,19 @@ class ServiceViewController: UIViewController, TableModelHost {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func refreshProviderInfrastructure() {
|
private func refreshProviderInfrastructure() {
|
||||||
|
let name = uncheckedProviderProfile.name
|
||||||
|
|
||||||
let hud = HUD()
|
let hud = HUD()
|
||||||
let isUpdating = InfrastructureFactory.shared.update(uncheckedProviderProfile.name, notBeforeInterval: AppConstants.Web.minimumUpdateInterval) { (response, error) in
|
let isUpdating = InfrastructureFactory.shared.update(name, notBeforeInterval: AppConstants.Web.minimumUpdateInterval) { (response, error) in
|
||||||
hud.hide()
|
hud.hide()
|
||||||
guard let response = response else {
|
guard let response = response else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.lastInfrastructureUpdate = response.1
|
self.lastInfrastructureUpdate = response.1
|
||||||
self.tableView.reloadData()
|
self.tableView.reloadData()
|
||||||
|
|
||||||
|
// invalidate current pool cache
|
||||||
|
InfrastructureCache.shared.removePoolModels(for: name)
|
||||||
}
|
}
|
||||||
if !isUpdating {
|
if !isUpdating {
|
||||||
hud.hide()
|
hud.hide()
|
||||||
|
|
|
@ -89,7 +89,7 @@ class ShortcutsConnectToViewController: UITableViewController, ProviderPoolViewC
|
||||||
guard let provider = selectedProfile as? ProviderConnectionProfile else {
|
guard let provider = selectedProfile as? ProviderConnectionProfile else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
vc.setPools(provider.pools(), currentPoolId: nil)
|
vc.setModels(InfrastructureCache.shared.poolModels(for: provider), currentPoolId: nil)
|
||||||
vc.delegate = self
|
vc.delegate = self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,8 @@
|
||||||
0E58BD9322404EF1006FB157 /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 0E58BD9122404EF1006FB157 /* Intents.intentdefinition */; };
|
0E58BD9322404EF1006FB157 /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 0E58BD9122404EF1006FB157 /* Intents.intentdefinition */; };
|
||||||
0E58BF65224152F9006FB157 /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 0E58BD9122404EF1006FB157 /* Intents.intentdefinition */; settings = {ATTRIBUTES = (no_codegen, ); }; };
|
0E58BF65224152F9006FB157 /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 0E58BD9122404EF1006FB157 /* Intents.intentdefinition */; settings = {ATTRIBUTES = (no_codegen, ); }; };
|
||||||
0E58BF68224305A8006FB157 /* Countries.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0E58BF6A224305A8006FB157 /* Countries.strings */; };
|
0E58BF68224305A8006FB157 /* Countries.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0E58BF6A224305A8006FB157 /* Countries.strings */; };
|
||||||
|
0E66A270225FE25800F9C779 /* PoolModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E66A26F225FE25800F9C779 /* PoolModel.swift */; };
|
||||||
|
0E66A272225FE5FB00F9C779 /* InfrastructureCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E66A271225FE5FB00F9C779 /* InfrastructureCache.swift */; };
|
||||||
0E6BE13F20CFBAB300A6DD36 /* DebugLogViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E6BE13E20CFBAB300A6DD36 /* DebugLogViewController.swift */; };
|
0E6BE13F20CFBAB300A6DD36 /* DebugLogViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E6BE13E20CFBAB300A6DD36 /* DebugLogViewController.swift */; };
|
||||||
0E773BF8224BF37600CDDC8E /* ShortcutsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E773BF7224BF37600CDDC8E /* ShortcutsViewController.swift */; };
|
0E773BF8224BF37600CDDC8E /* ShortcutsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E773BF7224BF37600CDDC8E /* ShortcutsViewController.swift */; };
|
||||||
0E89DFCE213EEDFA00741BA1 /* WizardProviderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E89DFCD213EEDFA00741BA1 /* WizardProviderViewController.swift */; };
|
0E89DFCE213EEDFA00741BA1 /* WizardProviderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E89DFCD213EEDFA00741BA1 /* WizardProviderViewController.swift */; };
|
||||||
|
@ -217,6 +219,8 @@
|
||||||
0E5E5DDE215119AF00E318A3 /* VPNStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNStatus.swift; sourceTree = "<group>"; };
|
0E5E5DDE215119AF00E318A3 /* VPNStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNStatus.swift; sourceTree = "<group>"; };
|
||||||
0E5E5DE1215119DD00E318A3 /* VPNConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNConfiguration.swift; sourceTree = "<group>"; };
|
0E5E5DE1215119DD00E318A3 /* VPNConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNConfiguration.swift; sourceTree = "<group>"; };
|
||||||
0E5E5DE421511C5F00E318A3 /* GracefulVPN.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GracefulVPN.swift; sourceTree = "<group>"; };
|
0E5E5DE421511C5F00E318A3 /* GracefulVPN.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GracefulVPN.swift; sourceTree = "<group>"; };
|
||||||
|
0E66A26F225FE25800F9C779 /* PoolModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PoolModel.swift; sourceTree = "<group>"; };
|
||||||
|
0E66A271225FE5FB00F9C779 /* InfrastructureCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfrastructureCache.swift; sourceTree = "<group>"; };
|
||||||
0E6BE13920CFB76800A6DD36 /* ApplicationError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationError.swift; sourceTree = "<group>"; };
|
0E6BE13920CFB76800A6DD36 /* ApplicationError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationError.swift; sourceTree = "<group>"; };
|
||||||
0E6BE13E20CFBAB300A6DD36 /* DebugLogViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DebugLogViewController.swift; sourceTree = "<group>"; };
|
0E6BE13E20CFBAB300A6DD36 /* DebugLogViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DebugLogViewController.swift; sourceTree = "<group>"; };
|
||||||
0E773BF7224BF37600CDDC8E /* ShortcutsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutsViewController.swift; sourceTree = "<group>"; };
|
0E773BF7224BF37600CDDC8E /* ShortcutsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutsViewController.swift; sourceTree = "<group>"; };
|
||||||
|
@ -476,7 +480,9 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
0EBE3AA3213DC1B000BFA2F5 /* HostConnectionProfile.swift */,
|
0EBE3AA3213DC1B000BFA2F5 /* HostConnectionProfile.swift */,
|
||||||
|
0E66A271225FE5FB00F9C779 /* InfrastructureCache.swift */,
|
||||||
0E79D13E21919EC900BB5FB2 /* PlaceholderConnectionProfile.swift */,
|
0E79D13E21919EC900BB5FB2 /* PlaceholderConnectionProfile.swift */,
|
||||||
|
0E66A26F225FE25800F9C779 /* PoolModel.swift */,
|
||||||
0E79D14021919F5600BB5FB2 /* ProfileKey.swift */,
|
0E79D14021919F5600BB5FB2 /* ProfileKey.swift */,
|
||||||
0EBE3AA4213DC1B000BFA2F5 /* ProviderConnectionProfile.swift */,
|
0EBE3AA4213DC1B000BFA2F5 /* ProviderConnectionProfile.swift */,
|
||||||
);
|
);
|
||||||
|
@ -1005,6 +1011,7 @@
|
||||||
files = (
|
files = (
|
||||||
0E3152BD223FA03D00F61841 /* GroupConstants.swift in Sources */,
|
0E3152BD223FA03D00F61841 /* GroupConstants.swift in Sources */,
|
||||||
0ECEB10A224FECEA00E9E551 /* DataUnit.swift in Sources */,
|
0ECEB10A224FECEA00E9E551 /* DataUnit.swift in Sources */,
|
||||||
|
0E66A270225FE25800F9C779 /* PoolModel.swift in Sources */,
|
||||||
0E3152C2223FA04800F61841 /* MockVPNProvider.swift in Sources */,
|
0E3152C2223FA04800F61841 /* MockVPNProvider.swift in Sources */,
|
||||||
0E533B162258E03B00EF94FC /* PoolGroup.swift in Sources */,
|
0E533B162258E03B00EF94FC /* PoolGroup.swift in Sources */,
|
||||||
0E3152D2223FA05400F61841 /* DebugLog.swift in Sources */,
|
0E3152D2223FA05400F61841 /* DebugLog.swift in Sources */,
|
||||||
|
@ -1035,6 +1042,7 @@
|
||||||
0E3152CD223FA05400F61841 /* ConnectionProfile.swift in Sources */,
|
0E3152CD223FA05400F61841 /* ConnectionProfile.swift in Sources */,
|
||||||
0E3152BC223FA03D00F61841 /* ApplicationError.swift in Sources */,
|
0E3152BC223FA03D00F61841 /* ApplicationError.swift in Sources */,
|
||||||
0E3152C9223FA04D00F61841 /* InfrastructureFactory.swift in Sources */,
|
0E3152C9223FA04D00F61841 /* InfrastructureFactory.swift in Sources */,
|
||||||
|
0E66A272225FE5FB00F9C779 /* InfrastructureCache.swift in Sources */,
|
||||||
0E58BD9322404EF1006FB157 /* Intents.intentdefinition in Sources */,
|
0E58BD9322404EF1006FB157 /* Intents.intentdefinition in Sources */,
|
||||||
0E3152D3223FA05400F61841 /* EndpointDataSource.swift in Sources */,
|
0E3152D3223FA05400F61841 /* EndpointDataSource.swift in Sources */,
|
||||||
0E3152D4223FA05400F61841 /* Preferences.swift in Sources */,
|
0E3152D4223FA05400F61841 /* Preferences.swift in Sources */,
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
//
|
||||||
|
// InfrastructureCache.swift
|
||||||
|
// Passepartout
|
||||||
|
//
|
||||||
|
// Created by Davide De Rosa on 4/11/19.
|
||||||
|
// Copyright (c) 2019 Davide De Rosa. All rights reserved.
|
||||||
|
//
|
||||||
|
// https://github.com/passepartoutvpn
|
||||||
|
//
|
||||||
|
// This file is part of Passepartout.
|
||||||
|
//
|
||||||
|
// Passepartout is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Passepartout is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public class InfrastructureCache {
|
||||||
|
public static let shared = InfrastructureCache()
|
||||||
|
|
||||||
|
private var poolModelsByName: [Infrastructure.Name: [PoolModel]]
|
||||||
|
|
||||||
|
private init() {
|
||||||
|
poolModelsByName = [:]
|
||||||
|
}
|
||||||
|
|
||||||
|
public func poolModels(for provider: ProviderConnectionProfile) -> [PoolModel] {
|
||||||
|
if let models = poolModelsByName[provider.name] {
|
||||||
|
return models
|
||||||
|
}
|
||||||
|
let freeModel = PoolModel(isFree: true)
|
||||||
|
let paidModel = PoolModel(isFree: false)
|
||||||
|
for p in provider.infrastructure.pools {
|
||||||
|
if p.isFree ?? false {
|
||||||
|
freeModel.addPool(p)
|
||||||
|
} else {
|
||||||
|
paidModel.addPool(p)
|
||||||
|
}
|
||||||
|
// if p.id == currentPoolId {
|
||||||
|
// currentPool = p
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
freeModel.sort()
|
||||||
|
paidModel.sort()
|
||||||
|
|
||||||
|
var models: [PoolModel] = []
|
||||||
|
if !freeModel.isEmpty {
|
||||||
|
models.append(freeModel)
|
||||||
|
}
|
||||||
|
if !paidModel.isEmpty {
|
||||||
|
models.append(paidModel)
|
||||||
|
}
|
||||||
|
poolModelsByName[provider.name] = models
|
||||||
|
return models
|
||||||
|
}
|
||||||
|
|
||||||
|
public func removePoolModels(for name: Infrastructure.Name? = nil) {
|
||||||
|
if let name = name {
|
||||||
|
poolModelsByName.removeValue(forKey: name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
poolModelsByName.removeAll()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
//
|
||||||
|
// PoolModel.swift
|
||||||
|
// Passepartout
|
||||||
|
//
|
||||||
|
// Created by Davide De Rosa on 4/11/19.
|
||||||
|
// Copyright (c) 2019 Davide De Rosa. All rights reserved.
|
||||||
|
//
|
||||||
|
// https://github.com/passepartoutvpn
|
||||||
|
//
|
||||||
|
// This file is part of Passepartout.
|
||||||
|
//
|
||||||
|
// Passepartout is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Passepartout is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public class PoolModel {
|
||||||
|
public let isFree: Bool
|
||||||
|
|
||||||
|
public var poolsByGroup: [PoolGroup: [Pool]]
|
||||||
|
|
||||||
|
public private(set) var sortedGroups: [PoolGroup]
|
||||||
|
|
||||||
|
public init(isFree: Bool) {
|
||||||
|
self.isFree = isFree
|
||||||
|
poolsByGroup = [:]
|
||||||
|
sortedGroups = []
|
||||||
|
}
|
||||||
|
|
||||||
|
public var isEmpty: Bool {
|
||||||
|
return sortedGroups.isEmpty
|
||||||
|
}
|
||||||
|
|
||||||
|
public func addPool(_ p: Pool) {
|
||||||
|
let group = p.group()
|
||||||
|
if var existingPools = poolsByGroup[group] {
|
||||||
|
existingPools.append(p)
|
||||||
|
poolsByGroup[group] = existingPools
|
||||||
|
} else {
|
||||||
|
poolsByGroup[group] = [p]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func sort() {
|
||||||
|
sortedGroups = poolsByGroup.keys.sorted()
|
||||||
|
}
|
||||||
|
}
|
|
@ -72,10 +72,6 @@ public class ProviderConnectionProfile: ConnectionProfile, Codable, Equatable {
|
||||||
presetId = infrastructure.defaults.preset
|
presetId = infrastructure.defaults.preset
|
||||||
}
|
}
|
||||||
|
|
||||||
public func pools() -> [Pool] {
|
|
||||||
return infrastructure.pools
|
|
||||||
}
|
|
||||||
|
|
||||||
private func validateEndpoint() {
|
private func validateEndpoint() {
|
||||||
guard let pool = pool, let preset = preset else {
|
guard let pool = pool, let preset = preset else {
|
||||||
manualAddress = nil
|
manualAddress = nil
|
||||||
|
|
Loading…
Reference in New Issue