# Rastreamento de entrega de mensagens no iOS

Existe um [método de API](/pt/developer/api-reference/device-api#messagedeliveryevent) no Pushwoosh que rastreia a entrega de notificações push. Os aplicativos iOS não suportam este método nativamente, porque as notificações push no iOS são gerenciadas pelo SO, não pelo SDK do Pushwoosh. Você pode adicionar o rastreamento de entrega adicionando uma Notification Service Extension ao seu projeto. Esta página mostra como implementar o rastreamento de entrega de mensagens para aplicativos iOS.

<Aside>
Requer o SDK do Pushwoosh para iOS 7.x, que suporta iOS 13.0 e posterior.
</Aside>

<Aside type="note">
Desde o SDK do Pushwoosh para iOS 7.1.0, a integração recomendada é a classe base `PushwooshNotificationServiceExtension` pronta para uso, mostrada abaixo. Ela envia o evento de entrega de mensagem, define o contador (badge), baixa o anexo de mídia e lida com o fallback obrigatório `serviceExtensionTimeWillExpire` para você. A API mais antiga `PWNotificationExtensionManager` ainda funciona, mas está obsoleta — veja [Integração legada](#legacy-integration).
</Aside>

## Adicionar a Notification Service Extension

1. No Xcode, selecione **File** > **New** > **Target...**

2. Selecione **Notification Service Extension** e pressione **Next.**

<img src="/ios-push-notifications-ios-message-delivery-tracking-1.webp" alt="Seletor de modelo de destino do Xcode com a Notification Service Extension selecionada"/>

3. Insira o nome do produto e pressione **Finish.**

<Aside type="caution">
Não selecione **Activate** na caixa de diálogo que é mostrada após pressionar **Finish**.
</Aside>

4. Pressione **Cancel** no prompt **Activate scheme**.

<img
  src="/ios-push-notifications-ios-message-delivery-tracking-2.webp"
  alt="Prompt 'Activate scheme' com 'Cancel' destacado"
  style={{ display: "block", margin: "0 auto", maxWidth: "40%", height: "auto" }}
  width="400"
/>

Ao cancelar, você mantém o Xcode depurando seu aplicativo em vez da extensão que acabou de criar. Se você a ativou por acidente, pode voltar a depurar seu aplicativo dentro do Xcode.

## Dependências para a Notification Service Extension (somente CocoaPods)

Se você usa o Swift Package Manager para gerenciar dependências, pode pular esta etapa, pois as dependências são adicionadas automaticamente.

Abra seu `Podfile` e adicione a dependência para o destino:

```ruby title="Podfile"
target 'NotificationServiceExtension' do
  use_frameworks!
  pod 'PushwooshXCFramework'
end
```

Execute os seguintes comandos no terminal para instalar as dependências:

```shell
rm -rf Podfile.lock
pod deintegrate
pod setup
pod repo update
pod install
```

## Adicionar código para rastrear eventos de entrega de mensagens

Faça sua extensão ser uma subclasse de `PushwooshNotificationServiceExtension`. Uma subclasse vazia é suficiente: o Pushwoosh envia o evento de entrega de mensagem, define o contador, baixa o anexo de mídia e lida com o fallback de tempo limite automaticamente.

Substitua o conteúdo gerado do seu arquivo **NotificationService**:

<Tabs>
<TabItem label="Swift">

```swift
import UserNotifications
import PushwooshFramework

class NotificationService: PushwooshNotificationServiceExtension {}
```

</TabItem>

<TabItem label="Objective-C">

```objective-c
#import <PushwooshFramework/PushwooshNotificationServiceExtension.h>

@interface NotificationService : PushwooshNotificationServiceExtension

@end

@implementation NotificationService

@end
```

</TabItem>
</Tabs>

<Aside type="tip">
Se você não precisar de nenhum código personalizado, pode pular o arquivo de origem completamente e apontar o `NSExtensionPrincipalClass` do Info.plist da extensão diretamente para `PushwooshNotificationServiceExtension`.
</Aside>

### ID do Aplicativo

Desde a versão 7.1.0, a extensão herda `Pushwoosh_APPID` (e outras chaves `Pushwoosh_*`) do Info.plist do aplicativo hospedeiro, então você não precisa mais duplicá-lo na extensão. Adicione `Pushwoosh_APPID` ao Info.plist da extensão apenas quando quiser substituir o valor do hospedeiro:

```xml title="NotificationService/Info.plist"
<key>Pushwoosh_APPID</key>
<string>XXXXX-XXXXX</string>
```

<Aside type="note">
Em versões do SDK do Pushwoosh para iOS anteriores à 7.1.0, a extensão não herda a configuração do aplicativo hospedeiro. Nessas versões, você deve adicionar `Pushwoosh_APPID` ao Info.plist da extensão.
</Aside>

### App Group (contador e proxy reverso)

Um App Group compartilhado entre o aplicativo e a extensão é necessário para sincronizar a contagem do contador (badge) e para ler as configurações de proxy reverso que o aplicativo hospedeiro armazena.

1. Adicione a capacidade **App Groups** ao destino da extensão e habilite o mesmo grupo lá que no aplicativo hospedeiro. Isso é obrigatório — sem o contêiner compartilhado, a contagem do contador e as configurações de proxy reverso não podem ser sincronizadas.

2. Forneça o nome do App Group. Assim como `Pushwoosh_APPID`, a extensão herda `PW_APP_GROUPS_NAME` do Info.plist do aplicativo hospedeiro desde a versão 7.1.0, então se você já o definiu lá para os contadores, não precisa adicioná-lo à extensão. Defina-o no Info.plist da extensão apenas para substituir o valor do hospedeiro, ou forneça-o programaticamente substituindo `pushwooshAppGroupsName`.

```xml title="App Info.plist"
<key>PW_APP_GROUPS_NAME</key>
<string>group.com.example.app</string>
```

<Aside type="caution">
Se o aplicativo hospedeiro usa um proxy reverso (`Pushwoosh_ALLOW_REVERSE_PROXY`), a extensão precisa deste App Group para ler a URL do proxy que o aplicativo armazenou lá. Sem ele, o evento de entrega é retido em vez de ser enviado diretamente, contornando o proxy.
</Aside>

## Personalizar a notificação (opcional)

A classe base expõe alguns pontos de substituição, do menor para o maior controle. O Pushwoosh ainda executa o evento de entrega, contador, anexo e fallback de tempo limite em todos os casos.

Defina o App Group programaticamente em vez de usar a chave do Info.plist:

```swift
override func pushwooshAppGroupsName() -> String? {
    "group.com.example.app"
}
```

Execute a preparação assíncrona antes que o Pushwoosh processe o push — por exemplo, pré-buscando mídias do Push Stories — sem substituir o `didReceive` padrão. Chame `completion` exatamente uma vez, na thread principal:

```swift
override func pushwooshPrepare(for request: UNNotificationRequest,
                              completion: @escaping () -> Void) {
    // trabalho assíncrono aqui
    completion()
}
```

Modifique o conteúdo antes que ele seja mostrado, substituindo `didReceive`. Chame `super` com seu próprio manipulador de conteúdo, altere o conteúdo dentro dele e, em seguida, encaminhe-o para o manipulador original:

```swift
override func didReceive(_ request: UNNotificationRequest,
                         withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
    super.didReceive(request) { content in
        let mutable = (content.mutableCopy() as? UNMutableNotificationContent) ?? content
        // personalize `mutable` aqui
        contentHandler(mutable)
    }
}
```

## Integração legada

<Aside type="caution">
`PWNotificationExtensionManager` está obsoleto desde a versão 7.1.0. Use-o apenas se não puder herdar de `PushwooshNotificationServiceExtension` — por exemplo, uma extensão que já estende a classe base de outro SDK, ou um wrapper multiplataforma (React Native, Flutter, Unity). Novas integrações devem usar a classe base acima.
</Aside>

Esta API de baixo nível aciona o mesmo processamento (evento de entrega, contador, anexo) a partir de um `UNNotificationServiceExtension` simples:

<Tabs>
<TabItem label="Swift">

```swift
import UserNotifications
import PushwooshFramework

class NotificationService: UNNotificationServiceExtension {

    override func didReceive(_ request: UNNotificationRequest,
                             withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        PWNotificationExtensionManager.sharedManager()
            .handleNotificationRequest(request, contentHandler: contentHandler)
    }
}
```

</TabItem>

<TabItem label="Objective-C">

```objective-c
#import "PWNotificationExtensionManager.h"

@interface NotificationService : UNNotificationServiceExtension

@end

@implementation NotificationService

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request
                   withContentHandler:(void (^)(UNNotificationContent *))contentHandler {
    [[PWNotificationExtensionManager sharedManager] handleNotificationRequest:request
                                                              contentHandler:contentHandler];
}

@end
```

</TabItem>
</Tabs>

## Compartilhe seu feedback conosco

Seu feedback nos ajuda a criar uma experiência melhor, então adoraríamos ouvir de você se tiver algum problema durante o processo de integração do SDK. Se você enfrentar alguma dificuldade, não hesite em compartilhar suas opiniões conosco [através deste formulário](https://docs.google.com/forms/d/e/1FAIpQLSd_0b8jwn-V_JmoPLIxIFYbHACCQhrzidOZV3ELywoQPXRSxw/viewform).