Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,6 @@ import io.flutter.plugin.common.StandardMessageCodec
import java.io.ByteArrayOutputStream
import java.nio.ByteBuffer
private object NotificationsPigeonUtils {

fun wrapResult(result: Any?): List<Any?> {
return listOf(result)
}

fun wrapError(exception: Throwable): List<Any?> {
return if (exception is FlutterError) {
listOf(
exception.code,
exception.message,
exception.details
)
} else {
listOf(
exception.javaClass.simpleName,
exception.toString(),
"Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception)
)
}
}
fun deepEquals(a: Any?, b: Any?): Boolean {
if (a is ByteArray && b is ByteArray) {
return a.contentEquals(b)
Expand Down Expand Up @@ -78,40 +58,6 @@ class FlutterError (
val details: Any? = null
) : Throwable()

/** Generated class from Pigeon that represents data sent in messages. */
data class NotificationDataFromLaunch (
/**
* The raw payload that is attached to the notification,
* holding the information required to carry out the navigation.
*
* See [NotificationHostApi.getNotificationDataFromLaunch].
*/
val payload: Map<Any?, Any?>
)
{
companion object {
fun fromList(pigeonVar_list: List<Any?>): NotificationDataFromLaunch {
val payload = pigeonVar_list[0] as Map<Any?, Any?>
return NotificationDataFromLaunch(payload)
}
}
fun toList(): List<Any?> {
return listOf(
payload,
)
}
override fun equals(other: Any?): Boolean {
if (other !is NotificationDataFromLaunch) {
return false
}
if (this === other) {
return true
}
return NotificationsPigeonUtils.deepEquals(toList(), other.toList()) }

override fun hashCode(): Int = toList().hashCode()
}

/**
* Generated class from Pigeon that represents data sent in messages.
* This class should not be extended by any user class outside of the generated file.
Expand Down Expand Up @@ -202,16 +148,11 @@ private open class NotificationsPigeonCodec : StandardMessageCodec() {
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
return when (type) {
129.toByte() -> {
return (readValue(buffer) as? List<Any?>)?.let {
NotificationDataFromLaunch.fromList(it)
}
}
130.toByte() -> {
return (readValue(buffer) as? List<Any?>)?.let {
IosNotificationTapEvent.fromList(it)
}
}
131.toByte() -> {
130.toByte() -> {
return (readValue(buffer) as? List<Any?>)?.let {
AndroidNotificationTapEvent.fromList(it)
}
Expand All @@ -221,16 +162,12 @@ private open class NotificationsPigeonCodec : StandardMessageCodec() {
}
override fun writeValue(stream: ByteArrayOutputStream, value: Any?) {
when (value) {
is NotificationDataFromLaunch -> {
stream.write(129)
writeValue(stream, value.toList())
}
is IosNotificationTapEvent -> {
stream.write(130)
stream.write(129)
writeValue(stream, value.toList())
}
is AndroidNotificationTapEvent -> {
stream.write(131)
stream.write(130)
writeValue(stream, value.toList())
}
else -> super.writeValue(stream, value)
Expand All @@ -240,46 +177,6 @@ private open class NotificationsPigeonCodec : StandardMessageCodec() {

val NotificationsPigeonMethodCodec = StandardMethodCodec(NotificationsPigeonCodec())

/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
interface NotificationHostApi {
/**
* Retrieves notification data if the app was launched by tapping on a notification.
*
* Returns `launchOptions.remoteNotification`,
* which is the raw APNs data dictionary
* if the app launch was opened by a notification tap,
* else null. See Apple doc:
* https://developer.apple.com/documentation/uikit/uiapplication/launchoptionskey/remotenotification
*/
fun getNotificationDataFromLaunch(): NotificationDataFromLaunch?

companion object {
/** The codec used by NotificationHostApi. */
val codec: MessageCodec<Any?> by lazy {
NotificationsPigeonCodec()
}
/** Sets up an instance of `NotificationHostApi` to handle messages through the `binaryMessenger`. */
@JvmOverloads
fun setUp(binaryMessenger: BinaryMessenger, api: NotificationHostApi?, messageChannelSuffix: String = "") {
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
run {
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.zulip.NotificationHostApi.getNotificationDataFromLaunch$separatedMessageChannelSuffix", codec)
if (api != null) {
channel.setMessageHandler { _, reply ->
val wrapped: List<Any?> = try {
listOf(api.getNotificationDataFromLaunch())
} catch (exception: Throwable) {
NotificationsPigeonUtils.wrapError(exception)
}
reply.reply(wrapped)
}
} else {
channel.setMessageHandler(null)
}
}
}
}
}

private class NotificationsPigeonStreamHandler<T>(
val wrapper: NotificationsPigeonEventChannelWrapper<T>
Expand Down
4 changes: 4 additions & 0 deletions ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
B34E9F092D776BEB0009AED2 /* Notifications.g.swift in Sources */ = {isa = PBXBuildFile; fileRef = B34E9F082D776BEB0009AED2 /* Notifications.g.swift */; };
B35E11A62F484E6800DE4085 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
B378A5012F45B08F0031EFA1 /* NotificationService.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = B378A4FA2F45B08F0031EFA1 /* NotificationService.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
B3C086B42FA237E1001ACFDD /* NotificationTapEventListener.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3C086B32FA237E1001ACFDD /* NotificationTapEventListener.swift */; };
B3D425322F6D40C200F9AE69 /* IosNative.g.swift in Sources */ = {isa = PBXBuildFile; fileRef = B340EB372F5B092B007AD309 /* IosNative.g.swift */; };
B3D425332F6D40C200F9AE69 /* IosNativeHostApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = B32717682F6C49E5007682B1 /* IosNativeHostApi.swift */; };
F311C174AF9C005CE4AADD72 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3EAE3F3F518B95B7BFEB4FE7 /* Pods_Runner.framework */; };
Expand Down Expand Up @@ -92,6 +93,7 @@
B34E9F082D776BEB0009AED2 /* Notifications.g.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notifications.g.swift; sourceTree = "<group>"; };
B378A4FA2F45B08F0031EFA1 /* NotificationService.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = NotificationService.appex; sourceTree = BUILT_PRODUCTS_DIR; };
B3AF53A72CA20BD10039801D /* Zulip.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Zulip.xcconfig; path = Flutter/Zulip.xcconfig; sourceTree = "<group>"; };
B3C086B32FA237E1001ACFDD /* NotificationTapEventListener.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationTapEventListener.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
Expand Down Expand Up @@ -216,6 +218,7 @@
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
B3C086B32FA237E1001ACFDD /* NotificationTapEventListener.swift */,
B32717682F6C49E5007682B1 /* IosNativeHostApi.swift */,
B34E9F082D776BEB0009AED2 /* Notifications.g.swift */,
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
Expand Down Expand Up @@ -575,6 +578,7 @@
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
B340EB382F5B092B007AD309 /* IosNative.g.swift in Sources */,
B32717692F6C49E5007682B1 /* IosNativeHostApi.swift in Sources */,
B3C086B42FA237E1001ACFDD /* NotificationTapEventListener.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
41 changes: 0 additions & 41 deletions ios/Runner/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,6 @@ import UIKit

IosNativeHostApiSetup.setUp(binaryMessenger: controller.binaryMessenger, api: IosNativeHostApiImpl())

// Retrieve the remote notification payload from launch options;
// this will be null if the launch wasn't triggered by a notification.
let notificationPayload =
launchOptions?[.remoteNotification] as? [AnyHashable: Any]
let api = NotificationHostApiImpl(
notificationPayload.map { NotificationDataFromLaunch(payload: $0) }
)
NotificationHostApiSetup.setUp(
binaryMessenger: controller.binaryMessenger,
api: api
)

notificationTapEventListener = NotificationTapEventListener()
NotificationTapEventsStreamHandler.register(
with: controller.binaryMessenger,
Expand All @@ -58,32 +46,3 @@ import UIKit
completionHandler()
}
}

private class NotificationHostApiImpl: NotificationHostApi {
private let maybeDataFromLaunch: NotificationDataFromLaunch?

init(_ maybeDataFromLaunch: NotificationDataFromLaunch?) {
self.maybeDataFromLaunch = maybeDataFromLaunch
}

func getNotificationDataFromLaunch() -> NotificationDataFromLaunch? {
maybeDataFromLaunch
}
}

// Adapted from Pigeon's Swift example for @EventChannelApi:
// https://github.com/flutter/packages/blob/2dff6213a/packages/pigeon/example/app/ios/Runner/AppDelegate.swift#L49-L74
class NotificationTapEventListener: NotificationTapEventsStreamHandler {
var eventSink: PigeonEventSink<NotificationTapEvent>?

override func onListen(
withArguments arguments: Any?,
sink: PigeonEventSink<NotificationTapEvent>
) {
eventSink = sink
}

func onNotificationTapEvent(payload: [AnyHashable: Any]) {
eventSink?.success(IosNotificationTapEvent(payload: payload))
}
}
38 changes: 38 additions & 0 deletions ios/Runner/NotificationTapEventListener.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import Flutter
import UIKit

// Adapted from Pigeon's Swift example for @EventChannelApi:
// https://github.com/flutter/packages/blob/2dff6213a/packages/pigeon/example/app/ios/Runner/AppDelegate.swift#L49-L74
class NotificationTapEventListener: NotificationTapEventsStreamHandler {
var eventSink: PigeonEventSink<NotificationTapEvent>?
var buffer: [NotificationTapEvent] = []

override func onListen(
withArguments arguments: Any?,
sink: PigeonEventSink<NotificationTapEvent>
) {
eventSink = sink
if !buffer.isEmpty {
buffer.forEach {
sink.success($0)
}
buffer.removeAll()
}
}

override func onCancel(withArguments arguments: Any?) {
if let eventSink = self.eventSink {
eventSink.endOfStream()
self.eventSink = nil
}
}

func onNotificationTapEvent(payload: [AnyHashable: Any]) {
let event = IosNotificationTapEvent(payload: payload)
if let eventSink = self.eventSink {
eventSink.success(event)
} else {
buffer.append(event)
}
}
}
Loading