From c2151451235d64b3c56ff7a264be1c04f8d5642f Mon Sep 17 00:00:00 2001 From: anlicheng <244108715@qq.com> Date: Fri, 3 Apr 2026 17:29:26 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=B3=BB=E7=BB=9F=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E9=80=9A=E7=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Tun/PacketTunnelProvider.swift | 5 + punchnet/Core/DarwinNotificationCenter.swift | 112 +++++++++++++++++++ punchnet/punchnetApp.swift | 4 + 3 files changed, 121 insertions(+) create mode 100644 punchnet/Core/DarwinNotificationCenter.swift diff --git a/Tun/PacketTunnelProvider.swift b/Tun/PacketTunnelProvider.swift index eff3c7b..c1e90c0 100644 --- a/Tun/PacketTunnelProvider.swift +++ b/Tun/PacketTunnelProvider.swift @@ -17,6 +17,11 @@ class PacketTunnelProvider: NEPacketTunnelProvider { private var rootTask: Task? override func startTunnel(options: [String: NSObject]?, completionHandler: @escaping (Error?) -> Void) { + + let shared = UserDefaults(suiteName: "group.com.jihe.punchnetmac") + let msg = shared?.string(forKey: "test_msg") + SDLLogger.shared.log("NE read message: \(msg ?? "failed")") + // host: "192.168.0.101", port: 1265 guard let options, let config = SDLConfiguration.parse(options: options) else { completionHandler(TunnelError.invalidConfiguration) diff --git a/punchnet/Core/DarwinNotificationCenter.swift b/punchnet/Core/DarwinNotificationCenter.swift new file mode 100644 index 0000000..02b3af4 --- /dev/null +++ b/punchnet/Core/DarwinNotificationCenter.swift @@ -0,0 +1,112 @@ +// +// DarwinNotificationName.swift +// punchnet +// +// Created by 安礼成 on 2026/4/3. +// +import Foundation + +// MARK: - Darwin Notification Name +public struct DarwinNotificationName: RawRepresentable, Hashable { + public let rawValue: String + + public init(rawValue: String) { + self.rawValue = rawValue + } +} + +// 预定义名称 +extension DarwinNotificationName { + static let vpnStatusChanged = DarwinNotificationName(rawValue: "com.jihe.punchnetmac.vpnStatusChanged") +} + + +// MARK: - Manager +public final class DarwinNotificationCenter { + public static let shared = DarwinNotificationCenter() + + private let center = CFNotificationCenterGetDarwinNotifyCenter() + + private var observers: [DarwinNotificationName: (DarwinNotificationName) -> Void] = [:] + private let lock = NSLock() + + private init() {} + + // MARK: - Add Observer + public func addObserver(for name: DarwinNotificationName, queue: DispatchQueue = .main, using block: @escaping (DarwinNotificationName) -> Void ) { + lock.lock() + defer { + lock.unlock() + } + + if observers[name] == nil { + // 首次注册到 Darwin Center + CFNotificationCenterAddObserver( + center, + UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque()), + { (_, observer, cfName, _, _) in + guard let observer, let cfName else { + return + } + + let instance = Unmanaged + .fromOpaque(observer) + .takeUnretainedValue() + + let name = DarwinNotificationName(rawValue: cfName.rawValue as String) + instance.handle(name: name) + }, + name.rawValue as CFString, + nil, + .deliverImmediately + ) + + observers[name] = { n in + queue.async { + block(n) + } + } + } + + } + + // MARK: - Remove Observer + public func removeObserver(for name: DarwinNotificationName) { + lock.lock() + defer { + lock.unlock() + } + + if observers[name] != nil { + CFNotificationCenterRemoveObserver( + center, + UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque()), + CFNotificationName(name.rawValue as CFString), + nil + ) + } + observers.removeValue(forKey: name) + + } + + // MARK: - Post + public func post(_ name: DarwinNotificationName) { + CFNotificationCenterPostNotification( + center, + CFNotificationName(name.rawValue as CFString), + nil, + nil, + true + ) + } + + // MARK: - Handle + private func handle(name: DarwinNotificationName) { + lock.lock() + let block = observers[name] + lock.unlock() + + block?(name) + } + +} diff --git a/punchnet/punchnetApp.swift b/punchnet/punchnetApp.swift index b3386d7..1735a88 100644 --- a/punchnet/punchnetApp.swift +++ b/punchnet/punchnetApp.swift @@ -90,6 +90,10 @@ class AppDelegate: NSObject, NSApplicationDelegate { func applicationWillFinishLaunching(_ notification: Notification) { + let shared = UserDefaults(suiteName: "group.com.jihe.punchnetmac") + shared?.set("App says hello", forKey: "test_msg") + shared?.synchronize() + } func applicationShouldTerminate(_ sender: NSApplication) -> NSApplication.TerminateReply {