iosflutternotificationsapple-push-notificationscallkit

App is not opening on click of Accept call (Background or Terminated state app)


I used this plugin flutter_callkit_incoming for configuring notification call notification in android and ios. Android is working fine. IOS i received notification very well. The only problem i am facing is when i accept the call it is not opening app automatically in IOS. When i open app manually it starts call. But ideally it should launch app on click of accept call.

Note: I added checkAndNavigationCallingPage() in WidgetsBinding.instance.addPostFrameCallback

I am sure i missed upon some configuration param. I am using latest lib. Below is my code from AppDelegate.swift

Please help me on resolving this issue.

import UIKit
import Flutter
import flutter_local_notifications
import flutter_callkit_incoming
import CallKit
import AVFAudio
import PushKit

@main
@objc class AppDelegate: FlutterAppDelegate, PKPushRegistryDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
      // This is required to make any communication available in the action isolate.
      FlutterLocalNotificationsPlugin.setPluginRegistrantCallback { (registry) in
        GeneratedPluginRegistrant.register(with: registry)
      }
      
      // Added as per documentation of flutter local notification package
      if #available(iOS 10.0, *) {
        UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
      }
      
      GeneratedPluginRegistrant.register(with: self)

              
      //Setup VOIP (flutter_callkit_incomming)
      let mainQueue = DispatchQueue.main
      let voipRegistry: PKPushRegistry = PKPushRegistry(queue: mainQueue)
      voipRegistry.delegate = self
      voipRegistry.desiredPushTypes = [PKPushType.voIP]
      
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }

   // As per flutter_callkit_incomming Start ///////////////////

    
    // Handle updated push credentials
    func pushRegistry(_ registry: PKPushRegistry, didUpdate credentials: PKPushCredentials, for type: PKPushType) {
        print(credentials.token)
        let deviceToken = credentials.token.map { String(format: "%02x", $0) }.joined()
        print(deviceToken)
        //Save deviceToken to your server
        SwiftFlutterCallkitIncomingPlugin.sharedInstance?.setDevicePushTokenVoIP(deviceToken)
    }
    
    func pushRegistry(_ registry: PKPushRegistry, didInvalidatePushTokenFor type: PKPushType) {
        print("didInvalidatePushTokenFor")
        SwiftFlutterCallkitIncomingPlugin.sharedInstance?.setDevicePushTokenVoIP("")
    }
    
    // Handle incoming pushes
    func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
        print("didReceiveIncomingPushWith")
        guard type == .voIP else { return }
        
        // Require by
        let id = payload.dictionaryPayload["id"] as? String ?? UUID().uuidString
        let nameCaller = (payload.dictionaryPayload["params"] as? [String: Any])? ["body"] as? String ?? ""
        let appName = (payload.dictionaryPayload["params"] as? [String: Any])? ["title"] as? String ?? ""
        // Phone number/Email/Any
        let handle = payload.dictionaryPayload["handle"] as? String ?? "generic"
        //Video call or audio call
        let isVideo = payload.dictionaryPayload["isVideo"] as? Int ?? 1
        //duration of ring
        let duration = payload.dictionaryPayload["duration"] as? Int ?? 30000
        // ringtone
        let ringtonePath = payload.dictionaryPayload["ringtonePath"] as? String ?? "system_ringtone_default"
        var args: NSDictionary = ["id": id, "nameCaller": nameCaller, "appName": appName, "handle": handle, "type": isVideo, "duration": duration, "ringtonePath": ringtonePath]
        let data = flutter_callkit_incoming.Data(args: args)
        data.extra =  payload.dictionaryPayload["params"] as? NSDictionary ?? [:]
        data.iconName = ""
        data.type = 1;
        print(data);
        SwiftFlutterCallkitIncomingPlugin.sharedInstance?.showCallkitIncoming(data, fromPushKit: true)
        
        //Make sure call completion()
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            completion()
        }
    }

   ///// as per flutter_callkit_incomming END //////
}

Below is git link:

https://github.com/hiennguyen92/flutter_callkit_incoming/issues/605


Solution

  • I moved endCall and endAllCalls function on actual call end , its working now. Problem i faced because it was working on Android and not on IOS.