Guide pratique : Intégration à la fonctionnalité Notifications Graph (iOS)
Les notifications Graph permettent à votre application d’envoyer et de gérer des notifications ciblant l’utilisateur sur plusieurs appareils.
Avec le SDK côté client Projet Rome sur iOS, votre application iOS peut s’inscrire pour recevoir des notifications publiées à partir de votre serveur d’applications ciblant un utilisateur connecté. Le SDK permet au client d’application de recevoir les nouvelles charges utiles de notification entrante, gérer l’état des notifications existantes et récupérer l’historique des notifications. Pour plus d’informations sur la fonctionnalité Notifications et la façon dont elle permet la remise de notifications centrées sur la personne, consultez Vue d’ensemble des notifications Microsoft Graph.
Toutes les fonctionnalités du SDK Projet Rome, notamment Notifications Graph, reposent sur une plateforme sous-jacente appelée « Plateforme d’appareils connectés ». Ce guide est conçu de façon à vous guider tout au long des étapes nécessaires pour commencer à utiliser la Plateforme d’appareils connectés et à expliquer comment utiliser les API du SDK afin d’implémenter des fonctionnalités spécifiques aux notifications Graph.
Les étapes ci-dessous font référence à du code tiré de l’exemple d’application iOS du projet Rome qui est disponible sur GitHub.
Consultez la page Informations de référence sur les API pour obtenir des liens vers la documentation de référence pertinente pour les scénarios de notification.
Configuration de la Plateforme d’appareils connectés et des notifications
Inscrire votre application
L’authentification de compte Microsoft (MSA) ou Azure Active Directory (AAD) est nécessaire pour pratiquement toutes les fonctionnalités du SDK du projet Rome (les API de partage de proximité étant l’exception). Si vous ne disposez pas déjà d’un compte MSA et que souhaitez en utiliser un, inscrivez-vous sur account.microsoft.com.
Notes
Les comptes Azure Active Directory (AAD) ne sont pas pris en charge avec les API de relais d’appareils.
En utilisant la méthode d’authentification de votre choix, vous devez inscrire votre application auprès de Microsoft en suivant les instructions qui se trouvent sur le portail d’inscription des applications. Si vous n’avez pas de compte de développeur Microsoft, vous devrez en créer un.
Quand vous inscrivez une application à l’aide d’un compte MSA, vous devez recevoir une chaîne d’ID client. Enregistrez-la pour plus tard. Elle permettra à votre application d’accéder aux ressources de la Plateforme d’appareils connectés de Microsoft. Si vous utilisez AAD, consultez Bibliothèques d’authentification d’Azure Active Directory pour savoir comment obtenir la chaîne d’ID client.
Ajouter le kit SDK
Le moyen le plus simple d’ajouter la Plateforme d’appareils connectés à votre application iOS est d’utiliser le gestionnaire de dépendances CocoaPods. Accédez au fichier Podfile de votre projet iOS et insérez l’entrée suivante :
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
Notes
Pour utiliser CocoaPod, vous devez utiliser le fichier .xcworkspace dans votre projet.
Configuration de l’authentification et de la gestion des comptes
La Plateforme d’appareils connectés exige l’utilisation d’un jeton OAuth pendant l’inscription. Vous pouvez générer et gérer les jetons OAuth en employant la méthode qui vous convient le mieux. Cependant, pour aider les développeurs dans la prise en main de la plateforme, nous avons inclus un fournisseur d’authentification dans l’exemple d’application iOS que vous pouvez utiliser pour générer et gérer des jetons d’actualisation dans votre application.
Si vous n’utilisez pas le code fourni, vous devez vous-même implémenter l’interface MCDConnectedDevicesAccountManager.
Si vous utilisez un compte MSA, incluez les étendues suivantes dans votre demande de connexion : "wl.offline_access"
, "ccs.ReadWrite"
, "dds.read"
, "dds.register"
, "wns.connect"
, "asimovrome.telemetry"
et "https://activity.windows.com/UserActivity.ReadWrite.CreatedByApp"
.
Notes
Les comptes Azure Active Directory (AAD) ne sont pas pris en charge avec les API de relais d’appareils.
Si vous utilisez un compte AAD, vous devrez demander les audiences suivantes : "https://cdpcs.access.microsoft.com"
, "https://cs.dds.microsoft.com"
, "https://wns.windows.com/"
et "https://activity.microsoft.com"
.
Que vous utilisiez l’implémentation MCDConnectedDevicesAccountManager fournie ou non, si vous utilisez AAD, vous devrez spécifier les autorisations suivantes dans l’inscription de votre application sur le portail Azure (portal.azure.com > Azure Active Directory > Inscriptions des applications) :
- Service de flux d’activités Microsoft
- Remettez et modifiez les notifications utilisateur pour cette application
- Lisez et écrivez l’activité de l’application dans le flux d’activités des utilisateurs
- Services de notifications Windows
- Connectez votre appareil au service de notification Windows
- Service d’annuaire d’appareils Microsoft
- Consultez votre liste d’appareils
- Faites-vous ajouter à votre liste d’appareils et d’applications
- Service de commande Microsoft
- Communiquez avec les appareils utilisateur
- Lisez les appareils utilisateur
Inscription de votre application pour les notifications Push
Pour assurer une prise en charge d’Apple Push Notification, inscrivez votre application auprès d’Apple. Veillez à noter l’ID d’expéditeur et la clé serveur que vous recevez, car vous en aurez besoin par la suite.
Une fois l’inscription effectuée, vous devez associer la fonctionnalité de notification Push à la Plateforme d’appareils connectés dans votre application.
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;
Inscrire votre application dans le Centre de développement Microsoft pour des expériences inter-appareils
Avertissement
Cette étape n’est nécessaire que si vous souhaitez utiliser les fonctionnalités du projet Rome pour accéder à des données ou effectuer des demandes à partir d’appareils non Windows. Si vous ciblez uniquement des appareils Windows, vous n’avez pas besoin d’effectuer cette étape.
Inscrivez votre application pour la fonctionnalité Expériences inter-appareils du tableau de bord Développeur Microsoft. Il s’agit d’une procédure différente de celle visant à inscrire une application MSA et AAD décrite plus haut. L’objectif principal de ce processus est de mapper les identités d’application d’une plateforme spécifique à une identité d’application multiplateforme qui est reconnue par la Plateforme d’appareils connectés. Cette étape permettra aussi l’envoi de notifications à l’aide des services de notification Push natifs correspondant aux plateformes mobiles utilises par votre application. Dans le cas d’iOS, elle permet l’envoi de notifications aux points de terminaison d’application iOS via APNS (Apple Push Notification Service).
Dans le tableau de bord du Centre de développement, accédez à Expériences inter-appareils dans le volet de navigation de gauche, puis choisissez de configurer une nouvelle application inter-appareils.
Le processus d’intégration du Centre de développement comprend les étapes suivantes :
Sélectionnez les plateformes prises en charge, à savoir celles sur lesquelles votre application sera présente et compatible avec les expériences inter-appareils. Dans le cas de l’intégration des notifications Graph, vous pouvez sélectionner Windows, Android et/ou iOS, selon les plateformes que vous utilisez.
Fournissez des ID d’application pour chaque plateforme utilisée. Pour les applications iOS, il s’agit du nom de package que vous avez attribué à votre application au moment de créer le projet. Notez que vous pouvez ajouter des ID différents (jusqu’à dix) par plateforme. Cela peut être utile si vous disposez de plusieurs versions d’une même application, voire différentes applications, et que vous souhaitez qu’elles puissent recevoir les mêmes notifications envoyées par votre serveur d’applications ciblant le même utilisateur.
Fournissez ou sélectionnez les ID d’application des inscriptions d’application MSA et/ou AAD obtenus aux étapes d’inscription d’application MSA/AAD précédentes.
Fournissez vos informations d’identification pour les plateformes de notification natives correspondant à votre application (c’est-à-dire, WNS pour Windows, FCM pour Android et/ou APNS pour iOS) pour permettre à votre serveur d’applications de transmettre les notifications ciblant l’utilisateur, dans le cas où vous en publiez.
Enfin, vérifiez votre domaine d’application inter-appareils pour être certain que votre application en est propriétaire et que vous pouvez l’utiliser comme identité inter-appareils pour votre application.
Utilisation de la plateforme
Créer une instance de la plateforme
Pour commencer, instanciez simplement la plateforme.
MCDConnectedDevicesPlatform* platform = [MCDConnectedDevicesPlatform new];
S’abonner à MCDConnectedDevicesAccountManager
Pour pouvoir accéder à la plateforme, l’utilisateur doit être authentifié. Vous devrez vous abonner aux événements MCDConnectedDevicesAccountManager pour être certain qu’un compte valide est utilisé.
[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
}
S’abonner à MCDConnectedDevicesNotificationRegistrationManager
De la même manière, la plateforme utilise des notifications pour la transmission de commandes entre les appareils. Par conséquent, vous devez vous abonner aux événements MCDConnectedDevicesNotificationRegistrationManager pour faire en sorte que les états d’inscription cloud sont valides pour le compte utilisé. Vérifiez l’état à l’aide de MCDConnectedDevicesNotificationRegistrationState
[MCDConnectedDevicesPlatform* platform.notificationRegistrationManager.notificationRegistrationStateChanged
subscribe:^(MCDConnectedDevicesNotificationRegistrationManager* manager __unused,
MCDConnectedDevicesNotificationRegistrationStateChangedEventArgs* args __unused) {
// Check state using MCDConnectedDevicesNotificationRegistrationState enum
}
Démarrer la plateforme
Maintenant que la plateforme est initialisée et que les gestionnaires d’événements sont en place, vous êtes prêt à démarrer la découverte d’appareils système distants.
[MCDConnectedDevicesPlatform* platform start];
Récupérer les comptes d’utilisateur connus de l’application
Il est important de vérifier que la liste des comptes d’utilisateurs connus de l’application est correctement synchronisée avec MCDConnectedDevicesAccountManager.
Utilisez MCDConnectedDevicesAccountManager.addAccountAsync pour ajouter un nouveau compte d’utilisateur.
[MCDConnectedDevicesPlatform* platform.accountManager
addAccountAsync:self.mcdAccount
callback:^(MCDConnectedDevicesAddAccountResult* _Nonnull result, NSError* _Nullable error) {
// Check state using **MCDConnectedDevicesAccountAddedStatus** enum
}
Pour supprimer un compte non valide, vous pouvez utiliser MCDConnectedDevicesAccountManager.removeAccountAsync
[MCDConnectedDevicesPlatform* platform.accountManager
removeAccountAsync:existingAccount
callback:^(MCDConnectedDevicesRemoveAccountResult* _Nonnull result __unused, NSError* _Nullable error) {
// Remove invalid user account
}
Initialiser un canal de notification Graph
Le SDK Projet Rome permet à votre application de vous abonner à différents canaux afin de recevoir et de gérer différents types de données utilisateur, notamment les notifications Graph, les activités de l’utilisateur, et bien plus encore. Ils sont tous stockés et synchronisés dans MCDUserDataFeed. MCDUserNotification est la classe et le type de données correspondant à une notification ciblée sur l’utilisateur qui est envoyée par le biais de la fonctionnalité Notifications Graph. Pour effectuer une intégration à la fonctionnalité Notification Graph et recevoir un MCDUserNotification publié par votre serveur d’applications, vous devez d’abord initialiser le flux de données utilisateur en créant un MCDUserNotificationChannel. Vous devez considérer cette opération comme l’étape d’initialisation de la plateforme ci-dessus : elle doit être vérifiée et éventuellement refaite chaque fois que l’application s’affiche au premier plan (mais pas avant l’initialisation de la plateforme).
Les méthodes suivantes initialisent un 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!";
}
À ce stade, vous devez avoir une référence à MCDUserNotificationChannel dans channel
.
Créer un MCDUserNotificationReader pour recevoir des MCDUserNotification entrants et accéder à l’historique des MCDUserNotification
Comme nous l’avons montré précédemment, le message silencieux APNS initial arrivant sur le client d’application contient uniquement un passage de relais, et vous devez transmettre cette charge utile en passage de relais à la Plateforme d’appareils connectés afin de déclencher le SDK pour effectuer une synchronisation complète avec le serveur d’appareils connectés, lequel contient tous les MCDUserNotifications publiés par votre serveur d’applications. Cette opération extrait la charge utile de notification complète publiée par votre serveur d’applications correspondant à ce passage de relais (et dans le cas où des notifications précédentes ont été publiées mais pas reçues sur ce client d’application en raison de la connectivité des appareils ou d’autres problèmes, elles seront également extraites). Avec ces synchronisations en temps réel effectuées en permanence par le SDK, le client d’application est en mesure d’accéder à un cache local de ce flux de données MCDUserNotification de l’utilisateur connecté. Dans ce cas, un MCDUserNotificationReader permet au client d’application d’accéder à ce flux de données (pour recevoir la dernière charge utile de notification par le biais du détecteur d’événements ou accéder à la collection d’éléments MCDUserNotification complète qui peut être utilisée comme modèle d’affichage de l’historique des notifications de l’utilisateur).
Réception de MCDUserNotifications
Vous devez d’abord instancier un MCDUserNotificationReader et obtenir tous les MCDUserNotifications existants dans le lecteur si la consommation de ces informations pour l’expérience que vous essayez d’activer vous intéresse. Étant donné que ce point de terminaison d’appareil particulier n’est peut-être pas le seul ou le premier point de terminaison que l’utilisateur a installé sur votre application, nous pouvons toujours présumer sans risque que le serveur d’applications a déjà publié des notifications à cet utilisateur connecté. Ajoutez alors un détecteur d’événements qui se déclenche quand la Plateforme d’appareils connectés effectue une synchronisation et qu’elle doit vous informer de nouveaux changements. Dans le cas de la fonctionnalité Notifications Graph, les nouveaux changements peuvent être de nouveaux MCDUserNotifications entrants publiés par votre serveur d’applications, ou des mises à jour, suppressions et expirations d’éléments MCDUserNotifcation qui se sont produits à partir du serveur ou à partir d’autres points de terminaison inscrits auxquels le même utilisateur s’est connecté.
Conseil
Ce détecteur d’événements est l’endroit où vous traitez la principale logique métier et où vous « consommez » le contenu de votre charge utile de notification en fonction de vos scénarios. Si vous utilisez actuellement une notification silencieuse APNS pour construire une notification visuelle dans le centre de notifications au niveau du système d’exploitation, ou si vous utilisez le contenu de la notification silencieuse pour mettre à jour une interface utilisateur dans l’application, c’est l’endroit approprié pour cela.
// 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();
}
}
}];
}
Mettre à jour l’état d’un MCDUserNotification existant
Dans la section précédente, nous avons mentionné qu’un changement de MCDUserNotification reçu par le biais du lecteur peut parfois être une mise à jour d’état sur un MCDUserNotification existant (qu’il soit marqué comme masqué ou marqué comme lu). Dans ce cas, le client d’application peut choisir les actions à entreprendre, comme l’activation du masquage universel en supprimant la notification visuelle correspondante sur cet appareil particulier. Si nous revenons un peu en arrière, votre client d’application est souvent celui qui a lancé, à partir d’un autre appareil, cette mise à jour de changement de MCDUserNotification pour commencer. Vous pouvez choisir le moment où mettre à jour l’état de vos MCDUserNotifications, mais en général, ils sont mis à jour quand la notification visuelle correspondante est traitée par l’utilisateur sur cet appareil, ou quand l’utilisateur poursuit le traitement de la notification dans une expérience interne à l’application que vous activez. Voici un exemple de ce à quoi devrait ressembler le flux : Votre serveur d’applications publie une notification ciblant l’utilisateur A. L’utilisateur A reçoit cette notification à la fois sur son PC et sur son téléphone où les clients d’application sont installés. L’utilisateur clique sur la notification sur le PC et parcourt l’application pour traiter la tâche correspondante. Le client d’application sur ce PC appelle alors le SDK de la Plateforme d’appareils connectés pour mettre à jour l’état de la notification utilisateur correspondante afin que cette mise à jour synchronisée soit disponible sur tous les appareils de cet utilisateur. Quand les autres clients d’application reçoivent cette mise à jour d’état en temps réel, ils suppriment l’alerte visuelle/le message/la notification toast correspondant du centre de notifications/de la barre de notifications de l’appareil. Voici comment les notifications sont universellement masquées sur les appareils d’un utilisateur.
Conseil
La classe MCDUserNotification fournit actuellement 2 types de mises à jour d’état : vous pouvez modifier le MCDUserNotificationReadState ou le MCDUserNotificationUserActionState, et définir votre propre logique sur ce qui doit se produire quand des notifications sont mises à jour. Par exemple, vous pouvez marquer l’état d’action comme Activated (Activé) ou Dismissed (Masqué), et vous appuyer sur cette valeur pour implémenter le masquage universel. Alternativement ou simultanément, vous pouvez marquer l’état de lecture comme Unread (Lu) ou Unread (Non lu) et, en vous appuyant sur cette valeur, déterminez quelles notifications doivent apparaître dans l’affichage de l’historique des notifications internes à l’application.
- (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);
}];
}
}