Flutter Call Kit

pub package Flutter Call Kit Plugin - Currently iOS >= 10.0 only


Flutter Call Kit utilises a brand new iOS 10 framework CallKit to make the life easier for VoIP developers using Flutter.

Note 1: This plugin works for only iOS. No android support yet

Note 2 This plugin was inspired by react-native-keep

For more information about CallKit on iOS, please see Official CallKit Framework Document or Introduction to CallKit by Xamarin


Connection Service


Add flutter_call_kit as a dependency in your pubspec.yaml file.


import 'package:flutter/material.dart';
import 'dart:async';
import 'package:uuid/uuid.dart';
import 'package:flutter_call_kit/flutter_call_kit.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  _MyAppState createState() => _MyAppState();

class _MyAppState extends State<MyApp> {
  bool _configured;
  String _currentCallId;
  FlutterCallKit _callKit = FlutterCallKit();
  void initState() {

  Future<void> configure() async {
      IOSOptions("My Awesome APP",
          imageName: 'sim_icon',
          supportsVideo: false,
          maximumCallGroups: 1,
          maximumCallsPerCallGroup: 1),
      didReceiveStartCallAction: _didReceiveStartCallAction,
      performAnswerCallAction: _performAnswerCallAction,
      performEndCallAction: _performEndCallAction,
      didActivateAudioSession: _didActivateAudioSession,
      didDisplayIncomingCall: _didDisplayIncomingCall,
      didPerformSetMutedCallAction: _didPerformSetMutedCallAction,
      didPerformDTMFAction: _didPerformDTMFAction,
      didToggleHoldAction: _didToggleHoldAction,
    setState(() {
      _configured = true;

  /// Use startCall to ask the system to start a call - Initiate an outgoing call from this point
  Future<void> startCall(String handle, String localizedCallerName) async {
    /// Your normal start call action
    await _callKit.startCall(currentCallId, handle, localizedCallerName);

  Future<void> reportEndCallWithUUID(String uuid, EndReason reason) async {
    await _callKit.reportEndCallWithUUID(uuid, reason);

  /// Event Listener Callbacks

  Future<void> _didReceiveStartCallAction(String uuid, String handle) async {
    // Get this event after the system decides you can start a call
    // You can now start a call from within your app

  Future<void> _performAnswerCallAction(String uuid) async {
    // Called when the user answers an incoming call

  Future<void> _performEndCallAction(String uuid) async {
    await _callKit.endCall(this.currentCallId);
    _currentCallId = null;

  Future<void> _didActivateAudioSession() async {
    // you might want to do following things when receiving this event:
    // - Start playing ringback if it is an outgoing call

  Future<void> _didDisplayIncomingCall(String error, String uuid, String handle,
      String localizedCallerName, bool fromPushKit) async {
    // You will get this event after RNCallKeep finishes showing incoming call UI
    // You can check if there was an error while displaying

  Future<void> _didPerformSetMutedCallAction(bool mute, String uuid) async {
    // Called when the system or user mutes a call

  Future<void> _didPerformDTMFAction(String digit, String uuid) async {
    // Called when the system or user performs a DTMF action

  Future<void> _didToggleHoldAction(bool hold, String uuid) async {
    // Called when the system or user holds a call

  String get currentCallId {
    if (_currentCallId == null) {
      final uuid = new Uuid();
      _currentCallId = uuid.v4();

    return _currentCallId;

  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
        body: Center(
          child: Text('Flutter Call Kit Configured: $_configured\n'),

Receiving a call when the application is not reachable.

In some case your application can be unreachable :

  • when the user kill the application
  • when it's in background since a long time (eg: after ~5mn the os will kill all connections).

To be able to wake up your application to display the incoming call, you can use https://github.com/peerwaya/flutter_voip_push_notification on iOS.

You have to send a push to your application with a library supporting PushKit pushes for iOS.


Since iOS 13, you'll have to report the incoming calls that wakes up your application with a VoIP push. Add this in your AppDelegate.m if you're using VoIP pushes to wake up your application :

- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(PKPushType)type withCompletionHandler:(void (^)(void))completion {
  // Process the received push
  [FlutterVoipPushNotificationPlugin didReceiveIncomingPushWithPayload:payload forType:(NSString *)type];

  // Retrieve information like handle and callerName here
  // NSString *uuid = /* fetch for payload or ... */ [[[NSUUID UUID] UUIDString] lowercaseString];
  // NSString *callerName = @"caller name here";
  // NSString *handle = @"caller number here";

  [FlutterCallKitPlugin reportNewIncomingCall:uuid handle:handle handleType:@"generic" hasVideo:false localizedCallerName:callerName fromPushKit: YES];



Any pull request, issue report and suggestion are highly welcome!





Foreign Function Interface for interoperability with the C programming language. [...]


HTML elements and other resources for web-based applications that need to interact with the browser and the DOM (Document Object Model). [...]
Low-level support for interoperating with JavaScript. [...]
Utility methods to efficiently manipulate typed JSInterop objects in cases where the name to call is not known at runtime. You should only use these methods when the same effect cannot be achieved with @JS annotations. These methods would be extension methods on JSObject if Dart supported extension methods.