@fishjam-cloud/ios-expo-voip
v0.29.0
Published
AppDelegate glue for Fishjam VoIP on iOS — registers PushKit at launch and routes Siri/Recents call intents. Install alongside @fishjam-cloud/react-native-client when VoIP options are enabled.
Readme
@fishjam-cloud/ios-expo-voip
iOS AppDelegate glue for Fishjam VoIP. Install it alongside
@fishjam-cloud/react-native-client when you enable VoIP options in the Fishjam config plugin.
It contains no JavaScript and no VoIP logic of its own — just an
ExpoAppDelegateSubscriber that forwards
two AppDelegate events into the Fishjam SDK:
didFinishLaunchingWithOptions→ starts the PushKit registry at launch, so VoIP pushes delivered before the JS bundle loads (cold start) can still report an incoming callapplication(_:continue:restorationHandler:)→ routes Siri and Phone-app Recents call intents (INStartCallIntent) into the SDK
Installation
npx expo install @fishjam-cloud/ios-expo-voipThat's it — Expo autolinking picks the module up during pod install. The subscriber only
activates when the FishjamVoIPEnabled Info.plist flag is present, which the
@fishjam-cloud/react-native-client config plugin writes automatically when voip options are
set. Apps that install this package without enabling VoIP get a no-op.
Also required: the aps-environment entitlement
This package arms PKPushRegistry at launch, but iOS only issues a VoIP token to an app that
declares the push entitlement. Without it registration silently never completes — no token, no
incoming calls — even though this subscriber ran correctly. Add it in app.json:
{
"expo": {
"ios": {
"entitlements": { "aps-environment": "development" }
}
}
}Use "production" for TestFlight / App Store builds, and make sure Push Notifications is
enabled for your App ID in the Apple Developer portal. VoIP pushes are never delivered to the
iOS Simulator; test on a real device.
Bare React Native (no Expo Modules)
If your app does not use ExpoAppDelegate, wire the two calls manually in your AppDelegate:
// in application(_:didFinishLaunchingWithOptions:)
VoIPManager.registerForVoIPPushes()
// in application(_:continue:restorationHandler:)
if VoIPManager.handleContinueUserActivity(userActivity) {
return true
}Android needs no equivalent — everything is handled declaratively via the manifest by the config plugin.
