Lets a native-call user share their iPhone screen (whole device, works
backgrounded). LiveKit 2.15.3 ships the broadcast stack (BroadcastManager +
LKSampleHandler + IPC), so:
- New Broadcast Upload Extension target "BroadcastExtension"
(com.bizgaze.connect.broadcast): SampleHandler.swift subclasses
LKSampleHandler; injected by mobile/scripts/add-broadcast-extension.rb
which also LINKS the LiveKit SPM product into the extension + sets the
App Group. Sources in mobile/ios-broadcast/.
- Plugin: Room created with ScreenShareCaptureOptions(useBroadcastExtension:
true); startScreenShare -> BroadcastManager.requestActivation() (system
picker); stopScreenShare -> requestStop(); BroadcastManagerDelegate ->
fires screenShareState to the web. LiveKit auto-publishes the track.
- ios-patch.sh: RTCScreenSharingExtension + RTCAppGroupIdentifier keys.
- codemagic.yaml: run the injector + sign the 3rd bundle id (.broadcast).
- home.html: toggleScreen native -> start/stop; screenShareState listener
reflects state + broadcasts meeting-screen so peers' stage shows it.
REQUIRES a one-time manual Apple portal step: enable the App Group on the
com.bizgaze.connect.broadcast App ID (see mobile/IOS_SETUP.md) or the
archive fails code-signing. SPM-linked extension is new on our CI — expect
build iteration. Web deployed (no-ops on builds without startScreenShare).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The @capacitor/push-notifications plugin does not add the Push Notifications
capability to the CI-generated Xcode project (that's a manual Xcode step), and
add-share-extension.rb only merged the App Group into App.entitlements, assuming
aps-environment was already there. It never was — so on device PushNotifications.
register() failed with 'no valid aps-environment entitlement', no APNs token was
obtained, and device_tokens stayed empty (server had nothing to push to).
ios-patch.sh now creates App/App.entitlements with aps-environment=production
before the share-extension script merges the App Group in. Still requires the App
ID to have Push Notifications enabled (so the profile carries the entitlement) and
the server APNS_* key set (Step 5) for end-to-end delivery.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds the reverse direction: share FROM Photos/Files/Safari INTO a Biz Connect
conversation. An app can only appear in the iOS share sheet as an app-extension
target, so this is real native work, not a web change.
Pieces:
- mobile/ios-share/ShareViewController.swift: a UI-less Share Extension. It stages
the shared items into the App Group container and opens bizconnect://share. It
deliberately does NOT reimplement the chat picker — that lives in the app, which
already has the chat list, search and upload progress. Appends to the manifest
(never overwrites), so sharing twice before opening the app loses nothing.
- mobile/scripts/add-share-extension.rb: injects the extension target into the
Capacitor-generated Xcode project on every CI build (Codemagic checks out fresh),
using the xcodeproj gem that ships with CocoaPods. Embeds it, sets the bundle id
<app>.share, and MERGES the App Group into the app's entitlements rather than
clobbering them (push's aps-environment must survive). Idempotent.
- mobile/plugins/share-inbox: getPending()/clear() to read that manifest — the App
Group container isn't one of Filesystem's known directories, so it needs a bridge.
- home.html: on bizconnect://share (and every resume, and cold-launch), read the
inbox and show a "Send to…" picker over the chat list; chosen files run the SAME
upload + /api/messages send as an in-app attachment. Reuses convertFileSrc to read
the staged bytes with no base64 marshalling.
- ios-patch.sh registers the bizconnect URL scheme; codemagic.yaml fetches a profile
for the .share bundle id too.
One-time manual gate (CI cannot toggle App capabilities): the App Group
group.com.bizgaze.connect must be created and enabled on both App IDs in the Apple
portal — documented in mobile/IOS_SETUP.md. Without it the two processes can't see
each other's files and sharing silently no-ops; everything else still works.
Validated cross-file: pod-name/jsName/method wiring for all three plugins, App
Group id identical in all 4 files, URL scheme consistent across extension/plist/web,
entitlement-merge preserves push. Needs a new iOS build (new targets + plugins).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Accessory bar: call Keyboard.setAccessoryBarVisible({isVisible:false}) on iOS in the native
IIFE, hiding the grey chevrons+Done strip above the keyboard. The plugin is already bundled
in the current TestFlight build, so this takes effect on a web deploy — no rebuild.
- Attach: tapping the paperclip now opens a composer-anchored Photos/Camera/Document menu
(like the emoji/mention popups) instead of firing the generic mid-screen OS chooser as the
first thing. Each option opens a type-scoped picker (image/*, capture). Web fix, all clients.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
iOS WebViews don't support getDisplayMedia, so sharing the device screen into a meeting needs a
native ReplayKit Broadcast Upload Extension (+ App Groups) — viewing a shared screen works today.
Also note native audio routing (AVAudioSession) as a phase-2 plugin. Adjusted the App Review note
so we don't advertise iOS screen-sharing before that extension ships.
The iOS app is a Capacitor shell over the live web UI — the web/server side is already fully
Capacitor-ready (nativePlatform() detects Capacitor; setupNativePush registers APNs tokens via
/api/v1/devices; the APNs sender is built into server/push.js, config-gated). So this adds only
the build/sign/upload path:
- codemagic.yaml: macOS-cloud workflow that generates the iOS project, patches Info.plist,
generates icons/splash, signs via an App Store Connect API key (automatic signing), archives,
and uploads to TestFlight. No Mac required.
- mobile/scripts/ios-patch.sh: adds the App-Review privacy usage strings (camera/mic/photos) +
display name to the generated Info.plist.
- mobile/IOS_SETUP.md: click-by-click runbook — ASC app record, API key, Codemagic integration,
first build, APNs key → server .env, and the public-submission checklist.
Bundle id com.bizgaze.connect. No secrets committed — Apple keys live in Codemagic + server .env.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>