Guia de instruções: integração às Notificações do Graph (iOS)

Notificações do Graph permitem que seu aplicativo envie e gerencie notificações direcionadas a usuários em vários dispositivos.

Com o SDK do lado do cliente do Project Rome no iOS, o aplicativo iOS pode se registrar para receber notificações publicadas de seu servidor de aplicativo direcionado a um usuário conectado. O SDK permite que o cliente do aplicativo receba novos conteúdos de notificações de entrada, gerencie o estado das notificações existentes e recupere o histórico de notificações. Para obter mais informações sobre as Notificações e como elas permitem a entrega da notificação centrada em humanos, confira Visão geral de Notificações do Microsoft Graph

Todos os recursos no SDK do Project Rome, incluindo Notificações do Graph e muito mais, são criados sobre uma plataforma subjacente chamada de Plataforma de dispositivos Conectados. Este guia foi projetado para orientar você durante as etapas necessárias para começar a usar a Plataforma de Dispositivos Conectados e explicar como consumir APIs no SDK para implementar Notificações do Graph – recursos específicos.

Essa etapas a seguir fará referência a código do aplicativo de exemplo do Project Rome para iOS que está disponível no GitHub.

Confira a página Referência de API para obter links para os documentos de referência relevantes para cenários de notificação.

Configurando a Plataforma de Dispositivos Conectados e Notificações

Registrar seu aplicativo

A autenticação da MSA (Conta Microsoft) ou do AAD (Azure Active Directory) é necessária para quase todos os recursos do SDK do Project Rome (exceto pela API de compartilhamento por proximidade). Se você ainda não tiver uma conta Microsoft e quiser usar uma, registre-se em account.microsoft.com.

Observação

Não há suporte para contas do AAD (Azure Active Directory) com as APIs de retransmissão do dispositivo.

Usando seu método de autenticação escolhido, você deve registrar seu aplicativo com a Microsoft seguindo as instruções no Portal de Registro de Aplicativo. Se você não tiver uma conta de desenvolvedor Microsoft, precisará criá-la.

Ao registrar um aplicativo usando uma MSA, você deverá receber uma cadeia de caracteres de ID do cliente. Salve para uso posterior. Isso permitirá que o aplicativo acesse recursos da Plataforma de Dispositivos Conectados da Microsoft. Se você estiver usando o AAD, confira Bibliotecas de autenticação do Azure Active Directory para obter instruções sobre como obter a cadeia de caracteres de ID do cliente.

Adicionar o SDK

A maneira mais simples de adicionar a Plataforma de Dispositivos Conectados ao aplicativo iOS é usando o gerenciador de dependências CocoaPods. Vá para seu projeto do iOS Podfile e insira a seguinte entrada:

platform :ios, "10.0"
workspace 'iOSSample'

target 'iOSSample' do
  # Uncomment the next line if you're using Swift or would like to use dynamic frameworks
  # use_frameworks!

	pod 'ProjectRomeSdk'

  # Pods for iOSSample

Observação

Para consumir o CocoaPod, você deve usar o arquivo .xcworkspace em seu projeto.

Configurar a autenticação e o gerenciamento de contas

A plataforma de dispositivos conectados exige que um token OAuth válido seja usado no processo de registro. Você pode usar seu método preferido para gerar e gerenciar os tokens OAuth. No entanto, para ajudar os desenvolvedores a começarem a usar a plataforma, incluímos um provedor de autenticação como parte do aplicativo de exemplo do iOS que você pode usar para gerar e gerenciar os tokens de atualização em seu aplicativo.

Se você não usar o código fornecido, você mesmo precisará implementar a interface MCDConnectedDevicesAccountManager.

Se você estiver usando uma MSA, inclua os seguintes escopos em sua solicitação de entrada: "wl.offline_access", "ccs.ReadWrite", "dds.read", "dds.register", "wns.connect", "asimovrome.telemetry" e "https://activity.windows.com/UserActivity.ReadWrite.CreatedByApp".

Observação

Não há suporte para contas do AAD (Azure Active Directory) com as APIs de retransmissão do dispositivo.

Se você estiver usando uma conta do AAD, precisará solicitar os seguintes públicos-alvo: "https://cdpcs.access.microsoft.com", "https://cs.dds.microsoft.com", "https://wns.windows.com/" e "https://activity.microsoft.com".

Não importa se você está usando a implementação MCDConnectedDevicesAccountManager fornecida ou não, se estiver usando o AAD, precisará especificar as seguintes permissões no registro do seu aplicativo no portal do Azure (portal.azure.com > Azure Active Directory > Registros de aplicativo):

  • Serviço de Feed de Atividades da Microsoft
    • Entregar e modificar as notificações de usuário para este aplicativo
    • Ler e gravar atividade do aplicativo para o feed de atividades dos usuários
  • Serviço de Notificação do Windows
    • Conecte seu dispositivo ao Serviço de Notificação do Windows
  • Serviço de Diretório do Dispositivos da Microsoft
    • Veja sua lista de dispositivos
    • Ser adicionado à sua lista de dispositivos e aplicativos
  • Serviço de Comando da Microsoft
    • Comunicar-se com dispositivos de usuário
    • Ler dispositivos de usuário

Registrar seu aplicativo para notificações por push

Registre seu aplicativo com a Apple para suporte ao Apple Push Notification. Não se esqueça de anotar a ID do remetente e a chave do servidor que você receber, pois você precisará deles mais tarde.

Depois de registrado, você precisa associar a funcionalidade de notificação por push com a plataforma de dispositivos conectados em seu aplicativo.

self.notificationRegistration = [[MCDConnectedDevicesNotificationRegistration alloc] init];
    if ([[UIApplication sharedApplication] isRegisteredForRemoteNotifications])
    {
        self.notificationRegistration.type = MCDNotificationTypeAPN;
    }
    else
    {
        self.notificationRegistration.type = MCDNotificationTypePolling;
    }
    self.notificationRegistration.appId = [[NSBundle mainBundle] bundleIdentifier];
    self.notificationRegistration.appDisplayName = (NSString*)[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"];
    self.notificationRegistration.token = deviceToken;
    self.isRegisteredWithToken = YES;

Registrar o aplicativo no Centro de Desenvolvimento do Microsoft Windows para experiências entre dispositivos

Aviso

Essa etapa só é necessária se você deseja usar os recursos do Project Rome para acessar dados de ou para fazer solicitações de dispositivos não Windows. Se direcionar somente a dispositivos Windows, você não precisará concluir esta etapa.

Registre o aplicativo para o recurso de experiências entre dispositivos do Painel do Desenvolvedor Microsoft. Este é um procedimento diferente do registro de aplicativo na MSA e no AAD visto acima. A meta principal para esse processo é mapear as identidades de aplicativo específico da plataforma com uma identidade de aplicativo multiplataforma que é reconhecida pela Plataforma de Dispositivos Conectados. Esta etapa também permite enviar notificações usando os serviços de notificação por push nativa correspondentes às plataformas móveis usadas pelo aplicativo. Para iOS, ele permite que notificações sejam enviadas a pontos de extremidade do aplicativo iOS por meio do APNs – Apple Push Notification Service.

Vá para o Painel do Centro de Desenvolvimento, navegue para Experiências entre Dispositivos no painel de navegação esquerdo e selecione configurar um novo aplicativo entre dispositivos. Painel do Centro de Desenvolvimento – Experiências entre dispositivos

O processo de integração do Centro de Desenvolvimento requer as seguintes etapas:

  • Selecionar as plataformas compatíveis – selecione as plataformas em que o aplicativo terá uma presença e será habilitado para experiências entre dispositivos. No caso de integração de Notificações do Graph, você pode selecionar do Windows, do Android e do iOS, dependendo de quais plataformas você está usando. Experiências entre dispositivos – Plataformas com suporte

  • Fornecer IDs de aplicativo – fornecer IDs do aplicativo para cada plataforma que você está usando. Para aplicativos iOS, isso é o nome do pacote que você atribuiu ao aplicativo quando criou o projeto. Observe que você pode adicionar IDs diferentes (até dez) por plataforma, caso você tenha várias versões do mesmo aplicativo ou até mesmo diferentes aplicativos que deseje que sejam capazes de receber as mesmas notificações enviadas pelo seu servidor de aplicativo, destinadas ao mesmo usuário. Experiências entre dispositivos – IDs do aplicativo

  • Forneça ou selecione as IDs do aplicativo dos registros de aplicativo na MSA e/ou no AAD obtidos nas etapas anteriores do registro de aplicativo no AAD ou na MSA. Experiências entre dispositivos – registros de aplicativo na MSA e no AAD

  • Forneça suas credenciais para as plataformas de notificação nativa relevantes ao seu aplicativo (ou seja, WNS para Windows, FCM para Android e/ou APNS para iOS) para permitir a entrega de notificações do seu servidor de aplicativos quando você publica notificações direcionadas ao usuário. Experiências entre dispositivos – credenciais de push

  • Por fim, verifique se seu domínio de aplicativo entre dispositivos para garantir que seu aplicativo tem a propriedade do domínio e pode usá-lo como uma identidade entre dispositivos para seu aplicativo. Experiências entre dispositivos – Verificação de domínio

Usar a plataforma

Criar uma instância da plataforma

Para começar a usar, simplesmente crie a instância da plataforma.

MCDConnectedDevicesPlatform* platform = [MCDConnectedDevicesPlatform new];

Assinar MCDConnectedDevicesAccountManager

A plataforma requer que um usuário autenticado a acesse. Você precisará assinar eventos MCDConnectedDevicesAccountManager para assegurar que uma conta válida esteja sendo usada.

[MCDConnectedDevicesPlatform* platform.accountManager.accessTokenRequested
     subscribe:^(MCDConnectedDevicesAccountManager* _Nonnull manager __unused,
                 MCDConnectedDevicesAccessTokenRequestedEventArgs* _Nonnull request __unused) {

                    // Get access token

                 }
[MCDConnectedDevicesPlatform* platform.platform.accountManager.accessTokenInvalidated
     subscribe:^(MCDConnectedDevicesAccountManager* _Nonnull manager __unused,
                 MCDConnectedDevicesAccessTokenInvalidatedEventArgs* _Nonnull request) {

                      // Refresh and renew existing access token

                 }

Assinar MCDConnectedDevicesNotificationRegistrationManager

Da mesma forma, a plataforma usa notificações para entregar comandos entre dispositivos. Portanto, você precisa assinar os eventos MCDConnectedDevicesNotificationRegistrationManager para assegurar que os estados de registro de nuvem sejam válidos para a conta que está sendo usada. Verificar o estado usando MCDConnectedDevicesNotificationRegistrationState

[MCDConnectedDevicesPlatform* platform.notificationRegistrationManager.notificationRegistrationStateChanged
     subscribe:^(MCDConnectedDevicesNotificationRegistrationManager* manager __unused,
                 MCDConnectedDevicesNotificationRegistrationStateChangedEventArgs* args __unused) {

                     // Check state using MCDConnectedDevicesNotificationRegistrationState enum

                 }

Iniciar a plataforma

Agora que a plataforma foi inicializada e os manipuladores de eventos estão em vigor, você está pronto para iniciar a descoberta de dispositivos do sistema remoto.

[MCDConnectedDevicesPlatform* platform start];

Recuperar as contas de usuário conhecidas do aplicativo

É importante garantir que a lista de contas de usuário conhecidas do aplicativo esteja sincronizada corretamente com o MCDConnectedDevicesAccountManager.

Use MCDConnectedDevicesAccountManager.addAccountAsync para adicionar uma nova conta de usuário.

[MCDConnectedDevicesPlatform* platform.accountManager
     addAccountAsync:self.mcdAccount
     callback:^(MCDConnectedDevicesAddAccountResult* _Nonnull result, NSError* _Nullable error) {

     // Check state using **MCDConnectedDevicesAccountAddedStatus** enum

     }

Para remover uma conta inválida, você pode usar MCDConnectedDevicesAccountManager.removeAccountAsync

 [MCDConnectedDevicesPlatform* platform.accountManager
     removeAccountAsync:existingAccount
     callback:^(MCDConnectedDevicesRemoveAccountResult* _Nonnull result __unused, NSError* _Nullable error) {

                    // Remove invalid user account

     }

Inicializar um canal de Notificação do Graph

O SDK do Project Rome permite que seu aplicativo assine diferentes canais para receber e gerenciar diferentes tipos de dados do usuário – incluindo Notificações do Graph, Atividades do Usuário e muito mais. Todos eles são armazenados e sincronizados no MCDUserDataFeed. MCDUserNotification é o tipo de classe e de dados correspondente a uma notificação direcionada ao usuário enviada por meio das Notificações do Graph. Para integrar com o gráfico de notificação e começar a receber MCDUserNotification publicada pelo seu servidor de aplicativo, você primeiro precisará inicializar o feed de dados do usuário criando um MCDUserNotificationChannel. Você deve tratar isso como a etapa de inicialização da plataforma acima: ela deve ser verificada e possivelmente refeita sempre que o aplicativo vem ao primeiro plano (mas não antes da inicialização da plataforma).

Os métodos a seguir inicializam um MCDUserNotificationChannel.

// You must be logged in to use UserNotifications
NSArray<MCDUserAccount*>* accounts = [[AppDataSource sharedInstance].accountProvider getUserAccounts];
if (accounts.count > 0)
{
    // Get a UserNotification channel, getting the default channel
    NSLog(@"Creating UserNotificationChannel");
    NSArray<MCDUserAccount*>* accounts = [[AppDataSource sharedInstance].accountProvider getUserAccounts];
    MCDUserDataFeed* userDataFeed = [MCDUserDataFeed userDataFeedForAccount:accounts[0]
        platform:[AppDataSource sharedInstance].platform
        activitySourceHost:CROSS_PLATFORM_APP_ID];
    NSArray<MCDSyncScope*>* syncScopes = @[ [MCDUserNotificationChannel syncScope] ];
    [userDataFeed addSyncScopes:syncScopes];
    self.channel = [MCDUserNotificationChannel userNotificationChannelWithUserDataFeed:userDataFeed];
}
else
{
    NSLog(@"Must log in to receive notifications for the logged in user!");
    self.createNotificationStatusField.text = @"Need to be logged in!";
}

Neste ponto, você deve ter uma referência a MCDUserNotificationChannel em channel.

Criar um MCDUserNotificationReader para receber MCDUserNotifications de entrada e acessar o histórico de MCDUserNotification

Como mostramos anteriormente, a notificação da mensagem silenciosa do APNs inicial que chega ao aplicativo cliente contém apenas um toque shoulder. Você precisará passar esse conteúdo de toque shoulder para a Plataforma de Dispositivos Conectados, a fim de disparar o SDK para executar uma sincronização completa com o servidor de Dispositivos Conectados, que contém todas as MCDUserNotifications publicadas pelo seu servidor de aplicativo. Isso efetuará pull do conteúdo de notificação completo publicado pelo seu servidor de aplicativo correspondente a este toque shoulder (e, caso alguma notificação tenha sido publicada anteriormente, mas não recebida nesse cliente do aplicativo devido à conectividade do dispositivo ou outros problemas, o pull dela será efetuado também). Com essas sincronizações em tempo real executadas constantemente pelo SDK, o cliente do aplicativo pode ter acesso a um cache local do feed de dados MCDUserNotification deste usuário conectado. Nesse caso, um MCDUserNotificationReader permite o acesso do cliente do aplicativo a esse feed de dados – para receber o conteúdo da notificação mais recente por meio do ouvinte de eventos ou para acessar a coleção MCDUserNotification completa que pode ser usada como modelo de exibição do histórico de notificações do usuário.

Receber MCDUserNotifications

Primeiro, você precisa instanciar um MCDUserNotificationReader e obter todos os MCDUserNotifications existentes já no leitor se você está interessado em consumir essas informações para a experiência que você está tentando habilitar. É seguro pressupor sempre que o servidor de aplicativo já publicou notificações para esse usuário conectado, considerando que esse ponto de extremidade de dispositivo específico pode não ser o único ou o primeiro ponto de extremidade em que o usuário instalou o aplicativo. Em seguida, adicione um ouvinte de eventos que é disparado quando a Plataforma de Dispositivos Conectados conclui uma sincronização e tem novas alterações sobre as quais notificá-lo. No caso de Notificações do Graph, novas alterações podem ser novas MCDUserNotifications de entrada publicadas pelo seu servidor de aplicativo ou exclusões, atualizações e expirações de MCDUserNotifcation que ocorreram do servidor ou de outros pontos de extremidade registrados dos quais o mesmo usuário fez logon.

Dica

É nesse ouvinte de eventos que você pode manipular a lógica de negócios principal e "consumir" o conteúdo da sua notificação com base em seus cenários. Se você está usando notificação silenciosa do APNs para construir uma notificação visual no centro de notificações no nível do sistema operacional ou se você usa o conteúdo da notificação silenciosa para atualizar algumas interfaces do usuário no aplicativo, esse é o lugar para fazer isso.

// Instantiate the reader from a MCDUserNotificationChannel
// Add a data change listener to subscribe to new changes when new notifications or notification updates are received
- (void)setupWithAccount:(MCDUserAccount*)account {
    dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{
        @synchronized (self) {
            MCDUserDataFeed* dataFeed = [MCDUserDataFeed userDataFeedForAccount:account platform:_platform activitySourceHost:@"graphnotifications.sample.windows.com"];
            [dataFeed addSyncScopes:@[[MCDUserNotificationChannel syncScope]]];
            self.channel = [MCDUserNotificationChannel userNotificationChannelWithUserDataFeed:dataFeed];
            self.reader = [self.channel createReader];
            
            __weak typeof(self) weakSelf = self;
            _readerRegistrationToken = [self.reader addDataChangedListener:^(__unused MCDUserNotificationReader* source) {
                NSLog(@"ME123 Got a change!");
                if (weakSelf) {
                    [weakSelf forceRead];
                } else {
                    NSLog(@"ME123 WEAKSELF FOR CHANGES IS NULL!!!");
                }
            }];
            
            [self forceRead];
        }
    });
}

// this is your own business logic when the event listener is fired
// In this case, the app reads the existing batch of notifications in the store and handle any new incoming notifications or notification updates after that
- (void)forceRead {
    NSLog(@"ME123 Forced to read!");
    [self.reader readBatchAsyncWithMaxSize:NSUIntegerMax completion:^(NSArray<MCDUserNotification *> * _Nullable notifications, NSError * _Nullable error) {
        if (error) {
            NSLog(@"ME123 Failed to read batch with error %@", error);
        } else {
            [self _handleNotifications:notifications];
            NSLog(@"ME123 Have %ld listeners", self.listenerMap.count);
            for (void (^listener)(void) in self.listenerMap.allValues) {
                NSLog(@"ME123 Calling a listener about an update!");
                listener();
            }
        }
    }];
}

Atualizar o estado de uma MCDUserNotification existente

Na seção anterior, mencionamos que, às vezes, uma alteração de MCDUserNotification recebida por meio do leitor poderia ser uma atualização de estado em uma MCDUserNotification existente – independentemente de ela estar sendo marcada como ignorada ou como lida. Nesse caso, o cliente do aplicativo pode decidir o que fazer, assim como habilitar a dispensa universal, removendo a notificação visual correspondente nesse dispositivo específico. Dando um passo para trás, seu cliente de aplicativo costuma ser aquele primeiro que iniciou esta atualização de alteração MCDUserNotification – de um dispositivo diferente. Você pode escolher a hora para atualizar o estado do MCDUserNotifications, mas geralmente eles são atualizados quando a notificação visual correspondente é manipulada pelo usuário nesse dispositivo ou a notificação é subsequentemente manipulada pelo usuário em alguma experiência no aplicativo habilitada por você. Aqui está um exemplo de como seria o fluxo: o servidor de aplicativos publica uma notificação direcionada ao usuário A, o qual recebe essa notificação no computador e telefone nos quais os clientes do aplicativo estão instalados. O usuário clica na notificação no PC e busca no aplicativo para desempenhar a tarefa correspondente. O cliente do aplicativo neste PC, em seguida, chamará no SDK da Plataforma de Dispositivos Conectados para atualizar o estado da UserNotification correspondente para que essa atualização seja sincronizada em todos os dispositivos deste usuário. Os outros clientes de aplicativo, ao receber esse estado de atualização em tempo real, removerão em seguida o alerta visual/mensagem/notificação do sistema correspondente do centro de notificações/bandeja de notificação/central de ações do dispositivo. É assim que as notificações são ignoradas universalmente em todos os dispositivos do usuário.

Dica

A classe MCDUserNotification atualmente fornece 2 tipos de atualizações de estado – você pode modificar o MCDUserNotificationReadState ou o MCDUserNotificationUserActionState e definir sua própria lógica para o que deve acontecer quando as notificações são atualizadas. Por exemplo, você pode marcar o estado da ação como Ativado ou Ignorado dinamizar esse valor para implementar a dispensa universal. Como alternativa ou simultaneamente, você pode marcar ReadState como lido ou não lido e, com base nisso, determinar quais notificações devem aparecer na exibição de histórico de notificações no aplicativo.

- (void)dismissNotification:(MCDUserNotification*)notification {
    @synchronized (self) {
        notification.userActionState = MCDUserNotificationUserActionStateDismissed;
        [notification saveAsync:^(__unused MCDUserNotificationUpdateResult * _Nullable result, __unused NSError * _Nullable err) {
            NSLog(@"ME123 Dismiss notification with result %d error %@", result.succeeded, err);
        }];
    }
}