diff --git a/WireGuard/WireGuard/Model/Configuration.swift b/WireGuard/WireGuard/Model/Configuration.swift index 4bed41b..d3d8b35 100644 --- a/WireGuard/WireGuard/Model/Configuration.swift +++ b/WireGuard/WireGuard/Model/Configuration.swift @@ -5,7 +5,7 @@ import Foundation @available(OSX 10.14, iOS 12.0, *) class TunnelConfiguration: Codable { - let interface: InterfaceConfiguration + var interface: InterfaceConfiguration var peers: [PeerConfiguration] = [] init(interface: InterfaceConfiguration) { self.interface = interface diff --git a/WireGuard/WireGuard/UI/iOS/AppDelegate.swift b/WireGuard/WireGuard/UI/iOS/AppDelegate.swift index aff3e69..d79b20e 100644 --- a/WireGuard/WireGuard/UI/iOS/AppDelegate.swift +++ b/WireGuard/WireGuard/UI/iOS/AppDelegate.swift @@ -2,11 +2,13 @@ // Copyright © 2018 WireGuard LLC. All rights reserved. import UIKit +import os.log @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? + var mainVC: MainViewController? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { @@ -15,9 +17,25 @@ class AppDelegate: UIResponder, UIApplicationDelegate { window.backgroundColor = UIColor.white self.window = window - window.rootViewController = MainViewController() + let mainVC = MainViewController() + window.rootViewController = mainVC window.makeKeyAndVisible() + self.mainVC = mainVC + + return true + } + + func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool { + // Based on importing code by Jeroen Leenarts in commit 815f12c + defer { + do { + try FileManager.default.removeItem(at: url) + } catch { + os_log("Failed to remove item from Inbox: %{public}@", log: OSLog.default, type: .debug, url.absoluteString) + } + } + mainVC?.openForEditing(configFileURL: url) return true } } diff --git a/WireGuard/WireGuard/UI/iOS/MainViewController.swift b/WireGuard/WireGuard/UI/iOS/MainViewController.swift index 95f1cb9..be90eca 100644 --- a/WireGuard/WireGuard/UI/iOS/MainViewController.swift +++ b/WireGuard/WireGuard/UI/iOS/MainViewController.swift @@ -4,6 +4,8 @@ import UIKit class MainViewController: UISplitViewController { + var tunnelsListVC: TunnelsListTableViewController? + override func loadView() { let detailVC = UIViewController() let detailNC = UINavigationController(rootViewController: detailVC) @@ -14,6 +16,8 @@ class MainViewController: UISplitViewController { self.viewControllers = [ masterNC, detailNC ] super.loadView() + + tunnelsListVC = masterVC } override func viewDidLoad() { @@ -22,6 +26,10 @@ class MainViewController: UISplitViewController { // On iPad, always show both masterVC and detailVC, even in portrait mode, like the Settings app self.preferredDisplayMode = .allVisible } + + func openForEditing(configFileURL: URL) { + tunnelsListVC?.openForEditing(configFileURL: configFileURL) + } } extension MainViewController: UISplitViewControllerDelegate { diff --git a/WireGuard/WireGuard/UI/iOS/TunnelsListTableViewController.swift b/WireGuard/WireGuard/UI/iOS/TunnelsListTableViewController.swift index abbf0ac..0500f18 100644 --- a/WireGuard/WireGuard/UI/iOS/TunnelsListTableViewController.swift +++ b/WireGuard/WireGuard/UI/iOS/TunnelsListTableViewController.swift @@ -6,6 +6,7 @@ import UIKit class TunnelsListTableViewController: UITableViewController { var tunnelsManager: TunnelsManager? = nil + var onTunnelsManagerReady: ((TunnelsManager) -> Void)? = nil init() { super.init(style: .plain) @@ -28,6 +29,8 @@ class TunnelsListTableViewController: UITableViewController { if let s = self { tunnelsManager.delegate = s s.tunnelsManager = tunnelsManager + s.onTunnelsManagerReady?(tunnelsManager) + s.onTunnelsManagerReady = nil s.tableView.reloadData() } } @@ -40,10 +43,7 @@ class TunnelsListTableViewController: UITableViewController { alert.addAction( UIAlertAction(title: "Create from scratch", style: .default) { [weak self] (action) in if let s = self, let tunnelsManager = s.tunnelsManager { - let editVC = TunnelEditTableViewController(tunnelsManager: tunnelsManager) - editVC.delegate = s - let editNC = UINavigationController(rootViewController: editVC) - s.present(editNC, animated: true) + s.presentViewControllerForTunnelCreation(tunnelsManager: tunnelsManager, tunnelConfiguration: nil) } } ) @@ -54,6 +54,41 @@ class TunnelsListTableViewController: UITableViewController { alert.popoverPresentationController?.barButtonItem = self.navigationItem.rightBarButtonItem self.present(alert, animated: true, completion: nil) } + + func openForEditing(configFileURL: URL) { + let tunnelConfiguration: TunnelConfiguration? + let name = configFileURL.deletingPathExtension().lastPathComponent + do { + let fileContents = try String(contentsOf: configFileURL) + try tunnelConfiguration = WgQuickConfigFileParser.parse(fileContents) + } catch { + showErrorAlert(title: "Could not import config", message: "There was an error importing the config file") + return + } + tunnelConfiguration?.interface.name = name + if let tunnelsManager = tunnelsManager { + presentViewControllerForTunnelCreation(tunnelsManager: tunnelsManager, tunnelConfiguration: tunnelConfiguration) + } else { + onTunnelsManagerReady = { [weak self] tunnelsManager in + self?.presentViewControllerForTunnelCreation(tunnelsManager: tunnelsManager, tunnelConfiguration: tunnelConfiguration) + } + } + } + + func presentViewControllerForTunnelCreation(tunnelsManager: TunnelsManager, tunnelConfiguration: TunnelConfiguration?) { + let editVC = TunnelEditTableViewController(tunnelsManager: tunnelsManager, tunnelConfiguration: tunnelConfiguration) + editVC.delegate = self + let editNC = UINavigationController(rootViewController: editVC) + self.present(editNC, animated: true) + } + + func showErrorAlert(title: String, message: String) { + let okAction = UIAlertAction(title: "Ok", style: .default) + let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) + alert.addAction(okAction) + + self.present(alert, animated: true, completion: nil) + } } // MARK: TunnelEditTableViewControllerDelegate