OneSignal / OneSignal-iOS-SDK

OneSignal is a free push notification service for mobile apps. This plugin makes it easy to integrate your native iOS app with OneSignal. https://onesignal.com
Other
488 stars 263 forks source link

iOS 15 Communication Notification support #1064

Open gopricy opened 2 years ago

gopricy commented 2 years ago

This isn't a bug report but more a feature request. From this link, iOS 15 brought communication notifications which is used by slack, spark, instagram etc.

I am curious on the support plan of OneSignal iOS sdk for Comminuication Notification feature.

emawby commented 2 years ago

@gopricy Hello thank you for reaching out. I would expect communication notifications to come from and be delivered to users of your app rather than being sent from OneSignal's dashboard. What features in particular would you like OneSignal to support for these notifications?

gopricy commented 2 years ago

@emawby Thanks for the quick response. We have an Instagram like app. Whenever a user create a post, all his subscribers should receive a notification. We want to use author's avatar as the notification icon utilizing the new Communification Notification feature.

We mainly use OneSignal API to send all notifications instead of through the dashboard, and we didn't find a customized avatar option in OneSignal API.

gopricy commented 2 years ago

@emawby is there any plan to support this use case in the future?

Dajust commented 1 year ago

Any hope of ever having this? 🥺

tcaish commented 9 months ago

I would also love this feature.

maximilien0405 commented 9 months ago

Yes me too !

nan-li commented 9 months ago

Hi all, thanks for checking in, You should be able to enable Communication Notifications yourselves by following Apple's guide.

tcaish commented 9 months ago

@nan-li This does not work for Expo-managed React Native apps since we do not have access to Apple's native programming language and system.

gpminsuk commented 7 months ago

I also need this feature!

gpminsuk commented 7 months ago

Sharing my code that I managed to work following the guide. This is NotificationService.swift file of the OneSignalNotificationServiceExtension

I am sending notifications using OneSignal REST API and didn't know where to add additional information needed for the photo url and person name, so I added to additional data structure myself which is in userInfo["custom"]["a"]

import UserNotifications
import Intents
import OneSignalExtension

class NotificationService: UNNotificationServiceExtension {

    private var contentHandler: ((UNNotificationContent) -> Void)?
    private var receivedRequest: UNNotificationRequest?
    private var bestAttemptContent: UNMutableNotificationContent?

    private func genMessageIntent(from request: UNNotificationRequest) -> INSendMessageIntent? {
        guard let custom = request.content.userInfo["custom"] as? [String: Any],
              let a = custom["a"] as? [String: Any],
              let name = a["name"] as? String,
              let urlString = a["url"] as? String,
              let url = URL(string: urlString) else {
            return nil
        }

        let handle = INPersonHandle(value: nil, type: .unknown)
        let avatar = INImage(url: url)
        let sender = INPerson(personHandle: handle, nameComponents: nil, displayName: name, image: avatar, contactIdentifier: nil, customIdentifier: nil)

        return INSendMessageIntent(
            recipients: nil,
            outgoingMessageType: .outgoingMessageText,
            content: nil,
            speakableGroupName: nil,
            conversationIdentifier: nil,
            serviceName: nil,
            sender: sender,
            attachments: nil
        )
    }

    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.receivedRequest = request
        self.contentHandler = contentHandler
        self.bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)

        guard let intent = genMessageIntent(from: request) else {
            forwardRequestToExtension()
            return
        }

        let interaction = INInteraction(intent: intent, response: nil)
        interaction.direction = .incoming

        interaction.donate { [weak self] error in
            guard let self = self, error == nil else { return }

            do {
                let content = try request.content.updating(from: intent)
                self.bestAttemptContent = (content.mutableCopy() as? UNMutableNotificationContent)
                self.forwardRequestToExtension()
            } catch {
                // Handle errors appropriately
            }
        }
    }

    private func forwardRequestToExtension() {
        guard let receivedRequest = receivedRequest, let bestAttemptContent = bestAttemptContent else { return }
        OneSignalExtension.didReceiveNotificationExtensionRequest(receivedRequest, with: bestAttemptContent, withContentHandler: contentHandler)
    }

    override func serviceExtensionTimeWillExpire() {
        guard let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent else { return }
        OneSignalExtension.serviceExtensionTimeWillExpireRequest(receivedRequest!, with: bestAttemptContent)
        contentHandler(bestAttemptContent)
    }
}

In addition to that I needed to add this in plist

    <key>NSUserActivityTypes</key>
    <array>
        <string>INSendMessageIntent</string>
    </array>
globemediaofficial commented 6 months ago

@gopricy @Dajust @tcaish I was able to implement Communication Notifications with the help of @gpminsuk's example code. I wrote a full guide for it, but keep in mind that this will not work with expo-managed apps since you need to edit NotificationService.swift in the native iOS project.

Guide: https://medium.com/@christopher.mathews/ios-communication-notifications-for-react-native-with-onesignal-35c83e75e24f