feat(client/ios): 实时统计+urltest 延迟与 macOS 对齐 + 修 pbxproj UUID 冲突

把 macOS 已验证的统计架构移植到 iOS,补齐连接页延迟(此前 iOS 同 macOS 根因:扩展没注入
clash_api + app 单 client Status+Group → urltest 恒空):
- 扩展 PacketTunnelProvider:加 injectClashApi(clash_api+cache_file)+ 进程内 StatsCollector
  (libbox 取速率 + clash /proxies、/group/delay 取 urltest);handleAppMessage 增 action="stats"。
- app StatsClient:改为每秒 sendProviderMessage("stats") 拉取 → VpnStatsStreamHandler 推送,
  去掉直连 socket 的单 client Status+Group 坏写法。

修两处编译阻断(框架补齐后才暴露,此前 iOS 从未编译到这步):
- pbxproj 致命 bug:StatsClient.swift 与 PacketTunnelProvider.swift 复用同一 UUID
  (...0002...AA/AB),Xcode 无法区分 → 文件错配 target、全模块 cannot-find 级联。
  PacketTunnelProvider.swift 改用独立 ...0007... ID。
- tunFd 的 CTLIOCGINFO 单行 | 链拆成子表达式,避免 Swift 类型检查器超时。

前置:scripts/build-libbox.sh apple ios 生成 client/ios/Frameworks/Libbox.xcframework(gitignore)。
Dart 侧无需改(iOS 同走 VpnNativeBridge,本轮 macOS 的广播流/_onStats 回退/连接态跳直连实测已共享)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
wangjia
2026-06-30 19:12:28 +08:00
parent 7add0259b4
commit ae5d497f0b
3 changed files with 271 additions and 153 deletions
+4 -4
View File
@@ -16,7 +16,7 @@
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
CAFE000000000001000000AB /* VpnManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAFE000000000001000000AA /* VpnManager.swift */; };
CAFE000000000002000000AB /* StatsClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAFE000000000002000000AA /* StatsClient.swift */; };
CAFE000000000002000000AB /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAFE000000000002000000AA /* PacketTunnelProvider.swift */; };
CAFE000000000007000000AB /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAFE000000000007000000AA /* PacketTunnelProvider.swift */; };
CAFE000000000004000000AB /* PacketTunnel.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = CAFE000000000004000000AA /* PacketTunnel.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
CAFE000000000006000000AC /* MemoryMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAFE000000000006000000AB /* MemoryMonitor.swift */; };
CAFE000000000081000000AB /* Libbox.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = CAFE000000000081000000AA /* Libbox.xcframework */; };
@@ -80,7 +80,7 @@
C890E0E50FB9E2909B5EA7B8 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
CAFE000000000001000000AA /* VpnManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VpnManager.swift; sourceTree = "<group>"; };
CAFE000000000002000000AA /* StatsClient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatsClient.swift; sourceTree = "<group>"; };
CAFE000000000002000000AA /* PacketTunnelProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PacketTunnelProvider.swift; sourceTree = "<group>"; };
CAFE000000000007000000AA /* PacketTunnelProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PacketTunnelProvider.swift; sourceTree = "<group>"; };
CAFE000000000003000000AA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
CAFE000000000004000000AA /* PacketTunnel.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = PacketTunnel.appex; sourceTree = BUILT_PRODUCTS_DIR; };
CAFE000000000005000000AA /* Runner.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
@@ -203,7 +203,7 @@
CAFE000000000020000000AA /* PacketTunnel */ = {
isa = PBXGroup;
children = (
CAFE000000000002000000AA /* PacketTunnelProvider.swift */,
CAFE000000000007000000AA /* PacketTunnelProvider.swift */,
CAFE000000000006000000AB /* MemoryMonitor.swift */,
CAFE000000000006000000AA /* PacketTunnel.entitlements */,
CAFE000000000003000000AA /* Info.plist */,
@@ -408,7 +408,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CAFE000000000002000000AB /* PacketTunnelProvider.swift in Sources */,
CAFE000000000007000000AB /* PacketTunnelProvider.swift in Sources */,
CAFE000000000006000000AC /* MemoryMonitor.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;