flutter_callkit_voximplant 1.0.0

  • Readme
  • Changelog
  • Example
  • Installing
  • new77

flutter_callkit_voximplant #

Flutter SDK for CallKit integration to Flutter applications on iOS

Supported on iOS >= 10

Install #

  1. Add flutter_callkit_voximplant as a dependency in your pubspec.yaml file.

  2. Add the following entry to your Info.plist file, located in <project root>/ios/Runner/Info.plist:

<key>UIBackgroundModes</key>
<array>
	<string>voip</string>
</array>

This entry required for CallKit to work

Usage #

API of the SDK is designed as close as possible to CallKit iOS Framework.

CallKit documentation can be found here

A few differences explained:

  • Use reportNewIncomingCallWithUUID native iOS method of FlutterCallkitPlugin to report new incoming call received via VoIP push notification
  • Use FCXPlugin.didDisplayIncomingCall (dart) handle incoming call reported with reportNewIncomingCallWithUUID
  • Use FCXPlugin.logLevel (dart) to adjust logging
  • Use FCXPlugin.processPushCompletion (dart) to execute completion block received from push (iOS 11+ only)
  • FCXCallController and FCXProvider are only allowed in single instance (use it as a singletone)

Initialization

import 'package:flutter_callkit_voximplant/flutter_callkit_voximplant.dart';

// init main plugin class:
FCXPlugin _plugin = FCXPlugin();
// init main CallKit classes:
FCXProvider _provider = FCXProvider();
FCXCallController _callController = FCXCallController();
// at this point CallKit classes are not ready yet
// configure it to use:
try {
  await _callController.configure();
  await _provider.configure(FCXProviderConfiguration('ExampleLocalizedName'));
} catch (_) {
  // handle exception
}

Making outgoing calls

To make an outgoing call, an app requests a FCXStartCallAction object from its FCXCallController object. The action consists of a UUID to uniquely identify the call and a FCXHandle object to specify the recipient.

Future<void> makeCall(String contactName, String uuid) async {
  FCXHandle handle = FCXHandle(FCXHandleType.Generic, contactName);
  FCXStartCallAction action = FCXStartCallAction(uuid, handle);
  await _callController.requestTransactionWithAction(action);
}

After the recipient answers the call, the system calls the provider's performAnswerCallAction method. In your implementation of that method, configure an AVAudioSession and call the fulfill() method on the action object when finished.

_provider.performAnswerCallAction = (answerCallAction) async {
  // configure audio session
  await answerCallAction.fulfill();
};

Receiving an Incoming Call

Using the information provided by the external notification, the app creates a UUID and a CXCallUpdate object to uniquely identify the call and the caller, and passes them both to the provider using the reportNewIncomingCall() method.

Future<void> handleIncomingCall(String contactName, String uuid) async {
  FCXCallUpdate callUpdate = FCXCallUpdate(localizedCallerName: contactName);
  await _provider.reportNewIncomingCall(uuid, callUpdate);
}

After the call is connected, the system calls the performStartCallAction method of the provider. In your implementation, this method responsible for configuring an AVAudioSession and calling fulfill() on the action when finished.

_provider.performStartCallAction = (startCallAction) async {
  // configure audio session
  await startCallAction.fulfill();
};

Handling push notifications

Note: This SDK is not related to PushKit

Push handling must be done through native iOS code due to iOS 13 PushKit VoIP restrictions.

Flutter CallKit SDK has built-in reportNewIncomingCallWithUUID:callUpdate:providerConfiguration:pushProcessingCompletion:) method (iOS) to correctly work with it

#import <Flutter/Flutter.h>
#import <FlutterCallkitPlugin.h>
#import <PushKit/PushKit.h>
#import <CallKit/CallKit.h>

@interface AppDelegate : FlutterAppDelegate<PKPushRegistryDelegate>

@end

@implementation AppDelegate

// 1. override PKPushRegistryDelegate methods
- (void)             pushRegistry:(PKPushRegistry *)registry 
didReceiveIncomingPushWithPayload:(PKPushPayload *)payload 
                          forType:(PKPushType)type {
    [self processPushWithPayload:payload.dictionaryPayload 
            andCompletionHandler:nil];
}

- (void)             pushRegistry:(PKPushRegistry *)registry 
didReceiveIncomingPushWithPayload:(PKPushPayload *)payload
                          forType:(PKPushType)type 
            withCompletionHandler:(void (^)(void))completion {
    [self processPushWithPayload:payload.dictionaryPayload
            andCompletionHandler:completion];
}

// 2. process push
-(void)processPushWithPayload:(NSDictionary *)payload 
         andCompletionHandler:(dispatch_block_t)completion {
    // 3. get uuid and other needed information from payload
    NSUUID *UUID = [[NSUUID alloc] initWithUUIDString:payload[@"UUID"]];
    NSString *localizedName = payload[@"identifier"];
    // 4. prepare call update
    CXCallUpdate *callUpdate = [CXCallUpdate new];
    callUpdate.localizedCallerName = localizedName;
    // 5. prepare provider configuration
    CXProviderConfiguration *configuration = 
        [[CXProviderConfiguration alloc] 
              initWithLocalizedName:@"ExampleLocalizedName"];
    // 6. send it to plugin
    [FlutterCallkitPlugin reportNewIncomingCallWithUUID:UUID
                                             callUpdate:callUpdate
                                  providerConfiguration:configuration
                               pushProcessingCompletion:completion];
}
@end

At this point CallKit will be set up to handle incoming call and will present its UI.

didDisplayIncomingCall of FCXPlugin will be called in dart code.

Call processPushCompletion from dart code once call successfully connected.

1.0.0 #

Release

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter_callkit_example/screens/main_screen.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MaterialApp(
    title: 'FlutterCallKit',
    home: MainScreen(),
  ));
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  flutter_callkit_voximplant: ^1.0.0

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:flutter_callkit_voximplant/flutter_callkit_voximplant.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
54
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
77
Learn more about scoring.

We analyzed this package on Apr 7, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.7.1
  • pana: 0.13.6
  • Flutter: 1.12.13+hotfix.8

Health suggestions

Format lib/flutter_callkit_voximplant.dart.

Run flutter format to format lib/flutter_callkit_voximplant.dart.

Format lib/src/actions/action.dart.

Run flutter format to format lib/src/actions/action.dart.

Format lib/src/actions/answer_call_action.dart.

Run flutter format to format lib/src/actions/answer_call_action.dart.

Fix additional 16 files with analysis or formatting issues.

Additional issues in the following files:

  • lib/src/actions/call_action.dart (Run flutter format to format lib/src/actions/call_action.dart.)
  • lib/src/actions/end_call_action.dart (Run flutter format to format lib/src/actions/end_call_action.dart.)
  • lib/src/actions/play_dtmf_call_action.dart (Run flutter format to format lib/src/actions/play_dtmf_call_action.dart.)
  • lib/src/actions/set_group_call_action.dart (Run flutter format to format lib/src/actions/set_group_call_action.dart.)
  • lib/src/actions/set_held_call_action.dart (Run flutter format to format lib/src/actions/set_held_call_action.dart.)
  • lib/src/actions/set_muted_call_action.dart (Run flutter format to format lib/src/actions/set_muted_call_action.dart.)
  • lib/src/actions/start_call_action.dart (Run flutter format to format lib/src/actions/start_call_action.dart.)
  • lib/src/call.dart (Run flutter format to format lib/src/call.dart.)
  • lib/src/call_controller.dart (Run flutter format to format lib/src/call_controller.dart.)
  • lib/src/call_observer.dart (Run flutter format to format lib/src/call_observer.dart.)
  • lib/src/call_update.dart (Run flutter format to format lib/src/call_update.dart.)
  • lib/src/exceptions.dart (Run flutter format to format lib/src/exceptions.dart.)
  • lib/src/handle.dart (Run flutter format to format lib/src/handle.dart.)
  • lib/src/log.dart (Run flutter format to format lib/src/log.dart.)
  • lib/src/provider.dart (Run flutter format to format lib/src/provider.dart.)
  • lib/src/transaction.dart (Run flutter format to format lib/src/transaction.dart.)

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.6.0 <3.0.0
flutter 0.0.0
uuid ^2.0.4 2.0.4
Transitive dependencies
charcode 1.1.3
collection 1.14.11 1.14.12
convert 2.1.1
crypto 2.1.4
meta 1.1.8
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8
Dev dependencies
flutter_test