diff --git a/ios/App/WebTerm/WebTerm.entitlements b/ios/App/WebTerm/WebTerm.entitlements new file mode 100644 index 0000000..5b04ea2 --- /dev/null +++ b/ios/App/WebTerm/WebTerm.entitlements @@ -0,0 +1,28 @@ + + + + + + aps-environment + development + + diff --git a/ios/project.yml b/ios/project.yml index 0ec6c85..0c0955e 100644 --- a/ios/project.yml +++ b/ios/project.yml @@ -21,6 +21,18 @@ settings: IPHONEOS_DEPLOYMENT_TARGET: "17.0" TARGETED_DEVICE_FAMILY: "1,2" # iPhone + iPad (T-iPad-1; adaptive layout) CODE_SIGN_STYLE: Automatic + # Free personal Apple team (O="Yaojia Wang"). Required for ANY device build: + # without it xcodebuild stops at 'Signing for "WebTerm" requires a + # development team'. Not a secret — a Team ID is public in every signed ipa. + DEVELOPMENT_TEAM: C738Z66SRW + # Default for the opt-in push-entitlements switch (A1). Empty ⇒ the target's + # CODE_SIGN_ENTITLEMENTS = "${WEBTERM_PUSH_ENTITLEMENTS}" resolves to nothing + # and no entitlements file is signed in. Declaring the default HERE (rather + # than relying on the setting being undefined) keeps the switch strictly + # generate-time: a project-level build setting outranks the build-time + # process environment, so an exported shell var can never silently attach + # entitlements to a build generated without it. + WEBTERM_PUSH_ENTITLEMENTS: "" packages: WireProtocol: @@ -37,16 +49,33 @@ packages: path: Packages/TestSupport # test doubles — WebTermTests only, never the app target # SwiftTerm is the ONLY third-party dependency, attached to the App target # ONLY (plan §2) — packages must never import it. + # + # PINNED, not floating (`from:`). The generated .xcodeproj — and with it + # Package.resolved, which lives inside the bundle — is gitignored, so every + # agent/CI run re-resolves from scratch: `from: 1.13.0` silently drifted to + # 1.15.0 and broke the App target, because SwiftTerm v1.14.0 added + # `public var hasActiveSelection` to iOSTerminalView, colliding with the + # same-named property TerminalScreen.swift:328 declares on its subclass + # (`error: overriding non-open property outside of its defining module` — + # unfixable with `override`, since SwiftTerm's is public, not open). + # 1.13.0 is the newest tag whose API the current App source compiles against. + # To raise the pin: first drop TerminalScreen.swift's local + # `hasActiveSelection` and use SwiftTerm's public one (that file is owned by + # the terminal-screen task, not by project.yml). SwiftTerm: url: https://github.com/migueldeicaza/SwiftTerm - from: 1.13.0 + exactVersion: 1.13.0 targets: WebTerm: type: application platform: iOS sources: - - App/WebTerm + # The .entitlements file lives next to the sources but must never be + # bundled as a resource — it is signing input, not app content. + - path: App/WebTerm + excludes: + - WebTerm.entitlements dependencies: - package: WireProtocol - package: SessionCore @@ -57,6 +86,21 @@ targets: settings: base: PRODUCT_BUNDLE_IDENTIFIER: com.yaojia.webterm + # XcodeGen's iOS-application preset injects Apple's DEPRECATED + # pre-Xcode-12 development identity string at target level (which + # outranks anything set in the project-level settings above), so it has + # to be overridden right here. "Apple Development" is the modern unified + # identity Xcode 12+ issues — it is what `security find-identity` + # actually holds, so the old string could only ever resolve by alias. + CODE_SIGN_IDENTITY: "Apple Development" + # OPT-IN push entitlements (frozen switch name WEBTERM_PUSH_ENTITLEMENTS). + # XcodeGen substitutes ${VAR} from the environment at `xcodegen generate` + # time when the var is SET, and leaves the literal placeholder when it is + # UNSET — the placeholder then resolves against the project-level + # WEBTERM_PUSH_ENTITLEMENTS: "" default, i.e. no entitlements. + # default (free team): xcodegen generate + # push on (paid team): WEBTERM_PUSH_ENTITLEMENTS=App/WebTerm/WebTerm.entitlements xcodegen generate + CODE_SIGN_ENTITLEMENTS: ${WEBTERM_PUSH_ENTITLEMENTS} # Target-level on purpose (T-iOS-19 finding): XcodeGen's target platform # default overrides a project-level value. iPad adaptation (T-iPad-1) # opens this to iPhone + iPad; the adaptive layout (LayoutPolicy / @@ -105,6 +149,17 @@ targets: NSExceptionAllowsInsecureHTTPLoads: true NSLocalNetworkUsageDescription: "连接你自己电脑上的 web-terminal 服务器" NSCameraUsageDescription: "扫描 web 终端的配对二维码" + # Voice push-to-talk (T-iOS-31, P2). Both keys are mandatory before the + # feature ships: missing either one = TCC crash the moment PTT is pressed. + # Added here by A1 because project.yml has a single owner. + NSMicrophoneUsageDescription: "按住说话,把你的口述录成终端输入" + NSSpeechRecognitionUsageDescription: "把你的口述转成文字,你确认后才送进终端" + # Silent APNs wake so a hook notification can be processed without the + # app in the foreground (T-iOS-21). A background MODE is not an Apple + # capability, so it is unconditional and safe on the free team — unlike + # the aps-environment ENTITLEMENT, which stays opt-in (see above). + UIBackgroundModes: + - remote-notification # Unit-test bundle for App-target logic (ViewModels & pure UI components, # W3 T-iOS-11…14). Added by the orchestrator as a coordination point