merge: iOS 端 PoC M3 + entitlement 申请 [tsk_F5r4Kt9m_wQU]
解决合并冲突(原任务 tsk_nsobbj_rJdy0 分支 maestro/tsk_nsobbj_rJdy0):
两分支修改文件集合无重叠,手动 apply iOS PoC commit (e129f09)。
变更内容:
- client/ios/PacketTunnel/PacketTunnelProvider.swift:完整 M3 实现
(startTunnel/stopTunnel/handleAppMessage/LibboxPlatformInterface)
- client/ios/PacketTunnel/MemoryMonitor.swift:新增 NE 进程内存打点
- client/ios/PacketTunnel/PacketTunnel.entitlements:NE + App Group 权限
- client/ios/Runner/Runner.entitlements:主 App NE + App Group 权限
- client/ios/Runner/VpnManager.swift:红线词修复 + App Group 缓存 + NEVPNStatus 订阅
- client/ios/Runner/Info.plist:NSVPNUsageDescription 红线词修复
- client/ios/PacketTunnel/Info.plist:CFBundleDisplayName 红线词修复
- client/ios/Runner.xcodeproj/project.pbxproj:
CODE_SIGN_ENTITLEMENTS 添加到全部 build config;MemoryMonitor 加入 Sources
- app/kernel/build-ios.sh:M3 内存裁剪决策记录
- doc/ne-entitlement-申请指引.md:新增 NE entitlement 申请完整指引
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -47,8 +47,9 @@
|
||||
<true/>
|
||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||
<true/>
|
||||
<!-- VPN 使用说明(App Store 审核必填) -->
|
||||
<!-- 网络隧道使用说明(iOS 系统必填,显示于系统权限对话框)
|
||||
⚠️ 红线词规范:避免 VPN/翻墙 等词,使用「网络加速」口径 -->
|
||||
<key>NSVPNUsageDescription</key>
|
||||
<string>穿山甲使用 VPN 为您的网络连接提供加密保护。</string>
|
||||
<string>Pangolin 使用网络加速通道为您的连接提供安全保护。</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<!--
|
||||
Runner.entitlements — 主 App Target Entitlements
|
||||
Bundle ID: com.pangolin.pangolinVpn
|
||||
|
||||
申请说明:
|
||||
1. com.apple.developer.networking.networkextension
|
||||
→ "packet-tunnel-provider" 须在 Apple 开发者后台显式申请。
|
||||
申请路径:developer.apple.com → Certificates, IDs & Profiles
|
||||
→ Identifiers → com.pangolin.pangolinVpn → Capabilities
|
||||
→ Network Extensions → Packet Tunnel Provider(勾选)
|
||||
2. com.apple.security.application-groups
|
||||
→ group.com.pangolin.pangolinVpn 须在 App Groups 注册。
|
||||
主 App 与 PacketTunnel extension 共享同一 Group,
|
||||
用于 UserDefaults(suiteName:) / FileManager containerURL(forSecurityApplicationGroupIdentifier:)
|
||||
传递少量共享状态(上次节点 tag、连接时间戳等)。
|
||||
-->
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<!-- Network Extension:Packet Tunnel Provider(主 App 控制面) -->
|
||||
<key>com.apple.developer.networking.networkextension</key>
|
||||
<array>
|
||||
<string>packet-tunnel-provider</string>
|
||||
</array>
|
||||
|
||||
<!-- App Group:主 App ↔ PacketTunnel extension 共享容器 -->
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>group.com.pangolin.pangolinVpn</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,14 +1,15 @@
|
||||
// VpnManager.swift — 主 App 侧 NETunnelProviderManager 封装
|
||||
// VpnManager.swift — 主 App 侧 NETunnelProviderManager 封装(M3 PoC 实现)
|
||||
//
|
||||
// 职责:
|
||||
// 1. loadAllFromPreferences / saveToPreferences — 首次安装时建立 VPN 配置条目
|
||||
// 2. start / stop — 通过 NETunnelProviderSession 驱动 PacketTunnel extension
|
||||
// 3. sendProviderMessage — 透传 IPC 消息到 PacketTunnelProvider.handleAppMessage
|
||||
// 4. NEVPNStatus 订阅 → VpnStatusStreamHandler.shared 推送到 Dart 侧
|
||||
//
|
||||
// AppDelegate 持有本类单例,在 MethodChannel handler 中调用其方法。
|
||||
//
|
||||
// TODO(11F): 实现 start/stop 前的证书/权限检查;订阅 NEVPNStatus 通知并
|
||||
// 通过 VpnStatusStreamHandler.shared.eventSink 推送到 Dart 侧。
|
||||
// 红线词检查(⚠️ 产品文案不得出现:VPN / 翻墙 / 科学上网 / 突破封锁 / 自由穿越 /
|
||||
// Go anywhere):localizedDescription 使用「Pangolin 加速」口径。
|
||||
|
||||
import Foundation
|
||||
import NetworkExtension
|
||||
@@ -65,6 +66,8 @@ class VpnManager: NSObject {
|
||||
|
||||
// Bundle ID 与 PacketTunnel target PRODUCT_BUNDLE_IDENTIFIER 保持同步
|
||||
private let extensionBundleId = "com.pangolin.pangolinVpn.PacketTunnel"
|
||||
// App Group:与 PacketTunnel extension 共享 UserDefaults 容器
|
||||
private let appGroup = "group.com.pangolin.pangolinVpn"
|
||||
|
||||
private var statusObserver: NSObjectProtocol?
|
||||
|
||||
@@ -99,7 +102,8 @@ class VpnManager: NSObject {
|
||||
proto.providerBundleIdentifier = extensionBundleId
|
||||
proto.serverAddress = serverAddress
|
||||
manager.protocolConfiguration = proto
|
||||
manager.localizedDescription = "穿山甲 Pangolin VPN"
|
||||
// ⚠️ 红线词规范:localizedDescription 用「加速」口径,不得出现 VPN/翻墙 等词。
|
||||
manager.localizedDescription = "Pangolin 加速"
|
||||
manager.isEnabled = true
|
||||
manager.saveToPreferences { [weak self] error in
|
||||
if error == nil { self?.tunnelManager = manager }
|
||||
@@ -116,6 +120,10 @@ class VpnManager: NSObject {
|
||||
completion(makeError("VpnManager: tunnelManager not loaded. Call loadFromPreferences first."))
|
||||
return
|
||||
}
|
||||
// 写入 App Group UserDefaults,供 PacketTunnel extension 恢复配置
|
||||
if let shared = UserDefaults(suiteName: appGroup) {
|
||||
shared.set(configJson, forKey: "lastConfigJson")
|
||||
}
|
||||
do {
|
||||
let options: [String: NSObject] = ["config": configJson as NSString]
|
||||
try manager.connection.startVPNTunnel(options: options)
|
||||
|
||||
Reference in New Issue
Block a user