diff --git a/app.config.js b/app.config.js index 1f8971209a..5b32a2e296 100644 --- a/app.config.js +++ b/app.config.js @@ -66,7 +66,6 @@ module.exports = function (_config) { infoPlist: { CADisableMinimumFrameDurationOnPhone: true, UIBackgroundModes: ['remote-notification'], - NSUserActivityTypes: ['INSendMessageIntent'], NSCameraUsageDescription: 'Used for profile pictures, posts, and other kinds of content.', NSMicrophoneUsageDescription: @@ -124,7 +123,6 @@ module.exports = function (_config) { 'com.apple.developer.kernel.increased-memory-limit': true, 'com.apple.developer.kernel.extended-virtual-addressing': true, 'com.apple.security.application-groups': 'group.app.bsky', - 'com.apple.developer.usernotifications.communication': true, // 'com.apple.developer.device-information.user-assigned-device-name': true, }, privacyManifests: { diff --git a/modules/BlueskyNSE/Info.plist b/modules/BlueskyNSE/Info.plist index e9271925e0..c2dd7eda69 100644 --- a/modules/BlueskyNSE/Info.plist +++ b/modules/BlueskyNSE/Info.plist @@ -8,13 +8,6 @@ com.apple.usernotifications.service NSExtensionPrincipalClass $(PRODUCT_MODULE_NAME).NotificationService - NSExtensionAttributes - - IntentsSupported - - INSendMessageIntent - - MainAppScheme bluesky diff --git a/modules/BlueskyNSE/NotificationService.swift b/modules/BlueskyNSE/NotificationService.swift index b441f48a91..481402890f 100644 --- a/modules/BlueskyNSE/NotificationService.swift +++ b/modules/BlueskyNSE/NotificationService.swift @@ -1,6 +1,5 @@ import UserNotifications import UIKit -import Intents let APP_GROUP = "group.app.bsky" typealias ContentHandler = (UNNotificationContent) -> Void @@ -41,18 +40,17 @@ class NotificationService: UNNotificationServiceExtension { } self.bestAttempt = bestAttempt - - if reason == "chat-message" || reason == "chat-reaction" { + if reason == "chat-message" { mutateWithChatMessage(bestAttempt) - let finalContent = createCommunicationNotification( - from: bestAttempt, - userInfo: request.content.userInfo - ) - contentHandler(finalContent) } else { mutateWithBadge(bestAttempt) - contentHandler(bestAttempt) } + + // Any image downloading (or other network tasks) should be handled at the end + // of this block. Otherwise, if there is a timeout and serviceExtensionTimeWillExpire + // gets called, we might not have all the needed mutations completed in time. + + contentHandler(bestAttempt) } override func serviceExtensionTimeWillExpire() { @@ -63,81 +61,6 @@ class NotificationService: UNNotificationServiceExtension { contentHandler(bestAttempt) } - // MARK: Communication Notification - - func createCommunicationNotification( - from content: UNMutableNotificationContent, - userInfo: [AnyHashable: Any] - ) -> UNNotificationContent { - let senderDisplayName = userInfo["senderDisplayName"] as? String ?? "Unknown" - let convoId = userInfo["convoId"] as? String - var avatarImage: INImage? = nil - if let avatarUrlString = userInfo["senderAvatarUrl"] as? String { - avatarImage = downloadAvatarImage(from: avatarUrlString) - } - - let senderHandleValue = userInfo["senderHandle"] as? String - let senderHandle = INPersonHandle(value: senderHandleValue, type: .unknown) - let sender = INPerson( - personHandle: senderHandle, - nameComponents: nil, - displayName: senderDisplayName, - image: avatarImage, - contactIdentifier: nil, - customIdentifier: nil - ) - - let intent = INSendMessageIntent( - recipients: nil, - outgoingMessageType: .outgoingMessageText, - content: content.body, - speakableGroupName: nil, - conversationIdentifier: convoId, - serviceName: nil, - sender: sender, - attachments: nil - ) - - let interaction = INInteraction(intent: intent, response: nil) - interaction.direction = .incoming - interaction.donate(completion: nil) - - do { - return try content.updating(from: intent) - } catch { - return content - } - } - - func downloadAvatarImage(from urlString: String) -> INImage? { - let thumbnailUrlString = urlString.replacingOccurrences( - of: "/img/avatar/", - with: "/img/avatar_thumbnail/" - ) - - guard let url = URL(string: thumbnailUrlString) else { return nil } - - var request = URLRequest(url: url) - request.timeoutInterval = 5 - - var imageData: Data? = nil - let semaphore = DispatchSemaphore(value: 0) - - let task = URLSession.shared.dataTask(with: request) { data, response, error in - if let data = data, - let httpResponse = response as? HTTPURLResponse, - httpResponse.statusCode == 200 { - imageData = data - } - semaphore.signal() - } - task.resume() - semaphore.wait() - - guard let data = imageData else { return nil } - return INImage(imageData: data) - } - // MARK: Mutations func mutateWithBadge(_ content: UNMutableNotificationContent) { diff --git a/modules/expo-background-notification-handler/android/src/main/java/expo/modules/backgroundnotificationhandler/BackgroundNotificationHandler.kt b/modules/expo-background-notification-handler/android/src/main/java/expo/modules/backgroundnotificationhandler/BackgroundNotificationHandler.kt index fba23dfa0c..4f8a6b892a 100644 --- a/modules/expo-background-notification-handler/android/src/main/java/expo/modules/backgroundnotificationhandler/BackgroundNotificationHandler.kt +++ b/modules/expo-background-notification-handler/android/src/main/java/expo/modules/backgroundnotificationhandler/BackgroundNotificationHandler.kt @@ -13,7 +13,7 @@ class BackgroundNotificationHandler( return } - if (remoteMessage.data["reason"] == "chat-message" || remoteMessage.data["reason"] == "chat-reaction") { + if (remoteMessage.data["reason"] == "chat-message") { mutateWithChatMessage(remoteMessage) } else { mutateWithOtherReason(remoteMessage)