newnode icon indicating copy to clipboard operation
newnode copied to clipboard

iOS: Extract network extension management into a separate file

Open ailinykh opened this issue 2 years ago • 2 comments

This is the first step of the ViewController refactoring process described in #139

All the network extension stuff is now moved into a separate component and the ViewController's dependency graph changed from this

flowchart LR
    viewController --> UIViewController
    viewController --> UIButton
    viewController --> UIImageView
    viewController --> UILabel
    viewController --> UserDefaults
    viewController --> NotificationCenter
    viewController --> MMWormhole
    viewController --> NETunnelProviderManager
    viewController --> NWPathMonitor
    viewController --> NEVPNStatus

    subgraph User Iinterface
        UIButton
        UIImageView
        UILabel
        UIViewController
    end

    subgraph Infrastructure
        UserDefaults
        NotificationCenter
        MMWormhole
    end

    subgraph Networking
        NETunnelProviderManager
        NWPathMonitor
        NEVPNStatus
    end

to this:

flowchart RL
    viewController --> UIViewController
    viewController --> UIButton
    viewController --> UIImageView
    viewController --> UILabel
    viewController --> UserDefaults
    viewController --> NotificationCenter
    viewController --> MMWormhole

    TunnelManagerImpl --> NETunnelProviderManager
    TunnelManagerImpl --> NEVPNStatus
    TunnelManagerImpl -.-> TunnelManager["<TunnelManager>"]
    TunnelManagerDelegate --> TunnelManagerState
    viewController --> TunnelManager
    viewController --> TunnelManagerDelegate

    subgraph User Interface
        UIButton
        UIImageView
        UILabel
        UIViewController
    end

    subgraph Infrastructure
        UserDefaults
        NotificationCenter
        MMWormhole
    end

    subgraph Network Extension
        NETunnelProviderManager
        NWPathMonitor
        NEVPNStatus
    end

    subgraph NewNode
        TunnelManager
        TunnelManagerDelegate
        TunnelManagerState

        TunnelManagerImpl
    end

There are some benefits of this approach:

  • ViewController does not depend on NetworkExtension, the dependency inversion principle applied
  • TunnelManager can be shared between iOS/macOS platforms without any change
  • We can have multiple implementations for the TunnelManager protocol which allows us to focus on UI improvements on the simulator. Like so:
    private lazy var tunnelManager: TunnelManager = {
#if targetEnvironment(simulator)
        TunnelManagerSimulator(delegate: self)
#else
        TunnelManagerImpl(delegate: self)
#endif
    }()
  • No need to use NWPathMonitor since we can rely on NWConnection state
  • Fixed bug when the connection fails after another VPN enabled

ailinykh avatar Jan 02 '23 19:01 ailinykh