Tutorial: Senden von Pushbenachrichtigungen an bestimmte Benutzer mit Azure Notification HubsTutorial: Send push notifications to specific users using Azure Notification Hubs

Ein ASP.NET WebAPI-Back-End wird verwendet, um Clients zu authentifizieren.This tutorial shows you how to use Azure Notification Hubs to send push notifications to a specific app user on a specific device. Zum Authentifizieren von Clients und Generieren von Benachrichtigungen wird ein ASP.NET WebAPI-Back-End verwendet, wie im Thema Registrieren von App-Back-End aus gezeigt.An ASP.NET WebAPI backend is used to authenticate clients and to generate notifications, as shown in the guidance topic Registering from your app backend.

In diesem Tutorial führen Sie die folgenden Schritte aus:In this tutorial, you take the following steps:

  • Erstellen des WebAPI-ProjektsCreate the WebAPI project
  • Authentifizieren von Clients beim WebAPI-Back-EndAuthenticate clients to the WebAPI backend
  • Registrieren für Benachrichtigungen unter Verwendung des WebAPI-Back-EndsRegister for notifications by using the WebAPI backend
  • Senden von Benachrichtigungen über das WebAPI-Back-EndSend notifications from the WebAPI backend
  • Veröffentlichen des neuen WebAPI-Back-EndsPublish the new WebAPI backend
  • Ändern der iOS-AppModify your iOS app
  • Testen der AnwendungTest the application

VoraussetzungenPrerequisites

In diesem Lernprogramm wird davon ausgegangen, dass Sie Ihren Notification Hub wie unter Erste Schritte mit Notification Hubs (iOS)beschrieben erstellt und konfiguriert haben.This tutorial assumes that you have created and configured your notification hub as described in Getting Started with Notification Hubs (iOS). Dieses Lernprogramm ist außerdem die Voraussetzung für das Lernprogramm Sichere Pushbenachrichtigungen (iOS) .This tutorial is also the prerequisite to the Secure Push (iOS) tutorial. Wenn Sie Mobile Apps als Back-End-Dienst verwenden möchten, lesen Sie Mobile Apps: Erste Schritte mit Push.If you want to use Mobile Apps as your backend service, see the Mobile Apps Get Started with Push.

Erstellen des WebAPI-ProjektsCreate the WebAPI project

In den folgenden Abschnitten wird die Erstellung eines neuen ASP.NET-WebAPI-Back-Ends erläutert.The following sections discuss the creation of a new ASP.NET WebAPI backend. Dieser Prozess hat drei Hauptfunktionen:This process has three main purposes:

  • Authentifizieren von Clients: Sie fügen einen Meldungshandler hinzu, um Clientanforderungen zu authentifizieren und den Benutzer der Anforderung zuzuordnen.Authenticate clients: You add a message handler to authenticate client requests and associate the user with the request.
  • Registrieren für Benachrichtigungen unter Verwendung des WebAPI-Back-Ends: Sie fügen einen Controller hinzu, um neue Registrierungen für ein Clientgerät zum Empfangen von Benachrichtigungen zu verarbeiten.Register for notifications by using the WebAPI backend: You add a controller to handle new registrations for a client device to receive notifications. Der authentifizierte Benutzername wird der Registrierung automatisch als Tag hinzugefügt.The authenticated username is automatically added to the registration as a tag.
  • Senden von Benachrichtigungen an Clients: Sie fügen einen Controller hinzu, um Benutzern die Möglichkeit zu geben, einen sicheren Pushvorgang an Geräte und Clients auszulösen, die dem Tag zugeordnet sind.Send notifications to clients: You add a controller to provide a way for users to trigger a secure push to devices and clients associated with the tag.

Gehen Sie zum Erstellen des neuen ASP.NET-WebAPI-Back-Ends wie folgt vor:Create the new ASP.NET WebAPI backend by doing the following actions:

Wichtig

Falls Sie Visual Studio 2015 oder eine ältere Version verwenden, vergewissern Sie sich vor Beginn dieses Tutorials, dass bei Ihnen die neueste Version des NuGet-Paket-Managers für Visual Studio installiert ist.If you are using Visual Studio 2015 or earlier, before starting this tutorial, ensure that you have installed the latest version of NuGet Package Manager for Visual Studio.

Um dies zu überprüfen, starten Sie Visual Studio.To check, start Visual Studio. Wählen Sie im Menü Extras die Option Erweiterungen und Updates aus.On the Tools menu, select Extensions and Updates. Suchen Sie in Ihrer Version von Visual Studio nach NuGet-Paket-Manager, und vergewissern Sie sich, dass Sie über die neueste Version verfügen.Search for NuGet Package Manager in your version of Visual Studio, and make sure you have the latest version. Deinstallieren Sie andernfalls Ihre Version, und installieren Sie den NuGet-Paket-Manager erneut.If your version is not the latest version, uninstall it, and then reinstall the NuGet Package Manager.

Hinweis

Stellen Sie sicher, dass Sie das Visual Studio Azure SDK für die Websitebereitstellung installiert haben.Make sure you have installed the Visual Studio Azure SDK for website deployment.

  1. Starten Sie Visual Studio oder Visual Studio Express.Start Visual Studio or Visual Studio Express.

  2. Wählen Sie Server-Explorer aus, und melden Sie sich bei Ihrem Azure-Konto an.Select Server Explorer, and sign in to your Azure account. Zur Erstellung der Websiteressourcen für Ihr Konto müssen Sie angemeldet sein.To create the web site resources on your account, you must be signed in.

  3. Klicken Sie in Visual Studio mit der rechten Maustaste auf die Visual Studio-Projektmappe, zeigen Sie auf Hinzufügen, und klicken Sie auf Neues Projekt.In Visual Studio, right-click Visual Studio solution, point to Add, and click New Project.

  4. Erweitern Sie Visual C# , wählen Sie Web aus, und klicken Sie auf ASP.NET-Webanwendung.Expand Visual C#, select Web, and click ASP.NET Web Application.

  5. Geben Sie im Feld Name die Zeichenfolge AppBackend ein, und wählen Sie dann OK aus.In the Name box, type AppBackend, and then select OK.

    Das Fenster „Neues Projekt“

  6. Aktivieren Sie im Fenster Neues ASP.NET-Projekt das Kontrollkästchen Web-API, und wählen Sie anschließend OK aus.In the New ASP.NET Project window, select the Web API check box, and then select OK.

    Das Fenster „Neues ASP.NET-Projekt“

  7. Wählen Sie im Fenster Microsoft Azure-Web-App konfigurieren ein Abonnement aus, und führen Sie anschließend in der Liste App Service-Plan eine der folgenden Aktionen aus:In the Configure Microsoft Azure Web App window, select a subscription and then, in the App Service plan list, do either of the following actions:

    • Wählen Sie einen bereits erstellten App Service-Plan aus.Select an app service plan that you've already created.
    • Wählen Sie Einen neuen App Services-Plan erstellen aus, und erstellen Sie einen neuen Plan.Select Create a new app service plan, and then create one.

    Sie benötigen für dieses Lernprogramm keine Datenbank.You do not need a database for this tutorial. Wählen Sie nach der Wahl Ihres App Service-Plans OK aus, um das Projekt zu erstellen.After you have selected your app service plan, select OK to create the project.

    Das Fenster „Microsoft Azure-Web-App konfigurieren“

    Wird diese Seite zum Konfigurieren des App Service-Plans nicht angezeigt, fahren Sie mit dem Tutorial fort.If you don't see this page for configure app service plan, continue with the tutorial. Sie können ihn später beim Veröffentlichen der App konfigurieren.You can configure it while publishing the app later.

Authentifizieren von Clients beim WebAPI-Back-EndAuthenticate clients to the WebAPI backend

In diesem Abschnitt erstellen Sie für das neue Back-End eine neue Meldungshandlerklasse namens AuthenticationTestHandler.In this section, you create a new message-handler class named AuthenticationTestHandler for the new backend. Diese Klasse wird von DelegatingHandler abgeleitet und als Meldungshandler hinzugefügt, damit alle beim Back-End eingehenden Anforderungen verarbeitet werden können.This class is derived from DelegatingHandler and added as a message handler so that it can process all requests that come into the backend.

  1. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt AppBackend, und wählen Sie Hinzufügen und anschließend Klasse aus.In Solution Explorer, right-click the AppBackend project, select Add, and then select Class.

  2. Geben Sie der neuen Klasse den Namen AuthenticationTestHandler.cs, und wählen Sie Hinzufügen aus, um die Klasse zu generieren.Name the new class AuthenticationTestHandler.cs, and then select Add to generate the class. Mit dieser Klasse werden Benutzer der Einfachheit halber unter Verwendung der Standardauthentifizierung authentifiziert.This class authenticates users by using Basic Authentication for simplicity. Ihre App kann ein beliebiges Authentifizierungsschema verwenden.Your app can use any authentication scheme.

  3. Fügen Sie in der Datei "AuthenticationTestHandler.cs" die folgenden using -Anweisungen hinzu:In AuthenticationTestHandler.cs, add the following using statements:

    using System.Net.Http;
    using System.Threading;
    using System.Security.Principal;
    using System.Net;
    using System.Text;
    using System.Threading.Tasks;
    
  4. Ersetzen Sie in der Datei „AuthenticationTestHandler.cs“ die Definition der Klasse AuthenticationTestHandler durch den folgenden Code:In AuthenticationTestHandler.cs, replace the AuthenticationTestHandler class definition with the following code:

    Der Handler autorisiert die Anforderung, wenn die folgenden drei Bedingungen erfüllt sind:The handler authorizes the request when the following three conditions are true:

    • Die Anforderung enthält einen Autorisierungsheader.The request includes an Authorization header.
    • Für die Anforderung wird die Standardauthentifizierung verwendet.The request uses basic authentication.
    • Bei der Benutzernamen-Zeichenfolge und der Kennwortzeichenfolge handelt es sich um die gleiche Zeichenfolge.The user name string and the password string are the same string.

    Andernfalls wird die Anforderung abgelehnt.Otherwise, the request is rejected. Diese Authentifizierung ist keine echte Vorgehensweise zur Authentifizierung und Autorisierung.This authentication is not a true authentication and authorization approach. Hierbei handelt es sich lediglich um ein einfaches Beispiel für dieses Tutorial.It is only a simple example for this tutorial.

    Wenn die Anforderungsnachricht von AuthenticationTestHandler authentifiziert und autorisiert wurde, wird der Benutzer der Standardauthentifizierung an die aktuelle Anforderung in HttpContext angefügt.If the request message is authenticated and authorized by AuthenticationTestHandler, the basic authentication user is attached to the current request on HttpContext. Die Benutzerinformationen in „HttpContext“ werden später von einem anderen Controller (RegisterController) verwendet, um der Registrierungsanforderung für die Benachrichtigung ein Tag hinzuzufügen.User information in HttpContext will be used by another controller (RegisterController) later to add a tag to the notification registration request.

    public class AuthenticationTestHandler : DelegatingHandler
    {
        protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var authorizationHeader = request.Headers.GetValues("Authorization").First();
    
            if (authorizationHeader != null && authorizationHeader
                .StartsWith("Basic ", StringComparison.InvariantCultureIgnoreCase))
            {
                string authorizationUserAndPwdBase64 =
                    authorizationHeader.Substring("Basic ".Length);
                string authorizationUserAndPwd = Encoding.Default
                    .GetString(Convert.FromBase64String(authorizationUserAndPwdBase64));
                string user = authorizationUserAndPwd.Split(':')[0];
                string password = authorizationUserAndPwd.Split(':')[1];
    
                if (verifyUserAndPwd(user, password))
                {
                    // Attach the new principal object to the current HttpContext object
                    HttpContext.Current.User =
                        new GenericPrincipal(new GenericIdentity(user), new string[0]);
                    System.Threading.Thread.CurrentPrincipal =
                        System.Web.HttpContext.Current.User;
                }
                else return Unauthorized();
            }
            else return Unauthorized();
    
            return base.SendAsync(request, cancellationToken);
        }
    
        private bool verifyUserAndPwd(string user, string password)
        {
            // This is not a real authentication scheme.
            return user == password;
        }
    
        private Task<HttpResponseMessage> Unauthorized()
        {
            var response = new HttpResponseMessage(HttpStatusCode.Forbidden);
            var tsc = new TaskCompletionSource<HttpResponseMessage>();
            tsc.SetResult(response);
            return tsc.Task;
        }
    }
    

    Hinweis

    Sicherheitshinweis: Die Klasse AuthenticationTestHandler ermöglicht keine wirkliche Authentifizierung.Security note: The AuthenticationTestHandler class does not provide true authentication. Sie wird nur verwendet, um eine Standardauthentifizierung zu imitieren, und ist nicht sicher.It is used only to mimic basic authentication and is not secure. Sie müssen einen sicheren Authentifizierungsmechanismus in Ihren Produktionsanwendungen und -diensten implementieren.You must implement a secure authentication mechanism in your production applications and services.

  5. Fügen Sie am Ende der Methode Register in der Klasse App_Start/WebApiConfig.cs den folgenden Code hinzu, um den Meldungshandler zu registrieren:To register the message handler, add the following code at the end of the Register method in the App_Start/WebApiConfig.cs class:

    config.MessageHandlers.Add(new AuthenticationTestHandler());
    
  6. Speichern Sie die Änderungen.Save your changes.

Registrieren für Benachrichtigungen unter Verwendung des WebAPI-Back-EndsRegister for notifications by using the WebAPI backend

In diesem Abschnitt wird dem WebAPI-Back-End ein neuer Controller hinzugefügt, um Anforderungen zum Registrieren eines Benutzers und eines Geräts für Benachrichtigungen unter Verwendung der Clientbibliothek für Notification Hubs zu verarbeiten.In this section, you add a new controller to the WebAPI backend to handle requests to register a user and a device for notifications by using the client library for notification hubs. Der Controller fügt ein Benutzertag für den Benutzer hinzu, der durch AuthenticationTestHandler authentifiziert und an „HttpContext“ angefügt wurde.The controller adds a user tag for the user that was authenticated and attached to HttpContext by AuthenticationTestHandler. Die Markierung hat das Zeichenfolgenformat "username:<actual username>".The tag has the string format, "username:<actual username>".

  1. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt AppBackend, und wählen Sie dann NuGet-Pakete verwalten aus.In Solution Explorer, right-click the AppBackend project and then select Manage NuGet Packages.

  2. Wählen Sie im linken Bereich Online aus, und geben Sie dann im Feld Suche die Zeichenfolge Microsoft.Azure.NotificationHubs ein.In the left pane, select Online and then, in the Search box, type Microsoft.Azure.NotificationHubs.

  3. Wählen Sie in der Ergebnisliste die Option Microsoft Azure Notification Hubs und anschließend Installieren aus.In the results list, select Microsoft Azure Notification Hubs, and then select Install. Schließen Sie die Installation ab, und schließen Sie dann das Fenster des NuGet-Paket-Managers.Complete the installation, and then close the NuGet Package Manager window.

    Dadurch wird mithilfe des Microsoft.Azure.NotificationHubs-NuGet-Pakets ein Verweis auf das Azure Notification Hubs-SDK hinzugefügt.This action adds a reference to the Azure Notification Hubs SDK by using the Microsoft.Azure.Notification Hubs NuGet package.

  4. Erstellen Sie eine neue Klassendatei, die die Verbindung mit dem Notification Hub darstellt, der zum Senden von Benachrichtigungen verwendet wird.Create a new class file that represents the connection with the notification hub that's used to send notifications. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf den Ordner Modelle, und wählen Sie dann Hinzufügen und anschließend Klasse aus.In Solution Explorer, right-click the Models folder, select Add, and then select Class. Nennen Sie die neue Klasse Notifications.cs, und wählen Sie dann Hinzufügen aus, um die Klasse zu generieren.Name the new class Notifications.cs, and then select Add to generate the class.

    Das Fenster „Neues Element hinzufügen“

  5. Fügen Sie die folgende using -Anweisung am Anfang der Datei "Notifications.cs" hinzu:In Notifications.cs, add the following using statement at the top of the file:

    using Microsoft.Azure.NotificationHubs;
    
  6. Ersetzen Sie die Definition der Klasse Notifications durch den folgenden Code und die beiden Platzhalter durch die Verbindungszeichenfolge (mit Vollzugriff) für Ihren Notification Hub bzw. durch den Namen des Hubs (verfügbar im Azure-Portal):Replace the Notifications class definition with the following code, and replace the two placeholders with the connection string (with full access) for your notification hub and the hub name (available at Azure portal):

    public class Notifications
    {
        public static Notifications Instance = new Notifications();
    
        public NotificationHubClient Hub { get; set; }
    
        private Notifications() {
            Hub = NotificationHubClient.CreateClientFromConnectionString("<your hub's DefaultFullSharedAccessSignature>",
                                                                            "<hub name>");
        }
    }
    

    Wichtig

    Geben Sie für den Hub den Namen und einen Wert für DefaultFullSharedAccessSignature ein, bevor Sie fortfahren.Enter the name and the DefaultFullSharedAccessSignature of your hub before proceeding further.

  7. Erstellen Sie als Nächstes einen neuen Controller namens RegisterController.Next, create a new controller named RegisterController. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf den Ordner Controller, und wählen Sie dann Hinzufügen und Controller aus.In Solution Explorer, right-click the Controllers folder, select Add, and then select Controller.

  8. Wählen Sie Web-API-2-Controller – Leer und anschließend Hinzufügen aus.Select Web API 2 Controller - Empty, and then select Add.

    Das Fenster „Gerüst hinzufügen“

  9. Geben Sie im Feld Controllername die Zeichenfolge RegisterController ein, um die neue Klasse zu benennen, und wählen Sie anschließend Hinzufügen aus.In the Controller name box, type RegisterController to name the new class, and then select Add.

    Das Fenster „Controller hinzufügen“

  10. Fügen Sie in der Datei "RegisterController.cs" die folgenden using -Anweisungen hinzu:In RegisterController.cs, add the following using statements:

    using Microsoft.Azure.NotificationHubs;
    using Microsoft.Azure.NotificationHubs.Messaging;
    using AppBackend.Models;
    using System.Threading.Tasks;
    using System.Web;
    
  11. Fügen Sie innerhalb der RegisterController -Klassendefinition den folgenden Code hinzu.Add the following code inside the RegisterController class definition. Mit diesem Code fügen Sie ein Benutzertag für den Benutzer hinzu, der HttpContext angefügt ist.In this code, you add a user tag for the user that's attached to HttpContext. Der Benutzer wurde mit dem von Ihnen hinzugefügten Nachrichtenfilter AuthenticationTestHandler authentifiziert und HttpContext angefügt.The user was authenticated and attached to HttpContext by the message filter that you added, AuthenticationTestHandler. Sie können auch optionale Überprüfungen hinzufügen, um zu überprüfen, dass der Benutzer die richtigen Berechtigungen besitzt, um sich für die angeforderten Tags zu registrieren.You can also add optional checks to verify that the user has rights to register for the requested tags.

    private NotificationHubClient hub;
    
    public RegisterController()
    {
        hub = Notifications.Instance.Hub;
    }
    
    public class DeviceRegistration
    {
        public string Platform { get; set; }
        public string Handle { get; set; }
        public string[] Tags { get; set; }
    }
    
    // POST api/register
    // This creates a registration id
    public async Task<string> Post(string handle = null)
    {
        string newRegistrationId = null;
    
        // make sure there are no existing registrations for this push handle (used for iOS and Android)
        if (handle != null)
        {
            var registrations = await hub.GetRegistrationsByChannelAsync(handle, 100);
    
            foreach (RegistrationDescription registration in registrations)
            {
                if (newRegistrationId == null)
                {
                    newRegistrationId = registration.RegistrationId;
                }
                else
                {
                    await hub.DeleteRegistrationAsync(registration);
                }
            }
        }
    
        if (newRegistrationId == null) 
            newRegistrationId = await hub.CreateRegistrationIdAsync();
    
        return newRegistrationId;
    }
    
    // PUT api/register/5
    // This creates or updates a registration (with provided channelURI) at the specified id
    public async Task<HttpResponseMessage> Put(string id, DeviceRegistration deviceUpdate)
    {
        RegistrationDescription registration = null;
        switch (deviceUpdate.Platform)
        {
            case "mpns":
                registration = new MpnsRegistrationDescription(deviceUpdate.Handle);
                break;
            case "wns":
                registration = new WindowsRegistrationDescription(deviceUpdate.Handle);
                break;
            case "apns":
                registration = new AppleRegistrationDescription(deviceUpdate.Handle);
                break;
            case "fcm":
                registration = new FcmRegistrationDescription(deviceUpdate.Handle);
                break;
            default:
                throw new HttpResponseException(HttpStatusCode.BadRequest);
        }
    
        registration.RegistrationId = id;
        var username = HttpContext.Current.User.Identity.Name;
    
        // add check if user is allowed to add these tags
        registration.Tags = new HashSet<string>(deviceUpdate.Tags);
        registration.Tags.Add("username:" + username);
    
        try
        {
            await hub.CreateOrUpdateRegistrationAsync(registration);
        }
        catch (MessagingException e)
        {
            ReturnGoneIfHubResponseIsGone(e);
        }
    
        return Request.CreateResponse(HttpStatusCode.OK);
    }
    
    // DELETE api/register/5
    public async Task<HttpResponseMessage> Delete(string id)
    {
        await hub.DeleteRegistrationAsync(id);
        return Request.CreateResponse(HttpStatusCode.OK);
    }
    
    private static void ReturnGoneIfHubResponseIsGone(MessagingException e)
    {
        var webex = e.InnerException as WebException;
        if (webex.Status == WebExceptionStatus.ProtocolError)
        {
            var response = (HttpWebResponse)webex.Response;
            if (response.StatusCode == HttpStatusCode.Gone)
                throw new HttpRequestException(HttpStatusCode.Gone.ToString());
        }
    }
    
  12. Speichern Sie die Änderungen.Save your changes.

Senden von Benachrichtigungen über das WebAPI-Back-EndSend notifications from the WebAPI backend

In diesem Abschnitt wird ein neuer Controller hinzugefügt, der Clientgeräten das Senden einer Benachrichtigung ermöglicht.In this section, you add a new controller that exposes a way for client devices to send a notification. Die Benachrichtigung basiert auf dem Benutzernamentag, das die Azure Notification Hubs .NET-Bibliothek des ASP.NET WebAPI-Back-Ends verwendet.The notification is based on the username tag that uses Azure Notification Hubs .NET Library in the ASP.NET WebAPI backend.

  1. Erstellen Sie einen weiteren neuen Domänencontroller namens NotificationsController. Verwenden Sie dazu die gleiche Vorgehensweise wie bei der Erstellung von RegisterController im vorherigen Abschnitt.Create another new controller named NotificationsController the same way you created RegisterController in the previous section.

  2. Fügen Sie in der Datei "NotificationsController.cs" die folgenden using -Anweisungen hinzu:In NotificationsController.cs, add the following using statements:

    using AppBackend.Models;
    using System.Threading.Tasks;
    using System.Web;
    
  3. Fügen Sie der Klasse NotificationsController die folgende Methode hinzu:Add the following method to the NotificationsController class:

    Mit diesem Code wird ein Benachrichtigungstyp gesendet, der auf dem Parameter pns des Plattformbenachrichtigungssystems (Plattform Notification System, PNS) basiert.This code sends a notification type that's based on the Platform Notification Service (PNS) pns parameter. Der Wert von to_tag dient zum Festlegen des username -Tags in der Nachricht.The value of to_tag is used to set the username tag on the message. Dieses Tag muss mit einem Benutzernamentag einer aktiven Notification Hub-Registrierung übereinstimmen.This tag must match a username tag of an active notification hub registration. Die Benachrichtigung wird aus dem Text der POST-Anforderung abgerufen und für den Ziel-PNS formatiert.The notification message is pulled from the body of the POST request and formatted for the target PNS.

    Abhängig von dem PNS, mit dem Ihre unterstützten Geräte Benachrichtigungen empfangen, werden Benachrichtigungen mit unterschiedlichen Formaten unterstützt.Depending on the PNS that your supported devices use to receive notifications, the notifications are supported by a variety of formats. Ein Beispiel: Angenommen, Sie verwenden auf Windows-Geräten eine Popupbenachrichtigung mit WNS, die nicht direkt durch ein anderes PNS unterstützt wird.For example, on Windows devices, you might use a toast notification with WNS that isn't directly supported by another PNS. In diesem Fall muss Ihr Back-End die Benachrichtigung so formatieren, dass sie mit dem PNS der zu unterstützenden Geräte kompatibel ist.In such an instance, your backend needs to format the notification into a supported notification for the PNS of devices you plan to support. Verwenden Sie anschließend die entsprechende Sende-API für die NotificationHubClient-Klasse.Then use the appropriate send API on the NotificationHubClient class.

    public async Task<HttpResponseMessage> Post(string pns, [FromBody]string message, string to_tag)
    {
        var user = HttpContext.Current.User.Identity.Name;
        string[] userTag = new string[2];
        userTag[0] = "username:" + to_tag;
        userTag[1] = "from:" + user;
    
        Microsoft.Azure.NotificationHubs.NotificationOutcome outcome = null;
        HttpStatusCode ret = HttpStatusCode.InternalServerError;
    
        switch (pns.ToLower())
        {
            case "wns":
                // Windows 8.1 / Windows Phone 8.1
                var toast = @"<toast><visual><binding template=""ToastText01""><text id=""1"">" + 
                            "From " + user + ": " + message + "</text></binding></visual></toast>";
                outcome = await Notifications.Instance.Hub.SendWindowsNativeNotificationAsync(toast, userTag);
                break;
            case "apns":
                // iOS
                var alert = "{\"aps\":{\"alert\":\"" + "From " + user + ": " + message + "\"}}";
                outcome = await Notifications.Instance.Hub.SendAppleNativeNotificationAsync(alert, userTag);
                break;
            case "fcm":
                // Android
                var notif = "{ \"data\" : {\"message\":\"" + "From " + user + ": " + message + "\"}}";
                outcome = await Notifications.Instance.Hub.SendFcmNativeNotificationAsync(notif, userTag);
                break;
        }
    
        if (outcome != null)
        {
            if (!((outcome.State == Microsoft.Azure.NotificationHubs.NotificationOutcomeState.Abandoned) ||
                (outcome.State == Microsoft.Azure.NotificationHubs.NotificationOutcomeState.Unknown)))
            {
                ret = HttpStatusCode.OK;
            }
        }
    
        return Request.CreateResponse(ret);
    }
    
  4. Drücken Sie F5, um die Anwendung auszuführen und sich zu vergewissern, dass soweit alles funktioniert.To run the application and ensure the accuracy of your work so far, select the F5 key. Die App öffnet einen Webbrowser und wird auf der Homepage von ASP.NET angezeigt.The app opens a web browser, and it is displayed on the ASP.NET home page.

Veröffentlichen des neuen WebAPI-Back-EndsPublish the new WebAPI backend

Als Nächstes wird die App auf einer Azure-Website bereitgestellt, damit sie für alle Geräte zur Verfügung steht.Next, you deploy the app to an Azure website to make it accessible from all devices.

  1. Klicken Sie mit der rechten Maustaste auf das Projekt AppBackend, und wählen Sie Veröffentlichen aus.Right-click the AppBackend project, and then select Publish.

  2. Wählen Sie Microsoft Azure App Service als Veröffentlichungsziel und anschließend **Veröffentlichen aus.Select Microsoft Azure App Service as your publish target, and then select **Publish. Das Fenster „App Service erstellen“ wird geöffnet.The Create App Service window opens. Hier können Sie alle Azure-Ressourcen erstellen, die zum Ausführen der ASP.NET-Web-App in Azure benötigt werden.Here you can create all the necessary Azure resources to run the ASP.NET web app in Azure.

    Die Kachel „Microsoft Azure App Service“

  3. Wählen Sie im Fenster App Service erstellen Ihr Azure-Konto aus.In the Create App Service window, select your Azure account. Wählen Sie Typ ändern > Web App aus.Select Change Type > Web App. Behalten Sie den Standardwert für Web-App-Name bei, und wählen Sie Abonnement, Ressourcengruppe und App Service-Plan aus.Keep the default Web App Name, and then select the Subscription, Resource Group, and App Service Plan.

  4. Klicken Sie auf Erstellen.Select Create.

  5. Notieren Sie sich die Website-URL aus der Zusammenfassung.Make a note of the Site URL property in the Summary section. Diese URL ist später im Tutorial Ihr Back-End-Endpunkt.This URL is your back-end endpoint later in the tutorial.

  6. Wählen Sie Veröffentlichen.Select Publish.

Nach Abschluss des Assistenten wird die ASP.NET Web-App in Azure veröffentlicht und anschließend im Standardbrowser geöffnet.After you've completed the wizard, it publishes the ASP.NET web app to Azure and then opens the app in the default browser. Ihre Anwendung kann in Azure App Services angezeigt werden.Your application is viewable in Azure App Services.

In der URL wird der von Ihnen angegebene Web-App-Name im Format „http://.azurewebsites.net“ verwendet.The URL uses the web app name that you specified earlier, with the format http://<app_name>.azurewebsites.net.

Ändern der iOS-AppModify your iOS app

  1. Öffnen Sie die Einzelseitenansicht-App, die Sie im Lernprogramm Erste Schritte mit Notification Hubs (iOS) erstellt haben.Open the Single Page view app you created in the Getting Started with Notification Hubs (iOS) tutorial.

    Hinweis

    In diesem Abschnitt wird davon ausgegangen, dass Sie Ihr Projekt mit einem leeren Organisationsnamen konfiguriert haben.This section assumes that your project is configured with an empty organization name. Falls nicht, müssen Sie allen Klassennamen Ihren Organisationsnamen voranstellen.If not, you need to prepend your organization name to all class names.

  2. Fügen Sie in der Datei Main.storyboard die im folgenden Screenshot abgebildeten Komponenten aus der Objektbibliothek hinzu.In the Main.storyboard file, add the components shown in the screenshot from the object library.

    Bearbeiten des Storybards in Xcode Interface Builder

    • Benutzername: Ein UITextField mit dem Platzhaltertext Enter Username, direkt unter der Bezeichnung zum Senden der Ergebnisse und durch den linken und rechten Rand und die Anordnung unter der Bezeichnung zum Senden der Ergebnisse beschränkt.Username: A UITextField with placeholder text, Enter Username, immediately beneath the send results label and constrained to the left and right margins and beneath the send results label.

    • Kennwort: Ein UITextField mit dem Platzhaltertext Enter Password, direkt unter dem Textfeld „Username“ und durch den linken und rechten Rand und die Anordnung unter dem Textfeld „Username“ beschränkt.Password: A UITextField with placeholder text, Enter Password, immediately beneath the username text field and constrained to the left and right margins and beneath the username text field. Aktivieren Sie die Option Secure Text Entry im Attribute Inspector unter Return Key.Check the Secure Text Entry option in the Attribute Inspector, under Return Key.

    • Log in: Ein bezeichneter UIButton direkt unter dem Kennwortfeld. Deaktivieren Sie die Option Enabled im Attributes Inspector unter Control-Content.Log in: A UIButton labeled immediately beneath the password text field and uncheck the Enabled option in the Attributes Inspector, under Control-Content

    • WNS: Bezeichnung und Switch, um das Senden der Benachrichtigung an den Windows-Benachrichtigungsdienst zu aktivieren, wenn er auf dem Hub eingerichtet wurde.WNS: Label and switch to enable sending the notification Windows Notification Service if it has been set up on the hub. Siehe dazu das Tutorial Erste Schritte für Windows.See the Windows Getting Started tutorial.

    • GCM: Bezeichnung und Switch, um das Senden der Benachrichtigung an Google Cloud Messaging zu aktivieren, wenn es auf dem Hub eingerichtet wurde.GCM: Label and switch to enable sending the notification to Google Cloud Messaging if it has been set up on the hub. Siehe dazu das Lernprogramm Erste Schritte für Android .See Android Getting Started tutorial.

    • APNS: Bezeichnung und Switch, um das Senden der Benachrichtigung an den Apple Platform Notification Service zu aktivieren.APNS: Label and switch to enable sending the notification to the Apple Platform Notification Service.

    • Recipient Username: ein UITextField mit dem Platzhaltertext Recipient username tag, direkt unter der GCM-Bezeichnung und durch den linken und rechten Rand und die Anordnung unter der GCM-Bezeichnung beschränkt.Recipient Username:A UITextField with placeholder text, Recipient username tag, immediately beneath the GCM label and constrained to the left and right margins and beneath the GCM label.

      Im Lernprogramm Erste Schritte mit Notification Hubs (iOS) wurden einige Komponenten hinzugefügt.Some components were added in the Getting Started with Notification Hubs (iOS) tutorial.

  3. Ziehen Sie bei gedrückter STRG-Taste die Komponenten in der Ansicht zu ViewController.h, und fügen Sie diese neuen Outlets hinzu.Ctrl drag from the components in the view to ViewController.h and add these new outlets.

    @property (weak, nonatomic) IBOutlet UITextField *UsernameField;
    @property (weak, nonatomic) IBOutlet UITextField *PasswordField;
    @property (weak, nonatomic) IBOutlet UITextField *RecipientField;
    @property (weak, nonatomic) IBOutlet UITextField *NotificationField;
    
    // Used to enable the buttons on the UI
    @property (weak, nonatomic) IBOutlet UIButton *LogInButton;
    @property (weak, nonatomic) IBOutlet UIButton *SendNotificationButton;
    
    // Used to enabled sending notifications across platforms
    @property (weak, nonatomic) IBOutlet UISwitch *WNSSwitch;
    @property (weak, nonatomic) IBOutlet UISwitch *GCMSwitch;
    @property (weak, nonatomic) IBOutlet UISwitch *APNSSwitch;
    
    - (IBAction)LogInAction:(id)sender;
    
  4. Fügen Sie in ViewController.h folgende #define-Zeile direkt hinter den import-Anweisungen hinzu.In ViewController.h, add the following #define after your import statements. Ersetzen Sie den Platzhalter <Enter Your Backend Endpoint> durch die Ziel-URL, die Sie im vorherigen Abschnitt zum Bereitstellen Ihres App-Back-Ends verwendet haben.Substitute the <Enter Your Backend Endpoint> placeholder with the Destination URL you used to deploy your app backend in the previous section. Beispiel: http://your_backend.azurewebsites.net.For example, http://your_backend.azurewebsites.net.

    #define BACKEND_ENDPOINT @"<Enter Your Backend Endpoint>"
    
  5. Erstellen Sie in Ihrem Projekt eine neue „Cocoa Touch“-Klasse mit dem Namen RegisterClient als Schnittstelle mit dem erstellten ASP.NET-Back-End.In your project, create a new Cocoa Touch class named RegisterClient to interface with the ASP.NET back-end you created. Erstellen Sie die Klasse, die von NSObjecterbt.Create the class inheriting from NSObject. Fügen Sie anschließend in RegisterClient.h den folgenden Code hinzu.Then add the following code in the RegisterClient.h.

    @interface RegisterClient : NSObject
    
    @property (strong, nonatomic) NSString* authenticationHeader;
    
    -(void) registerWithDeviceToken:(NSData*)token tags:(NSSet*)tags
        andCompletion:(void(^)(NSError*))completion;
    
    -(instancetype) initWithEndpoint:(NSString*)Endpoint;
    
    @end
    
  6. Aktualisieren Sie in RegisterClient.m den @interface-Abschnitt:In the RegisterClient.m, update the @interface section:

    @interface RegisterClient ()
    
    @property (strong, nonatomic) NSURLSession* session;
    @property (strong, nonatomic) NSURLSession* endpoint;
    
    -(void) tryToRegisterWithDeviceToken:(NSData*)token tags:(NSSet*)tags retry:(BOOL)retry
                andCompletion:(void(^)(NSError*))completion;
    -(void) retrieveOrRequestRegistrationIdWithDeviceToken:(NSString*)token
                completion:(void(^)(NSString*, NSError*))completion;
    -(void) upsertRegistrationWithRegistrationId:(NSString*)registrationId deviceToken:(NSString*)token
                tags:(NSSet*)tags andCompletion:(void(^)(NSURLResponse*, NSError*))completion;
    
    @end
    
  7. Ersetzen Sie den @implementation-Abschnitt in „RegisterClient.m“ durch den folgenden Code:Replace the @implementation section in the RegisterClient.m with the following code:

    @implementation RegisterClient
    
    // Globals used by RegisterClient
    NSString *const RegistrationIdLocalStorageKey = @"RegistrationId";
    
    -(instancetype) initWithEndpoint:(NSString*)Endpoint
    {
        self = [super init];
        if (self) {
            NSURLSessionConfiguration* config = [NSURLSessionConfiguration defaultSessionConfiguration];
            _session = [NSURLSession sessionWithConfiguration:config delegate:nil delegateQueue:nil];
            _endpoint = Endpoint;
        }
        return self;
    }
    
    -(void) registerWithDeviceToken:(NSData*)token tags:(NSSet*)tags
                andCompletion:(void(^)(NSError*))completion
    {
        [self tryToRegisterWithDeviceToken:token tags:tags retry:YES andCompletion:completion];
    }
    
    -(void) tryToRegisterWithDeviceToken:(NSData*)token tags:(NSSet*)tags retry:(BOOL)retry
                andCompletion:(void(^)(NSError*))completion
    {
        NSSet* tagsSet = tags?tags:[[NSSet alloc] init];
    
        NSString *deviceTokenString = [[token description]
            stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
        deviceTokenString = [[deviceTokenString stringByReplacingOccurrencesOfString:@" " withString:@""]
                                uppercaseString];
    
        [self retrieveOrRequestRegistrationIdWithDeviceToken: deviceTokenString
            completion:^(NSString* registrationId, NSError *error) {
            NSLog(@"regId: %@", registrationId);
            if (error) {
                completion(error);
                return;
            }
    
            [self upsertRegistrationWithRegistrationId:registrationId deviceToken:deviceTokenString
                tags:tagsSet andCompletion:^(NSURLResponse * response, NSError *error) {
                if (error) {
                    completion(error);
                    return;
                }
    
                NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
                if (httpResponse.statusCode == 200) {
                    completion(nil);
                } else if (httpResponse.statusCode == 410 && retry) {
                    [self tryToRegisterWithDeviceToken:token tags:tags retry:NO andCompletion:completion];
                } else {
                    NSLog(@"Registration error with response status: %ld", (long)httpResponse.statusCode);
    
                    completion([NSError errorWithDomain:@"Registration" code:httpResponse.statusCode
                                userInfo:nil]);
                }
    
            }];
        }];
    }
    
    -(void) upsertRegistrationWithRegistrationId:(NSString*)registrationId deviceToken:(NSData*)token
                tags:(NSSet*)tags andCompletion:(void(^)(NSURLResponse*, NSError*))completion
    {
        NSDictionary* deviceRegistration = @{@"Platform" : @"apns", @"Handle": token,
                                                @"Tags": [tags allObjects]};
        NSData* jsonData = [NSJSONSerialization dataWithJSONObject:deviceRegistration
                            options:NSJSONWritingPrettyPrinted error:nil];
    
        NSLog(@"JSON registration: %@", [[NSString alloc] initWithData:jsonData
                                            encoding:NSUTF8StringEncoding]);
    
        NSString* endpoint = [NSString stringWithFormat:@"%@/api/register/%@", _endpoint,
                                registrationId];
        NSURL* requestURL = [NSURL URLWithString:endpoint];
        NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:requestURL];
        [request setHTTPMethod:@"PUT"];
        [request setHTTPBody:jsonData];
        NSString* authorizationHeaderValue = [NSString stringWithFormat:@"Basic %@",
                                                self.authenticationHeader];
        [request setValue:authorizationHeaderValue forHTTPHeaderField:@"Authorization"];
        [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    
        NSURLSessionDataTask* dataTask = [self.session dataTaskWithRequest:request
            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
        {
            if (!error)
            {
                completion(response, error);
            }
            else
            {
                NSLog(@"Error request: %@", error);
                completion(nil, error);
            }
        }];
        [dataTask resume];
    }
    
    -(void) retrieveOrRequestRegistrationIdWithDeviceToken:(NSString*)token
                completion:(void(^)(NSString*, NSError*))completion
    {
        NSString* registrationId = [[NSUserDefaults standardUserDefaults]
                                    objectForKey:RegistrationIdLocalStorageKey];
    
        if (registrationId)
        {
            completion(registrationId, nil);
            return;
        }
    
        // request new one & save
        NSURL* requestURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@/api/register?handle=%@",
                                _endpoint, token]];
        NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:requestURL];
        [request setHTTPMethod:@"POST"];
        NSString* authorizationHeaderValue = [NSString stringWithFormat:@"Basic %@",
                                                self.authenticationHeader];
        [request setValue:authorizationHeaderValue forHTTPHeaderField:@"Authorization"];
    
        NSURLSessionDataTask* dataTask = [self.session dataTaskWithRequest:request
            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
        {
            NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*) response;
            if (!error && httpResponse.statusCode == 200)
            {
                NSString* registrationId = [[NSString alloc] initWithData:data
                    encoding:NSUTF8StringEncoding];
    
                // remove quotes
                registrationId = [registrationId substringWithRange:NSMakeRange(1,
                                    [registrationId length]-2)];
    
                [[NSUserDefaults standardUserDefaults] setObject:registrationId
                    forKey:RegistrationIdLocalStorageKey];
                [[NSUserDefaults standardUserDefaults] synchronize];
    
                completion(registrationId, nil);
            }
            else
            {
                NSLog(@"Error status: %ld, request: %@", (long)httpResponse.statusCode, error);
                if (error)
                    completion(nil, error);
                else {
                    completion(nil, [NSError errorWithDomain:@"Registration" code:httpResponse.statusCode
                                userInfo:nil]);
                }
            }
        }];
        [dataTask resume];
    }
    
    @end
    

    Dieser Code implementiert die im Artikel Registrieren über ein App-Back-End erläuterte Logik unter Verwendung von NSURLSession zum Durchführen von REST-Aufrufen an das App-Back-End und von NSUserDefaults zum lokalen Speichern der vom Notification Hub zurückgegebenen registrationId.This code implements the logic explained in the guidance article Registering from your app backend using NSURLSession to perform REST calls to your app backend, and NSUserDefaults to locally store the registrationId returned by the notification hub.

    Die authorizationHeader-Eigenschaft dieser Klasse muss festgelegt werden, damit die Klasse ordnungsgemäß funktioniert.This class requires its property authorizationHeader to be set in order to work properly. Diese Eigenschaft wird von der ViewController-Klasse nach der Anmeldung festgelegt.This property is set by the ViewController class after the login.

  8. Fügen Sie in ViewController.h eine #import-Anweisung für RegisterClient.h hinzu.In ViewController.h, add a #import statement for RegisterClient.h. Fügen Sie dann eine Deklaration für das Gerätetoken und einen Verweis auf eine RegisterClient-Instanz im @interface-Abschnitt hinzu:Then add a declaration for the device token and reference to a RegisterClient instance in the @interface section:

    #import "RegisterClient.h"
    
    @property (strong, nonatomic) NSData* deviceToken;
    @property (strong, nonatomic) RegisterClient* registerClient;
    
  9. Fügen Sie in "ViewController.m" eine private Methodendeklaration im @interface -Abschnitt hinzu:In ViewController.m, add a private method declaration in the @interface section:

    @interface ViewController () <UITextFieldDelegate, NSURLConnectionDataDelegate, NSXMLParserDelegate>
    
    // create the Authorization header to perform Basic authentication with your app back-end
    -(void) createAndSetAuthenticationHeaderWithUsername:(NSString*)username
                    AndPassword:(NSString*)password;
    
    @end
    

    Hinweis

    Der folgende Codeausschnitt ist kein sicheres Authentifizierungsschema. Sie sollten die Implementierung von createAndSetAuthenticationHeaderWithUsername:AndPassword: durch Ihren spezifischen Authentifizierungsmechanismus ersetzen, der ein von der RegisterClient-Klasse verwendetes Authentifizierungstoken generiert, z.B. OAuth, Active Directory.The following snippet is not a secure authentication scheme, you should substitute the implementation of the createAndSetAuthenticationHeaderWithUsername:AndPassword: with your specific authentication mechanism that generates an authentication token to be consumed by the register client class, e.g. OAuth, Active Directory.

  10. Fügen Sie dann im @implementation-Abschnitt von ViewController.m den folgenden Code ein, der die Implementierung zum Festlegen des Gerätetokens und Authentifizierungsheaders hinzugefügt.Then in the @implementation section of ViewController.m, add the following code, which adds the implementation for setting the device token and authentication header.

    -(void) setDeviceToken: (NSData*) deviceToken
    {
        _deviceToken = deviceToken;
        self.LogInButton.enabled = YES;
    }
    
    -(void) createAndSetAuthenticationHeaderWithUsername:(NSString*)username
                    AndPassword:(NSString*)password;
    {
        NSString* headerValue = [NSString stringWithFormat:@"%@:%@", username, password];
    
        NSData* encodedData = [[headerValue dataUsingEncoding:NSUTF8StringEncoding] base64EncodedDataWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn];
    
        self.registerClient.authenticationHeader = [[NSString alloc] initWithData:encodedData
                                                    encoding:NSUTF8StringEncoding];
    }
    
    -(BOOL)textFieldShouldReturn:(UITextField *)textField
    {
        [textField resignFirstResponder];
        return YES;
    }
    

    Beachten Sie, dass die Festlegung des Gerätetokens die Schaltfläche „Log in“ (Anmelden) aktiviert.Notice how setting the device token enables the log in button. Dies liegt daran, dass sich der Ansichtscontroller bei der Anmeldeaktion für Pushbenachrichtigungen beim App-Back-End registriert.It's because as a part of the login action, the view controller registers for push notifications with the app backend. Daher soll erst auf die Anmeldeaktion zugegriffen werden können, wenn das Gerätetoken ordnungsgemäß eingerichtet wurde.Hence, do not want Log In action to be accessible until the device token has been properly set up. Sie können die Anmeldung von der Pushregistrierung entkoppeln, solange die Anmeldung vor der Registrierung erfolgt.You can decouple the login from the push registration as long as the former happens before the latter.

  11. Verwenden Sie in "ViewController.m" die folgenden Codeausschnitte zum Implementieren der Aktionsmethode für die Schaltfläche Log In und einer Methode zum Senden der Benachrichtigungsmeldung mithilfe des ASP.NET-Back-Ends.In ViewController.m, use the following snippets to implement the action method for your Log In button and a method to send the notification message using the ASP.NET backend.

    - (IBAction)LogInAction:(id)sender {
        // create authentication header and set it in register client
        NSString* username = self.UsernameField.text;
        NSString* password = self.PasswordField.text;
    
        [self createAndSetAuthenticationHeaderWithUsername:username AndPassword:password];
    
        __weak ViewController* selfie = self;
        [self.registerClient registerWithDeviceToken:self.deviceToken tags:nil
            andCompletion:^(NSError* error) {
            if (!error) {
                dispatch_async(dispatch_get_main_queue(),
                ^{
                    selfie.SendNotificationButton.enabled = YES;
                    [self MessageBox:@"Success" message:@"Registered successfully!"];
                });
            }
        }];
    }
    
    - (void)SendNotificationASPNETBackend:(NSString*)pns UsernameTag:(NSString*)usernameTag
                Message:(NSString*)message
    {
        NSURLSession* session = [NSURLSession
            sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:nil
            delegateQueue:nil];
    
        // Pass the pns and username tag as parameters with the REST URL to the ASP.NET backend
        NSURL* requestURL = [NSURL URLWithString:[NSString
            stringWithFormat:@"%@/api/notifications?pns=%@&to_tag=%@", BACKEND_ENDPOINT, pns,
            usernameTag]];
    
        NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:requestURL];
        [request setHTTPMethod:@"POST"];
    
        // Get the mock authenticationheader from the register client
        NSString* authorizationHeaderValue = [NSString stringWithFormat:@"Basic %@",
            self.registerClient.authenticationHeader];
        [request setValue:authorizationHeaderValue forHTTPHeaderField:@"Authorization"];
    
        //Add the notification message body
        [request setValue:@"application/json;charset=utf-8" forHTTPHeaderField:@"Content-Type"];
        [request setHTTPBody:[message dataUsingEncoding:NSUTF8StringEncoding]];
    
        // Execute the send notification REST API on the ASP.NET Backend
        NSURLSessionDataTask* dataTask = [session dataTaskWithRequest:request
            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
        {
            NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*) response;
            if (error || httpResponse.statusCode != 200)
            {
                NSString* status = [NSString stringWithFormat:@"Error Status for %@: %d\nError: %@\n",
                                    pns, httpResponse.statusCode, error];
                dispatch_async(dispatch_get_main_queue(),
                ^{
                    // Append text because all 3 PNS calls may also have information to view
                    [self.sendResults setText:[self.sendResults.text stringByAppendingString:status]];
                });
                NSLog(status);
            }
    
            if (data != NULL)
            {
                xmlParser = [[NSXMLParser alloc] initWithData:data];
                [xmlParser setDelegate:self];
                [xmlParser parse];
            }
        }];
        [dataTask resume];
    }
    
  12. Aktualisieren Sie die Aktion für die Schaltfläche Send Notification , sodass das ASP.NET-Back-End verwendet wird und der Sendevorgang an ein beliebiges durch einen Switch aktiviertes PNS erfolgt.Update the action for the Send Notification button to use the ASP.NET backend and send to any PNS enabled by a switch.

    - (IBAction)SendNotificationMessage:(id)sender
    {
        //[self SendNotificationRESTAPI];
        [self SendToEnabledPlatforms];
    }
    
    -(void)SendToEnabledPlatforms
    {
        NSString* json = [NSString stringWithFormat:@"\"%@\"",self.notificationMessage.text];
    
        [self.sendResults setText:@""];
    
        if ([self.WNSSwitch isOn])
            [self SendNotificationASPNETBackend:@"wns" UsernameTag:self.RecipientField.text Message:json];
    
        if ([self.GCMSwitch isOn])
            [self SendNotificationASPNETBackend:@"gcm" UsernameTag:self.RecipientField.text Message:json];
    
        if ([self.APNSSwitch isOn])
            [self SendNotificationASPNETBackend:@"apns" UsernameTag:self.RecipientField.text Message:json];
    }
    
  13. Fügen Sie in der Funktion ViewDidLoad Folgendes hinzu, um die RegisterClient-Instanz zu instanziieren und den Delegat für Ihre Textfelder festzulegen.In the ViewDidLoad function, add the following to instantiate the RegisterClient instance and set the delegate for your text fields.

    self.UsernameField.delegate = self;
    self.PasswordField.delegate = self;
    self.RecipientField.delegate = self;
    self.registerClient = [[RegisterClient alloc] initWithEndpoint:BACKEND_ENDPOINT];
    
  14. Entfernen Sie jetzt in AppDelegate.m den gesamten Inhalt der application:didRegisterForPushNotificationWithDeviceToken:-Methode, und ersetzen Sie ihn durch Folgendes, um sicherzustellen, dass der Ansichtscontroller das neueste Gerätetoken aus APNs abgerufen hat:Now in AppDelegate.m, remove all the content of the method application:didRegisterForPushNotificationWithDeviceToken: and replace it with the following (to make sure that the view controller contains the latest device token retrieved from APNs):

    // Add import to the top of the file
    #import "ViewController.h"
    
    - (void)application:(UIApplication *)application
                didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
    {
        ViewController* rvc = (ViewController*) self.window.rootViewController;
        rvc.deviceToken = deviceToken;
    }
    
  15. Stellen Sie schließlich sicher, dass AppDelegate.m die folgende Methode enthält:Finally in AppDelegate.m, make sure you have the following method:

    - (void)application:(UIApplication *)application didReceiveRemoteNotification: (NSDictionary *)userInfo {
        NSLog(@"%@", userInfo);
        [self MessageBox:@"Notification" message:[[userInfo objectForKey:@"aps"] valueForKey:@"alert"]];
    }
    

Testen der AnwendungTest the application

  1. Unter XCode führen Sie die App auf einem physischen iOS-Gerät aus (im Simulator funktionieren Pushbenachrichtigungen nicht).In XCode, run the app on a physical iOS device (push notifications do not work in the simulator).

  2. Geben Sie in der Benutzeroberfläche der iOS-App denselben Wert für den Benutzernamen und das Kennwort ein.In the iOS app UI, enter same value for both username and password. Tippen Sie dann auf Log In.Then click Log In.

    iOS-Testanwendung

  3. Ein Popupfenster sollte angezeigt werden, in dem Sie über eine erfolgreiche Registrierung informiert werden.You should see a pop-up informing you of registration success. Klicken Sie auf OK.Click OK.

    iOS-Testbenachrichtigung

  4. Geben Sie im TextfeldRecipient username tag das Benutzernamenstag ein, das bei der Anmeldung von einem anderen Gerät verwendet wird.In the *Recipient username tag text field, enter the user name tag used with the registration from another device.

  5. Geben Sie eine Benachrichtigungsmeldung ein, und klicken Sie auf Send Notification.Enter a notification message and click Send Notification. Die Benachrichtigungsmeldung wird nur auf den Geräten empfangen, die für das Empfänger-Benutzernamenstag registriert sind.Only the devices that have a registration with the recipient user name tag receive the notification message. Sie wird nur an diese Benutzer gesendet.It is only sent to those users.

    Mit Tag versehene iOS-Testbenachrichtigung

Nächste SchritteNext steps

In diesem Tutorial haben Sie gelernt, wie Sie Pushbenachrichtigungen an bestimmte Benutzer senden, deren Registrierungen Tags zugeordnet sind.In this tutorial, you learned how to push notifications to specific users that have tags associated with their registrations. Um zu erfahren, wie Sie standortbasierte Pushbenachrichtigungen senden, fahren Sie mit dem folgenden Tutorial fort:To learn how to push location-based notifications, advance to the following tutorial: