99 lines
3.0 KiB
Swift
99 lines
3.0 KiB
Swift
//
|
||
// VPNManager.swift
|
||
// sdlan
|
||
//
|
||
// Created by 安礼成 on 2024/1/17.
|
||
//
|
||
|
||
import Foundation
|
||
import NetworkExtension
|
||
import SwiftUI
|
||
|
||
// vpn管理类
|
||
class VPNManager: ObservableObject {
|
||
static let shared = VPNManager()
|
||
|
||
@Published var vpnStatus: VPNStatus = .disconnected
|
||
@Published var title: String = "启动"
|
||
@Published var color: Color = .white
|
||
|
||
enum VPNStatus {
|
||
case connected
|
||
case disconnected
|
||
}
|
||
|
||
private init() {
|
||
|
||
}
|
||
|
||
// 开启vpn
|
||
func enableVpn(options: [String : NSObject]? = nil) async throws {
|
||
let manager = try await loadAndCreateProviderManager()
|
||
try await manager.loadFromPreferences()
|
||
self.addVPNStatusObserver(manager)
|
||
|
||
try manager.connection.startVPNTunnel(options: options)
|
||
}
|
||
|
||
// 关闭vpn
|
||
func disableVpn() async throws {
|
||
let managers = try await NETunnelProviderManager.loadAllFromPreferences()
|
||
managers.first?.connection.stopVPNTunnel()
|
||
}
|
||
|
||
// MARK: - Private Methods
|
||
|
||
// 监控系统VPN的状态的变化
|
||
private func addVPNStatusObserver(_ manager: NETunnelProviderManager) {
|
||
NotificationCenter.default.removeObserver(self)
|
||
|
||
NotificationCenter.default.addObserver(forName: .NEVPNStatusDidChange, object: manager.connection, queue: .main) { [unowned self] (notification) -> Void in
|
||
// 更新vpn的状态
|
||
switch manager.connection.status {
|
||
case .invalid, .disconnected, .disconnecting:
|
||
self.vpnStatus = .disconnected
|
||
self.title = "启动"
|
||
self.color = .white
|
||
case .connecting, .connected, .reasserting:
|
||
self.vpnStatus = .connected
|
||
self.title = "停止"
|
||
self.color = .red
|
||
@unknown default:
|
||
self.vpnStatus = .disconnected
|
||
self.title = "启动"
|
||
self.color = .red
|
||
}
|
||
}
|
||
}
|
||
|
||
// MARK: - Private Methods
|
||
|
||
// 加载或者创建相关的配置
|
||
private func loadAndCreateProviderManager() async throws -> NETunnelProviderManager {
|
||
let managers = try await NETunnelProviderManager.loadAllFromPreferences()
|
||
|
||
let manager = managers.first ?? NETunnelProviderManager()
|
||
manager.localizedDescription = "punchnet"
|
||
manager.isEnabled = true
|
||
|
||
// 设置相关参数,在PacketTunnel中可以用
|
||
let protocolConfiguration = NETunnelProviderProtocol()
|
||
protocolConfiguration.serverAddress = "punchnet"
|
||
protocolConfiguration.providerConfiguration = [String:AnyObject]()
|
||
protocolConfiguration.providerBundleIdentifier = "com.jihe.punchnet.Tun"
|
||
manager.protocolConfiguration = protocolConfiguration
|
||
manager.isOnDemandEnabled = false
|
||
|
||
manager.isEnabled = true
|
||
|
||
try await manager.saveToPreferences()
|
||
|
||
return manager
|
||
}
|
||
|
||
deinit {
|
||
NotificationCenter.default.removeObserver(self)
|
||
}
|
||
|
||
}
|