// AppDelegate.swift — Flutter ↔ 原生通道注册 // // 通道契约(见 lib/bridge/vpn_bridge.dart 头部注释): // MethodChannel : pangolin/vpn // EventChannel : pangolin/vpn/status → VpnStatusStreamHandler // EventChannel : pangolin/vpn/stats → VpnStatsStreamHandler // // VpnManager.shared 持有 NETunnelProviderManager 与 NEVPNStatus 订阅。 import UIKit import Flutter import NetworkExtension @main @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { GeneratedPluginRegistrant.register(with: self) guard let controller = window?.rootViewController as? FlutterViewController else { return super.application(application, didFinishLaunchingWithOptions: launchOptions) } let messenger = controller.binaryMessenger // ── MethodChannel ──────────────────────────────────────── let vpnChannel = FlutterMethodChannel(name: "pangolin/vpn", binaryMessenger: messenger) vpnChannel.setMethodCallHandler { [weak self] call, result in self?.handleVpnMethod(call: call, result: result) } // ── EventChannel: status ───────────────────────────────── FlutterEventChannel(name: "pangolin/vpn/status", binaryMessenger: messenger) .setStreamHandler(VpnStatusStreamHandler.shared) // ── EventChannel: stats ────────────────────────────────── FlutterEventChannel(name: "pangolin/vpn/stats", binaryMessenger: messenger) .setStreamHandler(VpnStatsStreamHandler.shared) // 预加载 VPN 偏好设置(首次为空,静默失败) VpnManager.shared.loadFromPreferences { error in if let error = error { NSLog("VpnManager: loadFromPreferences error: %@", error.localizedDescription) } } return super.application(application, didFinishLaunchingWithOptions: launchOptions) } // ── MethodChannel handler ───────────────────────────────────── private func handleVpnMethod(call: FlutterMethodCall, result: @escaping FlutterResult) { switch call.method { case "start": let configJson = call.arguments as? String ?? "{}" VpnManager.shared.start(configJson: configJson) { error in if let error = error { result(FlutterError( code: "START_FAILED", message: error.localizedDescription, details: nil )) } else { result(nil) } } case "stop": VpnManager.shared.stop() result(nil) case "getStatus": result(VpnManager.shared.statusString) case "selectOutbound": let tag = call.arguments as? String ?? "auto" NSLog("VPN: selectOutbound tag=%@", tag) // TODO(11F): sendProviderMessage → PacketTunnelProvider outbound selector result(nil) case "getActiveOutbound": // TODO(11F): query from PacketTunnelProvider via sendProviderMessage result("auto") case "setKillSwitch": let on = call.arguments as? Bool ?? false NSLog("VPN: setKillSwitch on=%d", on ? 1 : 0) // TODO(11F): 通过 include/excludeRoutes 实现 Kill Switch result(nil) default: result(FlutterMethodNotImplemented) } } }