From 62edab0131afd42611d1614bd0f52c0207b829d2 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Sun, 21 Jul 2024 23:43:18 +0800 Subject: [PATCH] :sparkles: Bug fixes in notification and support iOS Communication Notification! --- ios/SolianNotifyExt/NotificationService.swift | 82 +++++++++++-------- lib/models/notification.dart | 8 +- lib/providers/websocket.dart | 3 + 3 files changed, 53 insertions(+), 40 deletions(-) diff --git a/ios/SolianNotifyExt/NotificationService.swift b/ios/SolianNotifyExt/NotificationService.swift index da40777..42c4efa 100644 --- a/ios/SolianNotifyExt/NotificationService.swift +++ b/ios/SolianNotifyExt/NotificationService.swift @@ -8,54 +8,64 @@ import UserNotifications import Intents +enum ParseNotificationPayloadError: Error { + case noMetadata(String) + case noAvatarUrl(String) +} + class NotificationService: UNNotificationServiceExtension { var contentHandler: ((UNNotificationContent) -> Void)? var bestAttemptContent: UNMutableNotificationContent? - func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) async { + override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { self.contentHandler = contentHandler bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) if let bestAttemptContent = bestAttemptContent { - switch bestAttemptContent.categoryIdentifier { - case "messaging.message", "messaging.callStart": - let metadata = bestAttemptContent.userInfo["metadata"] as! [AnyHashable : Any] - let handle = INPersonHandle(value: String(metadata["user_id"] as! Int), type: .unknown) - let avatar = INImage( - url: URL(string: bestAttemptContent.userInfo["avatar"] as! String)! - )! - let sender = INPerson(personHandle: handle, - nameComponents: nil, - displayName: metadata["user_nick"] as? String, - image: avatar, - contactIdentifier: nil, - customIdentifier: nil) - let intent = INSendMessageIntent(recipients: nil, - outgoingMessageType: .outgoingMessageText, - content: bestAttemptContent.body, - speakableGroupName: nil, - conversationIdentifier: String(metadata["channel_id"] as! Int), - serviceName: nil, - sender: sender, - attachments: nil) - - let interaction = INInteraction(intent: intent, response: nil) - interaction.direction = .incoming - - do { - try await interaction.donate() + do { + switch bestAttemptContent.categoryIdentifier { + case "messaging.message", "messaging.callStart": + guard let metadata = bestAttemptContent.userInfo["metadata"] as? [AnyHashable : Any] else { + throw ParseNotificationPayloadError.noMetadata("The notification has no metadata.") + } + let userId = metadata["user_id"] as! Int + let userName = metadata["user_name"] as? String + let userNick = metadata["user_nick"] as? String - let updatedContent = try request.content.updating(from: intent) - contentHandler(updatedContent) - } catch { - return + guard let avatarUrl = bestAttemptContent.userInfo["avatar"] as? String else { + throw ParseNotificationPayloadError.noMetadata("The notification has no avatar url.") + } + + let handle = INPersonHandle(value: String(userId), type: .unknown) + let avatar = INImage( + url: URL(string: avatarUrl)! + )! + let sender = INPerson(personHandle: handle, + nameComponents: nil, + displayName: userNick, + image: avatar, + contactIdentifier: nil, + customIdentifier: userName) + let intent = INSendMessageIntent(recipients: nil, + outgoingMessageType: .outgoingMessageText, + content: bestAttemptContent.body, + speakableGroupName: nil, + conversationIdentifier: String(metadata["channel_id"] as! Int), + serviceName: "PostPigeon", + sender: sender, + attachments: nil) + + let interaction = INInteraction(intent: intent, response: nil) + interaction.direction = .incoming + interaction.donate(completion: nil) + break + default: + contentHandler(bestAttemptContent) + break } - - break - default: + } catch { contentHandler(bestAttemptContent) - break } } } diff --git a/lib/models/notification.dart b/lib/models/notification.dart index 63774dc..ad8b528 100755 --- a/lib/models/notification.dart +++ b/lib/models/notification.dart @@ -9,7 +9,7 @@ class Notification { String? avatar; String? picture; int? senderId; - int recipientId; + int accountId; Notification({ required this.id, @@ -22,7 +22,7 @@ class Notification { required this.avatar, required this.picture, required this.senderId, - required this.recipientId, + required this.accountId, }); factory Notification.fromJson(Map json) => Notification( @@ -40,7 +40,7 @@ class Notification { avatar: json['avatar'], picture: json['picture'], senderId: json['sender_id'], - recipientId: json['recipient_id'], + accountId: json['account_id'], ); Map toJson() => { @@ -54,6 +54,6 @@ class Notification { 'avatar': avatar, 'picture': picture, 'sender_id': senderId, - 'recipient_id': recipientId, + 'account_id': accountId, }; } diff --git a/lib/providers/websocket.dart b/lib/providers/websocket.dart index bafc71f..bf83a67 100644 --- a/lib/providers/websocket.dart +++ b/lib/providers/websocket.dart @@ -127,6 +127,8 @@ class WebSocketProvider extends GetxController { if (deviceUuid == null || deviceUuid.isEmpty) { log("Unable to active push notifications, couldn't get device uuid"); + } else { + log('Device UUID is $deviceUuid'); } if (PlatformInfo.isIOS || PlatformInfo.isMacOS) { @@ -136,6 +138,7 @@ class WebSocketProvider extends GetxController { provider = 'firebase'; token = await FirebaseMessaging.instance.getToken(); } + log('Device Push Token is $token'); final client = auth.configureClient('auth');