]> git.ipfire.org Git - thirdparty/wireguard-apple.git/commitdiff
Most similar views now shared between ViewControllers
authorEric Kuck <eric@bluelinelabs.com>
Fri, 14 Dec 2018 23:12:59 +0000 (17:12 -0600)
committerEric Kuck <eric@bluelinelabs.com>
Fri, 14 Dec 2018 23:15:22 +0000 (17:15 -0600)
Signed-off-by: Eric Kuck <eric@bluelinelabs.com>
28 files changed:
WireGuard/Shared/Model/Endpoint.swift
WireGuard/WireGuard.xcodeproj/project.pbxproj
WireGuard/WireGuard/Tunnel/ActivateOnDemandSetting.swift
WireGuard/WireGuard/Tunnel/TunnelStatus.swift [new file with mode: 0644]
WireGuard/WireGuard/Tunnel/TunnelsManager.swift
WireGuard/WireGuard/UI/iOS/AppDelegate.swift
WireGuard/WireGuard/UI/iOS/EditTunnel/TunnelEditReadOnlyKeyValueCell.swift
WireGuard/WireGuard/UI/iOS/EditTunnel/TunnelEditTableViewController.swift
WireGuard/WireGuard/UI/iOS/MainViewController.swift
WireGuard/WireGuard/UI/iOS/QRScanViewController.swift
WireGuard/WireGuard/UI/iOS/Settings/SettingsButtonCell.swift [deleted file]
WireGuard/WireGuard/UI/iOS/Settings/SettingsKeyValueCell.swift [deleted file]
WireGuard/WireGuard/UI/iOS/SettingsTableViewController.swift [moved from WireGuard/WireGuard/UI/iOS/Settings/SettingsTableViewController.swift with 94% similarity]
WireGuard/WireGuard/UI/iOS/SharedViews/BorderedTextButton.swift [moved from WireGuard/WireGuard/UI/iOS/TunnelList/BorderedTextButton.swift with 89% similarity]
WireGuard/WireGuard/UI/iOS/SharedViews/ButtonCell.swift [moved from WireGuard/WireGuard/UI/iOS/EditTunnel/TunnelEditButtonCell.swift with 90% similarity]
WireGuard/WireGuard/UI/iOS/SharedViews/CheckmarkCell.swift [moved from WireGuard/WireGuard/UI/iOS/EditTunnel/TunnelEditSectionListCell.swift with 93% similarity]
WireGuard/WireGuard/UI/iOS/SharedViews/CopyableLabelTableViewCell.swift [moved from WireGuard/WireGuard/UI/iOS/CopyableLabelTableViewCell.swift with 83% similarity]
WireGuard/WireGuard/UI/iOS/SharedViews/EditableKeyValueCell.swift [moved from WireGuard/WireGuard/UI/iOS/EditTunnel/TunnelEditKeyValueCell.swift with 94% similarity]
WireGuard/WireGuard/UI/iOS/SharedViews/KeyValueCell.swift [moved from WireGuard/WireGuard/UI/iOS/TunnelDetail/TunnelDetailKeyValueCell.swift with 92% similarity]
WireGuard/WireGuard/UI/iOS/SharedViews/ScrollableLabel.swift [moved from WireGuard/WireGuard/UI/iOS/ScrollableLabel.swift with 100% similarity]
WireGuard/WireGuard/UI/iOS/SharedViews/SwitchCell.swift [moved from WireGuard/WireGuard/UI/iOS/EditTunnel/TunnelEditSwitchCell.swift with 82% similarity]
WireGuard/WireGuard/UI/iOS/TunnelDetail/TunnelDetailActivateOnDemandCell.swift [deleted file]
WireGuard/WireGuard/UI/iOS/TunnelDetail/TunnelDetailButtonCell.swift [deleted file]
WireGuard/WireGuard/UI/iOS/TunnelDetail/TunnelDetailStatusCell.swift [deleted file]
WireGuard/WireGuard/UI/iOS/TunnelDetail/TunnelDetailTableViewController.swift
WireGuard/WireGuard/UI/iOS/TunnelList/TunnelListCell.swift
WireGuard/WireGuard/UI/iOS/TunnelList/TunnelsListTableViewController.swift
WireGuard/WireGuardNetworkExtension/PacketTunnelProvider.swift

index bbf84d43873998064cb3491f59e9b05c0aa6708f..41ea41fe58989129b4fbad8bd03c5687a00f89a5 100644 (file)
@@ -61,7 +61,7 @@ extension Endpoint {
 extension Endpoint: Codable {
     public func encode(to encoder: Encoder) throws {
         var container = encoder.singleValueContainer()
-        try container.encode(self.stringRepresentation())
+        try container.encode(stringRepresentation())
     }
     public init(from decoder: Decoder) throws {
         let container = try decoder.singleValueContainer()
index 53f25241b4c6db9ea80ffdd5e8ebeb9d40274c84..311a1b8a8fdd120927a07bc746a72de3979f5786 100644 (file)
@@ -8,19 +8,15 @@
 
 /* Begin PBXBuildFile section */
                5F45417D21C1B23600994C13 /* UITableViewCell+Reuse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F45417C21C1B23600994C13 /* UITableViewCell+Reuse.swift */; };
-               5F45418A21C2D45B00994C13 /* TunnelEditKeyValueCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F45418921C2D45B00994C13 /* TunnelEditKeyValueCell.swift */; };
+               5F45418A21C2D45B00994C13 /* EditableKeyValueCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F45418921C2D45B00994C13 /* EditableKeyValueCell.swift */; };
                5F45418C21C2D48200994C13 /* TunnelEditReadOnlyKeyValueCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F45418B21C2D48200994C13 /* TunnelEditReadOnlyKeyValueCell.swift */; };
-               5F45418E21C2D51100994C13 /* TunnelEditButtonCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F45418D21C2D51100994C13 /* TunnelEditButtonCell.swift */; };
-               5F45419021C2D53800994C13 /* TunnelEditSwitchCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F45418F21C2D53800994C13 /* TunnelEditSwitchCell.swift */; };
-               5F45419221C2D55800994C13 /* TunnelEditSectionListCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F45419121C2D55800994C13 /* TunnelEditSectionListCell.swift */; };
-               5F45419421C2D5C500994C13 /* TunnelDetailActivateOnDemandCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F45419321C2D5C500994C13 /* TunnelDetailActivateOnDemandCell.swift */; };
-               5F45419621C2D5DB00994C13 /* TunnelDetailButtonCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F45419521C2D5DB00994C13 /* TunnelDetailButtonCell.swift */; };
-               5F45419821C2D60500994C13 /* TunnelDetailKeyValueCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F45419721C2D60500994C13 /* TunnelDetailKeyValueCell.swift */; };
-               5F45419A21C2D61D00994C13 /* TunnelDetailStatusCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F45419921C2D61D00994C13 /* TunnelDetailStatusCell.swift */; };
-               5F45419C21C2D64800994C13 /* SettingsButtonCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F45419B21C2D64800994C13 /* SettingsButtonCell.swift */; };
-               5F45419E21C2D66400994C13 /* SettingsKeyValueCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F45419D21C2D66400994C13 /* SettingsKeyValueCell.swift */; };
+               5F45419021C2D53800994C13 /* SwitchCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F45418F21C2D53800994C13 /* SwitchCell.swift */; };
+               5F45419221C2D55800994C13 /* CheckmarkCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F45419121C2D55800994C13 /* CheckmarkCell.swift */; };
+               5F45419821C2D60500994C13 /* KeyValueCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F45419721C2D60500994C13 /* KeyValueCell.swift */; };
                5F4541A021C2D6B700994C13 /* TunnelListCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F45419F21C2D6B700994C13 /* TunnelListCell.swift */; };
                5F4541A221C2D6DF00994C13 /* BorderedTextButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F4541A121C2D6DF00994C13 /* BorderedTextButton.swift */; };
+               5F4541A621C4449E00994C13 /* ButtonCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F4541A521C4449E00994C13 /* ButtonCell.swift */; };
+               5F4541A921C451D100994C13 /* TunnelStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F4541A821C451D100994C13 /* TunnelStatus.swift */; };
                6BB8400421892C920003598F /* CopyableLabelTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BB8400321892C920003598F /* CopyableLabelTableViewCell.swift */; };
                6F0068572191AFD200419BE9 /* ScrollableLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F0068562191AFD200419BE9 /* ScrollableLabel.swift */; };
                6F5A2B4621AFDED40081EDD8 /* FileManager+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F5A2B4421AFDE020081EDD8 /* FileManager+Extension.swift */; };
 
 /* Begin PBXFileReference section */
                5F45417C21C1B23600994C13 /* UITableViewCell+Reuse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITableViewCell+Reuse.swift"; sourceTree = "<group>"; };
-               5F45418921C2D45B00994C13 /* TunnelEditKeyValueCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelEditKeyValueCell.swift; sourceTree = "<group>"; };
+               5F45418921C2D45B00994C13 /* EditableKeyValueCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditableKeyValueCell.swift; sourceTree = "<group>"; };
                5F45418B21C2D48200994C13 /* TunnelEditReadOnlyKeyValueCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelEditReadOnlyKeyValueCell.swift; sourceTree = "<group>"; };
-               5F45418D21C2D51100994C13 /* TunnelEditButtonCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelEditButtonCell.swift; sourceTree = "<group>"; };
-               5F45418F21C2D53800994C13 /* TunnelEditSwitchCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelEditSwitchCell.swift; sourceTree = "<group>"; };
-               5F45419121C2D55800994C13 /* TunnelEditSectionListCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelEditSectionListCell.swift; sourceTree = "<group>"; };
-               5F45419321C2D5C500994C13 /* TunnelDetailActivateOnDemandCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelDetailActivateOnDemandCell.swift; sourceTree = "<group>"; };
-               5F45419521C2D5DB00994C13 /* TunnelDetailButtonCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelDetailButtonCell.swift; sourceTree = "<group>"; };
-               5F45419721C2D60500994C13 /* TunnelDetailKeyValueCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelDetailKeyValueCell.swift; sourceTree = "<group>"; };
-               5F45419921C2D61D00994C13 /* TunnelDetailStatusCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelDetailStatusCell.swift; sourceTree = "<group>"; };
-               5F45419B21C2D64800994C13 /* SettingsButtonCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsButtonCell.swift; sourceTree = "<group>"; };
-               5F45419D21C2D66400994C13 /* SettingsKeyValueCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsKeyValueCell.swift; sourceTree = "<group>"; };
+               5F45418F21C2D53800994C13 /* SwitchCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwitchCell.swift; sourceTree = "<group>"; };
+               5F45419121C2D55800994C13 /* CheckmarkCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckmarkCell.swift; sourceTree = "<group>"; };
+               5F45419721C2D60500994C13 /* KeyValueCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyValueCell.swift; sourceTree = "<group>"; };
                5F45419F21C2D6B700994C13 /* TunnelListCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelListCell.swift; sourceTree = "<group>"; };
                5F4541A121C2D6DF00994C13 /* BorderedTextButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BorderedTextButton.swift; sourceTree = "<group>"; };
+               5F4541A521C4449E00994C13 /* ButtonCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonCell.swift; sourceTree = "<group>"; };
+               5F4541A821C451D100994C13 /* TunnelStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelStatus.swift; sourceTree = "<group>"; };
                6BB8400321892C920003598F /* CopyableLabelTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CopyableLabelTableViewCell.swift; sourceTree = "<group>"; };
                6F0068562191AFD200419BE9 /* ScrollableLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollableLabel.swift; sourceTree = "<group>"; };
                6F5A2B4421AFDE020081EDD8 /* FileManager+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FileManager+Extension.swift"; sourceTree = "<group>"; };
                6F61F1EA21B937EF00483816 /* WireGuardResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WireGuardResult.swift; sourceTree = "<group>"; };
                6F628C3C217F09E9003482A3 /* TunnelViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelViewModel.swift; sourceTree = "<group>"; };
                6F628C3E217F3413003482A3 /* DNSServer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DNSServer.swift; sourceTree = "<group>"; };
-               6F628C40217F47DB003482A3 /* TunnelDetailTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TunnelDetailTableViewController.swift; sourceTree = "<group>"; };
+               6F628C40217F47DB003482A3 /* TunnelDetailTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TunnelDetailTableViewController.swift; path = TunnelDetail/TunnelDetailTableViewController.swift; sourceTree = "<group>"; };
                6F689999218043390012E523 /* WireGuard-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "WireGuard-Bridging-Header.h"; sourceTree = "<group>"; };
                6F6899A42180447E0012E523 /* x25519.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = x25519.h; sourceTree = "<group>"; };
                6F6899A52180447E0012E523 /* x25519.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = x25519.c; sourceTree = "<group>"; };
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
-               5F45418521C2C6AB00994C13 /* Settings */ = {
-                       isa = PBXGroup;
-                       children = (
-                               6FDEF805218725D200D8FBF6 /* SettingsTableViewController.swift */,
-                               5F45419B21C2D64800994C13 /* SettingsButtonCell.swift */,
-                               5F45419D21C2D66400994C13 /* SettingsKeyValueCell.swift */,
-                       );
-                       path = Settings;
-                       sourceTree = "<group>";
-               };
                5F45418621C2C6B400994C13 /* EditTunnel */ = {
                        isa = PBXGroup;
                        children = (
                                6F7774F221774263006A79B3 /* TunnelEditTableViewController.swift */,
-                               5F45418921C2D45B00994C13 /* TunnelEditKeyValueCell.swift */,
                                5F45418B21C2D48200994C13 /* TunnelEditReadOnlyKeyValueCell.swift */,
-                               5F45418D21C2D51100994C13 /* TunnelEditButtonCell.swift */,
-                               5F45418F21C2D53800994C13 /* TunnelEditSwitchCell.swift */,
-                               5F45419121C2D55800994C13 /* TunnelEditSectionListCell.swift */,
                        );
                        path = EditTunnel;
                        sourceTree = "<group>";
                };
-               5F45418721C2C6C100994C13 /* TunnelDetail */ = {
+               5F45418821C2C6CC00994C13 /* TunnelList */ = {
                        isa = PBXGroup;
                        children = (
-                               6F628C40217F47DB003482A3 /* TunnelDetailTableViewController.swift */,
-                               5F45419321C2D5C500994C13 /* TunnelDetailActivateOnDemandCell.swift */,
-                               5F45419521C2D5DB00994C13 /* TunnelDetailButtonCell.swift */,
-                               5F45419721C2D60500994C13 /* TunnelDetailKeyValueCell.swift */,
-                               5F45419921C2D61D00994C13 /* TunnelDetailStatusCell.swift */,
+                               6F7774E321718281006A79B3 /* TunnelsListTableViewController.swift */,
+                               5F45419F21C2D6B700994C13 /* TunnelListCell.swift */,
                        );
-                       path = TunnelDetail;
+                       path = TunnelList;
                        sourceTree = "<group>";
                };
-               5F45418821C2C6CC00994C13 /* TunnelList */ = {
+               5F4541A721C44F5B00994C13 /* SharedViews */ = {
                        isa = PBXGroup;
                        children = (
-                               6F7774E321718281006A79B3 /* TunnelsListTableViewController.swift */,
-                               5F45419F21C2D6B700994C13 /* TunnelListCell.swift */,
+                               6BB8400321892C920003598F /* CopyableLabelTableViewCell.swift */,
+                               6F0068562191AFD200419BE9 /* ScrollableLabel.swift */,
+                               5F45418F21C2D53800994C13 /* SwitchCell.swift */,
+                               5F45419721C2D60500994C13 /* KeyValueCell.swift */,
+                               5F4541A521C4449E00994C13 /* ButtonCell.swift */,
+                               5F45419121C2D55800994C13 /* CheckmarkCell.swift */,
+                               5F45418921C2D45B00994C13 /* EditableKeyValueCell.swift */,
                                5F4541A121C2D6DF00994C13 /* BorderedTextButton.swift */,
                        );
-                       path = TunnelList;
+                       path = SharedViews;
                        sourceTree = "<group>";
                };
                6F5D0C1B218352EF000F85AD /* WireGuardNetworkExtension */ = {
                6F7774DE217181B1006A79B3 /* iOS */ = {
                        isa = PBXGroup;
                        children = (
+                               5F4541A721C44F5B00994C13 /* SharedViews */,
                                5F45418821C2C6CC00994C13 /* TunnelList */,
-                               5F45418721C2C6C100994C13 /* TunnelDetail */,
                                5F45418621C2C6B400994C13 /* EditTunnel */,
-                               5F45418521C2C6AB00994C13 /* Settings */,
-                               6BB8400321892C920003598F /* CopyableLabelTableViewCell.swift */,
                                6FDEF7E52185EFAF00D8FBF6 /* QRScanViewController.swift */,
+                               6F628C40217F47DB003482A3 /* TunnelDetailTableViewController.swift */,
+                               6FDEF805218725D200D8FBF6 /* SettingsTableViewController.swift */,
                                6F7774E0217181B1006A79B3 /* AppDelegate.swift */,
                                6F7774DF217181B1006A79B3 /* MainViewController.swift */,
                                6F919EC2218A2AE90023B400 /* ErrorPresenter.swift */,
-                               6F0068562191AFD200419BE9 /* ScrollableLabel.swift */,
                                5F45417C21C1B23600994C13 /* UITableViewCell+Reuse.swift */,
                        );
                        path = iOS;
                        children = (
                                6F7774EE21722D97006A79B3 /* TunnelsManager.swift */,
                                6FFA5DA32197085D0001E2F7 /* ActivateOnDemandSetting.swift */,
+                               5F4541A821C451D100994C13 /* TunnelStatus.swift */,
                        );
                        path = Tunnel;
                        sourceTree = "<group>";
                                6F7774EF21722D97006A79B3 /* TunnelsManager.swift in Sources */,
                                6BB8400421892C920003598F /* CopyableLabelTableViewCell.swift in Sources */,
                                5F45417D21C1B23600994C13 /* UITableViewCell+Reuse.swift in Sources */,
-                               5F45419221C2D55800994C13 /* TunnelEditSectionListCell.swift in Sources */,
+                               5F45419221C2D55800994C13 /* CheckmarkCell.swift in Sources */,
                                6FE254FF219C60290028284D /* ZipExporter.swift in Sources */,
                                6F693A562179E556008551C1 /* Endpoint.swift in Sources */,
-                               5F45418E21C2D51100994C13 /* TunnelEditButtonCell.swift in Sources */,
                                6F0068572191AFD200419BE9 /* ScrollableLabel.swift in Sources */,
                                6FDEF7E62185EFB200D8FBF6 /* QRScanViewController.swift in Sources */,
                                6FFA5D952194454A0001E2F7 /* NETunnelProviderProtocol+Extension.swift in Sources */,
+                               5F4541A921C451D100994C13 /* TunnelStatus.swift in Sources */,
                                6F61F1E921B932F700483816 /* WireGuardAppError.swift in Sources */,
-                               5F45418A21C2D45B00994C13 /* TunnelEditKeyValueCell.swift in Sources */,
+                               5F45418A21C2D45B00994C13 /* EditableKeyValueCell.swift in Sources */,
                                6F6899A62180447E0012E523 /* x25519.c in Sources */,
                                6F7774E2217181B1006A79B3 /* AppDelegate.swift in Sources */,
                                6FDEF80021863C0100D8FBF6 /* ioapi.c in Sources */,
                                6FDEF7FC21863B6100D8FBF6 /* zip.c in Sources */,
                                6F628C3F217F3413003482A3 /* DNSServer.swift in Sources */,
-                               5F45419C21C2D64800994C13 /* SettingsButtonCell.swift in Sources */,
                                6F628C3D217F09E9003482A3 /* TunnelViewModel.swift in Sources */,
-                               5F45419821C2D60500994C13 /* TunnelDetailKeyValueCell.swift in Sources */,
+                               5F4541A621C4449E00994C13 /* ButtonCell.swift in Sources */,
+                               5F45419821C2D60500994C13 /* KeyValueCell.swift in Sources */,
                                6F919EC3218A2AE90023B400 /* ErrorPresenter.swift in Sources */,
                                6F5A2B4821AFF49A0081EDD8 /* FileManager+Extension.swift in Sources */,
                                5F45418C21C2D48200994C13 /* TunnelEditReadOnlyKeyValueCell.swift in Sources */,
                                6FDEF8082187442100D8FBF6 /* WgQuickConfigFileWriter.swift in Sources */,
                                6FE254FB219C10800028284D /* ZipImporter.swift in Sources */,
-                               5F45419A21C2D61D00994C13 /* TunnelDetailStatusCell.swift in Sources */,
                                6F7774EA217229DB006A79B3 /* IPAddressRange.swift in Sources */,
-                               5F45419621C2D5DB00994C13 /* TunnelDetailButtonCell.swift in Sources */,
                                6F7774E82172020C006A79B3 /* Configuration.swift in Sources */,
                                6FDEF7FB21863B6100D8FBF6 /* unzip.c in Sources */,
-                               5F45419E21C2D66400994C13 /* SettingsKeyValueCell.swift in Sources */,
                                6F6899A8218044FC0012E523 /* Curve25519.swift in Sources */,
                                5F4541A021C2D6B700994C13 /* TunnelListCell.swift in Sources */,
                                6F628C41217F47DB003482A3 /* TunnelDetailTableViewController.swift in Sources */,
                                6F61F1EB21B937EF00483816 /* WireGuardResult.swift in Sources */,
                                6F7774F321774263006A79B3 /* TunnelEditTableViewController.swift in Sources */,
                                6FDEF802218646BA00D8FBF6 /* ZipArchive.swift in Sources */,
-                               5F45419021C2D53800994C13 /* TunnelEditSwitchCell.swift in Sources */,
+                               5F45419021C2D53800994C13 /* SwitchCell.swift in Sources */,
                                6FDEF806218725D200D8FBF6 /* SettingsTableViewController.swift in Sources */,
                                5F4541A221C2D6DF00994C13 /* BorderedTextButton.swift in Sources */,
                                6F7774E1217181B1006A79B3 /* MainViewController.swift in Sources */,
                                6FFA5DA42197085D0001E2F7 /* ActivateOnDemandSetting.swift in Sources */,
-                               5F45419421C2D5C500994C13 /* TunnelDetailActivateOnDemandCell.swift in Sources */,
-                               6FF717E521B2CB1E0045A474 /* InternetReachability.swift in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index 0aeda6f94668650b0f97df9793edd67a23a33a16..907109831a7ec56136bda7215e2756c862e36ea3 100644 (file)
@@ -63,9 +63,9 @@ extension ActivateOnDemandSetting {
         }
         self.activateOnDemandOption = activateOnDemandOption
         if activateOnDemandOption == .none {
-            self.isActivateOnDemandEnabled = false
+            isActivateOnDemandEnabled = false
         } else {
-            self.isActivateOnDemandEnabled = tunnelProviderManager.isOnDemandEnabled
+            isActivateOnDemandEnabled = tunnelProviderManager.isOnDemandEnabled
         }
     }
 }
diff --git a/WireGuard/WireGuard/Tunnel/TunnelStatus.swift b/WireGuard/WireGuard/Tunnel/TunnelStatus.swift
new file mode 100644 (file)
index 0000000..9f03417
--- /dev/null
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: MIT
+// Copyright © 2018 WireGuard LLC. All Rights Reserved.
+
+import Foundation
+import NetworkExtension
+
+@objc enum TunnelStatus: Int {
+    case inactive
+    case activating
+    case active
+    case deactivating
+    case reasserting // Not a possible state at present
+    case restarting // Restarting tunnel (done after saving modifications to an active tunnel)
+    case waiting    // Waiting for another tunnel to be brought down
+    
+    init(from systemStatus: NEVPNStatus) {
+        switch systemStatus {
+        case .connected:
+            self = .active
+        case .connecting:
+            self = .activating
+        case .disconnected:
+            self = .inactive
+        case .disconnecting:
+            self = .deactivating
+        case .reasserting:
+            self = .reasserting
+        case .invalid:
+            self = .inactive
+        }
+    }
+}
+
+extension TunnelStatus: CustomDebugStringConvertible {
+    public var debugDescription: String {
+        switch self {
+        case .inactive: return "inactive"
+        case .activating: return "activating"
+        case .active: return "active"
+        case .deactivating: return "deactivating"
+        case .reasserting: return "reasserting"
+        case .restarting: return "restarting"
+        case .waiting: return "waiting"
+        }
+    }
+}
index 6f932676d46d13127d9f7f0afc98a06ec9a954e7..4c2f2ed60de14dd6b0711918c8a01945ae5e7468 100644 (file)
@@ -86,8 +86,8 @@ class TunnelsManager {
     private var statusObservationToken: AnyObject?
 
     init(tunnelProviders: [NETunnelProviderManager]) {
-        self.tunnels = tunnelProviders.map { TunnelContainer(tunnel: $0) }.sorted { $0.name < $1.name }
-        self.startObservingTunnelStatuses()
+        tunnels = tunnelProviders.map { TunnelContainer(tunnel: $0) }.sorted { $0.name < $1.name }
+        startObservingTunnelStatuses()
     }
 
     static func create(completionHandler: @escaping (WireGuardResult<TunnelsManager>) -> Void) {
@@ -112,7 +112,7 @@ class TunnelsManager {
             return
         }
 
-        if self.tunnels.contains(where: { $0.name == tunnelName }) {
+        if tunnels.contains(where: { $0.name == tunnelName }) {
             completionHandler(.failure(TunnelsManagerError.tunnelAlreadyExistsWithThatName))
             return
         }
@@ -151,7 +151,7 @@ class TunnelsManager {
             return
         }
         let tail = tunnelConfigurations.dropFirst()
-        self.add(tunnelConfiguration: head) { [weak self, tail] result in
+        add(tunnelConfiguration: head) { [weak self, tail] result in
             DispatchQueue.main.async {
                 self?.addMultiple(tunnelConfigurations: tail, numberSuccessful: numberSuccessful + (result.isSuccess ? 1 : 0), completionHandler: completionHandler)
             }
@@ -168,7 +168,7 @@ class TunnelsManager {
         let tunnelProviderManager = tunnel.tunnelProvider
         let isNameChanged = (tunnelName != tunnelProviderManager.localizedDescription)
         if isNameChanged {
-            if self.tunnels.contains(where: { $0.name == tunnelName }) {
+            if tunnels.contains(where: { $0.name == tunnelName }) {
                 completionHandler(TunnelsManagerError.tunnelAlreadyExistsWithThatName)
                 return
             }
@@ -249,13 +249,13 @@ class TunnelsManager {
     }
 
     func tunnel(named tunnelName: String) -> TunnelContainer? {
-        return self.tunnels.first { $0.name == tunnelName }
+        return tunnels.first { $0.name == tunnelName }
     }
 
     func startActivation(of tunnel: TunnelContainer) {
         guard tunnels.contains(tunnel) else { return } // Ensure it's not deleted
         guard tunnel.status == .inactive else {
-            self.activationDelegate?.tunnelActivationAttemptFailed(tunnel: tunnel, error: .tunnelIsNotInactive)
+            activationDelegate?.tunnelActivationAttemptFailed(tunnel: tunnel, error: .tunnelIsNotInactive)
             return
         }
 
@@ -272,7 +272,7 @@ class TunnelsManager {
             return
         }
 
-        tunnel.startActivation(activationDelegate: self.activationDelegate)
+        tunnel.startActivation(activationDelegate: activationDelegate)
     }
 
     func startDeactivation(of tunnel: TunnelContainer) {
@@ -346,7 +346,7 @@ class TunnelsManager {
     }
 
     deinit {
-        if let statusObservationToken = self.statusObservationToken {
+        if let statusObservationToken = statusObservationToken {
             NotificationCenter.default.removeObserver(statusObservationToken)
         }
     }
@@ -371,8 +371,8 @@ class TunnelContainer: NSObject {
                 self.activationTimer = activationTimer
                 RunLoop.main.add(activationTimer, forMode: .default)
             } else {
-                self.activationTimer?.invalidate()
-                self.activationTimer = nil
+                activationTimer?.invalidate()
+                activationTimer = nil
             }
         }
     }
@@ -383,11 +383,11 @@ class TunnelContainer: NSObject {
     private var lastTunnelConnectionStatus: NEVPNStatus?
 
     init(tunnel: NETunnelProviderManager) {
-        self.name = tunnel.localizedDescription ?? "Unnamed"
+        name = tunnel.localizedDescription ?? "Unnamed"
         let status = TunnelStatus(from: tunnel.connection.status)
         self.status = status
-        self.isActivateOnDemandEnabled = tunnel.isOnDemandEnabled
-        self.tunnelProvider = tunnel
+        isActivateOnDemandEnabled = tunnel.isOnDemandEnabled
+        tunnelProvider = tunnel
         super.init()
     }
 
@@ -400,9 +400,9 @@ class TunnelContainer: NSObject {
     }
 
     func refreshStatus() {
-        let status = TunnelStatus(from: self.tunnelProvider.connection.status)
+        let status = TunnelStatus(from: tunnelProvider.connection.status)
         self.status = status
-        self.isActivateOnDemandEnabled = self.tunnelProvider.isOnDemandEnabled
+        isActivateOnDemandEnabled = tunnelProvider.isOnDemandEnabled
     }
 
     //swiftlint:disable:next function_body_length
@@ -413,9 +413,9 @@ class TunnelContainer: NSObject {
             return
         }
 
-        wg_log(.debug, message: "startActivation: Entering (tunnel: \(self.name))")
+        wg_log(.debug, message: "startActivation: Entering (tunnel: \(name))")
 
-        self.status = .activating // Ensure that no other tunnel can attempt activation until this tunnel is done trying
+        status = .activating // Ensure that no other tunnel can attempt activation until this tunnel is done trying
 
         guard tunnelProvider.isEnabled else {
             // In case the tunnel had gotten disabled, re-enable and save it,
@@ -440,14 +440,14 @@ class TunnelContainer: NSObject {
         // Start the tunnel
         do {
             wg_log(.debug, staticMessage: "startActivation: Starting tunnel")
-            self.isAttemptingActivation = true
+            isAttemptingActivation = true
             let activationAttemptId = UUID().uuidString
             self.activationAttemptId = activationAttemptId
             try (tunnelProvider.connection as? NETunnelProviderSession)?.startTunnel(options: ["activationAttemptId": activationAttemptId])
             wg_log(.debug, staticMessage: "startActivation: Success")
             activationDelegate?.tunnelActivationAttemptSucceeded(tunnel: self)
         } catch let error {
-            self.isAttemptingActivation = false
+            isAttemptingActivation = false
             guard let systemError = error as? NEVPNError else {
                 wg_log(.error, message: "Failed to activate tunnel: Error: \(error)")
                 status = .inactive
@@ -481,47 +481,6 @@ class TunnelContainer: NSObject {
     }
 }
 
-@objc enum TunnelStatus: Int {
-    case inactive
-    case activating
-    case active
-    case deactivating
-    case reasserting // Not a possible state at present
-    case restarting // Restarting tunnel (done after saving modifications to an active tunnel)
-    case waiting    // Waiting for another tunnel to be brought down
-
-    init(from systemStatus: NEVPNStatus) {
-        switch systemStatus {
-        case .connected:
-            self = .active
-        case .connecting:
-            self = .activating
-        case .disconnected:
-            self = .inactive
-        case .disconnecting:
-            self = .deactivating
-        case .reasserting:
-            self = .reasserting
-        case .invalid:
-            self = .inactive
-        }
-    }
-}
-
-extension TunnelStatus: CustomDebugStringConvertible {
-    public var debugDescription: String {
-        switch self {
-        case .inactive: return "inactive"
-        case .activating: return "activating"
-        case .active: return "active"
-        case .deactivating: return "deactivating"
-        case .reasserting: return "reasserting"
-        case .restarting: return "restarting"
-        case .waiting: return "waiting"
-        }
-    }
-}
-
 extension NEVPNStatus: CustomDebugStringConvertible {
     public var debugDescription: String {
         switch self {
index 31463465fcee8b8c89f5b61546936a1300e08f91..428f73243247746ea7e63663b6f4d5b377d66f60 100644 (file)
@@ -15,7 +15,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
         Logger.configureGlobal(withFilePath: FileManager.appLogFileURL?.path)
 
         let window = UIWindow(frame: UIScreen.main.bounds)
-        window.backgroundColor = UIColor.white
+        window.backgroundColor = .white
         self.window = window
 
         let mainVC = MainViewController()
index 48c87982423a8beb2ee01d7802d20a466432f24e..15d58d60fa3faed631218bb28427722aa7853427 100644 (file)
@@ -6,29 +6,36 @@ import UIKit
 class TunnelEditReadOnlyKeyValueCell: CopyableLabelTableViewCell {
     var key: String {
         get { return keyLabel.text ?? "" }
-        set(value) {keyLabel.text = value }
+        set(value) { keyLabel.text = value }
     }
     var value: String {
         get { return valueLabel.text }
         set(value) { valueLabel.text = value }
     }
     
-    let keyLabel: UILabel
-    let valueLabel: ScrollableLabel
+    override var textToCopy: String? {
+        return valueLabel.text
+    }
     
-    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
-        keyLabel = UILabel()
+    let keyLabel: UILabel = {
+        let keyLabel = UILabel()
         keyLabel.font = UIFont.preferredFont(forTextStyle: .body)
         keyLabel.adjustsFontForContentSizeCategory = true
-        valueLabel = ScrollableLabel()
+        keyLabel.textColor = .gray
+        return keyLabel
+    }()
+    
+    let valueLabel: ScrollableLabel = {
+        let valueLabel = ScrollableLabel()
         valueLabel.label.font = UIFont.preferredFont(forTextStyle: .body)
         valueLabel.label.adjustsFontForContentSizeCategory = true
-        
+        valueLabel.textColor = .gray
+        return valueLabel
+    }()
+    
+    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
         super.init(style: style, reuseIdentifier: reuseIdentifier)
         
-        keyLabel.textColor = UIColor.gray
-        valueLabel.textColor = UIColor.gray
-        
         contentView.addSubview(keyLabel)
         keyLabel.translatesAutoresizingMaskIntoConstraints = false
         keyLabel.textAlignment = .right
@@ -44,7 +51,7 @@ class TunnelEditReadOnlyKeyValueCell: CopyableLabelTableViewCell {
             keyLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
             keyLabel.leftAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leftAnchor),
             widthRatioConstraint
-            ])
+        ])
         
         contentView.addSubview(valueLabel)
         valueLabel.translatesAutoresizingMaskIntoConstraints = false
@@ -52,11 +59,7 @@ class TunnelEditReadOnlyKeyValueCell: CopyableLabelTableViewCell {
             valueLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
             valueLabel.leftAnchor.constraint(equalToSystemSpacingAfter: keyLabel.rightAnchor, multiplier: 1),
             valueLabel.rightAnchor.constraint(equalTo: contentView.layoutMarginsGuide.rightAnchor)
-            ])
-    }
-    
-    override var textToCopy: String? {
-        return self.valueLabel.text
+        ])
     }
     
     required init?(coder aDecoder: NSCoder) {
index 8d055d235af81141becac3142a751815463a0efa..393294e5eaba310c1a7603efb0b8b7ac3ed8fd5b 100644 (file)
@@ -72,18 +72,18 @@ class TunnelEditTableViewController: UITableViewController {
 
     override func viewDidLoad() {
         super.viewDidLoad()
-        self.title = tunnel == nil ? "New configuration" : "Edit configuration"
-        self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .save, target: self, action: #selector(saveTapped))
-        self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelTapped))
-
-        self.tableView.estimatedRowHeight = 44
-        self.tableView.rowHeight = UITableView.automaticDimension
-
-        self.tableView.register(TunnelEditKeyValueCell.self)
-        self.tableView.register(TunnelEditReadOnlyKeyValueCell.self)
-        self.tableView.register(TunnelEditButtonCell.self)
-        self.tableView.register(TunnelEditSwitchCell.self)
-        self.tableView.register(TunnelEditSelectionListCell.self)
+        title = tunnel == nil ? "New configuration" : "Edit configuration"
+        navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .save, target: self, action: #selector(saveTapped))
+        navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelTapped))
+
+        tableView.estimatedRowHeight = 44
+        tableView.rowHeight = UITableView.automaticDimension
+
+        tableView.register(EditableKeyValueCell.self)
+        tableView.register(TunnelEditReadOnlyKeyValueCell.self)
+        tableView.register(ButtonCell.self)
+        tableView.register(SwitchCell.self)
+        tableView.register(CheckmarkCell.self)
     }
 
     private func loadSections() {
@@ -95,13 +95,13 @@ class TunnelEditTableViewController: UITableViewController {
     }
 
     @objc func saveTapped() {
-        self.tableView.endEditing(false)
+        tableView.endEditing(false)
         let tunnelSaveResult = tunnelViewModel.save()
         switch tunnelSaveResult {
         case .error(let errorMessage):
             let erroringConfiguration = (tunnelViewModel.interfaceData.validatedConfiguration == nil) ? "Interface" : "Peer"
             ErrorPresenter.showErrorAlert(title: "Invalid \(erroringConfiguration)", message: errorMessage, from: self)
-            self.tableView.reloadData() // Highlight erroring fields
+            tableView.reloadData() // Highlight erroring fields
         case .saved(let tunnelConfiguration):
             if let tunnel = tunnel {
                 // We're modifying an existing tunnel
@@ -133,7 +133,7 @@ class TunnelEditTableViewController: UITableViewController {
 
     @objc func cancelTapped() {
         dismiss(animated: true, completion: nil)
-        self.delegate?.tunnelEditingCancelled()
+        delegate?.tunnelEditingCancelled()
     }
 }
 
@@ -201,7 +201,7 @@ extension TunnelEditTableViewController {
     }
 
     private func generateKeyPairCell(for tableView: UITableView, at indexPath: IndexPath, with field: TunnelViewModel.InterfaceField) -> UITableViewCell {
-        let cell: TunnelEditButtonCell = tableView.dequeueReusableCell(for: indexPath)
+        let cell: ButtonCell = tableView.dequeueReusableCell(for: indexPath)
         cell.buttonText = field.rawValue
         cell.onTapped = { [weak self] in
             guard let self = self else { return }
@@ -225,7 +225,7 @@ extension TunnelEditTableViewController {
     }
 
     private func interfaceFieldKeyValueCell(for tableView: UITableView, at indexPath: IndexPath, with field: TunnelViewModel.InterfaceField) -> UITableViewCell {
-        let cell: TunnelEditKeyValueCell = tableView.dequeueReusableCell(for: indexPath)
+        let cell: EditableKeyValueCell = tableView.dequeueReusableCell(for: indexPath)
         cell.key = field.rawValue
 
         switch field {
@@ -287,7 +287,7 @@ extension TunnelEditTableViewController {
     }
 
     private func deletePeerCell(for tableView: UITableView, at indexPath: IndexPath, peerData: TunnelViewModel.PeerData, field: TunnelViewModel.PeerField) -> UITableViewCell {
-        let cell: TunnelEditButtonCell = tableView.dequeueReusableCell(for: indexPath)
+        let cell: ButtonCell = tableView.dequeueReusableCell(for: indexPath)
         cell.buttonText = field.rawValue
         cell.hasDestructiveAction = true
         cell.onTapped = { [weak self, weak peerData] in
@@ -313,7 +313,7 @@ extension TunnelEditTableViewController {
     }
 
     private func excludePrivateIPsCell(for tableView: UITableView, at indexPath: IndexPath, peerData: TunnelViewModel.PeerData, field: TunnelViewModel.PeerField) -> UITableViewCell {
-        let cell: TunnelEditSwitchCell = tableView.dequeueReusableCell(for: indexPath)
+        let cell: SwitchCell = tableView.dequeueReusableCell(for: indexPath)
         cell.message = field.rawValue
         cell.isEnabled = peerData.shouldAllowExcludePrivateIPsControl
         cell.isOn = peerData.excludePrivateIPsValue
@@ -328,7 +328,7 @@ extension TunnelEditTableViewController {
     }
 
     private func peerFieldKeyValueCell(for tableView: UITableView, at indexPath: IndexPath, peerData: TunnelViewModel.PeerData, field: TunnelViewModel.PeerField) -> UITableViewCell {
-        let cell: TunnelEditKeyValueCell = tableView.dequeueReusableCell(for: indexPath)
+        let cell: EditableKeyValueCell = tableView.dequeueReusableCell(for: indexPath)
         cell.key = field.rawValue
 
         switch field {
@@ -377,7 +377,7 @@ extension TunnelEditTableViewController {
     }
 
     private func addPeerCell(for tableView: UITableView, at indexPath: IndexPath) -> UITableViewCell {
-        let cell: TunnelEditButtonCell = tableView.dequeueReusableCell(for: indexPath)
+        let cell: ButtonCell = tableView.dequeueReusableCell(for: indexPath)
         cell.buttonText = "Add peer"
         cell.onTapped = { [weak self] in
             guard let self = self else { return }
@@ -398,7 +398,7 @@ extension TunnelEditTableViewController {
 
     private func onDemandCell(for tableView: UITableView, at indexPath: IndexPath) -> UITableViewCell {
         if indexPath.row == 0 {
-            let cell: TunnelEditSwitchCell = tableView.dequeueReusableCell(for: indexPath)
+            let cell: SwitchCell = tableView.dequeueReusableCell(for: indexPath)
             cell.message = "Activate on demand"
             cell.isOn = activateOnDemandSetting.isActivateOnDemandEnabled
             cell.onSwitchToggled = { [weak self] isOn in
@@ -419,7 +419,7 @@ extension TunnelEditTableViewController {
             }
             return cell
         } else {
-            let cell: TunnelEditSelectionListCell = tableView.dequeueReusableCell(for: indexPath)
+            let cell: CheckmarkCell = tableView.dequeueReusableCell(for: indexPath)
             let rowOption = activateOnDemandOptions[indexPath.row - 1]
             let selectedOption = activateOnDemandSetting.activateOnDemandOption
             assert(selectedOption != .none)
@@ -455,7 +455,7 @@ extension TunnelEditTableViewController {
         alert.popoverPresentationController?.sourceView = sourceView
         alert.popoverPresentationController?.sourceRect = sourceView.bounds
 
-        self.present(alert, animated: true, completion: nil)
+        present(alert, animated: true, completion: nil)
     }
 }
 
index 2fc46b2f9bd2df8b1187bd6ec396948198130644..82e6f81ae197b0b9ddfc276e2c6129a2d2775a00 100644 (file)
@@ -12,20 +12,20 @@ class MainViewController: UISplitViewController {
 
     init() {
         let detailVC = UIViewController()
-        detailVC.view.backgroundColor = UIColor.white
+        detailVC.view.backgroundColor = .white
         let detailNC = UINavigationController(rootViewController: detailVC)
 
         let masterVC = TunnelsListTableViewController()
         let masterNC = UINavigationController(rootViewController: masterVC)
 
-        self.tunnelsListVC = masterVC
+        tunnelsListVC = masterVC
 
         super.init(nibName: nil, bundle: nil)
 
-        self.viewControllers = [ masterNC, detailNC ]
+        viewControllers = [ masterNC, detailNC ]
 
         // State restoration
-        self.restorationIdentifier = "MainVC"
+        restorationIdentifier = "MainVC"
         masterNC.restorationIdentifier = "MasterNC"
         detailNC.restorationIdentifier = "DetailNC"
     }
@@ -35,10 +35,10 @@ class MainViewController: UISplitViewController {
     }
 
     override func viewDidLoad() {
-        self.delegate = self
+        delegate = self
 
         // On iPad, always show both masterVC and detailVC, even in portrait mode, like the Settings app
-        self.preferredDisplayMode = .allVisible
+        preferredDisplayMode = .allVisible
 
         // Create the tunnels manager, and when it's ready, inform tunnelsListVC
         TunnelsManager.create { [weak self] result in
@@ -56,7 +56,7 @@ class MainViewController: UISplitViewController {
             tunnelsManager.activationDelegate = self
 
             self.onTunnelsManagerReady?(tunnelsManager)
-        self.onTunnelsManagerReady = nil
+            self.onTunnelsManagerReady = nil
         }
     }
 }
index a03b70944fa32e1f7142750c1197362f4f6e40ad..1e231ec9b9111b89e1dfb3217332778fd10229ca 100644 (file)
@@ -2,7 +2,6 @@
 // Copyright © 2018 WireGuard LLC. All Rights Reserved.
 
 import AVFoundation
-import CoreData
 import UIKit
 
 protocol QRScanViewControllerDelegate: class {
@@ -18,8 +17,8 @@ class QRScanViewController: UIViewController {
     override func viewDidLoad() {
         super.viewDidLoad()
 
-        self.title = "Scan QR code"
-        self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelTapped))
+        title = "Scan QR code"
+        navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelTapped))
 
         let tipLabel = UILabel()
         tipLabel.text = "Tip: Generate with `qrencode -t ansiutf8 < tunnel.conf`"
@@ -102,7 +101,7 @@ class QRScanViewController: UIViewController {
             }
         }
 
-        previewLayer?.frame = self.view.bounds
+        previewLayer?.frame = view.bounds
     }
 
     func scanDidComplete(withCode code: String) {
diff --git a/WireGuard/WireGuard/UI/iOS/Settings/SettingsButtonCell.swift b/WireGuard/WireGuard/UI/iOS/Settings/SettingsButtonCell.swift
deleted file mode 100644 (file)
index d795ab4..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-// SPDX-License-Identifier: MIT
-// Copyright © 2018 WireGuard LLC. All Rights Reserved.
-
-import UIKit
-
-class SettingsButtonCell: UITableViewCell {
-    var buttonText: String {
-        get { return button.title(for: .normal) ?? "" }
-        set(value) { button.setTitle(value, for: .normal) }
-    }
-    var onTapped: (() -> Void)?
-    
-    let button: UIButton = {
-        let button = UIButton(type: .system)
-        button.titleLabel?.font = UIFont.preferredFont(forTextStyle: .body)
-        button.titleLabel?.adjustsFontForContentSizeCategory = true
-        return button
-    }()
-    
-    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
-        super.init(style: style, reuseIdentifier: reuseIdentifier)
-        
-        contentView.addSubview(button)
-        button.translatesAutoresizingMaskIntoConstraints = false
-        NSLayoutConstraint.activate([
-            button.topAnchor.constraint(equalTo: contentView.layoutMarginsGuide.topAnchor),
-            contentView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: button.bottomAnchor),
-            button.centerXAnchor.constraint(equalTo: contentView.centerXAnchor)
-            ])
-        
-        button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
-    }
-    
-    @objc func buttonTapped() {
-        onTapped?()
-    }
-    
-    required init?(coder aDecoder: NSCoder) {
-        fatalError("init(coder:) has not been implemented")
-    }
-    
-    override func prepareForReuse() {
-        super.prepareForReuse()
-        buttonText = ""
-        onTapped = nil
-    }
-}
diff --git a/WireGuard/WireGuard/UI/iOS/Settings/SettingsKeyValueCell.swift b/WireGuard/WireGuard/UI/iOS/Settings/SettingsKeyValueCell.swift
deleted file mode 100644 (file)
index 532f1d1..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-// SPDX-License-Identifier: MIT
-// Copyright © 2018 WireGuard LLC. All Rights Reserved.
-
-import UIKit
-
-class SettingsKeyValueCell: UITableViewCell {
-    var key: String {
-        get { return textLabel?.text ?? "" }
-        set(value) { textLabel?.text = value }
-    }
-    var value: String {
-        get { return detailTextLabel?.text ?? "" }
-        set(value) { detailTextLabel?.text = value }
-    }
-    
-    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
-        super.init(style: .value1, reuseIdentifier: SettingsKeyValueCell.reuseIdentifier)
-    }
-    
-    required init?(coder aDecoder: NSCoder) {
-        fatalError("init(coder:) has not been implemented")
-    }
-    
-    override func prepareForReuse() {
-        super.prepareForReuse()
-        key = ""
-        value = ""
-    }
-}
similarity index 94%
rename from WireGuard/WireGuard/UI/iOS/Settings/SettingsTableViewController.swift
rename to WireGuard/WireGuard/UI/iOS/SettingsTableViewController.swift
index 5e8aee6006d02aaf4e09bb1731e8bf7537e2de84..b583c5bf7c24d1c469ff4662ce8ff2f8fc05cc09 100644 (file)
@@ -40,15 +40,15 @@ class SettingsTableViewController: UITableViewController {
         tableView.rowHeight = UITableView.automaticDimension
         tableView.allowsSelection = false
 
-        tableView.register(SettingsKeyValueCell.self)
-        tableView.register(SettingsButtonCell.self)
+        tableView.register(KeyValueCell.self)
+        tableView.register(ButtonCell.self)
 
         tableView.tableFooterView = UIImageView(image: UIImage(named: "wireguard.pdf"))
     }
 
     override func viewDidLayoutSubviews() {
         super.viewDidLayoutSubviews()
-        guard let logo = self.tableView.tableFooterView else { return }
+        guard let logo = tableView.tableFooterView else { return }
         
         let bottomPadding = max(tableView.layoutMargins.bottom, 10)
         let fullHeight = max(tableView.contentSize.height, tableView.bounds.size.height - tableView.layoutMargins.top - bottomPadding)
@@ -167,7 +167,8 @@ extension SettingsTableViewController {
     override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
         let field = settingsFieldsBySection[indexPath.section][indexPath.row]
         if field == .iosAppVersion || field == .goBackendVersion {
-            let cell: SettingsKeyValueCell = tableView.dequeueReusableCell(for: indexPath)
+            let cell: KeyValueCell = tableView.dequeueReusableCell(for: indexPath)
+            cell.copyableGesture = false
             cell.key = field.rawValue
             if field == .iosAppVersion {
                 var appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "Unknown version"
@@ -180,7 +181,7 @@ extension SettingsTableViewController {
             }
             return cell
         } else if field == .exportZipArchive {
-            let cell: SettingsButtonCell = tableView.dequeueReusableCell(for: indexPath)
+            let cell: ButtonCell = tableView.dequeueReusableCell(for: indexPath)
             cell.buttonText = field.rawValue
             cell.onTapped = { [weak self] in
                 self?.exportConfigurationsAsZipFile(sourceView: cell.button)
@@ -188,7 +189,7 @@ extension SettingsTableViewController {
             return cell
         } else {
             assert(field == .exportLogFile)
-            let cell: SettingsButtonCell = tableView.dequeueReusableCell(for: indexPath)
+            let cell: ButtonCell = tableView.dequeueReusableCell(for: indexPath)
             cell.buttonText = field.rawValue
             cell.onTapped = { [weak self] in
                 self?.exportLogForLastActivatedTunnel(sourceView: cell.button)
similarity index 89%
rename from WireGuard/WireGuard/UI/iOS/TunnelList/BorderedTextButton.swift
rename to WireGuard/WireGuard/UI/iOS/SharedViews/BorderedTextButton.swift
index 5114c09b7758f5f36b2835187ec89ca75dddebea..94b76d62773ebe13bec4dc44f61f4b6ceade9734 100644 (file)
@@ -33,9 +33,9 @@ class BorderedTextButton: UIView {
         addSubview(button)
         button.translatesAutoresizingMaskIntoConstraints = false
         NSLayoutConstraint.activate([
-            button.centerXAnchor.constraint(equalTo: self.centerXAnchor),
-            button.centerYAnchor.constraint(equalTo: self.centerYAnchor)
-            ])
+            button.centerXAnchor.constraint(equalTo: centerXAnchor),
+            button.centerYAnchor.constraint(equalTo: centerYAnchor)
+        ])
         
         button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
     }
similarity index 90%
rename from WireGuard/WireGuard/UI/iOS/EditTunnel/TunnelEditButtonCell.swift
rename to WireGuard/WireGuard/UI/iOS/SharedViews/ButtonCell.swift
index af70183f716d99e0b6888af52969e8e996956f45..470299339158965de7b60ed96036e9a93607d475 100644 (file)
@@ -3,14 +3,14 @@
 
 import UIKit
 
-class TunnelEditButtonCell: UITableViewCell {
+class ButtonCell: UITableViewCell {
     var buttonText: String {
         get { return button.title(for: .normal) ?? "" }
         set(value) { button.setTitle(value, for: .normal) }
     }
     var hasDestructiveAction: Bool {
-        get { return button.tintColor == UIColor.red }
-        set(value) { button.tintColor = value ? UIColor.red : buttonStandardTintColor }
+        get { return button.tintColor == .red }
+        set(value) { button.tintColor = value ? .red : buttonStandardTintColor }
     }
     var onTapped: (() -> Void)?
     
similarity index 93%
rename from WireGuard/WireGuard/UI/iOS/EditTunnel/TunnelEditSectionListCell.swift
rename to WireGuard/WireGuard/UI/iOS/SharedViews/CheckmarkCell.swift
index ca0352eb2a77fe7e75d5c325df514e78f70c7643..db4b6c95be9bbb37b7fc7d9e6c572f91af2f0b98 100644 (file)
@@ -3,7 +3,7 @@
 
 import UIKit
 
-class TunnelEditSelectionListCell: UITableViewCell {
+class CheckmarkCell: UITableViewCell {
     var message: String {
         get { return textLabel?.text ?? "" }
         set(value) { textLabel!.text = value }
@@ -13,6 +13,7 @@ class TunnelEditSelectionListCell: UITableViewCell {
             accessoryType = isChecked ? .checkmark : .none
         }
     }
+    
     override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
         isChecked = false
         super.init(style: .default, reuseIdentifier: reuseIdentifier)
similarity index 83%
rename from WireGuard/WireGuard/UI/iOS/CopyableLabelTableViewCell.swift
rename to WireGuard/WireGuard/UI/iOS/SharedViews/CopyableLabelTableViewCell.swift
index daddf0aa16c06e93ba3c109eb5fdbf8bc14e9917..93a9ef7eb77b962b1615e60c5dff8f767f11748d 100644 (file)
@@ -17,13 +17,13 @@ class CopyableLabelTableViewCell: UITableViewCell {
     override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
         super.init(style: style, reuseIdentifier: reuseIdentifier)
         let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTapGesture(_:)))
-        self.addGestureRecognizer(gestureRecognizer)
-        self.isUserInteractionEnabled = true
+        addGestureRecognizer(gestureRecognizer)
+        isUserInteractionEnabled = true
     }
 
     // MARK: - UIGestureRecognizer
     @objc func handleTapGesture(_ recognizer: UIGestureRecognizer) {
-        if !self.copyableGesture {
+        if !copyableGesture {
             return
         }
         guard recognizer.state == .recognized else { return }
@@ -31,7 +31,7 @@ class CopyableLabelTableViewCell: UITableViewCell {
         if let recognizerView = recognizer.view,
             let recognizerSuperView = recognizerView.superview, recognizerView.becomeFirstResponder() {
             let menuController = UIMenuController.shared
-            menuController.setTargetRect(self.detailTextLabel?.frame ?? recognizerView.frame, in: self.detailTextLabel?.superview ?? recognizerSuperView)
+            menuController.setTargetRect(detailTextLabel?.frame ?? recognizerView.frame, in: detailTextLabel?.superview ?? recognizerSuperView)
             menuController.setMenuVisible(true, animated: true)
         }
     }
@@ -50,6 +50,6 @@ class CopyableLabelTableViewCell: UITableViewCell {
 
     override func prepareForReuse() {
         super.prepareForReuse()
-        self.copyableGesture = true
+        copyableGesture = true
     }
 }
similarity index 94%
rename from WireGuard/WireGuard/UI/iOS/EditTunnel/TunnelEditKeyValueCell.swift
rename to WireGuard/WireGuard/UI/iOS/SharedViews/EditableKeyValueCell.swift
index 432d75b609f51ccbbae0e2cf18768c52566c4790..48956eb971f0ce101b96d7901fdbc8603084d05e 100644 (file)
@@ -3,10 +3,10 @@
 
 import UIKit
 
-class TunnelEditKeyValueCell: UITableViewCell {
+class EditableKeyValueCell: UITableViewCell {
     var key: String {
         get { return keyLabel.text ?? "" }
-        set(value) {keyLabel.text = value }
+        set(value) { keyLabel.text = value }
     }
     var value: String {
         get { return valueTextField.text ?? "" }
@@ -89,7 +89,7 @@ class TunnelEditKeyValueCell: UITableViewCell {
     
     func configureForContentSize() {
         var constraints = [NSLayoutConstraint]()
-        if self.traitCollection.preferredContentSizeCategory.isAccessibilityCategory {
+        if traitCollection.preferredContentSizeCategory.isAccessibilityCategory {
             // Stack vertically
             if !isStackedVertically {
                 constraints = [
@@ -113,9 +113,9 @@ class TunnelEditKeyValueCell: UITableViewCell {
             }
         }
         if !constraints.isEmpty {
-            NSLayoutConstraint.deactivate(self.contentSizeBasedConstraints)
+            NSLayoutConstraint.deactivate(contentSizeBasedConstraints)
             NSLayoutConstraint.activate(constraints)
-            self.contentSizeBasedConstraints = constraints
+            contentSizeBasedConstraints = constraints
         }
     }
     
@@ -136,7 +136,7 @@ class TunnelEditKeyValueCell: UITableViewCell {
     }
 }
 
-extension TunnelEditKeyValueCell: UITextFieldDelegate {
+extension EditableKeyValueCell: UITextFieldDelegate {
     func textFieldDidBeginEditing(_ textField: UITextField) {
         textFieldValueOnBeginEditing = textField.text ?? ""
         isValueValid = true
similarity index 92%
rename from WireGuard/WireGuard/UI/iOS/TunnelDetail/TunnelDetailKeyValueCell.swift
rename to WireGuard/WireGuard/UI/iOS/SharedViews/KeyValueCell.swift
index cbe1c147ebde9e856ebceb5cb40b951e25d1079b..78026eab8492c764009e3195809258a3a1008931 100644 (file)
@@ -3,7 +3,7 @@
 
 import UIKit
 
-class TunnelDetailKeyValueCell: CopyableLabelTableViewCell {
+class KeyValueCell: CopyableLabelTableViewCell {
     var key: String {
         get { return keyLabel.text ?? "" }
         set(value) { keyLabel.text = value }
@@ -14,7 +14,7 @@ class TunnelDetailKeyValueCell: CopyableLabelTableViewCell {
     }
     
     override var textToCopy: String? {
-        return self.valueLabel.text
+        return valueLabel.text
     }
     
     let keyLabel: UILabel = {
@@ -46,14 +46,14 @@ class TunnelDetailKeyValueCell: CopyableLabelTableViewCell {
         NSLayoutConstraint.activate([
             keyLabel.leftAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leftAnchor),
             keyLabel.topAnchor.constraint(equalToSystemSpacingBelow: contentView.layoutMarginsGuide.topAnchor, multiplier: 0.5)
-            ])
+        ])
         
         contentView.addSubview(valueLabel)
         valueLabel.translatesAutoresizingMaskIntoConstraints = false
         NSLayoutConstraint.activate([
             valueLabel.rightAnchor.constraint(equalTo: contentView.layoutMarginsGuide.rightAnchor),
             contentView.layoutMarginsGuide.bottomAnchor.constraint(equalToSystemSpacingBelow: valueLabel.bottomAnchor, multiplier: 0.5)
-            ])
+        ])
         
         keyLabel.setContentCompressionResistancePriority(.defaultHigh + 1, for: .horizontal)
         keyLabel.setContentHuggingPriority(.defaultHigh, for: .horizontal)
@@ -64,7 +64,7 @@ class TunnelDetailKeyValueCell: CopyableLabelTableViewCell {
     
     func configureForContentSize() {
         var constraints = [NSLayoutConstraint]()
-        if self.traitCollection.preferredContentSizeCategory.isAccessibilityCategory {
+        if traitCollection.preferredContentSizeCategory.isAccessibilityCategory {
             // Stack vertically
             if !isStackedVertically {
                 constraints = [
@@ -88,9 +88,9 @@ class TunnelDetailKeyValueCell: CopyableLabelTableViewCell {
             }
         }
         if !constraints.isEmpty {
-            NSLayoutConstraint.deactivate(self.contentSizeBasedConstraints)
+            NSLayoutConstraint.deactivate(contentSizeBasedConstraints)
             NSLayoutConstraint.activate(constraints)
-            self.contentSizeBasedConstraints = constraints
+            contentSizeBasedConstraints = constraints
         }
     }
     
similarity index 82%
rename from WireGuard/WireGuard/UI/iOS/EditTunnel/TunnelEditSwitchCell.swift
rename to WireGuard/WireGuard/UI/iOS/SharedViews/SwitchCell.swift
index 658fb951f1883f4b84d1f71b7ae9987b949959a4..d0c29aac1d2294a3291188b0f319f4aa19ed560c 100644 (file)
@@ -3,10 +3,10 @@
 
 import UIKit
 
-class TunnelEditSwitchCell: UITableViewCell {
+class SwitchCell: UITableViewCell {
     var message: String {
         get { return textLabel?.text ?? "" }
-        set(value) { textLabel!.text = value }
+        set(value) { textLabel?.text = value }
     }
     var isOn: Bool {
         get { return switchView.isOn }
@@ -16,31 +16,32 @@ class TunnelEditSwitchCell: UITableViewCell {
         get { return switchView.isEnabled }
         set(value) {
             switchView.isEnabled = value
-            textLabel?.textColor = value ? UIColor.black : UIColor.gray
+            textLabel?.textColor = value ? .black : .gray
         }
     }
     
     var onSwitchToggled: ((Bool) -> Void)?
     
-    let switchView: UISwitch
+    let switchView = UISwitch()
     
     override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
-        switchView = UISwitch()
         super.init(style: .default, reuseIdentifier: reuseIdentifier)
+        
         accessoryView = switchView
         switchView.addTarget(self, action: #selector(switchToggled), for: .valueChanged)
     }
+
+    required init?(coder aDecoder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
     
     @objc func switchToggled() {
         onSwitchToggled?(switchView.isOn)
     }
     
-    required init?(coder aDecoder: NSCoder) {
-        fatalError("init(coder:) has not been implemented")
-    }
-    
     override func prepareForReuse() {
         super.prepareForReuse()
+        isEnabled = true
         message = ""
         isOn = false
     }
diff --git a/WireGuard/WireGuard/UI/iOS/TunnelDetail/TunnelDetailActivateOnDemandCell.swift b/WireGuard/WireGuard/UI/iOS/TunnelDetail/TunnelDetailActivateOnDemandCell.swift
deleted file mode 100644 (file)
index 9507c45..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-// SPDX-License-Identifier: MIT
-// Copyright © 2018 WireGuard LLC. All Rights Reserved.
-
-import UIKit
-
-class TunnelDetailActivateOnDemandCell: UITableViewCell {
-    var tunnel: TunnelContainer? {
-        didSet(value) {
-            update(from: tunnel?.activateOnDemandSetting())
-            onDemandStatusObservervationToken = tunnel?.observe(\.isActivateOnDemandEnabled) { [weak self] tunnel, _ in
-                self?.update(from: tunnel.activateOnDemandSetting())
-            }
-        }
-    }
-    
-    var onDemandStatusObservervationToken: AnyObject?
-    
-    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
-        super.init(style: .value1, reuseIdentifier: reuseIdentifier)
-        textLabel?.text = "Activate on demand"
-        textLabel?.font = UIFont.preferredFont(forTextStyle: .body)
-        textLabel?.adjustsFontForContentSizeCategory = true
-        detailTextLabel?.font = UIFont.preferredFont(forTextStyle: .body)
-        detailTextLabel?.adjustsFontForContentSizeCategory = true
-    }
-    
-    required init?(coder aDecoder: NSCoder) {
-        fatalError("init(coder:) has not been implemented")
-    }
-    
-    func update(from activateOnDemandSetting: ActivateOnDemandSetting?) {
-        detailTextLabel?.text = TunnelViewModel.activateOnDemandDetailText(for: activateOnDemandSetting)
-    }
-    
-    override func prepareForReuse() {
-        super.prepareForReuse()
-        textLabel?.text = "Activate on demand"
-        detailTextLabel?.text = ""
-    }
-}
diff --git a/WireGuard/WireGuard/UI/iOS/TunnelDetail/TunnelDetailButtonCell.swift b/WireGuard/WireGuard/UI/iOS/TunnelDetail/TunnelDetailButtonCell.swift
deleted file mode 100644 (file)
index 8710616..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-// SPDX-License-Identifier: MIT
-// Copyright © 2018 WireGuard LLC. All Rights Reserved.
-
-import UIKit
-
-class TunnelDetailButtonCell: UITableViewCell {
-    var buttonText: String {
-        get { return button.title(for: .normal) ?? "" }
-        set(value) { button.setTitle(value, for: .normal) }
-    }
-    var hasDestructiveAction: Bool {
-        get { return button.tintColor == UIColor.red }
-        set(value) { button.tintColor = value ? UIColor.red : buttonStandardTintColor }
-    }
-    var onTapped: (() -> Void)?
-    
-    let button: UIButton = {
-        let button = UIButton(type: .system)
-        button.titleLabel?.font = UIFont.preferredFont(forTextStyle: .body)
-        button.titleLabel?.adjustsFontForContentSizeCategory = true
-        return button
-    }()
-    
-    var buttonStandardTintColor: UIColor
-    
-    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
-        buttonStandardTintColor = button.tintColor
-        super.init(style: style, reuseIdentifier: reuseIdentifier)
-        
-        contentView.addSubview(button)
-        button.translatesAutoresizingMaskIntoConstraints = false
-        NSLayoutConstraint.activate([
-            button.topAnchor.constraint(equalTo: contentView.layoutMarginsGuide.topAnchor),
-            contentView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: button.bottomAnchor),
-            button.centerXAnchor.constraint(equalTo: contentView.centerXAnchor)
-            ])
-        
-        button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
-    }
-    
-    @objc func buttonTapped() {
-        onTapped?()
-    }
-    
-    required init?(coder aDecoder: NSCoder) {
-        fatalError("init(coder:) has not been implemented")
-    }
-    
-    override func prepareForReuse() {
-        super.prepareForReuse()
-        buttonText = ""
-        onTapped = nil
-        hasDestructiveAction = false
-    }
-}
diff --git a/WireGuard/WireGuard/UI/iOS/TunnelDetail/TunnelDetailStatusCell.swift b/WireGuard/WireGuard/UI/iOS/TunnelDetail/TunnelDetailStatusCell.swift
deleted file mode 100644 (file)
index 0dd1ee9..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-// SPDX-License-Identifier: MIT
-// Copyright © 2018 WireGuard LLC. All Rights Reserved.
-
-import UIKit
-
-class TunnelDetailStatusCell: UITableViewCell {
-    var tunnel: TunnelContainer? {
-        didSet(value) {
-            update(from: tunnel?.status)
-            statusObservervationToken = tunnel?.observe(\.status) { [weak self] tunnel, _ in
-                self?.update(from: tunnel.status)
-            }
-        }
-    }
-    var isSwitchInteractionEnabled: Bool {
-        get { return statusSwitch.isUserInteractionEnabled }
-        set(value) { statusSwitch.isUserInteractionEnabled = value }
-    }
-    var onSwitchToggled: ((Bool) -> Void)?
-    private var isOnSwitchToggledHandlerEnabled = true
-    
-    let statusSwitch: UISwitch
-    private var statusObservervationToken: AnyObject?
-    
-    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
-        statusSwitch = UISwitch()
-        super.init(style: .default, reuseIdentifier: TunnelDetailKeyValueCell.reuseIdentifier)
-        accessoryView = statusSwitch
-        
-        statusSwitch.addTarget(self, action: #selector(switchToggled), for: .valueChanged)
-    }
-    
-    @objc func switchToggled() {
-        if isOnSwitchToggledHandlerEnabled {
-            onSwitchToggled?(statusSwitch.isOn)
-        }
-    }
-    
-    private func update(from status: TunnelStatus?) {
-        guard let status = status else {
-            reset()
-            return
-        }
-        let text: String
-        switch status {
-        case .inactive:
-            text = "Inactive"
-        case .activating:
-            text = "Activating"
-        case .active:
-            text = "Active"
-        case .deactivating:
-            text = "Deactivating"
-        case .reasserting:
-            text = "Reactivating"
-        case .restarting:
-            text = "Restarting"
-        case .waiting:
-            text = "Waiting"
-        }
-        textLabel?.text = text
-        DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(200)) { [weak statusSwitch] in
-            guard let statusSwitch = statusSwitch else { return }
-            statusSwitch.isOn = !(status == .deactivating || status == .inactive)
-            statusSwitch.isUserInteractionEnabled = (status == .inactive || status == .active)
-        }
-        textLabel?.textColor = (status == .active || status == .inactive) ? UIColor.black : UIColor.gray
-    }
-    
-    required init?(coder aDecoder: NSCoder) {
-        fatalError("init(coder:) has not been implemented")
-    }
-    
-    private func reset() {
-        textLabel?.text = "Invalid"
-        statusSwitch.isOn = false
-        textLabel?.textColor = UIColor.gray
-        statusSwitch.isUserInteractionEnabled = false
-    }
-    
-    override func prepareForReuse() {
-        super.prepareForReuse()
-        reset()
-    }
-}
index af4cf83ae8e4dc7ac4d07fddb6f4c228e7ac42bf..ed48d0f0db08745ac56fdab0ae11564dc080c3eb 100644 (file)
@@ -29,6 +29,8 @@ class TunnelDetailTableViewController: UITableViewController {
     let tunnel: TunnelContainer
     var tunnelViewModel: TunnelViewModel
     private var sections = [Section]()
+    private var onDemandStatusObservervationToken: AnyObject?
+    private var statusObservervationToken: AnyObject?
 
     init(tunnelsManager: TunnelsManager, tunnel: TunnelContainer) {
         self.tunnelsManager = tunnelsManager
@@ -41,22 +43,26 @@ class TunnelDetailTableViewController: UITableViewController {
     required init?(coder aDecoder: NSCoder) {
         fatalError("init(coder:) has not been implemented")
     }
+    
+    deinit {
+        onDemandStatusObservervationToken = nil
+        statusObservervationToken = nil
+    }
 
     override func viewDidLoad() {
         super.viewDidLoad()
-        self.title = tunnelViewModel.interfaceData[.name]
-        self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(editTapped))
+        title = tunnelViewModel.interfaceData[.name]
+        navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(editTapped))
 
-        self.tableView.estimatedRowHeight = 44
-        self.tableView.rowHeight = UITableView.automaticDimension
-        self.tableView.allowsSelection = false
-        self.tableView.register(TunnelDetailStatusCell.self)
-        self.tableView.register(TunnelDetailKeyValueCell.self)
-        self.tableView.register(TunnelDetailButtonCell.self)
-        self.tableView.register(TunnelDetailActivateOnDemandCell.self)
+        tableView.estimatedRowHeight = 44
+        tableView.rowHeight = UITableView.automaticDimension
+        tableView.allowsSelection = false
+        tableView.register(SwitchCell.self)
+        tableView.register(KeyValueCell.self)
+        tableView.register(ButtonCell.self)
 
         // State restoration
-        self.restorationIdentifier = "TunnelDetailVC:\(tunnel.name)"
+        restorationIdentifier = "TunnelDetailVC:\(tunnel.name)"
     }
 
     private func loadSections() {
@@ -76,8 +82,7 @@ class TunnelDetailTableViewController: UITableViewController {
         present(editNC, animated: true)
     }
 
-    func showConfirmationAlert(message: String, buttonTitle: String, from sourceView: UIView,
-                               onConfirmed: @escaping (() -> Void)) {
+    func showConfirmationAlert(message: String, buttonTitle: String, from sourceView: UIView, onConfirmed: @escaping (() -> Void)) {
         let destroyAction = UIAlertAction(title: buttonTitle, style: .destructive) { _ in
             onConfirmed()
         }
@@ -90,7 +95,7 @@ class TunnelDetailTableViewController: UITableViewController {
         alert.popoverPresentationController?.sourceView = sourceView
         alert.popoverPresentationController?.sourceRect = sourceView.bounds
 
-        self.present(alert, animated: true, completion: nil)
+        present(alert, animated: true, completion: nil)
     }
 }
 
@@ -100,8 +105,8 @@ extension TunnelDetailTableViewController: TunnelEditTableViewControllerDelegate
     func tunnelSaved(tunnel: TunnelContainer) {
         tunnelViewModel = TunnelViewModel(tunnelConfiguration: tunnel.tunnelConfiguration())
         loadSections()
-        self.title = tunnel.name
-        self.tableView.reloadData()
+        title = tunnel.name
+        tableView.reloadData()
     }
     func tunnelEditingCancelled() {
         // Nothing to do
@@ -161,8 +166,40 @@ extension TunnelDetailTableViewController {
     }
 
     private func statusCell(for tableView: UITableView, at indexPath: IndexPath) -> UITableViewCell {
-        let cell: TunnelDetailStatusCell = tableView.dequeueReusableCell(for: indexPath)
-        cell.tunnel = self.tunnel
+        let cell: SwitchCell = tableView.dequeueReusableCell(for: indexPath)
+        
+        let statusUpdate: (SwitchCell, TunnelStatus) -> Void = { cell, status in
+            let text: String
+            switch status {
+            case .inactive:
+                text = "Inactive"
+            case .activating:
+                text = "Activating"
+            case .active:
+                text = "Active"
+            case .deactivating:
+                text = "Deactivating"
+            case .reasserting:
+                text = "Reactivating"
+            case .restarting:
+                text = "Restarting"
+            case .waiting:
+                text = "Waiting"
+            }
+            cell.textLabel?.text = text
+            DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(200)) { [weak cell] in
+                cell?.switchView.isOn = !(status == .deactivating || status == .inactive)
+                cell?.switchView.isUserInteractionEnabled = (status == .inactive || status == .active)
+            }
+            cell.isEnabled = status == .active || status == .inactive
+        }
+        
+        statusUpdate(cell, tunnel.status)
+        statusObservervationToken = tunnel.observe(\.status) { [weak cell] tunnel, _ in
+            guard let cell = cell else { return }
+            statusUpdate(cell, tunnel.status)
+        }
+        
         cell.onSwitchToggled = { [weak self] isOn in
             guard let self = self else { return }
             if isOn {
@@ -176,7 +213,7 @@ extension TunnelDetailTableViewController {
 
     private func interfaceCell(for tableView: UITableView, at indexPath: IndexPath) -> UITableViewCell {
         let field = tunnelViewModel.interfaceData.filterFieldsWithValueOrControl(interfaceFields: interfaceFields)[indexPath.row]
-        let cell: TunnelDetailKeyValueCell = tableView.dequeueReusableCell(for: indexPath)
+        let cell: KeyValueCell = tableView.dequeueReusableCell(for: indexPath)
         cell.key = field.rawValue
         cell.value = tunnelViewModel.interfaceData[field]
         return cell
@@ -184,20 +221,24 @@ extension TunnelDetailTableViewController {
 
     private func peerCell(for tableView: UITableView, at indexPath: IndexPath, with peerData: TunnelViewModel.PeerData) -> UITableViewCell {
         let field = peerData.filterFieldsWithValueOrControl(peerFields: peerFields)[indexPath.row]
-        let cell: TunnelDetailKeyValueCell = tableView.dequeueReusableCell(for: indexPath)
+        let cell: KeyValueCell = tableView.dequeueReusableCell(for: indexPath)
         cell.key = field.rawValue
         cell.value = peerData[field]
         return cell
     }
 
     private func onDemandCell(for tableView: UITableView, at indexPath: IndexPath) -> UITableViewCell {
-        let cell: TunnelDetailActivateOnDemandCell = tableView.dequeueReusableCell(for: indexPath)
-        cell.tunnel = self.tunnel
+        let cell: KeyValueCell = tableView.dequeueReusableCell(for: indexPath)
+        cell.key = "Activate on demand"
+        cell.value = TunnelViewModel.activateOnDemandDetailText(for: tunnel.activateOnDemandSetting())
+        onDemandStatusObservervationToken = tunnel.observe(\.isActivateOnDemandEnabled) { [weak cell] tunnel, _ in
+            cell?.value = TunnelViewModel.activateOnDemandDetailText(for: tunnel.activateOnDemandSetting())
+        }
         return cell
     }
 
     private func deleteConfigurationCell(for tableView: UITableView, at indexPath: IndexPath) -> UITableViewCell {
-        let cell: TunnelDetailButtonCell = tableView.dequeueReusableCell(for: indexPath)
+        let cell: ButtonCell = tableView.dequeueReusableCell(for: indexPath)
         cell.buttonText = "Delete tunnel"
         cell.hasDestructiveAction = true
         cell.onTapped = { [weak self] in
index f0a16bf4932e702e77a546dedd0e4018eaed66f3..14a7194927137d2ada25d6959a5e1921750d9a33 100644 (file)
@@ -47,14 +47,14 @@ class TunnelListCell: UITableViewCell {
         NSLayoutConstraint.activate([
             statusSwitch.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
             contentView.rightAnchor.constraint(equalTo: statusSwitch.rightAnchor)
-            ])
+        ])
         
         contentView.addSubview(busyIndicator)
         busyIndicator.translatesAutoresizingMaskIntoConstraints = false
         NSLayoutConstraint.activate([
             busyIndicator.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
             statusSwitch.leftAnchor.constraint(equalToSystemSpacingAfter: busyIndicator.rightAnchor, multiplier: 1)
-            ])
+        ])
         
         contentView.addSubview(nameLabel)
         nameLabel.translatesAutoresizingMaskIntoConstraints = false
@@ -66,7 +66,7 @@ class TunnelListCell: UITableViewCell {
             nameLabel.leftAnchor.constraint(equalToSystemSpacingAfter: contentView.layoutMarginsGuide.leftAnchor, multiplier: 1),
             busyIndicator.leftAnchor.constraint(equalToSystemSpacingAfter: nameLabel.rightAnchor, multiplier: 1),
             bottomAnchorConstraint
-            ])
+        ])
         
         accessoryType = .disclosureIndicator
         
index eda09af3d035697a0b32a4dfc363e220a2eac668..0188c62766f1ac5895315e8191da23ce302c1366 100644 (file)
@@ -96,7 +96,8 @@ class TunnelsListTableViewController: UIViewController {
     }
 
     @objc func addButtonTapped(sender: AnyObject) {
-        if self.tunnelsManager == nil { return } // Do nothing until we've loaded the tunnels
+        guard tunnelsManager != nil else { return }
+        
         let alert = UIAlertController(title: "", message: "Add a new WireGuard tunnel", preferredStyle: .actionSheet)
         let importFileAction = UIAlertAction(title: "Create from file or archive", style: .default) { [weak self] _ in
             self?.presentViewControllerForFileImport()
@@ -125,29 +126,30 @@ class TunnelsListTableViewController: UIViewController {
             alert.popoverPresentationController?.sourceView = sender
             alert.popoverPresentationController?.sourceRect = sender.bounds
         }
-        self.present(alert, animated: true, completion: nil)
+        present(alert, animated: true, completion: nil)
     }
 
     @objc func settingsButtonTapped(sender: UIBarButtonItem!) {
-        if self.tunnelsManager == nil { return } // Do nothing until we've loaded the tunnels
+        guard tunnelsManager != nil else { return }
+        
         let settingsVC = SettingsTableViewController(tunnelsManager: tunnelsManager)
         let settingsNC = UINavigationController(rootViewController: settingsVC)
         settingsNC.modalPresentationStyle = .formSheet
-        self.present(settingsNC, animated: true)
+        present(settingsNC, animated: true)
     }
 
     func presentViewControllerForTunnelCreation(tunnelsManager: TunnelsManager, tunnelConfiguration: TunnelConfiguration?) {
         let editVC = TunnelEditTableViewController(tunnelsManager: tunnelsManager, tunnelConfiguration: tunnelConfiguration)
         let editNC = UINavigationController(rootViewController: editVC)
         editNC.modalPresentationStyle = .formSheet
-        self.present(editNC, animated: true)
+        present(editNC, animated: true)
     }
 
     func presentViewControllerForFileImport() {
         let documentTypes = ["com.wireguard.config.quick", String(kUTTypeText), String(kUTTypeZipArchive)]
         let filePicker = UIDocumentPickerViewController(documentTypes: documentTypes, in: .import)
         filePicker.delegate = self
-        self.present(filePicker, animated: true)
+        present(filePicker, animated: true)
     }
 
     func presentViewControllerForScanningQRCode() {
@@ -155,7 +157,7 @@ class TunnelsListTableViewController: UIViewController {
         scanQRCodeVC.delegate = self
         let scanQRCodeNC = UINavigationController(rootViewController: scanQRCodeVC)
         scanQRCodeNC.modalPresentationStyle = .fullScreen
-        self.present(scanQRCodeNC, animated: true)
+        present(scanQRCodeNC, animated: true)
     }
 
     func importFromFile(url: URL, completionHandler: (() -> Void)?) {
index e2588f82691b4dddadb80192298e3eb5c1bb1eb6..0bc791583554cc658207035bb514c88f6a52c3b3 100644 (file)
@@ -33,7 +33,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
         let activationAttemptId = options?["activationAttemptId"] as? String
         let errorNotifier = ErrorNotifier(activationAttemptId: activationAttemptId, tunnelProvider: self)
 
-        guard let tunnelProviderProtocol = self.protocolConfiguration as? NETunnelProviderProtocol,
+        guard let tunnelProviderProtocol = protocolConfiguration as? NETunnelProviderProtocol,
             let tunnelConfiguration = tunnelProviderProtocol.tunnelConfiguration() else {
                 errorNotifier.notify(PacketTunnelProviderError.savedProtocolConfigurationIsInvalid)
                 startTunnelCompletionHandler(PacketTunnelProviderError.savedProtocolConfigurationIsInvalid)