Skip to content

Instantly share code, notes, and snippets.

@adityagokula2210
Created November 12, 2024 11:21
Show Gist options
  • Select an option

  • Save adityagokula2210/b51d344956f3bcff0dda9e2146b5e361 to your computer and use it in GitHub Desktop.

Select an option

Save adityagokula2210/b51d344956f3bcff0dda9e2146b5e361 to your computer and use it in GitHub Desktop.
import Flutter
import CallKit
import flutter_callkit_incoming
import UIKit
import PushKit
func createUUID(sessionid: String) -> String {
let components = sessionid.components(separatedBy: ".")
if let lastComponent = components.last {
let truncatedString = String(lastComponent.prefix(32)) // Discard extra
characters
let uuid = truncatedString.replacingOccurrences(of:
"(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})", with: "$1-$2-$3-$4-$5", options:
.regularExpression, range: nil).uppercased()
return uuid;
}
return UUID().uuidString;
}
func convertDictionaryToJsonString(dictionary: [String: Any]) -> String? {
do {
let jsonData = try JSONSerialization.data(withJSONObject: dictionary, options:
.sortedKeys)
if let jsonString = String(data: jsonData, encoding: .utf8) {
return jsonString
}
} catch {
print("Error converting dictionary to JSON: \(error.localizedDescription)")
}
return nil
}
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate, PKPushRegistryDelegate {
var pushRegistry: PKPushRegistry!
var callController: CXCallController?
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey:
Any]?
) -> Bool {
// Register the Flutter plugin
GeneratedPluginRegistrant.register(with: self)
let controller : FlutterViewController = window?.rootViewController as!
FlutterViewController
let appInfoChannel = FlutterMethodChannel(name: "com.cometchat.flutter_pn",
binaryMessenger:
controller.binaryMessenger)
appInfoChannel.setMethodCallHandler({
(call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
if call.method == "getAppInfo" {
var appInfo: [String: String] = [:]
appInfo["bundleId"] = Bundle.main.bundleIdentifier
appInfo["version"] =
Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
result(appInfo)
} else if call.method == "endCall" {
if let activeCall = self.activeCallSession {
SwiftFlutterCallkitIncomingPlugin.sharedInstance?.endCall(activeCall)
result(true)
}else {
result(false)}
} else {
result(FlutterMethodNotImplemented)
}
})
// Set up the PushKit registry
pushRegistry = PKPushRegistry(queue: DispatchQueue.main)
pushRegistry.delegate = self
pushRegistry.desiredPushTypes = Set([.voIP]) // Specify VoIP push type
let providerConfiguration = CXProviderConfiguration(localizedName: "Your App")
providerConfiguration.supportsVideo = false
providerConfiguration.supportedHandleTypes = [.phoneNumber]
let callKitProvider = CXProvider(configuration: providerConfiguration)
callController = CXCallController()
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self as?
UNUserNotificationCenterDelegate
}
return super.application(application, didFinishLaunchingWithOptions:
launchOptions)
}
func endCall(callUUID: UUID) {
// 1. Create the End Call Action
let endCallAction = CXEndCallAction(call: callUUID)
// 2. Create the transaction
let transaction = CXTransaction(action: endCallAction)
// 3. Request the transaction through the call controller
callController?.request(transaction, completion: { error in
if let error = error {
print("Failed to end call: \(error.localizedDescription)")
} else {
print("Call ended successfully.")
}
})
}
// PKPushRegistryDelegate method to handle updates to push credentials
func pushRegistry(_ registry: PKPushRegistry, didUpdate credentials:
PKPushCredentials, for type: PKPushType) {
print("VoIP token: \(credentials.token)") // Make sure you see the token in the
logs
let deviceToken = credentials.token.map { String(format: "%02x", $0) }.joined()
print("Device Token (hex): \(deviceToken)") // Print the token in hex format
// Send token to Flutter plugin
SwiftFlutterCallkitIncomingPlugin.sharedInstance?.setDevicePushTokenVoIP(deviceToken)
}
// PKPushRegistryDelegate method to handle token invalidation
func pushRegistry(_ registry: PKPushRegistry, didInvalidatePushTokenFor type:
PKPushType) {
print("didInvalidatePushTokenFor")
// Clear the device token if it gets invalidated
SwiftFlutterCallkitIncomingPlugin.sharedInstance?.setDevicePushTokenVoIP("")
}
var activeCallSession: flutter_callkit_incoming.Data?
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload:
PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
// Check if the app is in the foreground
if UIApplication.shared.applicationState == .active {
// App is in the foreground, do nothing or perform any desired action
return
}
guard type == .voIP else { return }
if let payloadData = payload.dictionaryPayload as? [String : Any] {
let category = payloadData["type"] as! String
switch category {
case "chat": break
case "action": break
case "custom": break
case "call":
let callAction = payloadData["callAction"] as! String
let senderName = payloadData["senderName"] as! String;
let handle = senderName
let sessionid = payloadData["sessionId"] as! String;
let callType = payloadData["callType"] as! String;
let callUUID = createUUID(sessionid: sessionid)
let data = flutter_callkit_incoming.Data(id: callUUID, nameCaller:
senderName, handle: handle, type: callType == "audio" ? 0:1 )
data.extra = ["message": convertDictionaryToJsonString(dictionary:
payloadData)]
switch callAction {
case "initiated":
data.duration = 55000 // has to be greater than the CometChat
duration
activeCallSession = data
SwiftFlutterCallkitIncomingPlugin.sharedInstance?.showCallkitIncoming(data, fromPushKit:
true)
break
case "unanswered", "cancelled", "rejected":
SwiftFlutterCallkitIncomingPlugin.sharedInstance?.endCall(data)
break
default: break
}
break
default: break
}
}
DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
completion()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment