// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 import Foundation import Flutter private let channelNamePrefix = "com.amazonaws.amplify/push_notification/" enum NativeEvent { case tokenReceived case notificationOpened case foregroundMessageReceived var eventName: String { switch self { case .tokenReceived: return "TOKEN_RECEIVED" case .notificationOpened: return "NOTIFICATION_OPENED" case .foregroundMessageReceived: return "FOREGROUND_MESSAGE_RECEIVED" } } var eventChannelName: String { return "\(channelNamePrefix)event/\(self.eventName)" } } enum AmplifyPushNotificationsEvent { case payload(payload: [AnyHashable: Any]) case error(error: FlutterError) } class PushNotificationEventsStreamHandler: NSObject, FlutterStreamHandler { private let eventChannel: FlutterEventChannel private var eventQueue: [AmplifyPushNotificationsEvent] = [] private var eventSink: FlutterEventSink? init(eventType: NativeEvent, binaryMessenger: FlutterBinaryMessenger) { eventChannel = FlutterEventChannel(name: eventType.eventChannelName, binaryMessenger: binaryMessenger) super.init() eventChannel.setStreamHandler(self) } func onListen( withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink ) -> FlutterError? { eventSink = events flushEvents() return nil } func onCancel( withArguments arguments: Any? ) -> FlutterError? { eventSink = nil eventQueue.removeAll() return nil } func sendEvent(payload: [AnyHashable: Any]) { if let eventSink = eventSink { eventSink(payload) } else { eventQueue.append( AmplifyPushNotificationsEvent.payload(payload: payload) ) } } func sendError(error: FlutterError) { if let eventSink = eventSink { eventSink(error) } else { eventQueue.append( AmplifyPushNotificationsEvent.error(error: error) ) } } private func flushEvents() { if let eventSink = eventSink { while !eventQueue.isEmpty { switch eventQueue.removeFirst() { case .payload(let payload): eventSink(payload) case .error(let error): eventSink(error) } } } } } protocol EventsStreamHandlersProtocol { var tokenReceived: PushNotificationEventsStreamHandler { get } var notificationOpened: PushNotificationEventsStreamHandler { get } var foregroundMessageReceived: PushNotificationEventsStreamHandler { get } } struct EventsStreamHandlers: EventsStreamHandlersProtocol { let tokenReceived: PushNotificationEventsStreamHandler let notificationOpened: PushNotificationEventsStreamHandler let foregroundMessageReceived: PushNotificationEventsStreamHandler init(binaryMessenger: FlutterBinaryMessenger) { tokenReceived = PushNotificationEventsStreamHandler( eventType: .tokenReceived, binaryMessenger: binaryMessenger ) notificationOpened = PushNotificationEventsStreamHandler( eventType: .notificationOpened, binaryMessenger: binaryMessenger ) foregroundMessageReceived = PushNotificationEventsStreamHandler( eventType: .foregroundMessageReceived, binaryMessenger: binaryMessenger ) } }