react-native-callkeep

repository·master·Indexed 21 days ago

https://github.com/react-native-webrtc/react-native-callkeep

A React Native bridge to iOS CallKit and Android ConnectionService Framework. It allows VoIP developers to integrate calls into the system's native calling UI, manage call states, and handle call lifecycle events such as answering, ending, and muting calls. Supports Android Self Managed mode for custom in-call UIs and requires real devices for testing as it does not work on simulators.

Tokens
12.9K
Snippets
45
Records
54
Agent score
76%

What's inside react-native-callkeep

  1. Implement Android Self Managed Mode

    master

    Self Managed mode allows your app to provide its own UI for managing calls (in-call UI and incoming call notifications). This is an 'all or nothing' approach.

    Implementation Steps:

    1. Set selfManaged: true in the setup options.
    2. Add <uses-permission android:name="android.permission.READ_CALL_LOG" /> to your android/src/main/AndroidManifest.xml.
    3. On an incoming call, call RNCallKeep.displayIncomingCall from React Native.
    4. Listen for the showIncomingCallUi event. When fired, you must show a high-priority incoming call UI (e.g., a high-priority notification).
    5. If the user answers, call answerCall or endCall via RNCallKeep.
    6. If Android prevents showing the notification, the createIncomingConnectionFailed event will fire; you should then reject the incoming SIP Invite.

    Best Practices:

    • Use React Native Headless Tasks to execute code in the background, ensuring they start as a Foreground Service.
    • Avoid flooding users with sticky notifications by managing your own Foreground Service instead of defining one in the CallKeep setup options.
    <!-- Required for Self Managed mode in android/src/main/AndroidManifest.xml -->
    <uses-permission android:name="android.permission.READ_CALL_LOG" />
  2. Handle Early iOS Events with didLoadWithEvents

    master

    On iOS, if a user interacts with a call (answers or ends it) while the app is in a killed state (before the JS bridge is initialized), those actions are lost unless you use didLoadWithEvents.

    This event acts as a cache that propagates native events that occurred before the JS context was ready. To use this reliably, you must perform setup in your AppDelegate.m.

    Note: This is a helper for early events; you must still subscribe to all other standard events normally.

    // Register this early in your app
    RNCallKeep.addEventListener('didLoadWithEvents', (events) => {
      // events is an Array of objects:
      // { name: string, data: object }
      // Example: { name: 'RNCallKeepPerformAnswerCallAction', data: { callUUID: '...' } }
      events.forEach(event => {
        // handle or ignore based on app logic
      });
    });
  3. Handle background calls with HeadlessTask in index.android.js

    master

    When using RNCallKeepBackgroundMessagingService to wake up a killed application, you must register a headless task in your index.android.js file to handle the incoming background message. The task receives an object containing name, callUUID, and handle.

    // index.android.js
    AppRegistry.registerHeadlessTask('RNCallKeepBackgroundMessage', () => ({ name, callUUID, handle }) => {
      // Make your call here
      
      return Promise.resolve();
    });
  4. Configure PushKit for incoming calls on iOS

    master

    Since iOS 13, you must report incoming calls that wake up your application via a VoIP push. In your AppDelegate.m, use RNCallKeep.reportNewIncomingCall within the didReceiveIncomingPushWithPayload method to register the call with the system.

    - (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(PKPushType)type withCompletionHandler:(void (^)(void))completion {
      // Process the received push
      [RNVoipPushNotificationManager didReceiveIncomingPushWithPayload:payload forType:(NSString *)type];
    
      // Retrieve information like handle and callerName here
      // NSString *uuid = ...
      // NSString *callerName = ...
      // NSDictionary *extra = ...
    
      [RNCallKeep reportNewIncomingCall: uuid
                                 handle: handle
                             handleType: @"generic"
                               hasVideo: NO
                    localizedCallerName: callerName
                        supportsHolding: YES
                           supportsDTMF: YES
                       supportsGrouping: YES
                            supportsUngrouping: YES
                                fromPushKit: YES
                                    payload: extra
                      withCompletionHandler: completion];
    }
  5. Configure iOS build settings and background modes

    master

    After adding the library, you must perform these additional configuration steps to ensure the library functions correctly:

    In Xcode, under Build Phases > Link Binary With Libraries, add the following frameworks and mark them as Optional:

    • CallKit.framework
    • Intents.framework

    2. Add header search path

    In Xcode, go to the Build Settings tab, search for Header Search Paths, and add: $(SRCROOT)/../node_modules/react-native-callkeep/ios/RNCallKeep

    3. Enable VoIP background mode

    To allow the app to handle calls in the background, add the voip string to the UIBackgroundModes key in your Info.plist file.

    <key>UIBackgroundModes</key>
    <array>
      <string>voip</string>
    </array>
  6. Install and run the CallKeep example project

    master

    To set up and run the provided example project, follow these steps:

    1. Install dependencies: Run yarn install in the root directory, then navigate to the ios folder and run pod install.
    2. Start Metro Bundler: Run yarn start to launch the bundler.
    3. Launch the application: In a separate terminal, run yarn android or yarn ios to build and run the app on your device or emulator.
    # Install dependencies
    yarn install
    
    cd ios
    pod install
    
    # Start metro bundler
    yarn start
    
    # Start the application
    yarn android # or yarn ios