omikit-plugin 3.2.50 → 3.2.52

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- //
1
+ //
2
2
  // CallUtils.swift
3
3
  // OMICall Contact Center
4
4
  //
@@ -13,548 +13,555 @@ import OmiKit
13
13
  import AVFoundation
14
14
 
15
15
  class CallManager {
16
-
17
- static private var instance: CallManager? = nil // Instance
18
- private let omiLib = OMISIPLib.sharedInstance()
19
- var videoManager: OMIVideoViewManager?
20
- var isSpeaker = false
21
- private var guestPhone : String = ""
22
- private var lastStatusCall : String?
23
- private var tempCallInfo : [String: Any]?
24
- private var lastTimeCall : Date = Date()
25
- /// Get instance
26
- static func shareInstance() -> CallManager {
27
- if (instance == nil) {
28
- instance = CallManager()
29
- }
30
- return instance!
31
- }
32
-
33
- func getAvailableCall() -> OMICall? {
34
- var currentCall = omiLib.getCurrentConfirmCall()
35
- if (currentCall == nil) {
36
- currentCall = omiLib.getNewestCall()
37
- }
38
- return currentCall
39
- }
40
-
41
- func transferCall(_ phoneNumber: String)-> Bool {
42
- var result = false;
43
- do {
44
- if let callInfo = self.omiLib.getCurrentConfirmCall() {
45
- dump(callInfo)
46
- if callInfo.callState != .disconnected {
47
- callInfo.blindTransferCall(withNumber: phoneNumber);
48
- result = true
49
- }
50
- }
51
- } catch let error {
52
- print("ERROR_WHEN_TRANSFER_CALL_IOS: ", error)
53
- }
54
- print("calllZiii 2 ==> \(result)")
55
- return result
56
- }
57
-
58
-
59
- func endCall(){
60
- do {
61
- if let callInfo = omiLib.getCurrentCall() {
62
- if callInfo.callState != .disconnected {
63
- self.omiLib.callManager.end(callInfo) { error in
64
- if error != nil {
65
- }
66
- }
67
- }
16
+
17
+ static private var instance: CallManager? = nil // Instance
18
+ private let omiLib = OMISIPLib.sharedInstance()
19
+ var videoManager: OMIVideoViewManager?
20
+ var isSpeaker = false
21
+ private var guestPhone : String = ""
22
+ private var lastStatusCall : String?
23
+ private var tempCallInfo : [String: Any]?
24
+ private var lastTimeCall : Date = Date()
25
+ /// Get instance
26
+ static func shareInstance() -> CallManager {
27
+ if (instance == nil) {
28
+ instance = CallManager()
29
+ }
30
+ return instance!
31
+ }
32
+
33
+ func getAvailableCall() -> OMICall? {
34
+ var currentCall = omiLib.getCurrentConfirmCall()
35
+ if (currentCall == nil) {
36
+ currentCall = omiLib.getNewestCall()
37
+ }
38
+ return currentCall
39
+ }
40
+
41
+ func transferCall(_ phoneNumber: String)-> Bool {
42
+ var result = false;
43
+ do {
44
+ if let callInfo = self.omiLib.getCurrentConfirmCall() {
45
+ dump(callInfo)
46
+ if callInfo.callState != .disconnected {
47
+ callInfo.blindTransferCall(withNumber: phoneNumber);
48
+ result = true
49
+ }
50
+ }
51
+ } catch let error {
52
+ print("ERROR_WHEN_TRANSFER_CALL_IOS: ", error)
53
+ }
54
+ print("calllZiii 2 ==> \(result)")
55
+ return result
56
+ }
57
+
58
+
59
+ func endCall(){
60
+ do {
61
+ if let callInfo = omiLib.getCurrentCall() {
62
+ if callInfo.callState != .disconnected {
63
+ self.omiLib.callManager.end(callInfo) { error in
64
+ if error != nil {
68
65
  }
69
- } catch let error {
70
- print("ERROR_WHEN_TRANSFER_CALL_IOS: ", error)
71
- }
72
- }
73
-
74
-
75
- func configNotification(data: [String: Any]) {
76
- let user = UserDefaults.standard
77
- if let title = data["missedCallTitle"] as? String, let message = data["prefixMissedCallMessage"] as? String {
78
- user.set(title, forKey: "omicall/missedCallTitle")
79
- user.set(message, forKey: "omicall/prefixMissedCallMessage")
80
- }
81
- }
82
-
83
- func convertDictionaryToJson(dictionary: [String: Any]) -> String? {
84
- do {
85
- let jsonData = try JSONSerialization.data(withJSONObject: dictionary, options: [])
86
- if let jsonString = String(data: jsonData, encoding: .utf8) {
87
- return jsonString
88
- }
89
- } catch {
90
- print("Error converting dictionary to JSON: \(error.localizedDescription)")
91
- }
92
- return nil
93
- }
94
-
95
- private func messageCall(type: Int) -> String {
96
- switch(type){
97
- case 0:
98
- return "INVALID_UUID"
99
- case 1:
100
- return "INVALID_PHONE_NUMBER"
101
- case 2:
102
- return "SAME_PHONE_NUMBER_WITH_PHONE_REGISTER"
103
- case 3:
104
- return "MAX_RETRY"
105
- case 4:
106
- return "PERMISSION_DENIED"
107
- case 5:
108
- return "COULD_NOT_FIND_END_POINT"
109
- case 6:
110
- return "REGISTER_ACCOUNT_FAIL"
111
- case 7:
112
- return "START_CALL_FAIL"
113
- case 9:
114
- return "HAVE_ANOTHER_CALL"
115
- default:
116
- return "START_CALL_SUCCESS"
117
- }
118
- }
119
-
120
- private func requestPermission(isVideo: Bool) {
121
- AVCaptureDevice.requestAccess(for: .audio) { _ in
122
- // print("request audio")
123
- }
124
- if isVideo {
125
- AVCaptureDevice.requestAccess(for: .video) { _ in
126
- // print("request video")
127
- }
128
- }
129
- }
130
-
131
- func initWithApiKeyEndpoint(params: [String: Any]) -> Bool {
132
- //request permission
133
- var result = false
134
- if let usrUuid = params["usrUuid"] as? String, let fullName = params["fullName"] as? String, let apiKey = params["apiKey"] as? String, let token = params["fcmToken"] as? String {
135
- if let projectID = params["projectId"] as? String, !projectID.isEmpty {
136
- OmiClient.setFcmProjectId(projectID)
137
- }
138
- result = OmiClient.initWithUUID(usrUuid, fullName: fullName, apiKey: apiKey)
139
- OmiClient.setUserPushNotificationToken(token)
140
- }
141
- if (result) {
142
- let isVideo = (params["isVideo"] as? Bool) ?? true
143
- requestPermission(isVideo: isVideo)
144
- }
145
- return result
146
- }
147
-
148
-
149
- func initWithUserPasswordEndpoint(params: [String: Any]) -> Bool {
150
- var result = false
151
- if let userName = params["userName"] as? String, let password = params["password"] as? String, let realm = params["realm"] as? String, let token = params["fcmToken"] as? String {
152
- if let projectID = params["projectId"] as? String, !projectID.isEmpty {
153
- OmiClient.setFcmProjectId(projectID)
154
- }
155
- OmiClient.initWithUsername(userName, password: password, realm: realm, proxy: "")
156
- OmiClient.setUserPushNotificationToken(token)
157
- result = true
158
- }
159
- let isVideo = (params["isVideo"] as? Bool) ?? true
160
- requestPermission(isVideo: isVideo)
161
- return result
162
- }
163
-
164
- func showMissedCall() {
165
- OmiClient.setMissedCall { call in
166
- UNUserNotificationCenter.current().getNotificationSettings { settings in
167
- switch settings.authorizationStatus {
168
- case .notDetermined:
169
- break
170
- case .authorized, .provisional:
171
- let user = UserDefaults.standard
172
- let title = user.string(forKey: "omicall/missedCallTitle") ?? ""
173
- let message = user.string(forKey: "omicall/prefixMissedCallMessage") ?? ""
174
- let content = UNMutableNotificationContent()
175
- content.title = title
176
- content.body = "\(message) \(call.callerNumber!)"
177
- content.sound = .default
178
- content.userInfo = [
179
- "omisdkCallerNumber": call.callerNumber,
180
- "omisdkIsVideo": call.isVideo,
181
- ]
182
- let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false)
183
- let id = Int.random(in: 0..<10000000)
184
- let request = UNNotificationRequest(identifier: "\(id)", content: content, trigger: trigger)
185
- UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
186
- default:
187
- break
188
- }
189
- }
190
- }
191
- }
192
-
193
-
194
- func registerNotificationCenter(showMissedCall: Bool) {
195
- DispatchQueue.main.async { [weak self] in
196
- guard let self = self else { return }
197
- NotificationCenter.default.removeObserver(CallManager.instance!)
198
- NotificationCenter.default.addObserver(CallManager.instance!,
199
- selector: #selector(self.callStateChanged(_:)),
200
- name: NSNotification.Name.OMICallStateChanged,
201
- object: nil
202
- )
203
- NotificationCenter.default.addObserver(CallManager.instance!,
204
- selector: #selector(self.callDealloc(_:)),
205
- name: NSNotification.Name.OMICallDealloc,
206
- object: nil
207
- )
208
- NotificationCenter.default.addObserver(CallManager.instance!,
209
- selector: #selector(self.switchBoardAnswer(_:)),
210
- name: NSNotification.Name.OMICallSwitchBoardAnswer,
211
- object: nil
212
- )
213
- NotificationCenter.default.addObserver(CallManager.instance!, selector: #selector(self.updateNetworkHealth(_:)), name: NSNotification.Name.OMICallNetworkQuality, object: nil)
214
- NotificationCenter.default.addObserver(CallManager.instance!, selector: #selector(self.audioChanged(_:)), name: NSNotification.Name.OMICallAudioRouteChange, object: nil)
215
- if (showMissedCall) {
216
- self.showMissedCall()
217
- }
218
- }
219
- }
220
-
221
- func registerVideoEvent() {
222
- DispatchQueue.main.async {
223
- NotificationCenter.default.addObserver(CallManager.instance!,
224
- selector: #selector(self.videoUpdate(_:)),
225
- name: NSNotification.Name.OMICallVideoInfo,
226
- object: nil
227
- )
228
- }
229
- }
230
-
231
- func removeVideoEvent() {
232
- DispatchQueue.main.async {
233
- NotificationCenter.default.removeObserver(CallManager.instance!, name: NSNotification.Name.OMICallVideoInfo, object: nil)
234
- }
235
- }
236
-
237
- @objc func audioChanged(_ notification: NSNotification) {
238
- guard let userInfo = notification.userInfo,
239
- let audioInfo = userInfo[OMINotificationCurrentAudioRouteKey] as? [[String: String]] else {
240
- return;
241
- }
242
- OmikitPlugin.instance?.sendEvent(withName: AUDIO_CHANGE, body: [
243
- "data": audioInfo,
244
- ])
245
-
246
- }
247
-
248
- @objc func updateNetworkHealth(_ notification: NSNotification) {
249
- guard let userInfo = notification.userInfo,
250
- let state = userInfo[OMINotificationNetworkStatusKey] as? Int else {
251
- return;
252
- }
253
- OmikitPlugin.instance.sendEvent(withName: CALL_QUALITY, body: ["quality": state])
254
- }
255
-
256
- @objc func videoUpdate(_ notification: NSNotification) {
257
- guard let userInfo = notification.userInfo,
258
- let state = userInfo[OMIVideoInfoState] as? Int else {
259
- return;
260
- }
261
- switch (state) {
262
- case 1:
263
- OmikitPlugin.instance.sendEvent(withName: REMOTE_VIDEO_READY, body: nil)
264
- break
66
+ }
67
+ }
68
+ }
69
+ } catch let error {
70
+ print("ERROR_WHEN_TRANSFER_CALL_IOS: ", error)
71
+ }
72
+ }
73
+
74
+
75
+ func configNotification(data: [String: Any]) {
76
+ let user = UserDefaults.standard
77
+ if let title = data["missedCallTitle"] as? String, let message = data["prefixMissedCallMessage"] as? String {
78
+ user.set(title, forKey: "omicall/missedCallTitle")
79
+ user.set(message, forKey: "omicall/prefixMissedCallMessage")
80
+ }
81
+ }
82
+
83
+ func convertDictionaryToJson(dictionary: [String: Any]) -> String? {
84
+ do {
85
+ let jsonData = try JSONSerialization.data(withJSONObject: dictionary, options: [])
86
+ if let jsonString = String(data: jsonData, encoding: .utf8) {
87
+ return jsonString
88
+ }
89
+ } catch {
90
+ print("Error converting dictionary to JSON: \(error.localizedDescription)")
91
+ }
92
+ return nil
93
+ }
94
+
95
+ private func messageCall(type: Int) -> String {
96
+ switch(type){
97
+ case 0:
98
+ return "INVALID_UUID"
99
+ case 1:
100
+ return "INVALID_PHONE_NUMBER"
101
+ case 2:
102
+ return "SAME_PHONE_NUMBER_WITH_PHONE_REGISTER"
103
+ case 3:
104
+ return "MAX_RETRY"
105
+ case 4:
106
+ return "PERMISSION_DENIED"
107
+ case 5:
108
+ return "COULD_NOT_FIND_END_POINT"
109
+ case 6:
110
+ return "REGISTER_ACCOUNT_FAIL"
111
+ case 7:
112
+ return "START_CALL_FAIL"
113
+ case 9:
114
+ return "HAVE_ANOTHER_CALL"
115
+ default:
116
+ return "START_CALL_SUCCESS"
117
+ }
118
+ }
119
+
120
+ private func requestPermission(isVideo: Bool) {
121
+ AVCaptureDevice.requestAccess(for: .audio) { _ in
122
+ // print("request audio")
123
+ }
124
+ if isVideo {
125
+ AVCaptureDevice.requestAccess(for: .video) { _ in
126
+ // print("request video")
127
+ }
128
+ }
129
+ }
130
+
131
+ func initWithApiKeyEndpoint(params: [String: Any]) -> Bool {
132
+ //request permission
133
+ var result = false
134
+ if let usrUuid = params["usrUuid"] as? String, let fullName = params["fullName"] as? String, let apiKey = params["apiKey"] as? String, let token = params["fcmToken"] as? String {
135
+ if let projectID = params["projectId"] as? String, !projectID.isEmpty {
136
+ OmiClient.setFcmProjectId(projectID)
137
+ }
138
+ result = OmiClient.initWithUUID(usrUuid, fullName: fullName, apiKey: apiKey)
139
+ OmiClient.setUserPushNotificationToken(token)
140
+ }
141
+ if (result) {
142
+ let isVideo = (params["isVideo"] as? Bool) ?? true
143
+ requestPermission(isVideo: isVideo)
144
+ }
145
+ return result
146
+ }
147
+
148
+
149
+ func initWithUserPasswordEndpoint(params: [String: Any]) -> Bool {
150
+ var result = false
151
+ if let userName = params["userName"] as? String, let password = params["password"] as? String, let realm = params["realm"] as? String, let token = params["fcmToken"] as? String {
152
+ if let projectID = params["projectId"] as? String, !projectID.isEmpty {
153
+ OmiClient.setFcmProjectId(projectID)
154
+ }
155
+ OmiClient.initWithUsername(userName, password: password, realm: realm, proxy: "")
156
+ OmiClient.setUserPushNotificationToken(token)
157
+ result = true
158
+ }
159
+ let isVideo = (params["isVideo"] as? Bool) ?? true
160
+ requestPermission(isVideo: isVideo)
161
+ return result
162
+ }
163
+
164
+ func showMissedCall() {
165
+ OmiClient.setMissedCall { call in
166
+ UNUserNotificationCenter.current().getNotificationSettings { settings in
167
+ switch settings.authorizationStatus {
168
+ case .notDetermined:
169
+ break
170
+ case .authorized, .provisional:
171
+ let user = UserDefaults.standard
172
+ let title = user.string(forKey: "omicall/missedCallTitle") ?? ""
173
+ let message = user.string(forKey: "omicall/prefixMissedCallMessage") ?? ""
174
+ let content = UNMutableNotificationContent()
175
+ content.title = title
176
+ content.body = "\(message) \(call.callerNumber!)"
177
+ content.sound = .default
178
+ content.userInfo = [
179
+ "omisdkCallerNumber": call.callerNumber,
180
+ "omisdkIsVideo": call.isVideo,
181
+ ]
182
+ let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false)
183
+ let id = Int.random(in: 0..<10000000)
184
+ let request = UNNotificationRequest(identifier: "\(id)", content: content, trigger: trigger)
185
+ UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
265
186
  default:
266
- break
267
- }
268
- }
269
-
270
- @objc func switchBoardAnswer(_ notification: NSNotification) {
271
- guard let userInfo = notification.userInfo,
272
- let sip = userInfo[OMINotificationSIPKey] as? String else {
273
- return;
274
- }
275
- guestPhone = sip
276
- OmikitPlugin.instance.sendEvent(withName: SWITCHBOARD_ANSWER, body: ["sip": sip])
277
- }
278
-
279
- @objc func callDealloc(_ notification: NSNotification) {
280
- if (tempCallInfo != nil) {
281
- tempCallInfo!["status"] = OMICallState.disconnected.rawValue
282
- OmikitPlugin.instance.sendEvent(withName: CALL_STATE_CHANGED, body: tempCallInfo!)
283
- }
284
- }
285
-
286
- @objc fileprivate func callStateChanged(_ notification: NSNotification) {
287
- guard let userInfo = notification.userInfo,
288
- let call = userInfo[OMINotificationUserInfoCallKey] as? OMICall,
289
- let callState = userInfo[OMINotificationUserInfoCallStateKey] as? Int else {
290
- return;
291
- }
292
-
187
+ break
188
+ }
189
+ }
190
+ }
191
+ }
192
+
193
+
194
+ func registerNotificationCenter(showMissedCall: Bool) {
195
+ DispatchQueue.main.async { [weak self] in
196
+ guard let self = self else { return }
197
+ NotificationCenter.default.removeObserver(CallManager.instance!)
198
+ NotificationCenter.default.addObserver(CallManager.instance!,
199
+ selector: #selector(self.callStateChanged(_:)),
200
+ name: NSNotification.Name.OMICallStateChanged,
201
+ object: nil
202
+ )
203
+ NotificationCenter.default.addObserver(CallManager.instance!,
204
+ selector: #selector(self.callDealloc(_:)),
205
+ name: NSNotification.Name.OMICallDealloc,
206
+ object: nil
207
+ )
208
+ NotificationCenter.default.addObserver(CallManager.instance!,
209
+ selector: #selector(self.switchBoardAnswer(_:)),
210
+ name: NSNotification.Name.OMICallSwitchBoardAnswer,
211
+ object: nil
212
+ )
213
+ NotificationCenter.default.addObserver(CallManager.instance!, selector: #selector(self.updateNetworkHealth(_:)), name: NSNotification.Name.OMICallNetworkQuality, object: nil)
214
+ NotificationCenter.default.addObserver(CallManager.instance!, selector: #selector(self.audioChanged(_:)), name: NSNotification.Name.OMICallAudioRouteChange, object: nil)
215
+ if (showMissedCall) {
216
+ self.showMissedCall()
217
+ }
218
+ }
219
+ }
220
+
221
+ func registerVideoEvent() {
222
+ DispatchQueue.main.async {
223
+ NotificationCenter.default.addObserver(CallManager.instance!,
224
+ selector: #selector(self.videoUpdate(_:)),
225
+ name: NSNotification.Name.OMICallVideoInfo,
226
+ object: nil
227
+ )
228
+ }
229
+ }
230
+
231
+ func removeVideoEvent() {
232
+ DispatchQueue.main.async {
233
+ NotificationCenter.default.removeObserver(CallManager.instance!, name: NSNotification.Name.OMICallVideoInfo, object: nil)
234
+ }
235
+ }
236
+
237
+ @objc func audioChanged(_ notification: NSNotification) {
238
+ guard let userInfo = notification.userInfo,
239
+ let audioInfo = userInfo[OMINotificationCurrentAudioRouteKey] as? [[String: String]] else {
240
+ return;
241
+ }
242
+ OmikitPlugin.instance?.sendEvent(withName: AUDIO_CHANGE, body: [
243
+ "data": audioInfo,
244
+ ])
245
+
246
+ }
247
+
248
+ @objc func updateNetworkHealth(_ notification: NSNotification) {
249
+ guard let userInfo = notification.userInfo,
250
+ let state = userInfo[OMINotificationNetworkStatusKey] as? Int else {
251
+ return;
252
+ }
253
+ OmikitPlugin.instance.sendEvent(withName: CALL_QUALITY, body: ["quality": state])
254
+ }
255
+
256
+ @objc func videoUpdate(_ notification: NSNotification) {
257
+ guard let userInfo = notification.userInfo,
258
+ let state = userInfo[OMIVideoInfoState] as? Int else {
259
+ return;
260
+ }
261
+ switch (state) {
262
+ case 1:
263
+ OmikitPlugin.instance.sendEvent(withName: REMOTE_VIDEO_READY, body: nil)
264
+ break
265
+ default:
266
+ break
267
+ }
268
+ }
269
+
270
+ @objc func switchBoardAnswer(_ notification: NSNotification) {
271
+ guard let userInfo = notification.userInfo,
272
+ let sip = userInfo[OMINotificationSIPKey] as? String else {
273
+ return;
274
+ }
275
+ guestPhone = sip
276
+ OmikitPlugin.instance.sendEvent(withName: SWITCHBOARD_ANSWER, body: ["sip": sip])
277
+ }
278
+
279
+ @objc func callDealloc(_ notification: NSNotification) {
280
+ if (tempCallInfo != nil) {
281
+ tempCallInfo!["status"] = OMICallState.disconnected.rawValue
282
+ OmikitPlugin.instance.sendEvent(withName: CALL_STATE_CHANGED, body: tempCallInfo!)
283
+ }
284
+ }
285
+
286
+ @objc fileprivate func callStateChanged(_ notification: NSNotification) {
287
+ guard let userInfo = notification.userInfo,
288
+ let call = userInfo[OMINotificationUserInfoCallKey] as? OMICall,
289
+ let callState = userInfo[OMINotificationUserInfoCallStateKey] as? Int else {
290
+ return;
291
+ }
292
+
293
+ var dataToSend: [String: Any] = [
294
+ "status": callState,
295
+ "callInfo": "",
296
+ "incoming": false,
297
+ "callerNumber": "",
298
+ "isVideo": false,
299
+ "transactionId": "",
300
+ "_id": ""
301
+ ]
302
+
303
+ if(call != nil){
304
+ if(call.isIncoming && callState == OMICallState.early.rawValue){
305
+ dataToSend["status"] = OMICallState.incoming.rawValue
306
+ }
307
+ dataToSend["_id"] = String(describing: OmiCallModel(omiCall: call).uuid)
308
+ dataToSend["incoming"] = call.isIncoming
309
+ dataToSend["callerNumber"] = call.callerNumber
310
+ dataToSend["isVideo"] = call.isVideo
311
+ dataToSend["transactionId"] = call.omiId
312
+ }
313
+
314
+ if (callState != OMICallState.disconnected.rawValue) {
315
+ OmikitPlugin.instance?.sendEvent(withName: CALL_STATE_CHANGED, body: dataToSend)
316
+ }
317
+
318
+ switch (callState) {
319
+ case OMICallState.confirmed.rawValue:
320
+ if (videoManager == nil && call.isVideo) {
321
+ videoManager = OMIVideoViewManager.init()
322
+ }
323
+ isSpeaker = call.isVideo
324
+ lastStatusCall = "answered"
325
+ OmikitPlugin.instance.sendMuteStatus()
326
+ break
327
+ case OMICallState.incoming.rawValue:
328
+ guestPhone = call.callerNumber ?? ""
329
+ break
330
+ case OMICallState.disconnected.rawValue:
331
+ tempCallInfo = getCallInfo(call: call)
332
+ if (videoManager != nil) {
333
+ videoManager = nil
334
+ }
335
+ lastStatusCall = nil
336
+ guestPhone = ""
337
+ var combinedDictionary: [String: Any] = dataToSend
338
+ if (tempCallInfo != nil && tempCallInfo?.count ?? 0 > 0) {
339
+ combinedDictionary.merge(tempCallInfo ?? [:], uniquingKeysWith: { (_, new) in new })
340
+ }
341
+ OmikitPlugin.instance?.sendEvent(withName: CALL_STATE_CHANGED, body: combinedDictionary )
342
+ lastTimeCall = Date()
343
+ tempCallInfo = [:]
344
+ break
345
+ default:
346
+ break
347
+ }
348
+ }
349
+
350
+ private func getCallInfo(call: OMICall) -> [String: Any] {
351
+ var direction = "outbound"
352
+ if (guestPhone.count < 10) {
353
+ direction = "inbound"
354
+ }
355
+ let user = OmiClient.getCurrentSip()
356
+ let status = call.callState == .confirmed ? "answered" : "no_answered"
357
+ let timeEnd = Int(Date().timeIntervalSince1970)
358
+ return [
359
+ "transaction_id" : call.omiId,
360
+ "direction" : direction,
361
+ "source_number" : user,
362
+ "destination_number" : guestPhone,
363
+ "time_start_to_answer" : call.createDate,
364
+ "time_end" : timeEnd,
365
+ "sip_user": user,
366
+ "disposition" : lastStatusCall == nil ? "no_answered" : "answered",
367
+ "code_end_call" : call.lastStatus
368
+ ]
369
+ }
370
+
371
+
372
+ /// Start call
373
+ func startCall(_ phoneNumber: String, isVideo: Bool, completion: @escaping (_ : String) -> Void) {
374
+ let secondsSinceCurrentTime = lastTimeCall.timeIntervalSinceNow
375
+ guestPhone = phoneNumber
376
+ OmiClient.startCall(phoneNumber, isVideo: isVideo) { status in
377
+ DispatchQueue.main.async {
378
+ let callCurrent = self.omiLib.getCurrentCall()
293
379
  var dataToSend: [String: Any] = [
294
- "status": callState,
295
- "callInfo": "",
296
- "incoming": false,
297
- "callerNumber": "",
298
- "isVideo": false,
299
- "transactionId": "",
300
- "_id": ""
301
- ]
302
-
303
- if(call != nil){
304
- if(call.isIncoming && callState == OMICallState.early.rawValue){
305
- dataToSend["status"] = OMICallState.incoming.rawValue
306
- }
307
- dataToSend["_id"] = String(describing: OmiCallModel(omiCall: call).uuid)
308
- dataToSend["incoming"] = call.isIncoming
309
- dataToSend["callerNumber"] = call.callerNumber
310
- dataToSend["isVideo"] = call.isVideo
311
- dataToSend["transactionId"] = call.omiId
312
- }
313
-
314
- if (callState != OMICallState.disconnected.rawValue) {
315
- OmikitPlugin.instance?.sendEvent(withName: CALL_STATE_CHANGED, body: dataToSend)
316
- }
317
-
318
- switch (callState) {
319
- case OMICallState.confirmed.rawValue:
320
- if (videoManager == nil && call.isVideo) {
321
- videoManager = OMIVideoViewManager.init()
322
- }
323
- isSpeaker = call.isVideo
324
- lastStatusCall = "answered"
325
- OmikitPlugin.instance.sendMuteStatus()
326
- break
327
- case OMICallState.incoming.rawValue:
328
- guestPhone = call.callerNumber ?? ""
329
- break
330
- case OMICallState.disconnected.rawValue:
331
- tempCallInfo = getCallInfo(call: call)
332
- if (videoManager != nil) {
333
- videoManager = nil
334
- }
335
- lastStatusCall = nil
336
- guestPhone = ""
337
- var combinedDictionary: [String: Any] = dataToSend
338
- if (tempCallInfo != nil && tempCallInfo?.count ?? 0 > 0) {
339
- combinedDictionary.merge(tempCallInfo ?? [:], uniquingKeysWith: { (_, new) in new })
340
- }
341
- OmikitPlugin.instance?.sendEvent(withName: CALL_STATE_CHANGED, body: combinedDictionary )
342
- lastTimeCall = Date()
343
- tempCallInfo = [:]
344
- break
345
- default:
346
- break
347
- }
348
- }
349
-
350
- private func getCallInfo(call: OMICall) -> [String: Any] {
351
- var direction = "outbound"
352
- if (guestPhone.count < 10) {
353
- direction = "inbound"
354
- }
355
- let user = OmiClient.getCurrentSip()
356
- let status = call.callState == .confirmed ? "answered" : "no_answered"
357
- let timeEnd = Int(Date().timeIntervalSince1970)
358
- return [
359
- "transaction_id" : call.omiId,
360
- "direction" : direction,
361
- "source_number" : user,
362
- "destination_number" : guestPhone,
363
- "time_start_to_answer" : call.createDate,
364
- "time_end" : timeEnd,
365
- "sip_user": user,
366
- "disposition" : lastStatusCall == nil ? "no_answered" : "answered",
367
- "code_end_call" : call.lastStatus
380
+ "status": status.rawValue,
381
+ "_id": "",
382
+ "message": self.messageCall(type: status.rawValue)
368
383
  ]
369
- }
370
-
371
-
372
- /// Start call
373
- func startCall(_ phoneNumber: String, isVideo: Bool, completion: @escaping (_ : String) -> Void) {
374
- let secondsSinceCurrentTime = lastTimeCall.timeIntervalSinceNow
375
- guestPhone = phoneNumber
376
- OmiClient.startCall(phoneNumber, isVideo: isVideo) { status in
377
- DispatchQueue.main.async {
378
- let callCurrent = self.omiLib.getCurrentCall()
379
- var dataToSend: [String: Any] = [
380
- "status": status.rawValue,
381
- "_id": "",
382
- "message": self.messageCall(type: status.rawValue)
383
- ]
384
-
385
- if(callCurrent != nil){
386
- dataToSend["_id"] = String(describing: OmiCallModel(omiCall: callCurrent!).uuid)
387
- }
388
-
389
- if let jsonString = self.convertDictionaryToJson(dictionary: dataToSend) {
390
- completion(jsonString)
391
- } else {
392
- completion("Conversion to JSON failed")
393
- }
394
- return
395
- }
396
- }
397
- }
398
-
399
- /// Start call
400
- func startCallWithUuid(_ uuid: String, isVideo: Bool, completion: @escaping (_ : String) -> Void) {
401
- let phoneNumber = OmiClient.getPhone(uuid)
402
- if let phone = phoneNumber {
403
- guestPhone = phoneNumber ?? ""
404
- DispatchQueue.main.async {
405
- OmiClient.startCall(phone, isVideo: isVideo) { statusCall in
406
- let callCurrent = self.omiLib.getCurrentCall()
407
- // completion(status.rawValue)
408
- var dataToSend: [String: Any] = [
409
- "status": statusCall.rawValue,
410
- "_id": "",
411
- "message": self.messageCall(type: statusCall.rawValue)
412
- ]
413
- if(callCurrent != nil){
414
- dataToSend["_id"] = String(describing: OmiCallModel(omiCall: callCurrent!).uuid)
415
- }
416
- if let jsonString = self.convertDictionaryToJson(dictionary: dataToSend) {
417
- completion(jsonString)
418
- } else {
419
- completion("Conversion to JSON failed")
420
- }
421
- return
422
-
423
- }
424
- }
425
- return
426
- }
427
- }
428
-
429
- func endAvailableCall() -> [String: Any] {
430
- guard let call = getAvailableCall() else {
431
- let callInfo = [
432
- "status": OMICallState.disconnected.rawValue,
433
- ]
434
- OmikitPlugin.instance.sendEvent(withName: CALL_STATE_CHANGED, body: callInfo)
435
- return [:]
436
- }
437
- tempCallInfo = getCallInfo(call: call)
438
- omiLib.callManager.end(call)
439
- return tempCallInfo!
440
- }
441
-
442
- func endAllCalls() {
443
- omiLib.callManager.endAllCalls()
444
- }
445
-
446
- func joinCall() {
447
- guard let call = getAvailableCall() else {
448
- return
449
- }
450
- OmiClient.answerIncommingCall(call.uuid)
451
- }
452
-
453
- func sendDTMF(character: String) {
454
- guard let call = getAvailableCall() else {
455
- return
456
- }
457
- try? call.sendDTMF(character)
458
- }
459
-
460
- /// Toogle mtue
461
- func toggleMute() {
462
- guard let call = getAvailableCall() else {
463
- return
464
- }
465
- try? call.toggleMute()
466
- }
467
-
468
- /// Toogle hold
469
- func toggleHold() {
470
- guard let call = getAvailableCall() else {
471
- return
472
- }
473
- try? call.toggleHold()
474
- }
475
-
476
- /// Toogle speaker
477
- func toogleSpeaker() {
478
- if !isSpeaker {
479
- try? AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker)
480
- } else {
481
- try? AVAudioSession.sharedInstance().overrideOutputAudioPort(.none)
482
- }
483
- isSpeaker = !isSpeaker
484
- OmikitPlugin.instance.sendSpeakerStatus()
485
- }
486
-
487
- func getAudioOutputs() -> [[String: String]] {
488
- return OmiClient.getAudioInDevices()
489
- }
490
-
491
- func setAudioOutputs(portType: String) {
492
- return OmiClient.setAudioOutputs(portType)
493
- }
494
-
495
- func getCurrentAudio() -> [[String: String]] {
496
- return OmiClient.getCurrentAudio()
497
- }
498
-
499
- //video call
500
- func toggleCamera() {
501
- if let videoManager = videoManager {
502
- videoManager.toggleCamera()
503
- }
504
- }
505
-
506
- func getCameraStatus() -> Bool {
507
- guard let videoManager = videoManager else { return false }
508
- return videoManager.isCameraOn
509
- }
510
-
511
- func switchCamera() {
512
- if let videoManager = videoManager {
513
- videoManager.switchCamera()
514
- }
515
- }
516
-
517
- func getLocalPreviewView(frame: CGRect) -> UIView? {
518
- guard let videoManager = videoManager else { return nil}
519
- return videoManager.createView(forVideoLocal: frame)
520
- }
521
-
522
- func getRemotePreviewView(frame: CGRect) -> UIView? {
523
- guard let videoManager = videoManager else { return nil }
524
- return videoManager.createView(forVideoRemote: frame)
525
- }
526
-
527
- func logout() {
528
- OmiClient.logout()
529
- }
530
-
531
- func getCurrentUser(completion: @escaping (([String: Any]) -> Void)) {
532
- if let sip = OmiClient.getCurrentSip() {
533
- getUserInfo(phone: sip, completion: completion)
534
- } else {
535
- completion([:])
384
+
385
+ if(callCurrent != nil){
386
+ dataToSend["_id"] = String(describing: OmiCallModel(omiCall: callCurrent!).uuid)
536
387
  }
537
- }
538
-
539
- func getGuestUser(completion: @escaping (([String: Any]) -> Void)) {
540
- getUserInfo(phone: guestPhone, completion: completion)
541
- }
542
-
543
- func getUserInfo(phone: String, completion: @escaping (([String: Any]) -> Void)) {
544
- if let account = OmiClient.getAccountInfo(phone) as? [String: Any] {
545
- completion(account)
388
+
389
+ if let jsonString = self.convertDictionaryToJson(dictionary: dataToSend) {
390
+ completion(jsonString)
546
391
  } else {
547
- completion([:])
548
- }
549
- }
550
-
551
- private func baseInfoFromCall(call: OMICall) -> [String: Any] {
552
- return [
553
- "callerNumber": call.callerNumber,
554
- "isVideo": call.isVideo,
555
- "transactionId": call.omiId,
556
- ]
557
- }
392
+ completion("Conversion to JSON failed")
393
+ }
394
+ return
395
+ }
396
+ }
397
+ }
398
+
399
+ /// Start call
400
+ func startCallWithUuid(_ uuid: String, isVideo: Bool, completion: @escaping (_ : String) -> Void) {
401
+ let phoneNumber = OmiClient.getPhone(uuid)
402
+ if let phone = phoneNumber {
403
+ guestPhone = phoneNumber ?? ""
404
+ DispatchQueue.main.async {
405
+ OmiClient.startCall(phone, isVideo: isVideo) { statusCall in
406
+ let callCurrent = self.omiLib.getCurrentCall()
407
+ // completion(status.rawValue)
408
+ var dataToSend: [String: Any] = [
409
+ "status": statusCall.rawValue,
410
+ "_id": "",
411
+ "message": self.messageCall(type: statusCall.rawValue)
412
+ ]
413
+ if(callCurrent != nil){
414
+ dataToSend["_id"] = String(describing: OmiCallModel(omiCall: callCurrent!).uuid)
415
+ }
416
+ if let jsonString = self.convertDictionaryToJson(dictionary: dataToSend) {
417
+ completion(jsonString)
418
+ } else {
419
+ completion("Conversion to JSON failed")
420
+ }
421
+ return
422
+
423
+ }
424
+ }
425
+ return
426
+ }
427
+ }
428
+
429
+ func endAvailableCall() -> [String: Any] {
430
+ guard let call = getAvailableCall() else {
431
+ let callInfo = [
432
+ "status": OMICallState.disconnected.rawValue,
433
+ ]
434
+ OmikitPlugin.instance.sendEvent(withName: CALL_STATE_CHANGED, body: callInfo)
435
+ return [:]
436
+ }
437
+ tempCallInfo = getCallInfo(call: call)
438
+ omiLib.callManager.end(call)
439
+ return tempCallInfo!
440
+ }
441
+
442
+ func endAllCalls() {
443
+ omiLib.callManager.endAllCalls()
444
+ }
445
+
446
+ func joinCall() {
447
+ guard let call = getAvailableCall() else {
448
+ return
449
+ }
450
+ OmiClient.answerIncommingCall(call.uuid)
451
+ }
452
+
453
+ func sendDTMF(character: String) {
454
+ guard let call = getAvailableCall() else {
455
+ return
456
+ }
457
+ try? call.sendDTMF(character)
458
+ }
459
+
460
+ /// Toogle mtue
461
+ func toggleMute() {
462
+ guard let call = getAvailableCall() else {
463
+ return
464
+ }
465
+ try? call.toggleMute()
466
+ }
467
+
468
+ /// Toogle hold
469
+ func toggleHold() -> Bool {
470
+ guard let call = getAvailableCall() else {
471
+ return false // Không có cuộc gọi khả dụng
472
+ }
473
+
474
+ do {
475
+ try call.toggleHold()
476
+ return true // Thành công
477
+ } catch {
478
+ print("Error toggling hold: \(error)")
479
+ return false // Thất bại
480
+ }
481
+ }
482
+
483
+ /// Toogle speaker
484
+ func toogleSpeaker() {
485
+ if !isSpeaker {
486
+ try? AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker)
487
+ } else {
488
+ try? AVAudioSession.sharedInstance().overrideOutputAudioPort(.none)
489
+ }
490
+ isSpeaker = !isSpeaker
491
+ OmikitPlugin.instance.sendSpeakerStatus()
492
+ }
493
+
494
+ func getAudioOutputs() -> [[String: String]] {
495
+ return OmiClient.getAudioInDevices()
496
+ }
497
+
498
+ func setAudioOutputs(portType: String) {
499
+ return OmiClient.setAudioOutputs(portType)
500
+ }
501
+
502
+ func getCurrentAudio() -> [[String: String]] {
503
+ return OmiClient.getCurrentAudio()
504
+ }
505
+
506
+ //video call
507
+ func toggleCamera() {
508
+ if let videoManager = videoManager {
509
+ videoManager.toggleCamera()
510
+ }
511
+ }
512
+
513
+ func getCameraStatus() -> Bool {
514
+ guard let videoManager = videoManager else { return false }
515
+ return videoManager.isCameraOn
516
+ }
517
+
518
+ func switchCamera() {
519
+ if let videoManager = videoManager {
520
+ videoManager.switchCamera()
521
+ }
522
+ }
523
+
524
+ func getLocalPreviewView(frame: CGRect) -> UIView? {
525
+ guard let videoManager = videoManager else { return nil}
526
+ return videoManager.createView(forVideoLocal: frame)
527
+ }
528
+
529
+ func getRemotePreviewView(frame: CGRect) -> UIView? {
530
+ guard let videoManager = videoManager else { return nil }
531
+ return videoManager.createView(forVideoRemote: frame)
532
+ }
533
+
534
+ func logout() {
535
+ OmiClient.logout()
536
+ }
537
+
538
+ func getCurrentUser(completion: @escaping (([String: Any]) -> Void)) {
539
+ if let sip = OmiClient.getCurrentSip() {
540
+ getUserInfo(phone: sip, completion: completion)
541
+ } else {
542
+ completion([:])
543
+ }
544
+ }
545
+
546
+ func getGuestUser(completion: @escaping (([String: Any]) -> Void)) {
547
+ getUserInfo(phone: guestPhone, completion: completion)
548
+ }
549
+
550
+ func getUserInfo(phone: String, completion: @escaping (([String: Any]) -> Void)) {
551
+ if let account = OmiClient.getAccountInfo(phone) as? [String: Any] {
552
+ completion(account)
553
+ } else {
554
+ completion([:])
555
+ }
556
+ }
557
+
558
+ private func baseInfoFromCall(call: OMICall) -> [String: Any] {
559
+ return [
560
+ "callerNumber": call.callerNumber,
561
+ "isVideo": call.isVideo,
562
+ "transactionId": call.omiId,
563
+ ]
564
+ }
558
565
  }
559
566
 
560
567