Merge branch 'improve-tunnel-status-reporting'
This commit is contained in:
commit
4ac3017c59
|
@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
- Tunnel failure reporting in UI. [#8](https://github.com/keeshux/passepartout-ios/pull/8)
|
||||||
- Explicit "Reconnect" button. [#9](https://github.com/keeshux/passepartout-ios/pull/9)
|
- Explicit "Reconnect" button. [#9](https://github.com/keeshux/passepartout-ios/pull/9)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
import TunnelKit
|
||||||
|
|
||||||
extension UITableViewCell {
|
extension UITableViewCell {
|
||||||
func applyChecked(_ checked: Bool, _ theme: Theme) {
|
func applyChecked(_ checked: Bool, _ theme: Theme) {
|
||||||
|
@ -66,7 +67,7 @@ extension SettingTableViewCell {
|
||||||
accessoryType = .none
|
accessoryType = .none
|
||||||
}
|
}
|
||||||
|
|
||||||
func applyVPN(_ theme: Theme, with vpnStatus: VPNStatus?) {
|
func applyVPN(_ theme: Theme, with vpnStatus: VPNStatus?, error: TunnelKitProvider.ProviderError?) {
|
||||||
leftTextColor = theme.palette.colorPrimaryText
|
leftTextColor = theme.palette.colorPrimaryText
|
||||||
guard let vpnStatus = vpnStatus else {
|
guard let vpnStatus = vpnStatus else {
|
||||||
rightText = L10n.Vpn.disabled
|
rightText = L10n.Vpn.disabled
|
||||||
|
@ -83,13 +84,41 @@ extension SettingTableViewCell {
|
||||||
rightText = L10n.Vpn.active
|
rightText = L10n.Vpn.active
|
||||||
rightTextColor = theme.palette.colorOn
|
rightTextColor = theme.palette.colorOn
|
||||||
|
|
||||||
case .disconnecting:
|
case .disconnecting, .disconnected:
|
||||||
rightText = L10n.Vpn.disconnecting
|
var disconnectionReason: String?
|
||||||
rightTextColor = theme.palette.colorIndeterminate
|
if let error = error {
|
||||||
|
switch error {
|
||||||
case .disconnected:
|
case .socketActivity, .timeout:
|
||||||
rightText = L10n.Vpn.inactive
|
disconnectionReason = L10n.Vpn.Errors.timeout
|
||||||
rightTextColor = theme.palette.colorOff
|
|
||||||
|
case .dnsFailure:
|
||||||
|
disconnectionReason = L10n.Vpn.Errors.dns
|
||||||
|
|
||||||
|
case .tlsFailed:
|
||||||
|
disconnectionReason = L10n.Vpn.Errors.tls
|
||||||
|
|
||||||
|
case .authenticationFailed:
|
||||||
|
disconnectionReason = L10n.Vpn.Errors.auth
|
||||||
|
|
||||||
|
case .networkChanged:
|
||||||
|
disconnectionReason = L10n.Vpn.Errors.network
|
||||||
|
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch vpnStatus {
|
||||||
|
case .disconnecting:
|
||||||
|
rightText = disconnectionReason ?? L10n.Vpn.disconnecting
|
||||||
|
rightTextColor = theme.palette.colorIndeterminate
|
||||||
|
|
||||||
|
case .disconnected:
|
||||||
|
rightText = disconnectionReason ?? L10n.Vpn.inactive
|
||||||
|
rightTextColor = theme.palette.colorOff
|
||||||
|
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -293,7 +293,7 @@ extension EndpointViewController: UITableViewDataSource, UITableViewDelegate {
|
||||||
|
|
||||||
setNeedsRefresh()
|
setNeedsRefresh()
|
||||||
commitChanges()
|
commitChanges()
|
||||||
tableView.reloadRows(at: updatedIndexPaths, with: .automatic)
|
tableView.reloadRows(at: updatedIndexPaths, with: .none)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Helpers
|
// MARK: Helpers
|
||||||
|
|
|
@ -88,6 +88,7 @@ class ServiceViewController: UIViewController, TableModelHost {
|
||||||
let nc = NotificationCenter.default
|
let nc = NotificationCenter.default
|
||||||
nc.addObserver(self, selector: #selector(applicationDidBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil)
|
nc.addObserver(self, selector: #selector(applicationDidBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil)
|
||||||
nc.addObserver(self, selector: #selector(vpnDidUpdate), name: .VPNDidChangeStatus, object: nil)
|
nc.addObserver(self, selector: #selector(vpnDidUpdate), name: .VPNDidChangeStatus, object: nil)
|
||||||
|
nc.addObserver(self, selector: #selector(vpnDidUpdate), name: .VPNDidReinstall, object: nil)
|
||||||
|
|
||||||
// run this no matter what
|
// run this no matter what
|
||||||
// XXX: convenient here vs AppDelegate for updating table
|
// XXX: convenient here vs AppDelegate for updating table
|
||||||
|
@ -529,7 +530,7 @@ extension ServiceViewController: UITableViewDataSource, UITableViewDelegate, Tog
|
||||||
}
|
}
|
||||||
|
|
||||||
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
|
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
|
||||||
cell.applyVPN(Theme.current, with: vpn.isEnabled ? vpn.status : nil)
|
cell.applyVPN(Theme.current, with: vpn.isEnabled ? vpn.status : nil, error: service.vpnLastError)
|
||||||
cell.leftText = L10n.Service.Cells.ConnectionStatus.caption
|
cell.leftText = L10n.Service.Cells.ConnectionStatus.caption
|
||||||
cell.accessoryType = .none
|
cell.accessoryType = .none
|
||||||
cell.isTappable = false
|
cell.isTappable = false
|
||||||
|
@ -901,7 +902,7 @@ extension ServiceViewController: UITableViewDataSource, UITableViewDelegate, Tog
|
||||||
guard service.isActiveProfile(profile) else {
|
guard service.isActiveProfile(profile) else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
tableView.reloadRows(at: [statusIndexPath], with: .automatic)
|
tableView.reloadRows(at: [statusIndexPath], with: .none)
|
||||||
}
|
}
|
||||||
|
|
||||||
func reloadSelectedRow(andRowAt indexPath: IndexPath? = nil) {
|
func reloadSelectedRow(andRowAt indexPath: IndexPath? = nil) {
|
||||||
|
|
|
@ -161,6 +161,12 @@
|
||||||
"vpn.inactive" = "Inactive";
|
"vpn.inactive" = "Inactive";
|
||||||
"vpn.disabled" = "Disabled";
|
"vpn.disabled" = "Disabled";
|
||||||
|
|
||||||
|
"vpn.errors.timeout" = "Timeout";
|
||||||
|
"vpn.errors.auth" = "Auth failed";
|
||||||
|
"vpn.errors.tls" = "TLS failed";
|
||||||
|
"vpn.errors.dns" = "DNS failed";
|
||||||
|
"vpn.errors.network" = "Network changed";
|
||||||
|
|
||||||
"issue_reporter.title" = "Submit debug log";
|
"issue_reporter.title" = "Submit debug log";
|
||||||
"issue_reporter.message" = "The debug log of your latest connections is crucial to resolve your connectivity issues and is completely anonymous.";
|
"issue_reporter.message" = "The debug log of your latest connections is crucial to resolve your connectivity issues and is completely anonymous.";
|
||||||
"issue_reporter.buttons.accept" = "I understand";
|
"issue_reporter.buttons.accept" = "I understand";
|
||||||
|
|
|
@ -47,6 +47,7 @@ class AppConstants {
|
||||||
// builder.debugLogFormat = "$DHH:mm:ss$d $N.$F:$l - $M"
|
// builder.debugLogFormat = "$DHH:mm:ss$d $N.$F:$l - $M"
|
||||||
builder.debugLogFormat = Log.debugFormat
|
builder.debugLogFormat = Log.debugFormat
|
||||||
builder.debugLogKey = "LastVPNLog"
|
builder.debugLogKey = "LastVPNLog"
|
||||||
|
builder.lastErrorKey = "LastVPNError"
|
||||||
return builder.build()
|
return builder.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -276,6 +276,23 @@ class ConnectionService: Codable {
|
||||||
return lines.joined(separator: "\n")
|
return lines.joined(separator: "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var vpnLastError: TunnelKitProvider.ProviderError? {
|
||||||
|
guard let key = tunnelConfiguration.lastErrorKey else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
guard let rawValue = defaults.string(forKey: key) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return TunnelKitProvider.ProviderError(rawValue: rawValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
func clearVpnLastError() {
|
||||||
|
guard let key = tunnelConfiguration.lastErrorKey else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defaults.removeObject(forKey: key)
|
||||||
|
}
|
||||||
|
|
||||||
// func eraseVpnLog() {
|
// func eraseVpnLog() {
|
||||||
// defaults.removeObject(forKey: Keys.vpnLog)
|
// defaults.removeObject(forKey: Keys.vpnLog)
|
||||||
// }
|
// }
|
||||||
|
|
|
@ -60,6 +60,7 @@ class HostConnectionProfile: ConnectionProfile, Codable, Equatable {
|
||||||
builder.shouldDebug = configuration.shouldDebug
|
builder.shouldDebug = configuration.shouldDebug
|
||||||
builder.debugLogFormat = configuration.debugLogFormat
|
builder.debugLogFormat = configuration.debugLogFormat
|
||||||
builder.debugLogKey = configuration.debugLogKey
|
builder.debugLogKey = configuration.debugLogKey
|
||||||
|
builder.lastErrorKey = configuration.lastErrorKey
|
||||||
|
|
||||||
return builder.build()
|
return builder.build()
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,6 +121,7 @@ class ProviderConnectionProfile: ConnectionProfile, Codable, Equatable {
|
||||||
builder.shouldDebug = configuration.shouldDebug
|
builder.shouldDebug = configuration.shouldDebug
|
||||||
builder.debugLogFormat = configuration.debugLogFormat
|
builder.debugLogFormat = configuration.debugLogFormat
|
||||||
builder.debugLogKey = configuration.debugLogKey
|
builder.debugLogKey = configuration.debugLogKey
|
||||||
|
builder.lastErrorKey = configuration.lastErrorKey
|
||||||
|
|
||||||
if let address = manualAddress {
|
if let address = manualAddress {
|
||||||
builder.prefersResolvedAddresses = true
|
builder.prefersResolvedAddresses = true
|
||||||
|
|
|
@ -686,6 +686,19 @@ internal enum L10n {
|
||||||
internal static let disconnecting = L10n.tr("Localizable", "vpn.disconnecting")
|
internal static let disconnecting = L10n.tr("Localizable", "vpn.disconnecting")
|
||||||
/// Inactive
|
/// Inactive
|
||||||
internal static let inactive = L10n.tr("Localizable", "vpn.inactive")
|
internal static let inactive = L10n.tr("Localizable", "vpn.inactive")
|
||||||
|
|
||||||
|
internal enum Errors {
|
||||||
|
/// Auth failed
|
||||||
|
internal static let auth = L10n.tr("Localizable", "vpn.errors.auth")
|
||||||
|
/// DNS failed
|
||||||
|
internal static let dns = L10n.tr("Localizable", "vpn.errors.dns")
|
||||||
|
/// Network changed
|
||||||
|
internal static let network = L10n.tr("Localizable", "vpn.errors.network")
|
||||||
|
/// Timeout
|
||||||
|
internal static let timeout = L10n.tr("Localizable", "vpn.errors.timeout")
|
||||||
|
/// TLS failed
|
||||||
|
internal static let tls = L10n.tr("Localizable", "vpn.errors.tls")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal enum Wizards {
|
internal enum Wizards {
|
||||||
|
|
|
@ -58,10 +58,12 @@ class GracefulVPN {
|
||||||
func prepare(withProfile profile: ConnectionProfile?, completionHandler: (() -> Void)?) {
|
func prepare(withProfile profile: ConnectionProfile?, completionHandler: (() -> Void)?) {
|
||||||
self.profile = profile
|
self.profile = profile
|
||||||
log.info("Preparing...")
|
log.info("Preparing...")
|
||||||
|
service.clearVpnLastError()
|
||||||
vpn?.prepare(completionHandler: completionHandler)
|
vpn?.prepare(completionHandler: completionHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
func reconnect(completionHandler: ((Error?) -> Void)?) {
|
func reconnect(completionHandler: ((Error?) -> Void)?) {
|
||||||
|
service.clearVpnLastError()
|
||||||
do {
|
do {
|
||||||
log.info("Reconnecting...")
|
log.info("Reconnecting...")
|
||||||
try vpn?.reconnect(configuration: service.vpnConfiguration(), completionHandler: completionHandler)
|
try vpn?.reconnect(configuration: service.vpnConfiguration(), completionHandler: completionHandler)
|
||||||
|
@ -71,6 +73,7 @@ class GracefulVPN {
|
||||||
}
|
}
|
||||||
|
|
||||||
func reinstall(completionHandler: ((Error?) -> Void)?) {
|
func reinstall(completionHandler: ((Error?) -> Void)?) {
|
||||||
|
service.clearVpnLastError()
|
||||||
do {
|
do {
|
||||||
log.info("Reinstalling...")
|
log.info("Reinstalling...")
|
||||||
try vpn?.install(configuration: service.vpnConfiguration(), completionHandler: completionHandler)
|
try vpn?.install(configuration: service.vpnConfiguration(), completionHandler: completionHandler)
|
||||||
|
|
|
@ -37,7 +37,9 @@ class StandardVPNProvider: VPNProvider {
|
||||||
init(bundleIdentifier: String) {
|
init(bundleIdentifier: String) {
|
||||||
self.bundleIdentifier = bundleIdentifier
|
self.bundleIdentifier = bundleIdentifier
|
||||||
|
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(vpnDidUpdate(_:)), name: .NEVPNStatusDidChange, object: nil)
|
let nc = NotificationCenter.default
|
||||||
|
nc.addObserver(self, selector: #selector(vpnDidUpdate(_:)), name: .NEVPNStatusDidChange, object: nil)
|
||||||
|
nc.addObserver(self, selector: #selector(vpnDidReinstall(_:)), name: .NEVPNConfigurationChange, object: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
|
@ -264,4 +266,8 @@ class StandardVPNProvider: VPNProvider {
|
||||||
|
|
||||||
NotificationCenter.default.post(name: .VPNDidChangeStatus, object: self)
|
NotificationCenter.default.post(name: .VPNDidChangeStatus, object: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc private func vpnDidReinstall(_ notification: Notification) {
|
||||||
|
NotificationCenter.default.post(name: .VPNDidReinstall, object: self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,4 +53,6 @@ extension Notification.Name {
|
||||||
static let VPNDidPrepare = Notification.Name("VPNDidPrepare")
|
static let VPNDidPrepare = Notification.Name("VPNDidPrepare")
|
||||||
|
|
||||||
static let VPNDidChangeStatus = Notification.Name("VPNDidChangeStatus")
|
static let VPNDidChangeStatus = Notification.Name("VPNDidChangeStatus")
|
||||||
|
|
||||||
|
static let VPNDidReinstall = Notification.Name("VPNDidReinstall")
|
||||||
}
|
}
|
||||||
|
|
2
Podfile
2
Podfile
|
@ -3,7 +3,7 @@ use_frameworks!
|
||||||
|
|
||||||
def shared_pods
|
def shared_pods
|
||||||
#pod 'TunnelKit', '~> 1.1.2'
|
#pod 'TunnelKit', '~> 1.1.2'
|
||||||
pod 'TunnelKit', :git => 'https://github.com/keeshux/tunnelkit', :commit => '29ec39f'
|
pod 'TunnelKit', :git => 'https://github.com/keeshux/tunnelkit', :commit => '9829475'
|
||||||
#pod 'TunnelKit', :path => '../tunnelkit'
|
#pod 'TunnelKit', :path => '../tunnelkit'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
20
Podfile.lock
20
Podfile.lock
|
@ -2,19 +2,19 @@ PODS:
|
||||||
- MBProgressHUD (1.1.0)
|
- MBProgressHUD (1.1.0)
|
||||||
- OpenSSL-Apple (1.1.0i-v2)
|
- OpenSSL-Apple (1.1.0i-v2)
|
||||||
- SwiftyBeaver (1.6.1)
|
- SwiftyBeaver (1.6.1)
|
||||||
- TunnelKit (1.2.0):
|
- TunnelKit (1.2.1):
|
||||||
- TunnelKit/AppExtension (= 1.2.0)
|
- TunnelKit/AppExtension (= 1.2.1)
|
||||||
- TunnelKit/Core (= 1.2.0)
|
- TunnelKit/Core (= 1.2.1)
|
||||||
- TunnelKit/AppExtension (1.2.0):
|
- TunnelKit/AppExtension (1.2.1):
|
||||||
- SwiftyBeaver
|
- SwiftyBeaver
|
||||||
- TunnelKit/Core
|
- TunnelKit/Core
|
||||||
- TunnelKit/Core (1.2.0):
|
- TunnelKit/Core (1.2.1):
|
||||||
- OpenSSL-Apple (~> 1.1.0h)
|
- OpenSSL-Apple (~> 1.1.0h)
|
||||||
- SwiftyBeaver
|
- SwiftyBeaver
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- MBProgressHUD
|
- MBProgressHUD
|
||||||
- TunnelKit (from `https://github.com/keeshux/tunnelkit`, commit `29ec39f`)
|
- TunnelKit (from `https://github.com/keeshux/tunnelkit`, commit `9829475`)
|
||||||
|
|
||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
https://github.com/cocoapods/specs.git:
|
https://github.com/cocoapods/specs.git:
|
||||||
|
@ -24,20 +24,20 @@ SPEC REPOS:
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
TunnelKit:
|
TunnelKit:
|
||||||
:commit: 29ec39f
|
:commit: '9829475'
|
||||||
:git: https://github.com/keeshux/tunnelkit
|
:git: https://github.com/keeshux/tunnelkit
|
||||||
|
|
||||||
CHECKOUT OPTIONS:
|
CHECKOUT OPTIONS:
|
||||||
TunnelKit:
|
TunnelKit:
|
||||||
:commit: 29ec39f
|
:commit: '9829475'
|
||||||
:git: https://github.com/keeshux/tunnelkit
|
:git: https://github.com/keeshux/tunnelkit
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
MBProgressHUD: e7baa36a220447d8aeb12769bf0585582f3866d9
|
MBProgressHUD: e7baa36a220447d8aeb12769bf0585582f3866d9
|
||||||
OpenSSL-Apple: a93b8f2eec8783ff40d9a9304de180ab68bb647c
|
OpenSSL-Apple: a93b8f2eec8783ff40d9a9304de180ab68bb647c
|
||||||
SwiftyBeaver: ccfcdf85a04d429f1633f668650b0ce8020bda3a
|
SwiftyBeaver: ccfcdf85a04d429f1633f668650b0ce8020bda3a
|
||||||
TunnelKit: aad1982c96ba0eace1494d4020ecdd1a34c5a788
|
TunnelKit: 6c790dfbcb0042d6a5dfe2fda5b0eb5b895afaf1
|
||||||
|
|
||||||
PODFILE CHECKSUM: 3d7c4db47830b499bdcf24c498e36b5c619e2ad1
|
PODFILE CHECKSUM: 9054389b89f51fe7517cfecebde6520280df4799
|
||||||
|
|
||||||
COCOAPODS: 1.6.0.beta.2
|
COCOAPODS: 1.6.0.beta.2
|
||||||
|
|
Loading…
Reference in New Issue