diff --git a/ios/Push.swift b/ios/Push.swift index 4278926..613109c 100644 --- a/ios/Push.swift +++ b/ios/Push.swift @@ -3,15 +3,16 @@ import NotificationCenter import React @objc(Push) -public class Push: RCTEventEmitter { +final public class Push: RCTEventEmitter { private var notificationCallbackDictionary: [String: () -> Void] = [:] - private var isInitialized = false - private var queue: [Action] = [] - - @objc public override init() { - super.init() - UNUserNotificationCenter.current().delegate = self + private static var isInitialized = false + @objc public static var emitter: RCTEventEmitter? + private static var queue: [Action] = [] + + override public init() { + super.init() + Self.emitter = self } enum NotificationType: String, CaseIterable { @@ -23,30 +24,32 @@ public class Push: RCTEventEmitter { let payload: Any! } - private func sendStoreAction(_ action: Action) { - self.sendEvent(withName: action.type.rawValue, body: action.payload) + private static func sendStoreAction(_ action: Action) { + if let emitter = self.emitter { + emitter.sendEvent(withName: action.type.rawValue, body: action.payload) + } } - @objc public func dispatch(type: String, payload: Any!) { + @objc public static func dispatch(type: String, payload: Any!) { let actionObj = Action(type: .init(rawValue: type) ?? .errorReceived, payload: payload) if isInitialized { - self.sendStoreAction(actionObj) + sendStoreAction(actionObj) } else { - self.queue.append(actionObj) + queue.append(actionObj) } } @objc public override func startObserving() { - isInitialized = true - for event in queue { - sendStoreAction(event) - } - queue = [] - } - - @objc public override func stopObserving() { - isInitialized = false - } + Self.isInitialized = true + for event in Self.queue { + Self.sendStoreAction(event) + } + Self.queue = [] + } + + @objc public override func stopObserving() { + Self.isInitialized = false + } public override func supportedEvents() -> [String]! { return NotificationType.allCases.map { $0.rawValue } @@ -104,16 +107,16 @@ public class Push: RCTEventEmitter { extension Push: UNUserNotificationCenterDelegate { - func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { + public func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { let tokenParts = deviceToken.map { data -> String in return String(format: "%02x", data) } let token = tokenParts.joined() - dispatch(type: NotificationType.deviceTokenReceived.rawValue, payload: token) + Self.dispatch(type: NotificationType.deviceTokenReceived.rawValue, payload: token) } - func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { - dispatch( + public func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { + Self.dispatch( type: NotificationType.errorReceived.rawValue, payload: error.localizedDescription ) @@ -121,41 +124,41 @@ extension Push: UNUserNotificationCenterDelegate { public func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { let uuid = UUID().uuidString - dispatch( + Self.dispatch( type: NotificationType.notificationReceived.rawValue, payload: ["payload": notification.request.content.userInfo, "uuid": uuid, "kind": "foreground"] ) notificationCallbackDictionary[uuid] = { completionHandler([.badge, .banner, .sound, .list]) } - DispatchQueue.main.asyncAfter(deadline: .now() + 29) { [weak self] in - if let callback = self?.notificationCallbackDictionary[uuid] { + DispatchQueue.main.asyncAfter(deadline: .now() + 29) { + if let callback = self.notificationCallbackDictionary[uuid] { callback() - self?.notificationCallbackDictionary.removeValue(forKey: uuid) + self.notificationCallbackDictionary.removeValue(forKey: uuid) } } } public func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse) async { - dispatch( + Self.dispatch( type: NotificationType.notificationReceived.rawValue, payload: ["payload": response.notification.request.content.userInfo, "kind": "opened"] ) } - func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { + public func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { let uuid = UUID().uuidString - dispatch( + Self.dispatch( type: NotificationType.notificationReceived.rawValue, payload: ["payload": userInfo, "uuid": uuid, "kind": "background"] ) notificationCallbackDictionary[uuid] = { completionHandler(.newData) } - DispatchQueue.main.asyncAfter(deadline: .now() + 29) { [weak self] in - if let callback = self?.notificationCallbackDictionary[uuid] { + DispatchQueue.main.asyncAfter(deadline: .now() + 29) { + if let callback = self.notificationCallbackDictionary[uuid] { callback() - self?.notificationCallbackDictionary.removeValue(forKey: uuid) + self.notificationCallbackDictionary.removeValue(forKey: uuid) } } }