Pular para o conteúdo principal

Visão geral

As Extensões de Serviço de Notificação permitem que você intercepte e modifique notificações push antes de serem exibidas ao usuário. Isso habilita:
  • Manipulação de dados em segundo plano
  • Estilos personalizados (cores, ícones, vibração)
  • Anexos de rich media (imagens, vídeos)
  • Entrega confirmada/análises
  • Opções de botões de ação
Você pode acessar os dados em suas notificações push enviadas do OneSignal através da classe OSNotification

Extensão de Serviço de Notificação do Android

Permite que você processe a notificação antes de ser mostrada ao usuário. Casos de uso comuns incluem:
  • Receber dados em segundo plano com ou sem exibir uma notificação.
  • Substituir configurações específicas de notificação dependendo da lógica do aplicativo do lado do cliente, como cor de destaque personalizada, padrão de vibração ou qualquer outra opção NotificationCompat disponível.
Para mais detalhes, consulte a documentação do Android sobre as opções do NotificationCompat.

1. Criar uma classe para a Extensão de Serviço

Crie uma classe que estende INotificationServiceExtension e implemente o método onNotificationReceived. O parâmetro do método onNotificationReceived é event do tipo INotificationReceivedEvent.
package your.package.name

import androidx.annotation.Keep;
import com.onesignal.notifications.IActionButton;
import com.onesignal.notifications.IDisplayableMutableNotification;
import com.onesignal.notifications.INotificationReceivedEvent;
import com.onesignal.notifications.INotificationServiceExtension;

@Keep // Keep is required to prevent minification from renaming or removing your class
public class NotificationServiceExtension implements INotificationServiceExtension {

     @Override
     public void onNotificationReceived(INotificationReceivedEvent event) {
        IDisplayableMutableNotification notification = event.getNotification();

        if (notification.getActionButtons() != null) {
           for (IActionButton button : notification.getActionButtons()) {
              // you can modify your action buttons here
           }
        }

     /* Add customizations here. See examples below for additional methods to modify the notification*/
     }
}

2. Exemplos de casos de uso

Os seguintes são exemplos comuns que você pode implementar na classe template de Extensão de Serviço de Notificação acima.
  • Impedir que a notificação seja exibida
  • Adicionar um campo personalizado
  • Alterar a cor e o ícone da notificação
event.preventDefault();

//Do some async work, then decide to show or dismiss
new Thread(() -> {
    try {
        Thread.sleep(1000);
    } catch (InterruptedException ignored) {}

    //Manually show the notification
    event.getNotification().display();
}).start();

3. Adicionar a Extensão de Serviço ao seu AndroidManifest.xml

Adicione o nome da classe e o valor como meta-data dentro do arquivo AndroidManifest.xml na tag do aplicativo. Ignore quaisquer avisos de “não utilizado”.
XML
<application>
  <!-- Keep android:name as shown, set android:value toyour class fully name spaced-->
  <meta-data
    android:name="com.onesignal.NotificationServiceExtension"
    android:value="com.onesignal.example.NotificationServiceExtension" />
</application>

Extensão de Serviço de Notificação do iOS

A UNNotificationServiceExtension permite que você modifique o conteúdo das notificações push antes de serem exibidas ao usuário e é necessária para outros recursos importantes como: Você provavelmente já configurou isso se seguiu nossas instruções de configuração do SDK Móvel para seu aplicativo, mas esta seção explicará como acessar os dados de payload de notificação do OneSignal e solucionar quaisquer problemas que você possa estar tendo.

Obtendo o payload de push do iOS

Ao seguir a configuração do SDK Móvel, você chegará à seção sobre adicionar o código à OneSignalNotificationServiceExtension. Nesse código, há o método OneSignalExtension.didReceiveNotificationExtensionRequest. É aqui que passamos o bestAttemptContent da notificação para o aplicativo antes de ser exibida ao usuário. Antes que este método seja chamado, você pode obter o payload da notificação e (se desejar) atualizá-lo antes de ser exibido ao usuário. Neste exemplo, enviamos uma notificação com os seguintes dados:
JSON
{
  "app_id": "YOUR_APP_ID",
  "target_channel": "push",
  "headings": {"en": "The message title"},
  "contents": {"en": "The message contents"},
  "data":{
    "additional_data_key_1":"value_1",
    "additional_data_key_2":"value_2"
    },
  "include_subscription_ids": ["SUBSCRIPTION_ID_1"]
}
Podemos acessar estes data adicionais dentro da OneSignalNotificationServiceExtension através do objeto custom usando o parâmetro a.
// Check if `bestAttemptContent` exists
if let bestAttemptContent = bestAttemptContent {

    // Try to retrieve the "custom" data from the notification payload
    if let customData = bestAttemptContent.userInfo["custom"] as? [String: Any],
       let additionalData = customData["a"] as? [String: Any] {

        // Convert the `additionalData` dictionary to a JSON string for logging
        if let jsonData = try? JSONSerialization.data(withJSONObject: additionalData, options: .prettyPrinted),
           let jsonString = String(data: jsonData, encoding: .utf8) {
            // Successfully converted to JSON; log the formatted JSON string
            print("The additionalData dictionary in JSON format:\n\(jsonString)")
        } else {
            // Failed to convert the `additionalData` dictionary to JSON
            print("Failed to convert additionalData to JSON format.")
        }
    }

    // Try to retrieve the "aps" data from the notification payload
    if let messageData = bestAttemptContent.userInfo["aps"] as? [String: Any],
       let apsData = messageData["alert"] as? [String: Any],
       let body = apsData["body"] as? String,  // Extract the "body" of the alert
       let title = apsData["title"] as? String {  // Extract the "title" of the alert
        // Successfully retrieved the body and title; log the values
        print("The message contents is: \(body), message headings is: \(title)")
    } else {
        // Failed to retrieve the "aps" data or its contents
        print("Unable to retrieve apsData")
    }

    // Pass the notification to OneSignal for further processing
    OneSignalExtension.didReceiveNotificationExtensionRequest(self.receivedRequest,
                                                              with: bestAttemptContent,
                                                              withContentHandler: self.contentHandler)
}
Example console output:
The additionalData dictionary in JSON format:
{
  "additional_data_key_1" : "value_1",
  "additional_data_key_2" : "value_2"
}
The message contents is: The message contents, message headings is: The message title

Solução de problemas da Extensão de Serviço de Notificação do iOS

Este guia é para depurar problemas com Imagens, Botões de Ação ou Entregas Confirmadas que não aparecem em aplicativos móveis iOS. Verifique suas Configurações do Xcode Em General > Targets, certifique-se de que seu main app target e o target OneSignalNotificationServiceExtension tenham os mesmos e corretos:
  • Supported Destinations
  • Minimum Deployment (iOS 14.5 ou superior)
Se você estiver usando Cocoapods, certifique-se de que eles correspondam ao seu target principal no Podfile para evitar erros de compilação.

Exemplo de Main App Target no Xcode

Exemplo de Target OneSignalNotificationServiceExtension no Xcode

Continuando na aba OneSignalNotificationServiceExtension > Info, expanda a chave NSExtension. Certifique-se de ver:
XML
 <dict>
   <key>NSExtensionPointIdentifier</key>
   <string>com.apple.usernotifications.service</string>
   <key>NSExtensionPrincipalClass</key>
   <string>$(PRODUCT_MODULE_NAME).NotificationService</string>
 </dict>
Exemplo:

Exemplo da chave NSExtension na aba Info

Se estiver usando Objective-C, em vez de $(PRODUCT_MODULE_NAME).NotificationService use NotificationService.
Desative “Copy only when installing” Selecione seu main app target > Build Phases > Embed App Extensions. Certifique-se de que “Copy only when installing” NÃO esteja marcado. Desmarque-o se estiver:

Configurações de build phase do main app target

Depurando a Extensão de Serviço de Notificação do iOS

Siga estas etapas para verificar se a Extensão de Serviço de Notificação está configurada corretamente.

1. Atualizar o código OneSignalNotificationServiceExtension

Abra o NotificationService.m ou NotificationService.swift e substitua todo o conteúdo do arquivo pelo código abaixo. (O código é o mesmo do nosso código de configuração original, apenas adicionando alguns logs adicionais.) Certifique-se de substituir YOUR_BUNDLE_ID pelo seu Bundle ID real.
import UserNotifications
import OneSignalExtension
import os.log

class NotificationService: UNNotificationServiceExtension {

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

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

        let userInfo = request.content.userInfo
        let custom = userInfo["custom"]
        print("Running NotificationServiceExtension: userInfo = \(userInfo.description)")
        print("Running NotificationServiceExtension: custom = \(custom.debugDescription)")
        //debug log types need to be enabled in Console > Action > Include Debug Messages
        //Replace YOUR_BUNDLE_ID with your actual Bundle ID
        os_log("%{public}@", log: OSLog(subsystem: "YOUR_BUNDLE_ID", category: "OneSignalNotificationServiceExtension"), type: OSLogType.debug, userInfo.debugDescription)

        if let bestAttemptContent = bestAttemptContent {
            /* DEBUGGING: Uncomment the 2 lines below to check this extension is executing
                          Note, this extension only runs when mutable-content is set
                          Setting an attachment or action buttons automatically adds this */
            print("Running NotificationServiceExtension")
            bestAttemptContent.body = "[Modified] " + bestAttemptContent.body

            OneSignalExtension.didReceiveNotificationExtensionRequest(self.receivedRequest, with: bestAttemptContent, withContentHandler: self.contentHandler)
        }
    }

    override func serviceExtensionTimeWillExpire() {
        // Called just before the extension will be terminated by the system.
        // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
        if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {
            OneSignalExtension.serviceExtensionTimeWillExpireRequest(self.receivedRequest, with: self.bestAttemptContent)
            contentHandler(bestAttemptContent)
        }
    }

}

2. Alterar seu Active Scheme

Defina seu Active Scheme para OneSignalNotificationServiceExtension.

Seleção de active scheme no Xcode

3. Compilar e executar o projeto

Compile e execute o projeto no Xcode em um dispositivo real.

4. Abrir o Console

No Xcode, selecione Window > Devices and Simulators.

Janela Devices and Simulators do Xcode

Você deve ver seu dispositivo conectado. Selecione Open Console.

Botão de acesso ao console do dispositivo

5. Verificar o Console

No Console:
  • Selecione Action > Include Debug Messages
  • Procure por OneSignalNotificationServiceExtension como a CATEGORY
  • Selecione Start

Configuração de depuração do console

Envie para este dispositivo uma notificação com uma mensagem (use a propriedade contents se estiver enviando pela API Create message). Neste exemplo, o payload é:
cURL
  //Replace with your own app data:
  //YOUR_API_KEY, YOUR_APP_ID, SUBSCRIPTION_ID_1

curl --request POST \
 --url 'https://api.onesignal.com/notifications' \
 --header 'Authorization: Key YOUR_API_KEY' \
 --header 'accept: application/json' \
 --header 'content-type: application/json' \
 --data '
{
"app_id": "YOUR_APP_ID",
"target_channel": "push",
"headings": {"en": "The message title"},
"contents": {"en": "The message contents"},
"data":{"additional_data_key_1":"value_1","additional_data_key_2":"value_2"},
"include_subscription_ids": [
"SUBSCRIPTION_ID_1"
]
}'
Você deve ver uma mensagem registrada com o aplicativo em execução e sem execução.

Exemplo de saída de depuração do console

Se você não vir uma mensagem, remova o OneSignal do seu aplicativo e siga nossa Configuração do SDK Móvel novamente para verificar se você configurou o OneSignal corretamente.