ConferenceSessionImp.swift 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. //
  2. // ConferenceSessionImp.swift
  3. // TUIRoomKit
  4. //
  5. // Created by CY zhao on 2024/8/13.
  6. //
  7. import Foundation
  8. import RTCRoomEngine
  9. import Factory
  10. import Combine
  11. let TUI_ROOM_CALLING_BELL_KEY = "RoomCallingBell"
  12. let TUI_ROOM_ENABLE_MUTE_MODE_KEY = "RoomEnableMuteMode"
  13. let TUI_ROOM_ENABLE_VIBRATION_MODE_KEY = "RoomEnableVibrationMode"
  14. class ConferenceSessionImp: NSObject {
  15. private(set) var isEnableWaterMark = false;
  16. private(set) var waterMarkText = "";
  17. private(set) var appGroup = "com.tencent.TUIRoomTXReplayKit-Screen"
  18. private(set) var hasCustomContacts = false
  19. private(set) lazy var bellPath: String? = {
  20. return UserDefaults.standard.object(forKey: TUI_ROOM_CALLING_BELL_KEY) as? String
  21. }()
  22. private(set) lazy var enableMuteMode: Bool = {
  23. return UserDefaults.standard.object(forKey: TUI_ROOM_ENABLE_MUTE_MODE_KEY) as? Bool ?? false
  24. }()
  25. private(set) lazy var enableVibrationMode: Bool = {
  26. return UserDefaults.standard.object(forKey: TUI_ROOM_ENABLE_VIBRATION_MODE_KEY) as? Bool ?? true
  27. }()
  28. private(set) lazy var participants: [User] = {
  29. return []
  30. }()
  31. private var observers = NSHashTable<ConferenceObserver>.weakObjects()
  32. // MARK: - Public
  33. override init() {
  34. super.init()
  35. subscribeEngine()
  36. }
  37. func addObserver(observer: ConferenceObserver) {
  38. guard !observers.contains(observer) else { return }
  39. observers.add(observer)
  40. }
  41. func removeObserver(observer: ConferenceObserver) {
  42. guard observers.contains(observer) else { return }
  43. observers.remove(observer)
  44. }
  45. func destroy() {
  46. unsubscribeEngine()
  47. observers.removeAllObjects()
  48. }
  49. func enableWaterMark() {
  50. self.isEnableWaterMark = true
  51. RoomKitReport.reportData(.metricsWaterMarkEnable)
  52. }
  53. func setWaterMarkText(waterMarkText: String) {
  54. self.waterMarkText = waterMarkText
  55. RoomKitReport.reportData(.metricsWaterMarkCustomText)
  56. }
  57. func setContactsViewProvider(_ provider: @escaping (ConferenceParticipants) -> ContactViewProtocol) {
  58. hasCustomContacts = true
  59. Container.shared.contactViewController.register { participants in
  60. provider(participants)
  61. }
  62. }
  63. func setCallingBell(filePath: String) {
  64. UserDefaults.standard.set(filePath, forKey: TUI_ROOM_CALLING_BELL_KEY)
  65. UserDefaults.standard.synchronize()
  66. }
  67. func enableMuteMode(enable: Bool) {
  68. UserDefaults.standard.set(enable, forKey: TUI_ROOM_ENABLE_MUTE_MODE_KEY)
  69. UserDefaults.standard.synchronize()
  70. }
  71. func enableVibrationMode(enable: Bool) {
  72. UserDefaults.standard.set(enable, forKey: TUI_ROOM_ENABLE_VIBRATION_MODE_KEY)
  73. UserDefaults.standard.synchronize()
  74. }
  75. func setAppGroup(_ appGroup: String) {
  76. self.appGroup = appGroup
  77. }
  78. func setParticipants(_ participants: [User]) {
  79. self.participants = participants
  80. }
  81. deinit {
  82. unsubscribeEngine()
  83. }
  84. // MARK: - Private
  85. private func subscribeEngine() {
  86. EngineEventCenter.shared.subscribeEngine(event: .onExitedRoom, observer: self)
  87. EngineEventCenter.shared.subscribeEngine(event: .onDestroyedRoom, observer: self)
  88. EngineEventCenter.shared.subscribeEngine(event: .onStartedRoom, observer: self)
  89. EngineEventCenter.shared.subscribeEngine(event: .onJoinedRoom, observer: self)
  90. EngineEventCenter.shared.subscribeEngine(event: .onRoomDismissed, observer: self)
  91. EngineEventCenter.shared.subscribeEngine(event: .onKickedOutOfRoom, observer: self)
  92. EngineEventCenter.shared.subscribeEngine(event: .onKickedOffLine, observer: self)
  93. EngineEventCenter.shared.subscribeEngine(event: .onUserSigExpired, observer: self)
  94. }
  95. private func unsubscribeEngine() {
  96. EngineEventCenter.shared.unsubscribeEngine(event: .onExitedRoom, observer: self)
  97. EngineEventCenter.shared.unsubscribeEngine(event: .onDestroyedRoom, observer: self)
  98. EngineEventCenter.shared.unsubscribeEngine(event: .onStartedRoom, observer: self)
  99. EngineEventCenter.shared.unsubscribeEngine(event: .onJoinedRoom, observer: self)
  100. EngineEventCenter.shared.unsubscribeEngine(event: .onRoomDismissed, observer: self)
  101. EngineEventCenter.shared.unsubscribeEngine(event: .onKickedOutOfRoom, observer: self)
  102. EngineEventCenter.shared.unsubscribeEngine(event: .onKickedOffLine, observer: self)
  103. EngineEventCenter.shared.unsubscribeEngine(event: .onUserSigExpired, observer: self)
  104. }
  105. @WeakLazyInjected(\.conferenceStore) private var operation
  106. }
  107. // MARK: - callback
  108. extension ConferenceSessionImp: RoomEngineEventResponder {
  109. func onEngineEvent(name: EngineEventCenter.RoomEngineEvent, param: [String : Any]?) {
  110. switch name {
  111. case .onStartedRoom:
  112. guard let roomInfo = param?["roomInfo"] as? TUIRoomInfo else { return }
  113. guard let error = param?["error"] as? TUIError else { return }
  114. guard let message = param?["mesasge"] as? String else { return }
  115. handleRoomStarted(roomInfo: roomInfo, error: error, message: message)
  116. case .onJoinedRoom:
  117. guard let roomInfo = param?["roomInfo"] as? TUIRoomInfo else { return }
  118. guard let error = param?["error"] as? TUIError else { return }
  119. guard let message = param?["mesasge"] as? String else { return }
  120. handleRoomJoined(roomInfo: roomInfo, error: error, message: message)
  121. case .onDestroyedRoom, .onRoomDismissed:
  122. handleRoomFinished(param: param)
  123. case .onExitedRoom, .onKickedOutOfRoom, .onKickedOffLine, .onUserSigExpired:
  124. handleRoomExited(param: param)
  125. default: break
  126. }
  127. }
  128. private func handleRoomStarted(roomInfo: TUIRoomInfo, error: TUIError, message: String) {
  129. let errorMessage = getErrorDescription(error: error, message: message)
  130. for observer in observers.allObjects {
  131. observer.onConferenceStarted?(roomInfo: roomInfo, error: error, message: errorMessage)
  132. }
  133. }
  134. private func handleRoomJoined(roomInfo: TUIRoomInfo, error: TUIError, message: String) {
  135. let errorMessage = getErrorDescription(error: error, message: message)
  136. for observer in observers.allObjects {
  137. observer.onConferenceJoined?(roomInfo: roomInfo, error: error, message: errorMessage)
  138. }
  139. }
  140. private func handleRoomFinished(param: [String : Any]?) {
  141. guard let roomInfo = param?["roomInfo"] as? TUIRoomInfo else { return }
  142. guard let reason = param?["reason"] as? ConferenceFinishedReason else { return }
  143. for observer in observers.allObjects {
  144. observer.onConferenceFinished?(roomInfo: roomInfo, reason: reason)
  145. }
  146. }
  147. private func handleRoomExited(param: [String : Any]?) {
  148. guard let roomInfo = param?["roomInfo"] as? TUIRoomInfo else { return }
  149. guard let reason = param?["reason"] as? ConferenceExitedReason else { return }
  150. for observer in observers.allObjects {
  151. observer.onConferenceExited?(roomInfo: roomInfo, reason: reason)
  152. }
  153. }
  154. private func getErrorDescription(error: TUIError, message: String) -> String {
  155. if error.isCommon, let description = error.description {
  156. return description
  157. } else {
  158. return message
  159. }
  160. }
  161. }
  162. extension Container {
  163. var contactViewController: ParameterFactory<ConferenceParticipants, ContactViewProtocol?> {
  164. promised().scope(.unique)
  165. }
  166. }