Comment utiliser les notifications Push dans les formulaires Xamarin

Je suis une application utilisant Xamarin.Forms ciblant IOS, Android et WP 8.

J’ai besoin de la fonctionnalité de notifications push dans mon application.

J’ai vu les démos pushsharp et semble prometteur. Mais tous les codes que j’ai vus se font séparément pour chaque plate-forme.

Je voudrais que cela soit fait dans le projet Xamarin.Forms, quelque part dans l’App.cs, afin de ne pas avoir à répéter le code pour enregistrer le périphérique et gérer le traitement des notifications push.

Toute aide serait grandement appréciée. Des exemples de codes ou de références de didacticiel sont les bienvenus.

Edit : Je l’ai implémenté en fonction de la réponse d’Idot. Voici le lien pour ma réponse.

Je viens de mettre en place une notification push il y a quelques jours et je partagerai ma solution ici (basée sur PushSharp )

Guide étape par étape:

1) Dans votre projet partagé, créez une interface appelée IPushNotificationRegister

 public interface IPushNotificationRegister { void ExtractTokenAndRegister(); } 

Cette interface est utilisée pour récupérer le jeton Push, puis l’envoyer au serveur. Ce jeton est unique par périphérique.

2) Dans votre projet partagé, vous devez appeler ExtractTokenAndRegister (en utilisant votre IOC préféré, je l’ai appelé juste après la connexion).

Implémentation Android:

3) Ajouter des récepteurs pour écouter les événements reçus par le service Google GCM:

une)

 [BroadcastReceiver] [IntentFilter(new[] { Intent.ActionBootCompleted })] public class GCMBootReceiver : BroadcastReceiver { public override void OnReceive(Context context, Intent intent) { MyIntentService.RunIntentInService(context, intent); SetResult(Result.Ok, null, null); } } 

b)

 [assembly: Permission(Name = "@PACKAGE_NAME@.permission.C2D_MESSAGE")] [assembly: UsesPermission(Name = "android.permission.WAKE_LOCK")] [assembly: UsesPermission(Name = "@PACKAGE_NAME@.permission.C2D_MESSAGE")] [assembly: UsesPermission(Name = "com.google.android.c2dm.permission.RECEIVE")] [assembly: UsesPermission(Name = "android.permission.GET_ACCOUNTS")] [assembly: UsesPermission(Name = "android.permission.INTERNET")] namespace Consumer.Mobile.Droid.PushNotification { [BroadcastReceiver(Permission = "com.google.android.c2dm.permission.SEND")] [IntentFilter(new ssortingng[] { "com.google.android.c2dm.intent.RECEIVE" }, Categories = new ssortingng[] { "@PACKAGE_NAME@" })] [IntentFilter(new ssortingng[] { "com.google.android.c2dm.intent.REGISTRATION" }, Categories = new ssortingng[] { "@PACKAGE_NAME@" })] [IntentFilter(new ssortingng[] { "com.google.android.gcm.intent.RETRY" }, Categories = new ssortingng[] { "@PACKAGE_NAME@" })] [IntentFilter (new[]{ Intent.ActionBootCompleted }, Categories = new[]{ Intent.CategoryDefault })] public class GCMBroadcastReceiver : BroadcastReceiver { public override void OnReceive(Context context, Intent intent) { MyIntentService.RunIntentInService(context, intent); SetResult(Result.Ok, null, null); } } } 

c) Ajouter un service d’intention pour traiter la notification

 using Android.App; using Android.Content; using Android.Graphics; using Android.Media; using Android.OS; using Android.Support.V4.App; using Consumer.Mobile.Infra; using Consumer.Mobile.Services.PushNotification; using Java.Lang; using XLabs.Ioc; using TaskStackBuilder = Android.Support.V4.App.TaskStackBuilder; namespace Consumer.Mobile.Droid.PushNotification { [Service] public class MyIntentService : IntentService { private readonly ILogger _logger; private readonly IPushNotificationService _notificationService; private readonly IPushNotificationRegister _pushNotificationRegister; public MyIntentService() { _logger = Resolver.Resolve(); _notificationService = Resolver.Resolve(); _pushNotificationRegister = Resolver.Resolve(); } static PowerManager.WakeLock _sWakeLock; static readonly object Lock = new object(); public static void RunIntentInService(Context context, Intent intent) { lock (Lock) { if (_sWakeLock == null) { // This is called from BroadcastReceiver, there is no init. var pm = PowerManager.FromContext(context); _sWakeLock = pm.NewWakeLock( WakeLockFlags.Partial, "My WakeLock Tag"); } } _sWakeLock.Acquire(); intent.SetClass(context, typeof(MyIntentService)); context.StartService(intent); } protected override void OnHandleIntent(Intent intent) { try { Context context = this.ApplicationContext; ssortingng action = intent.Action; if (action.Equals("com.google.android.c2dm.intent.REGISTRATION")) { HandleRegistration(context, intent); } else if (action.Equals("com.google.android.c2dm.intent.RECEIVE")) { HandleMessage(context, intent); } } finally { lock (Lock) { //Sanity check for null as this is a public method if (_sWakeLock != null) _sWakeLock.Release(); } } } private void HandleMessage(Context context, Intent intent) { Intent resultIntent = new Intent(this, typeof(MainActivity)); TaskStackBuilder stackBuilder = TaskStackBuilder.Create(this); var c = Class.FromType(typeof(MainActivity)); stackBuilder.AddParentStack(c); stackBuilder.AddNextIntent(resultIntent); ssortingng alert = intent.GetSsortingngExtra("Alert"); int number = intent.GetIntExtra("Badge", 0); var imageUrl = intent.GetSsortingngExtra("ImageUrl"); var title = intent.GetSsortingngExtra("Title"); Bitmap bitmap = GetBitmap(imageUrl); PendingIntent resultPendingIntent = stackBuilder.GetPendingIntent(0, (int)PendingIntentFlags.UpdateCurrent); NotificationCompat.Builder builder = new NotificationCompat.Builder(this) .SetAutoCancel(true) // dismiss the notification from the notification area when the user clicks on it .SetContentIntent(resultPendingIntent) // start up this activity when the user clicks the intent. .SetContentTitle(title) // Set the title .SetNumber(number) // Display the count in the Content Info .SetSmallIcon(Resource.Drawable.Icon) // This is the icon to display .SetLargeIcon(bitmap) .SetSound(RingtoneManager.GetDefaultUri(RingtoneType.Notification)) .SetContentText(alert); // the message to display. // Build the notification: Notification notification = builder.Build(); // Get the notification manager: NotificationManager notificationManager = GetSystemService(Context.NotificationService) as NotificationManager; // Publish the notification: const int notificationId = 0; notificationManager.Notify(notificationId, notification); } private void HandleRegistration(Context context, Intent intent) { var token = intent.GetSsortingngExtra("registration_id"); _logger.Info(this.Class.SimpleName, "Received Token : " + token); if (_pushNotificationRegister.ShouldSendToken(token)) { var uid = Android.Provider.Settings.Secure.GetSsortingng(MainActivity.Context.ContentResolver, Android.Provider.Settings.Secure.AndroidId); _notificationService.AddPushToken(token, DeviceUtils.GetDeviceType(), uid); } } private Bitmap GetBitmap(ssortingng url) { try { System.Net.WebRequest request = System.Net.WebRequest.Create(url); System.Net.WebResponse response = request.GetResponse(); System.IO.Stream responseStream = response.GetResponseStream(); return BitmapFactory.DecodeStream(responseStream); } catch (System.Net.WebException) { return null; } } } } 

d) Implémenter l’interface IPushNotificationRegister :

 using Android.App; using Android.Content; using Consumer.Mobile.Services; using Consumer.Mobile.Services.PushNotification; [assembly: Permission(Name = "@PACKAGE_NAME@.permission.C2D_MESSAGE")] [assembly: UsesPermission(Name = "@PACKAGE_NAME@.permission.C2D_MESSAGE")] // Gives the app permission to register and receive messages. [assembly: UsesPermission(Name = "com.google.android.c2dm.permission.RECEIVE")] // Needed to keep the processor from sleeping when a message arrives [assembly: UsesPermission(Name = "android.permission.WAKE_LOCK")] [assembly: UsesPermission(Name = "android.permission.RECEIVE_BOOT_COMPLETED")] namespace Consumer.Mobile.Droid.PushNotification { public class PushNotificationRegister : IPushNotificationRegister { public override void ExtractTokenAndRegister() { ssortingng senders = AndroidConfig.GCMSenderId; Intent intent = new Intent("com.google.android.c2dm.intent.REGISTER"); intent.SetPackage("com.google.android.gsf"); intent.PutExtra("app", PendingIntent.GetBroadcast(MainActivity.Context, 0, new Intent(), 0)); intent.PutExtra("sender", senders); MainActivity.Context.StartService(intent); } } } 

Implémentation iOS:

4) Dans votre AppDelegate , ajoutez la méthode suivante:

une)

 public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken) { var deviceTokenSsortingng = deviceToken.ToSsortingng().Replace("<","").Replace(">", "").Replace(" ", ""); var notificationService = Resolver.Resolve(); var pushNotificationRegister = Resolver.Resolve(); if (pushNotificationRegister.ShouldSendToken(deviceTokenSsortingng)) { var uid = UIDevice.CurrentDevice.IdentifierForVendor.AsSsortingng(); notificationService.AddPushToken(deviceTokenSsortingng, DeviceUtils.GetDeviceType(), uid); } } 

b) Implémenter IPushNotificationRegister :

 using Consumer.Mobile.Services; using Consumer.Mobile.Services.PushNotification; using UIKit; namespace Consumer.Mobile.iOS.PushNotification { public class iOSPushNotificationRegister : IPushNotificationRegister { public override void ExtractTokenAndRegister() { const UIRemoteNotificationType notificationTypes = UIRemoteNotificationType.Alert | UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound; UIApplication.SharedApplication.RegisterForRemoteNotificationTypes(notificationTypes); } } } 

En ce qui concerne WP, je ne l’ai pas implémenté.

Si vous avez besoin du code du côté serveur en utilisant PushSharp, faites-le moi savoir.

Vous pouvez vérifier les exemples de clients sur lesquels j’ai basé ma solution ici

On m’a suggéré d’utiliser le plugin suivant pour le support et les formulaires xamarin.

Ce plugin fonctionne bien

https://github.com/rdelrosario/xamarin-plugins/tree/master/PushNotification

Mettra à jour la réponse une fois que je le ferai fonctionner.

METTRE À JOUR :

J’ai reçu des notifications push pour iOS et Android.

J’ai utilisé Google Cloud Messaging Client , un excellent composant pour Android, et je n’ai pas eu à écrire une grande partie du code comme mentionné dans cette réponse .

Mon implémentation iOS était similaire à celle-ci , pas beaucoup de code requirejs.

Et pour pousser les notifications du serveur, j’ai utilisé le paquet nuget de PushSharp .

Je n’ai pas implémenté dans WP, car cela n’était pas nécessaire dans mon projet.

Cette aide de Xamarin sur les notifications push mérite d’être lue si vous souhaitez implémenter les notifications Push.

Mise à jour (juin 2018) – Utilisez le plug-in suivant pour FCM sur iOS et Android, ti prend en charge Xamarin.Forms – FirebasePushNotificationPlugin

Dans Xamarin Forms, vous pouvez également utiliser un SDK de notifications comme Donky (qui est l’équivalent européen de l’American Urban Airship); vous pouvez facilement faire un projet de notifications évolutives en une seule journée, j’ai créé deux fois des clones de clones WhatsApp en moins de 35 minutes à chaque fois en utilisant ce SDK. Voir http://docs.mobiledonky.com

Cela n’est pas possible dans Xamarin.Forms pur mais est relativement sortingvial pour implémenter une solution grâce à laquelle ils peuvent être manipulés dans App.cs (bien que cela nécessitera des implémentations spécifiques à la plateforme).

Jetez un coup d’œil à l’implémentation IXForms du projet Xamarin.Forms.Labs où les notifications sont renvoyées au projet Forms:

https://github.com/XLabs/Xamarin-Forms-Labs

et plus précisément:

https://github.com/XLabs/Xamarin-Forms-Labs/tree/master/src/Platform/XLabs.Platform/Mvvm

Il y a un article de blog récemment sur l’implémentation des notifications Push sur les formulaires Xamarin (ainsi que sur chaque plateforme individuelle car il n’y a pas d’implémentation basée sur Forms), en utilisant Azure Mobile Services.

http://www.xamarinhelp.com/push-notifications/

Vous pourriez regarder le composant Appboy qui a un support pour cela en dehors de la boîte. https://components.xamarin.com/view/appboy-sdk-bindings

Comme d’autres l’ont dit, vous ne pouvez pas faire de manière générique sans certains composants spécifiques à la plate-forme.