Call native code android & ios

development_aamir
Aamir Muhammad 2 years ago
parent 7c980cc353
commit 7f0a466915

@ -0,0 +1,420 @@
// VoIPCenter.swift
//
//
// //
// // VoIPCenter.swift
// // flutter_ios_voip_kit
// //
// // Created by on 2020/07/02.
// //
//
// import Foundation
// import Flutter
// import PushKit
// import CallKit
// import AVFoundation
//
// extension String {
// internal init(deviceToken: Data) {
// self = deviceToken.map { String(format: "%.2hhx", $0) }.joined()
// }
// }
//
// class VoIPCenter: NSObject, URLSessionDelegate {
//
//
//
//
// // MARK: - event channel
//
// private let eventChannel: FlutterEventChannel
// private var eventSink: FlutterEventSink?
//
// private enum EventChannel: String {
// case onDidReceiveIncomingPush
// case onDidAcceptIncomingCall
// case onDidRejectIncomingCall
//
// case onDidUpdatePushToken
// case onDidActivateAudioSession
// case onDidDeactivateAudioSession
// }
//
// // MARK: - PushKit
//
// private let didUpdateTokenKey = "Did_Update_VoIP_Device_Token"
// private let pushRegistry: PKPushRegistry
//
// var token: String? {
// if let didUpdateDeviceToken = UserDefaults.standard.data(forKey: didUpdateTokenKey) {
// let token = String(deviceToken: didUpdateDeviceToken)
// print("🎈 VoIP didUpdateDeviceToken: \(token)")
// return token
// }
//
// guard let cacheDeviceToken = self.pushRegistry.pushToken(for: .voIP) else {
// return nil
// }
//
// let token = String(deviceToken: cacheDeviceToken)
// print("🎈 VoIP cacheDeviceToken: \(token)")
// return token
// }
//
// // MARK: - CallKit
//
// let callKitCenter: CallKitCenter
//
// fileprivate var audioSessionMode: AVAudioSession.Mode
// fileprivate let ioBufferDuration: TimeInterval
// fileprivate let audioSampleRate: Double
//
// init(eventChannel: FlutterEventChannel) {
// self.eventChannel = eventChannel
// self.pushRegistry = PKPushRegistry(queue: .main)
// self.pushRegistry.desiredPushTypes = [.voIP]
// self.callKitCenter = CallKitCenter()
//
// if let path = Bundle.main.path(forResource: "Info", ofType: "plist"), let plist = NSDictionary(contentsOfFile: path) {
// self.audioSessionMode = ((plist["FIVKAudioSessionMode"] as? String) ?? "audio") == "video" ? .videoChat : .voiceChat
// self.ioBufferDuration = plist["FIVKIOBufferDuration"] as? TimeInterval ?? 0.005
// self.audioSampleRate = plist["FIVKAudioSampleRate"] as? Double ?? 44100.0
// } else {
// self.audioSessionMode = .voiceChat
// self.ioBufferDuration = TimeInterval(0.005)
// self.audioSampleRate = 44100.0
// }
//
// super.init()
// self.eventChannel.setStreamHandler(self)
// self.pushRegistry.delegate = self
// self.callKitCenter.setup(delegate: self)
// }
// }
//
// extension VoIPCenter: PKPushRegistryDelegate {
//
// // MARK: - PKPushRegistryDelegate
//
// public func pushRegistry(_ registry: PKPushRegistry, didUpdate pushCredentials: PKPushCredentials, for type: PKPushType) {
// print("🎈 VoIP didUpdate pushCredentials")
// UserDefaults.standard.set(pushCredentials.token, forKey: didUpdateTokenKey)
//
// self.eventSink?(["event": EventChannel.onDidUpdatePushToken.rawValue,
// "token": pushCredentials.token.hexString])
// }
//
// // NOTE: iOS11 or more support
//
// public func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
// print("🎈 VoIP didRecyeiveIncomingPushWith completion: \(payload.dictionaryPayload)")
//
// let info = self.parse(payload: payload)
// let callerName = info?["incoming_caller_name"] as! String
// self.callKitCenter.incomingCall(uuidString: info?["uuid"] as! String,
// callerId: info?["incoming_caller_id"] as! String,
// callerName: callerName) { error in
// if let error = error {
// print(" reportNewIncomingCall error: \(error.localizedDescription)")
// return
// }
// self.eventSink?(["event": EventChannel.onDidReceiveIncomingPush.rawValue,
// "payload": info as Any,
// "incoming_caller_name": callerName])
// completion()
// }
// }
//
// // NOTE: iOS10 support
//
// public func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType) {
// print("🎈 VoIP didReceiveIncomingPushWith: \(payload.dictionaryPayload)")
//
//
// let info = self.parse(payload: payload)
// let callerName = info?["incoming_caller_name"] as! String
// self.callKitCenter.incomingCall(uuidString: info?["uuid"] as! String,
// callerId: info?["incoming_caller_id"] as! String,
// callerName: callerName) { error in
// if let error = error {
// print(" reportNewIncomingCall error: \(error.localizedDescription)")
// return
// }
// self.eventSink?(["event": EventChannel.onDidReceiveIncomingPush.rawValue,
// "payload": info as Any,
// "incoming_caller_name": callerName])
// }
// }
//
// private func parse(payload: PKPushPayload) -> [String: Any]? {
// do {
// let data = try JSONSerialization.data(withJSONObject: payload.dictionaryPayload, options: .prettyPrinted)
// let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
//
// if let aps = json?["aps"] as? [String: Any] {
// if let alertString = aps["alert"] as? String {
// let alertData = alertString.data(using: .utf8)
// let alertJson = try JSONSerialization.jsonObject(with: alertData!, options: []) as? [String: Any]
// return alertJson
// } else if let alertDictionary = aps["alert"] as? [String: Any] {
// return alertDictionary
// }
// }
//
// return nil
// } catch let error as NSError {
// print(" VoIP parsePayload: \(error.localizedDescription)")
// return nil
// }
// }
//
//
//
// // private func parse(payload: PKPushPayload) -> [String: Any]? {
// // do {
// // let data = try JSONSerialization.data(withJSONObject: payload.dictionaryPayload, options: .prettyPrinted)
// // let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
// // let aps = json?["aps"] as? [String: Any]
// // return aps?["alert"] as? [String: Any]
// // } catch let error as NSError {
// // print(" VoIP parsePayload: \(error.localizedDescription)")
// // return nil
// // }
// // }
//
//
// }
//
// extension VoIPCenter: CXProviderDelegate , APIDelegate {
// func didReceiveAPIResponse(data: Data?) {
// print("didReceiveAPIResponse")
// }
//
// func didFailAPIRequest(error: Error) {
// print("didFailAPIRequest")
// }
//
//
// // MARK: - CXProviderDelegate
//
// public func providerDidReset(_ provider: CXProvider) {
// print("🚫 VoIP providerDidReset")
// }
//
// public func provider(_ provider: CXProvider, perform action: CXStartCallAction) {
// print("🤙 VoIP CXStartCallAction")
// self.callKitCenter.connectingOutgoingCall()
// action.fulfill()
// }
//
// public func provider(_ provider: CXProvider, perform action: CXAnswerCallAction) {
// print(" VoIP CXAnswerCallAction")
// self.callKitCenter.answerCallAction = action
// self.configureAudioSession()
// self.eventSink?(["event": EventChannel.onDidAcceptIncomingCall.rawValue,
// "uuid": self.callKitCenter.uuidString as Any,
// "incoming_caller_id": self.callKitCenter.incomingCallerId as Any])
// }
//
// public func provider(_ provider: CXProvider, perform action: CXEndCallAction) {
// print(" VoIP CXEndCallAction")
// if (self.callKitCenter.isCalleeBeforeAcceptIncomingCall) {
// self.eventSink?(["event": EventChannel.onDidRejectIncomingCall.rawValue,
// "uuid": self.callKitCenter.uuidString as Any,
// "incoming_caller_id": self.callKitCenter.incomingCallerId as Any])
// if let callerId = self.callKitCenter.incomingCallerId {
// let components = callerId.components(separatedBy: "-")
// if components.count == 3 {
// let targetUserID = components[0]
// let currentUserID = components[1]
// print(" VoIP CXEndCallBeforeApi")
// APIClient.shared.postRequest(delegate: self, currentUserID: currentUserID,targetUserID:targetUserID)
// self.callKitCenter.disconnected(reason: .remoteEnded)
// action.fulfill()
// print(" VoIP CXEndCallAfterApi")
// } else {
// print("Invalid input string format")
// }
// } else {
// print("incomingCallerId is not a String")
// }
// }
//
// }
//
//
//
// public func provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession) {
// print("🔈 VoIP didActivate audioSession")
// self.eventSink?(["event": EventChannel.onDidActivateAudioSession.rawValue])
// }
//
// public func provider(_ provider: CXProvider, didDeactivate audioSession: AVAudioSession) {
// print("🔇 VoIP didDeactivate audioSession")
// self.eventSink?(["event": EventChannel.onDidDeactivateAudioSession.rawValue])
// }
//
// // This is a workaround for known issue, when audio doesn't start from lockscreen call
// // https://stackoverflow.com/questions/55391026/no-sound-after-connecting-to-webrtc-when-app-is-launched-in-background-using-pus
// private func configureAudioSession() {
// let sharedSession = AVAudioSession.sharedInstance()
// do {
// try sharedSession.setCategory(.playAndRecord,
// options: [AVAudioSession.CategoryOptions.allowBluetooth,
// AVAudioSession.CategoryOptions.defaultToSpeaker])
// try sharedSession.setMode(audioSessionMode)
// try sharedSession.setPreferredIOBufferDuration(ioBufferDuration)
// try sharedSession.setPreferredSampleRate(audioSampleRate)
// } catch {
// print(" VoIP Failed to configure `AVAudioSession`")
// }
// }
// }
//
// // Aamir Work
//
// protocol APIDelegate: AnyObject {
// func didReceiveAPIResponse(data: Data?)
// func didFailAPIRequest(error: Error)
// }
//
//
// class APIClient {
// static let shared = APIClient()
//
// func postRequest(delegate: APIDelegate, currentUserID: String, targetUserID: String) {
// DispatchQueue.global(qos: .background).async {
// self.getApiToken(currentUserID: currentUserID) { data, error in
// if let error = error {
// print("Error: \(error.localizedDescription)")
// } else if let data = data {
// do{
// let sem = DispatchSemaphore(value: 0)
// do {
// let json = try JSONSerialization.jsonObject(with: data, options: [])
// guard let dictionary = json as? [String: Any] else {
// print("Error parsing JSON")
// return
// }
// guard let responseDictionary = dictionary["response"] as? [String: Any] else {
// print("Error parsing response")
// return
// }
//
// guard let token = responseDictionary["token"] as? String else {
// print("Error getting token")
// return
// }
// print("OneSignal User Token After Login JSON: \(token)")
//
// self.makeEndCallRequest(currentUserID: currentUserID, targetUserID: targetUserID, token: token) { data, error in
// if let error = error {
// print("Error: \(error.localizedDescription)")
// } else if let data = data {
// sem.signal()
// _ = String(data: data, encoding: .utf8)
// print("Call Ended Successfully")
// }
// }
// }
// sem.wait()
// }catch{
// print("Error parsing JSON: \(error)")
// }
// }
//
// }
// }
//
// }
//
// private func getApiToken(currentUserID: String, completion: @escaping (Data?, Error?) -> Void) {
// let parameters = """
// {
// "employeeNumber": "\(currentUserID)",
// "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG"
// }
// """
// let postData = parameters.data(using: .utf8)
// var request = URLRequest(url: URL(string: "https://apiderichat.hmg.com/api/user/externaluserlogin")!,
// timeoutInterval: Double.infinity)
// request.addValue("application/json", forHTTPHeaderField: "Content-Type")
// request.httpMethod = "POST"
// request.httpBody = postData
// let task = URLSession.shared.dataTask(with: request) { data, response, error in
// if let error = error {
// completion(nil, error)
// return
// }
// guard let httpResponse = response as? HTTPURLResponse else {
// let error = NSError(domain: "InvalidResponse", code: 0, userInfo: nil)
// completion(nil, error)
// return
// }
// guard (200...299).contains(httpResponse.statusCode) else {
// let error = NSError(domain: "HTTPError", code: httpResponse.statusCode, userInfo: nil)
// completion(nil, error)
// return
// }
// completion(data, nil)
// }
//
// task.resume()
// }
//
//
// private func makeEndCallRequest(currentUserID: String, targetUserID: String, token: String, completion: @escaping (Data?, Error?) -> Void) {
// let parameters = """
// {
// "currentUserId": \(currentUserID),
// "targetUserId": \(targetUserID),
// "secretKey": "derichatmobileuser",
// "targetUserToken": "\(token)"
// }
// """
// print("OneSignal Params: \(parameters)")
// let postData = parameters.data(using: .utf8)
// var request = URLRequest(url: URL(string: "https://apiderichat.hmg.com/api/user/calldecline")!,
// timeoutInterval: Double.infinity)
// request.addValue("application/json", forHTTPHeaderField: "Content-Type")
// request.httpMethod = "POST"
// request.httpBody = postData
// let task = URLSession.shared.dataTask(with: request) { data, response, error in
// if let error = error {
// completion(nil, error)
// return
// }
// guard let httpResponse = response as? HTTPURLResponse else {
// let error = NSError(domain: "InvalidResponse", code: 0, userInfo: nil)
// completion(nil, error)
// return
// }
// guard (200...299).contains(httpResponse.statusCode) else {
// let error = NSError(domain: "HTTPError", code: httpResponse.statusCode, userInfo: nil)
// completion(nil, error)
// return
// }
// completion(data, nil)
// }
//
// task.resume()
// }
//
// }
//
//
// // End Aamir Work
// extension VoIPCenter: FlutterStreamHandler {
//
// // MARK: - FlutterStreamHandlerevent channel
//
// public func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
// self.eventSink = events
// return nil
// }
//
// public func onCancel(withArguments arguments: Any?) -> FlutterError? {
// self.eventSink = nil
// return nil
// }
// }

@ -338,7 +338,7 @@ class ChatApiClient {
} }
// Call Decline On App Terminated State // Call Decline On App Terminated State
Future<Response> callDecline({required int cUserID, required int tUserID, required String targetUsertoken}) async { Future<Response> callDecline({required int cUserID, required int tUserID, String? targetUsertoken}) async {
Response response = await ApiClient().postJsonForResponse( Response response = await ApiClient().postJsonForResponse(
"${ApiConsts.chatLoginTokenUrl}calldecline", "${ApiConsts.chatLoginTokenUrl}calldecline",
{"currentUserId": cUserID, "targetUserId": tUserID, "secretKey": "derichatmobileuser", "targetUserToken": targetUsertoken}, {"currentUserId": cUserID, "targetUserId": tUserID, "secretKey": "derichatmobileuser", "targetUserToken": targetUsertoken},
@ -359,7 +359,7 @@ class ChatApiClient {
"app_id": ApiConsts.oneSignalAppID, "app_id": ApiConsts.oneSignalAppID,
"identifier": value, "identifier": value,
"device_type": 0, "device_type": 0,
"test_type": !kReleaseMode ? 1 : 0 "test_type": !kReleaseMode || kDebugMode ? 1 : 0
// 1 // 1
}, },
); );

@ -154,7 +154,7 @@ class ChatVoipCall {
IosCallPayload _iosCallPayload = IosCallPayload(incomingCallerId: iosCallPayload.incomingCallerId!.split("-")[0], incomingCallReciverId: iosCallPayload.incomingCallerId!.split("-")[1]); IosCallPayload _iosCallPayload = IosCallPayload(incomingCallerId: iosCallPayload.incomingCallerId!.split("-")[0], incomingCallReciverId: iosCallPayload.incomingCallerId!.split("-")[1]);
ALM.UserAutoLoginModel model = await ChatApiClient().getUserCallToken(userid: iosCallPayload.incomingCallerId!.split("-")[1]); ALM.UserAutoLoginModel model = await ChatApiClient().getUserCallToken(userid: iosCallPayload.incomingCallerId!.split("-")[1]);
await ChatApiClient() await ChatApiClient()
.callDecline(cUserID: int.parse(_iosCallPayload.incomingCallerId!), tUserID: int.parse(_iosCallPayload.incomingCallReciverId.toString()), targetUsertoken: model.response!.token!); .callDecline(cUserID: int.parse(_iosCallPayload.incomingCallerId!), tUserID: int.parse(_iosCallPayload.incomingCallReciverId.toString()), targetUsertoken: model.response!.token);
} catch (err) { } catch (err) {
print(err); print(err);
} }

@ -119,6 +119,7 @@ class _LoginScreenState extends State<LoginScreen> with WidgetsBindingObserver {
String uuid, String uuid,
String callerId, String callerId,
) async { ) async {
timeOutTimer.cancel();
await ChatVoipCall().voipDeclineCall(_iosCallPayload); await ChatVoipCall().voipDeclineCall(_iosCallPayload);
await voIPKit.endCall(); await voIPKit.endCall();
}; };
@ -135,7 +136,7 @@ class _LoginScreenState extends State<LoginScreen> with WidgetsBindingObserver {
} }
void _timeOut() async { void _timeOut() async {
timeOutTimer = Timer(const Duration(seconds: 25), () async { timeOutTimer = Timer(const Duration(seconds: 20), () async {
String? incomingCallerName = await voIPKit.getIncomingCallerName(); String? incomingCallerName = await voIPKit.getIncomingCallerName();
voIPKit.unansweredIncomingCall( voIPKit.unansweredIncomingCall(
skipLocalNotification: false, skipLocalNotification: false,

Loading…
Cancel
Save