Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

222 linhas
9.5 KiB

  1. //
  2. // PusherService.swift
  3. // pusher_client
  4. //
  5. // Created by Romario Chinloy on 10/26/20.
  6. //
  7. import Flutter
  8. import PusherSwiftWithEncryption
  9. class PusherService: MChannel {
  10. static let CHANNEL_NAME = "com.github.chinloyal/pusher_client"
  11. static let EVENT_STREAM = "com.github.chinloyal/pusher_client_stream"
  12. static let LOG_TAG = "PusherClientPlugin"
  13. static let PRIVATE_PREFIX = "private-"
  14. static let PRIVATE_ENCRYPTED_PREFIX = "private-encrypted-"
  15. static let PRESENCE_PREFIX = "presence-"
  16. private var _pusherInstance: Pusher!
  17. private var bindedEvents = Dictionary<String, String>()
  18. struct Utils {
  19. static var enableLogging = true
  20. static func debugLog(msg: String) {
  21. if(enableLogging) {
  22. debugPrint("D/\(PusherService.LOG_TAG): \(msg)")
  23. }
  24. }
  25. static func errorLog(msg: String) {
  26. if(enableLogging) {
  27. debugPrint("E/\(PusherService.LOG_TAG): \(msg)")
  28. }
  29. }
  30. }
  31. func register(messenger: FlutterBinaryMessenger) {
  32. let methodChannel = FlutterMethodChannel(name: PusherService.CHANNEL_NAME, binaryMessenger: messenger)
  33. methodChannel.setMethodCallHandler { (_ call:FlutterMethodCall, result:@escaping FlutterResult) in
  34. switch call.method {
  35. case "init":
  36. self.`init`(call, result: result)
  37. case "connect":
  38. self.connect(result: result)
  39. case "disconnect":
  40. self.disconnect(result: result)
  41. case "getSocketId":
  42. self.getSocketId(result: result)
  43. case "subscribe":
  44. self.subscribe(call, result: result)
  45. case "unsubscribe":
  46. self.unsubscribe(call, result: result)
  47. case "bind":
  48. self.bind(call, result: result)
  49. case "unbind":
  50. self.unbind(call, result: result)
  51. case "trigger":
  52. self.trigger(call, result: result)
  53. default:
  54. result(FlutterMethodNotImplemented)
  55. }
  56. }
  57. let eventChannel = FlutterEventChannel(name: PusherService.EVENT_STREAM, binaryMessenger: messenger)
  58. eventChannel.setStreamHandler(StreamHandler.default)
  59. }
  60. func `init`(_ call:FlutterMethodCall, result:@escaping FlutterResult) {
  61. do {
  62. let json = call.arguments as! String
  63. let pusherArgs: PusherArgs = try JSONDecoder().decode(PusherArgs.self, from: json.data(using: .utf8)!)
  64. Utils.enableLogging = pusherArgs.initArgs.enableLogging
  65. if(_pusherInstance == nil) {
  66. let pusherOptions = PusherClientOptions(
  67. authMethod: pusherArgs.pusherOptions.auth == nil ? .noMethod : AuthMethod.authRequestBuilder(authRequestBuilder: AuthRequestBuilder(pusherAuth: pusherArgs.pusherOptions.auth!)),
  68. host: pusherArgs.pusherOptions.cluster != nil ? .cluster(pusherArgs.pusherOptions.cluster!) : .host(pusherArgs.pusherOptions.host),
  69. port: pusherArgs.pusherOptions.encrypted ? pusherArgs.pusherOptions.wssPort : pusherArgs.pusherOptions.wsPort,
  70. useTLS: pusherArgs.pusherOptions.encrypted,
  71. activityTimeout: Double(pusherArgs.pusherOptions.activityTimeout) / 1000
  72. )
  73. _pusherInstance = Pusher(key: pusherArgs.appKey, options: pusherOptions)
  74. _pusherInstance.connection.reconnectAttemptsMax = pusherArgs.pusherOptions.maxReconnectionAttempts
  75. _pusherInstance.connection.maxReconnectGapInSeconds = Double(pusherArgs.pusherOptions.maxReconnectGapInSeconds)
  76. _pusherInstance.connection.pongResponseTimeoutInterval = Double(pusherArgs.pusherOptions.pongTimeout) / 1000
  77. _pusherInstance.connection.delegate = ConnectionListener.default
  78. Utils.debugLog(msg: "Pusher initialized")
  79. result(nil)
  80. }
  81. } catch let err {
  82. Utils.errorLog(msg: err.localizedDescription)
  83. result(FlutterError(code: "INIT_ERROR", message: err.localizedDescription, details: err))
  84. }
  85. }
  86. func connect(result:@escaping FlutterResult) {
  87. _pusherInstance.connect()
  88. result(nil)
  89. }
  90. func disconnect(result:@escaping FlutterResult) {
  91. _pusherInstance.disconnect()
  92. Utils.debugLog(msg: "Disconnect")
  93. result(nil)
  94. }
  95. func getSocketId(result:@escaping FlutterResult) {
  96. result(_pusherInstance.connection.socketId)
  97. }
  98. func subscribe(_ call:FlutterMethodCall, result:@escaping FlutterResult) {
  99. let channelMap = call.arguments as! [String: String]
  100. let channelName: String = channelMap["channelName"]!
  101. var channel: PusherChannel
  102. if(!channelName.starts(with: PusherService.PRESENCE_PREFIX)) {
  103. channel = _pusherInstance.subscribe(channelName)
  104. } else {
  105. channel = _pusherInstance.subscribeToPresenceChannel(channelName: channelName)
  106. for pEvent in Constants.PresenceEvents.allCases {
  107. channel.bind(eventName: pEvent.rawValue, eventCallback: ChannelEventListener.default.onEvent)
  108. }
  109. }
  110. for pEvent in Constants.Events.allCases {
  111. channel.bind(eventName: pEvent.rawValue, eventCallback: ChannelEventListener.default.onEvent)
  112. }
  113. Utils.debugLog(msg: "Subscribed: \(channelName)")
  114. result(nil)
  115. }
  116. func unsubscribe(_ call:FlutterMethodCall, result:@escaping FlutterResult) {
  117. let channelMap = call.arguments as! [String: String]
  118. let channelName: String = channelMap["channelName"]!
  119. _pusherInstance.unsubscribe(channelName)
  120. Utils.debugLog(msg: "Unsubscribed: \(channelName)")
  121. result(nil)
  122. }
  123. /**
  124. * Note binding can happen before the channel has been subscribed to
  125. */
  126. func bind(_ call:FlutterMethodCall, result:@escaping FlutterResult) {
  127. let map = call.arguments as! [String: String]
  128. let channelName: String = map["channelName"]!
  129. let eventName: String = map["eventName"]!
  130. var channel: PusherChannel
  131. if(!channelName.starts(with: PusherService.PRESENCE_PREFIX)) {
  132. channel = _pusherInstance.connection.channels.find(name: channelName)!
  133. bindedEvents[channelName + eventName] = channel.bind(eventName: eventName, eventCallback: ChannelEventListener.default.onEvent)
  134. } else {
  135. channel = _pusherInstance.connection.channels.findPresence(name: channelName)!
  136. bindedEvents[channelName + eventName] = channel.bind(eventName: eventName, eventCallback: ChannelEventListener.default.onEvent)
  137. }
  138. Utils.debugLog(msg: "[BIND] \(eventName)")
  139. result(nil)
  140. }
  141. func unbind(_ call:FlutterMethodCall, result:@escaping FlutterResult) {
  142. let map = call.arguments as! [String: String]
  143. let channelName: String = map["channelName"]!
  144. let eventName: String = map["eventName"]!
  145. var channel: PusherChannel
  146. let callBackId = bindedEvents[channelName + eventName]
  147. if(callBackId != nil) {
  148. if(!channelName.starts(with: PusherService.PRESENCE_PREFIX)) {
  149. channel = _pusherInstance.connection.channels.find(name: channelName)!
  150. channel.unbind(eventName: eventName, callbackId: callBackId!)
  151. } else {
  152. channel = _pusherInstance.connection.channels.findPresence(name: channelName)!
  153. channel.unbind(eventName: eventName, callbackId: callBackId!)
  154. }
  155. }
  156. Utils.debugLog(msg: "[UNBIND] \(eventName)")
  157. result(nil)
  158. }
  159. func trigger(_ call:FlutterMethodCall, result:@escaping FlutterResult) {
  160. do {
  161. let json = call.arguments as! String
  162. let clientEvent: ClientEvent = try JSONDecoder().decode(ClientEvent.self, from: json.data(using: .utf8)!)
  163. let channelName = clientEvent.channelName
  164. let eventName = clientEvent.eventName
  165. let data: String = clientEvent.data ?? ""
  166. let errorMessage = "Trigger can only be called on private and presence channels."
  167. switch clientEvent.channelName {
  168. case _ where channelName.starts(with: PusherService.PRIVATE_ENCRYPTED_PREFIX):
  169. result(FlutterError(code: "TRIGGER_ERROR", message: errorMessage, details: nil))
  170. case _ where channelName.starts(with: PusherService.PRIVATE_PREFIX):
  171. let channel: PusherChannel = _pusherInstance.connection.channels.find(name: channelName)!
  172. channel.trigger(eventName: eventName, data: data)
  173. case _ where channelName.starts(with: PusherService.PRESENCE_PREFIX):
  174. let channel: PusherPresenceChannel = _pusherInstance.connection.channels.findPresence(name: channelName)!
  175. channel.trigger(eventName: eventName, data: data)
  176. default:
  177. result(FlutterError(code: "TRIGGER_ERROR", message: errorMessage, details: nil))
  178. }
  179. Utils.debugLog(msg: "[TRIGGER] \(eventName)")
  180. result(nil)
  181. } catch let err {
  182. Utils.errorLog(msg: err.localizedDescription)
  183. result(FlutterError(code: "TRIGGER_ERROR", message: err.localizedDescription, details: err))
  184. }
  185. }
  186. }