|
|
|
@ -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: - FlutterStreamHandler(event 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
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|