解决view的状态变化问题

This commit is contained in:
anlicheng 2026-03-03 15:19:12 +08:00
parent e2cbaff567
commit 5004c0daef
2 changed files with 27 additions and 11 deletions

View File

@ -8,12 +8,16 @@
import Foundation import Foundation
import NetworkExtension import NetworkExtension
import SwiftUI import SwiftUI
import Observation
// vpn // vpn
@Observable
class VPNManager { class VPNManager {
static let shared = VPNManager() static let shared = VPNManager()
private var observation: NSKeyValueObservation? private var manager: NETunnelProviderManager?
private var statusObserver: NSObjectProtocol?
var vpnStatus: VPNStatus = .disconnected var vpnStatus: VPNStatus = .disconnected
enum VPNStatus { enum VPNStatus {
@ -30,26 +34,34 @@ class VPNManager {
NSLog("enable vpn with options: \(options)") NSLog("enable vpn with options: \(options)")
let manager = try await loadAndCreateProviderManager() let manager = try await loadAndCreateProviderManager()
try await manager.loadFromPreferences() try await manager.loadFromPreferences()
self.addVPNStatusObserver(manager) self.manager = manager
self.addVPNStatusObserver(manager)
try manager.connection.startVPNTunnel(options: options) try manager.connection.startVPNTunnel(options: options)
} }
// vpn // vpn
func disableVpn() async throws { func disableVpn() async throws {
let managers = try await NETunnelProviderManager.loadAllFromPreferences() guard let manager = self.manager else {
managers.first?.connection.stopVPNTunnel() return
}
try await manager.loadFromPreferences()
manager.connection.stopVPNTunnel()
} }
// MARK: - Private Methods // MARK: - Private Methods
// VPN // VPN
private func addVPNStatusObserver(_ manager: NETunnelProviderManager) { private func addVPNStatusObserver(_ manager: NETunnelProviderManager) {
self.observation = manager.connection.observe(\.status, options: [.initial, .new]) {[weak self] connection, change in if let statusObserver {
guard let status = change.newValue else { NotificationCenter.default.removeObserver(statusObserver)
return self.statusObserver = nil
} }
switch status {
self.statusObserver = NotificationCenter.default.addObserver(forName: .NEVPNStatusDidChange, object: manager.connection, queue: .main) {[weak self] _ in
NSLog("status channge: \(manager.connection.status)")
switch manager.connection.status {
case .invalid, .disconnected, .disconnecting: case .invalid, .disconnected, .disconnecting:
self?.vpnStatus = .disconnected self?.vpnStatus = .disconnected
case .connecting, .connected, .reasserting: case .connecting, .connected, .reasserting:
@ -86,7 +98,9 @@ class VPNManager {
} }
deinit { deinit {
NotificationCenter.default.removeObserver(self) if let statusObserver {
NotificationCenter.default.removeObserver(statusObserver)
}
} }
} }

View File

@ -22,6 +22,7 @@ struct NetworkView: View {
// //
@State private var connectState: ConnectState = .disconnected @State private var connectState: ConnectState = .disconnected
@State private var isOn: Bool = false @State private var isOn: Bool = false
@State private var vpnManager: VPNManager = VPNManager.shared
// //
enum ShowMode { enum ShowMode {
@ -93,7 +94,8 @@ struct NetworkView: View {
} }
.padding(.top, 10) .padding(.top, 10)
.padding(.leading, 10) .padding(.leading, 10)
.onChange(of: VPNManager.shared.vpnStatus) { _, newState in .onChange(of: vpnManager.vpnStatus) { _, newState in
NSLog("print view change: \(newState)")
switch newState { switch newState {
case .connected: case .connected:
self.connectState = .connected self.connectState = .connected