解决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 NetworkExtension
import SwiftUI
import Observation
// vpn
@Observable
class VPNManager {
static let shared = VPNManager()
private var observation: NSKeyValueObservation?
private var manager: NETunnelProviderManager?
private var statusObserver: NSObjectProtocol?
var vpnStatus: VPNStatus = .disconnected
enum VPNStatus {
@ -30,26 +34,34 @@ class VPNManager {
NSLog("enable vpn with options: \(options)")
let manager = try await loadAndCreateProviderManager()
try await manager.loadFromPreferences()
self.addVPNStatusObserver(manager)
self.manager = manager
self.addVPNStatusObserver(manager)
try manager.connection.startVPNTunnel(options: options)
}
// vpn
func disableVpn() async throws {
let managers = try await NETunnelProviderManager.loadAllFromPreferences()
managers.first?.connection.stopVPNTunnel()
guard let manager = self.manager else {
return
}
try await manager.loadFromPreferences()
manager.connection.stopVPNTunnel()
}
// MARK: - Private Methods
// VPN
private func addVPNStatusObserver(_ manager: NETunnelProviderManager) {
self.observation = manager.connection.observe(\.status, options: [.initial, .new]) {[weak self] connection, change in
guard let status = change.newValue else {
return
}
switch status {
if let statusObserver {
NotificationCenter.default.removeObserver(statusObserver)
self.statusObserver = nil
}
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:
self?.vpnStatus = .disconnected
case .connecting, .connected, .reasserting:
@ -86,7 +98,9 @@ class VPNManager {
}
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 isOn: Bool = false
@State private var vpnManager: VPNManager = VPNManager.shared
//
enum ShowMode {
@ -93,7 +94,8 @@ struct NetworkView: View {
}
.padding(.top, 10)
.padding(.leading, 10)
.onChange(of: VPNManager.shared.vpnStatus) { _, newState in
.onChange(of: vpnManager.vpnStatus) { _, newState in
NSLog("print view change: \(newState)")
switch newState {
case .connected:
self.connectState = .connected