Tutorial: Senden von Pushbenachrichtigungen an Xamarin.Forms-Apps mit Azure Notification Hubs über einen Back-End-DienstTutorial: Send push notifications to Xamarin.Forms apps using Azure Notification Hubs via a backend service

Beispiel herunterladen Herunterladen des BeispielsDownload Sample Download the sample

In diesem Tutorial verwenden Sie Azure Notification Hubs, um Pushbenachrichtigungen an eine Xamarin.Forms-Anwendung für Android und iOS zu senden.In this tutorial, you use Azure Notification Hubs to push notifications to a Xamarin.Forms application targeting Android and iOS.

Ein ASP.NET Core-Web-API-Backend wird verwendet, um die Geräteregistrierung für den Client unter Verwendung des neuesten und besten Installationsansatzes zu verarbeiten.An ASP.NET Core Web API backend is used to handle device registration for the client using the latest and best Installation approach. Der Dienst senden auch plattformübergreifend Pushbenachrichtigungen.The service will also send push notifications in a cross-platform manner.

Diese Vorgänge werden mithilfe des Notification Hubs SDKs für Back-End-Vorgänge verarbeitet.These operations are handled using the Notification Hubs SDK for backend operations. Weitere Details zum allgemeinen Ansatz finden Sie in der Dokumentation zur Registrierung Ihres App-Back-Ends.Further detail on the overall approach is provided in the Registering from your app backend documentation.

In diesem Tutorial werden die folgenden Schritte erklärt:This tutorial takes you through the following steps:

VoraussetzungenPrerequisites

Um dies nachvollziehen zu können, benötigen Sie Folgendes:To follow along, you require:

  • Ein Azure-Abonnement, in dem Sie Ressourcen erstellen und verwalten können.An Azure subscription where you can create and manage resources.
  • Einen Mac mit der installierten Edition Visual Studio für Mac oder einen PC, auf dem Visual Studio 2019 ausgeführt wirdA Mac with Visual Studio for Mac installed or a PC running Visual Studio 2019.
  • Benutzer von Visual Studio 2019 müssen darüber hinaus die Workloads Mobile-Entwicklung mit .NET und ASP.NET und Webentwicklung installiert haben.Visual Studio 2019 users must also have Mobile development with .NET and ASP.NET and web development workloads installed.
  • Die Möglichkeit, die App entweder unter Android (physische oder Emulatorgeräte) oder iOS (nur physische Geräte) auszuführen.The ability to run the app on either Android (physical or emulator devices) or iOS (physical devices only).

Für Android benötigen Sie Folgendes:For Android, you must have:

  • Ein vom Entwickler entsperrtes physisches Gerät oder einen Emulator (mit API 26 und höher und installierten Google Play Services) .A developer unlocked physical device or an emulator (running API 26 and above with Google Play Services installed).

Für iOS benötigen Sie Folgendes:For iOS, you must have:

Hinweis

Der iOS-Simulator unterstützt keine Remotebenachrichtigungen, sodass zum Nachverfolgen dieses Beispiels unter iOS ein physisches Gerät erforderlich ist.The iOS Simulator does not support remote notifications and so a physical device is required when exploring this sample on iOS. Für dieses Tutorial müssen Sie die App aber nicht unter beiden Betriebssystemen (Android und iOS) ausführen.However, you do not need to run the app on both Android and iOS in order to complete this tutorial.

Sie können die Schritte in diesem Beispiel zu den Grundprinzipien ohne vorherige Erfahrung ausführen.You can follow the steps in this first-principles example with no prior experience. Kenntnisse der folgenden Aspekte sind jedoch von Vorteil.However, you'll benefit from having familiarity with the following aspects.

Wichtig

Die angegebenen Schritte gelten speziell für Visual Studio für Mac.The steps provided are specific to Visual Studio for Mac. Sie können zwar auch für Visual Studio 2019 ausgeführt werden, es gibt aber einige Unterschiede, die berücksichtigt werden müssen.It's possible to follow along using Visual Studio 2019 but there may be some differences to reconcile. Beispielsweise weichen u. a. die Beschreibungen der Benutzeroberfläche und Workflows, die Vorlagennamen und die Umgebungskonfiguration ab.For example, descriptions of user interface and workflows, template names, environment configuration, and so on.

Einrichten von Push Notification Services und Azure Notification HubsSet up Push Notification Services and Azure Notification Hub

In diesem Abschnitt richten Sie Firebase Cloud Messaging (FCM) und Apple Push Notification Services (APNS) ein.In this section, you set up Firebase Cloud Messaging (FCM) and Apple Push Notification Services (APNS). Anschließend erstellen und konfigurieren Sie einen Notification Hub für das Arbeiten mit diesen Diensten.You then create and configure a notification hub to work with those services.

Erstellen eines Firebase-Projekts und Aktivieren von Firebase Cloud Messaging für AndroidCreate a Firebase project and enable Firebase Cloud Messaging for Android

  1. Melden Sie sich bei der Firebase-Konsole an.Sign in to the Firebase console. Erstellen Sie ein neues Firebase-Projekt, wobei Sie PushDemo als Projektnamen eingeben.Create a new Firebase project entering PushDemo as the Project name.

    Hinweis

    Es wird ein eindeutiger Name für Sie generiert.A unique name will be generated for you. Standardmäßig besteht dies aus einer Variante des von Ihnen angegebenen Namens (in Kleinbuchstaben) und einer generierten Zahl, getrennt durch einen Bindestrich.By default this is comprised of a lowercase variant of the name you provided plus a generated number separated by a dash. Wenn Sie möchten, können Sie dies ändern, vorausgesetzt, es ist immer noch global eindeutig.You can change this if you want provided it is still globally unique.

  2. Klicken Sie nach der Erstellung Ihres Projekts auf Add Firebase to your Android app (Firebase der Android-App hinzufügen).After you create your project, select Add Firebase to your Android app.

    Hinzufügen von Firebase zu Ihrer Android-App

  3. Führen Sie auf der Seite Hinzufügen von Firebase zu Ihrer Android-App die folgenden Schritte aus.On the Add Firebase to your Android app page, take the following steps.

    1. Geben Sie in Android-Paketname einen Namen für Ihr Paket ein.For the Android package name, enter a name for your package. Beispiel: com.<organization_identifier>.<package_name>.For example: com.<organization_identifier>.<package_name>.

      Angeben des Paketnamens

    2. Wählen Sie Register app (App registrieren) aus.Select Register app.

    3. Klicken Sie auf google-services.json herunterladen.Select Download google-services.json. Speichern Sie die Datei dann zur späteren Verwendung in einem lokalen Ordner, und wählen Sie Weiter aus.Then save the file into a local folder for use later on and select Next.

      Herunterladen von „google-services.json“

    4. Wählen Sie Weiter aus.Select Next.

    5. Wählen Sie Weiter zur Konsole aus.Select Continue to console

      Hinweis

      Wenn die Schaltfläche Weiter zur Konsole aufgrund der Aktivierung von Installation überprüfen nicht aktiviert ist, wählen Sie Diesen Schritt überspringen aus.If the Continue to console button is not enabled, due to the verify installation check, then choose Skip this step.

  4. Klicken Sie in der Firebase-Konsole auf das Zahnrad für Ihr Projekt.In the Firebase console, select the cog for your project. Klicken Sie dann auf Projekteinstellungen.Then select Project Settings.

    Klicken auf „Projekteinstellungen“

    Hinweis

    Wenn Sie die Datei google-services.json nicht heruntergeladen haben, können Sie dies auf dieser Seite tun.If you haven't downloaded the google-services.json file, you can do download it on this page.

  5. Wechseln Sie oben zur Registerkarte Cloud Messaging.Switch to the Cloud Messaging tab at the top. Kopieren und speichern Sie den Serverschlüssel für eine spätere Verwendung.Copy and save the Server key for later use. Dieser Wert dient zum Konfigurieren des Notification Hub.You use this value to configure your notification hub.

    Kopieren des Serverschlüssels

Registrieren der iOS-App für PushbenachrichtigungenRegister your iOS app for push notifications

Zum Senden von Pushbenachrichtigungen an eine iOS-App registrieren Sie Ihre Anwendung bei Apple, und registrieren Sie sie auch für Pushbenachrichtigungen.To send push notifications to an iOS app, register your application with Apple, and also register for push notifications.

  1. Falls Sie Ihre App noch nicht registriert haben, navigieren Sie im Apple Developer Center zum iOS-Bereitstellungsportal.If you haven't already registered your app, browse to the iOS Provisioning Portal at the Apple Developer Center. Melden Sie sich mit Ihrer Apple-ID beim Portal an, navigieren Sie zu Zertifikate, Bezeichner und Profile, und wählen Sie dann Bezeichner aus.Sign in to the portal with your Apple ID, navigate to Certificates, Identifiers & Profiles, then select Identifiers. Klicken Sie auf + , um eine neue App zu registrieren.Click + to register a new app.

    iOS-Bereitstellungsportal: Seite mit App-IDs

  2. Aktivieren Sie auf dem Bildschirm zum Registrieren eines neuen Bezeichners das Optionsfeld App-IDs.On the Register a New Identifier screen, select the App IDs radio button. Klicken Sie anschließend auf Weiter.Then select Continue.

    Seite zum Registrieren einer neuen ID im iOS-Bereitstellungsportal

  3. Aktualisieren Sie die folgenden drei Werte für Ihre neue App, und wählen Sie dann Weiter aus:Update the following three values for your new app, and then select Continue:

    • Beschreibung: Geben Sie einen aussagekräftigen Namen für Ihre App ein.Description: Type a descriptive name for your app.

    • Paket-ID: Geben Sie eine Bundle-ID im Format com.. ein, wie im Leitfaden zur App-Verteilung erwähnt.Bundle ID: Enter a Bundle ID of the form com.<organization_identifier>.<product_name> as mentioned in the App Distribution Guide. Im folgenden Screenshot wird der Wert mobcat als Organisationsbezeichner und der Wret PushDemo als Produktname verwendet.In the following screenshot, the mobcat value is used as an organization identifier and the PushDemo value is used as the product name.

      Seite zum Registrieren einer App-ID im iOS-Bereitstellungsportal

    • Push Notifications (Pushbenachrichtigungen): Aktivieren Sie die Option Pushbenachrichtigungen im Bereich Funktionen.Push Notifications: Check the Push Notifications option in the Capabilities section.

      Formular zum Registrieren einer neuen App-ID

      Hierdurch wird Ihre App-ID generiert, und Sie werden zur Bestätigung der Daten aufgefordert.This action generates your App ID and requests that you confirm the information. Wählen Sie Weiter und dann Registrieren aus, um die neue App-ID zu bestätigen.Select Continue, then select Register to confirm the new App ID.

      Neue App-ID bestätigen

      Nachdem Sie Registrieren ausgewählt haben, wird die neue App-ID als Position auf der Seite Zertifikate, Bezeichner und Profile angezeigt.After you select Register, you see the new App ID as a line item in the Certificates, Identifiers & Profiles page.

  4. Suchen Sie auf der Seite Zertifikate, Bezeichner und Profile unter Bezeichner das von Ihnen erstellte Zeilenelement „App-ID“.In the Certificates, Identifiers & Profiles page, under Identifiers, locate the App ID line item that you created. Wählen Sie dann die entsprechende Zeile aus, um den Bildschirm App-ID-Konfiguration bearbeiten anzuzeigen.Then, select its row to display the Edit your App ID Configuration screen.

Erstellen eines Zertifikats für Notification HubsCreating a certificate for Notification Hubs

Ein Zertifikat ist erforderlich, damit der Benachrichtigungshub mit Apple Push Notification Services (APNS) arbeiten und auf eine von zwei Arten bereitgestellt werden kann:A certificate is required to enable the notification hub to work with Apple Push Notification Services (APNS) and can be provided in one of two ways:

  1. Erstellen eines P12-Pushzertifikats, das direkt in den Benachrichtigungshub hochgeladen werden kann (der ursprüngliche Ansatz)Creating a p12 push certificate that can be uploaded directly to Notification Hub (the original approach)

  2. Erstellen eines P8-Zertifikats, das für die tokenbasierte Authentifizierung verwendet werden kann (der neuere und empfohlene Ansatz)Creating a p8 certificate that can be used for token-based authentication (the newer and recommended approach)

Die neuere Methode bietet eine Reihe von Vorteilen. Diese sind unter Tokenbasierte Authentifizierung (HTTP/2) für APNS dokumentiert.The newer approach has a number of benefits as documented in Token-based (HTTP/2) authentication for APNS. Es sind weniger Schritte erforderlich, sie ist zudem aber für bestimmte Szenarien vorgeschrieben.Fewer steps are required but is also mandated for specific scenarios. Es werden jedoch die Schritte für beide Ansätze beschrieben, da beide für die Zwecke dieses Tutorials funktionieren.However, steps have been provided for both approaches since either will work for the purposes of this tutorial.

OPTION 1: Erstellen eines P12-Pushzertifikats, das direkt in den Notification Hub hochgeladen werden kannOPTION 1: Creating a p12 push certificate that can be uploaded directly to Notification Hub
  1. Führen Sie auf Ihrem Mac das Tool "Schlüsselbundverwaltung" aus.On your Mac, run the Keychain Access tool. Es kann im Ordner Dienstprogramme oder im Ordner Andere auf dem Launchpad geöffnet werden.It can be opened from the Utilities folder or the Other folder on the Launchpad.

  2. Wählen Sie die Option Schlüsselbundverwaltung aus, erweitern Sie Zertifikatsassistent, und wählen Sie dann Zertifikat einer Zertifizierungsinstanz anfordern aus.Select Keychain Access, expand Certificate Assistant, and then select Request a Certificate from a Certificate Authority.

    Anfordern eines neuen Zertifikats mithilfe der Schlüsselbundverwaltung

    Hinweis

    Die Schlüsselbundverwaltung wählt standardmäßig das erste Element in der Liste aus.By default, Keychain Access selects the first item in the list. Dies kann ein Problem darstellen, wenn Sie sich in der Kategorie Zertifikate befinden und Zertifizierungsstelle der Apple Worldwide Developer Relations nicht das erste Element in der Liste ist.This can be a problem if you're in the Certificates category and Apple Worldwide Developer Relations Certification Authority is not the first item in the list. Stellen Sie sicher, dass Sie über ein Element verfügen, das kein Schlüssel ist, bzw. dass der Schlüssel Zertifizierungsstelle der Apple Worldwide Developer Relations ausgewählt ist, bevor Sie die Zertifikatsignieranforderung (Certificate Signing Request, CSR) generieren.Make sure you have a non-key item, or the Apple Worldwide Developer Relations Certification Authority key is selected, before generating the CSR (Certificate Signing Request).

  3. Wählen Sie Ihre E-Mail-Adresse des Benutzers aus, und geben Sie den Wert für Allgemeiner Name ein. Vergewissern Sie sich, dass Saved to disk (Auf Datenträger gespeichert) aktiviert ist, und wählen Sie dann Weiter aus.Select your User Email Address, enter your Common Name value, make sure that you specify Saved to disk, and then select Continue. Lassen Sie das Feld CA Email Address (E-Mail der Zertifizierungsstelle) leer, da dieser Wert nicht erforderlich ist.Leave CA Email Address blank as it isn't required.

    Erwartete Zertifikatinformationen

  4. Geben Sie unter Sichern unter einen Namen für die CSR-Datei (Zertifikatsignieranforderung) ein, wählen Sie unter Ort den Speicherort und dann Speichern aus.Enter a name for the Certificate Signing Request (CSR) file in Save As, select the location in Where, and then select Save.

    Auswählen eines Dateinamens für das Zertifikat

    Dadurch wird die CSR-Datei am ausgewählten Speicherort gespeichert.This action saves the CSR file in the selected location. Der Standardspeicherort lautet Desktop.The default location is Desktop. Merken Sie sich den für diese Datei festgelegten Speicherort.Remember the location chosen for the file.

  5. Zurück auf der Seite Zertifikate, Bezeichner und Profile scrollen Sie im iOS-Bereitstellungsportal nach unten bis zur markierten Option Pushbenachrichtigungen, und wählen Sie dann Konfigurieren aus, um das Zertifikat zu erstellen.Back on the Certificates, Identifiers & Profiles page in the iOS Provisioning Portal, scroll down to the checked Push Notifications option, and then select Configure to create the certificate.

    Bearbeiten der Seite für App-IDs

  6. Das Fenster für die TLS/SSL-Zertifikate von Apple Push Notification Service wird angezeigt.The Apple Push Notification service TLS/SSL Certificates window appears. Wählen Sie im Abschnitt des TLS/SSL-Zertifikats für die Entwicklung die Schaltfläche Zertifikat erstellen aus.Select the Create Certificate button under the Development TLS/SSL Certificate section.

    Schaltfläche zum Erstellen eines Zertifikats für die App-ID

    Der Bildschirm Ein neues Zertifikat erstellen wird angezeigt.The Create a new Certificate screen is displayed.

    Hinweis

    In diesem Lernprogramm wird ein Entwicklungszertifikat verwendet.This tutorial uses a development certificate. Derselbe Prozess wird auch zum Registrieren eines Produktionszertifikats durchgeführt.The same process is used when registering a production certificate. Achten Sie darauf, dass Sie denselben Zertifikattyp beim Senden von Benachrichtigungen verwenden.Just make sure that you use the same certificate type when sending notifications.

  7. Klicken Sie auf Datei auswählen, wechseln Sie zum Speicherort der CSR-Datei, und doppelklicken Sie dann auf den Namen des Zertifikats, um es zu laden.Select Choose File, browse to the location where you saved the CSR file, and then double-click the certificate name to load it. Klicken Sie anschließend auf Weiter.Then select Continue.

  8. Wählen Sie nach der Erstellung des Zertifikats im Portal die Schaltfläche Herunterladen aus.After the portal creates the certificate, select the Download button. Speichern Sie das Zertifikat, und merken Sie sich den Speicherort.Save the certificate, and remember the location to which it's saved.

    Downloadseite für das generierte Zertifikat

    Das Zertifikat wird heruntergeladen und auf Ihrem Computer im Ordner Downloads gespeichert.The certificate is downloaded and saved to your computer in your Downloads folder.

    Suchen der Zertifikatdatei im Ordner „Downloads“

    Hinweis

    Standardmäßig heißt das heruntergeladene Entwicklungszertifikat aps_development.cer.By default, the downloaded development certificate is named aps_development.cer.

  9. Doppelklicken Sie auf dem heruntergeladenen Pushzertifikat aps_development.cer.Double-click the downloaded push certificate aps_development.cer. Das neue Zertifikat wird im Schlüsselbund installiert, wie in der folgenden Abbildung gezeigt:This action installs the new certificate in the Keychain, as shown in the following image:

    Zertifikatliste der Schlüsselbundverwaltung mit neuem Zertifikat

    Hinweis

    Der Name in Ihrem Zertifikat kann anders lauten, ihm wird jedoch Apple Development iOS Push Services vorangestellt und der passende Bundlebezeichner zugeordnet.Although the name in your certificate might be different, the name will be prefixed with Apple Development iOS Push Services and have the appropriate bundle identifier associated with it.

  10. CONTROL + Klicken Sie in der Schlüsselbundverwaltung auf das neue Pushzertifikat, das Sie in der Kategorie Zertifikate erstellt haben.In Keychain Access, Control + Click on the new push certificate that you created in the Certificates category. Wählen Sie die Option Exportieren, benennen Sie die Datei, wählen Sie das Format P12 aus, und wählen Sie dann die Option Speichern.Select Export, name the file, select the p12 format, and then select Save.

    Exportieren des Zertifikats im p12-Format

    Sie können das Zertifikat mit einem Kennwort schützen, aber ein Kennwort ist optional.You can choose to protect the certificate with a password, but a password is optional. Wenn Sie die Kennworterstellung umgehen möchten, klicken Sie auf OK.Click OK if you want to bypass password creation. Notieren Sie sich den Dateinamen und den Speicherort des exportierten P12-Zertifikats,Make a note of the file name and location of the exported p12 certificate. Sie werden zum Aktivieren der Authentifizierung mit APNS verwendet.They're used to enable authentication with APNs.

    Hinweis

    Dateiname und Speicherort Ihrer P12-Datei können sich von den in diesem Tutorial abgebildeten Informationen unterscheiden.Your p12 file name and location might be different than what is pictured in this tutorial.

OPTION 2: Erstellen eines P8-Zertifikats, das für die tokenbasierte Authentifizierung verwendet werden kannOPTION 2: Creating a p8 certificate that can be used for token-based authentication
  1. Notieren Sie sich folgende Angaben:Make note of the following details:

    • App-ID-Präfix (Team-ID)App ID Prefix (Team ID)
    • Bundle-IDBundle ID
  2. Klicken Sie in Zertifikate, Bezeichner und Profile auf Schlüssel.Back in Certificates, Identifiers & Profiles, click Keys.

    Hinweis

    Wenn Sie bereits einen Schlüssel für APNS konfiguriert haben, können Sie das P8-Zertifikat wiederverwenden, das Sie direkt nach der Erstellung heruntergeladen haben.If you already have a key configured for APNS, you can re-use the p8 certificate that you downloaded right after it was created. In diesem Fall können Sie die Schritte 3 bis 5 überspringen.If so, you can ignore steps 3 through 5.

  3. Klicken Sie auf die Schaltfläche + (oder die Schaltfläche Schlüssel erstellen), um einen neuen Schlüssel zu erstellen.Click the + button (or the Create a key button) to create a new key.

  4. Geben Sie einen geeigneten Wert für den Schlüsselnamen an, aktivieren Sie die Option Apple Push Notification Service (APNS) , und klicken Sie dann auf Weiter und auf dem nächsten Bildschirm auf Registrieren.Provide a suitable Key Name value, then check the Apple Push Notifications service (APNS) option, and then click Continue, followed by Register on the next screen.

  5. Klicken Sie auf Herunterladen, und verschieben Sie die P8-Datei (mit dem Präfix AuthKey_ ) in ein sicheres lokales Verzeichnis. Klicken Sie dann auf Fertig.Click Download and then move the p8 file (prefixed with AuthKey_) to a secure local directory, then click Done.

    Hinweis

    Bewahren Sie die P8-Datei an einem sicheren Ort auf (und speichern Sie eine Sicherungskopie).Be sure to keep your p8 file in a secure place (and save a backup). Nach dem Herunterladen kann der Schlüssel nicht erneut heruntergeladen werden, weil die Kopie auf dem Server gelöscht wird.After downloading your key, it cannot be re-downloaded as the server copy is removed.

  6. Klicken Sie unter Schlüssel auf den erstellten Schlüssel (oder auf einen vorhandenen Schlüssel, falls Sie stattdessen einen solchen verwenden möchten).On Keys, click on the key that you created (or an existing key if you have chosen to use that instead).

  7. Notieren Sie sich den Wert der Schlüssel-ID.Make note of the Key ID value.

  8. Öffnen Sie das P8-Zertifikat in einer geeigneten Anwendung wie z. B. Visual Studio Code.Open your p8 certificate in a suitable application of your choice such as Visual Studio Code. Notieren Sie sich den Schlüsselwert (zwischen -----BEGIN PRIVATE KEY----- und -----END PRIVATE KEY----- ).Make note of the key value (between -----BEGIN PRIVATE KEY----- and -----END PRIVATE KEY-----).

    -----BEGIN PRIVATE KEY----------BEGIN PRIVATE KEY-----
    <Schlüsselwert><key_value>
    -----END PRIVATE KEY----------END PRIVATE KEY-----

    Hinweis

    Dies ist der Tokenwert, der später verwendet wird, um den Notification Hub zu konfigurieren.This is the token value that will be used later to configure Notification Hub.

Nach Abschluss dieser Schritte verfügen Sie über folgende Informationen, die Sie später unter Konfigurieren Ihres Benachrichtigungshubs mit APNS-Informationen verwenden werden:At the end of these steps, you should have the following information for use later in Configure your notification hub with APNS information:

  • Team-ID (siehe Schritt 1)Team ID (see step 1)
  • Bundle-ID (siehe Schritt 1)Bundle ID (see step 1)
  • Schlüssel-ID (siehe Schritt 7)Key ID (see step 7)
  • Tokenwert (P8-Schlüsselwert, der in Schritt 8 abgerufen wurde)Token value (p8 key value obtained in step 8)

Erstellen eines Bereitstellungsprofils für die AppCreate a provisioning profile for the app

  1. Wechseln Sie zurück zum iOS-Bereitstellungsportal, wählen Sie Zertifikate, Bezeichner und Profile aus, wählen Sie im Menü auf der linken Seite Profile und dann + aus, um ein neues Profil zu erstellen.Return to the iOS Provisioning Portal, select Certificates, Identifiers & Profiles, select Profiles from the left menu, and then select + to create a new profile. Der Bildschirm zum Registrieren eines neuen Bereitstellungsprofils wird angezeigt.The Register a New Provisioning Profile screen appears.

  2. Wählen Sie unter Entwicklung, die Option iOS-App-Entwicklung als Bereitstellungsprofiltyp aus, und wählen Sie anschließend Weiter.Select iOS App Development under Development as the provisioning profile type, and then select Continue.

    Bereitstellungsprofilliste

  3. Wählen Sie anschließend die von Ihnen erstellte App-ID in der Dropdownliste App ID (App-ID) und dann Weiter aus.Next, select the app ID you created from the App ID drop-down list, and select Continue.

    Auswählen der App-ID

  4. Wählen Sie im Fenster Select certificates (Zertifikate auswählen) das Entwicklungszertifikat aus, das Sie für die Codesignierung verwenden, und wählen Sie dann Continue (Weiter).In the Select certificates window, select the development certificate that you use for code signing, and select Continue.

    Hinweis

    Bei diesem Zertifikat handelt es sich nicht um das im vorherigen Schritt erstellte Pushzertifikat,This certificate is not the push certificate you created in the previous step. sondern um Ihr Entwicklungszertifikat.This is your development certificate. Wenn kein solches vorhanden ist, müssen Sie es erstellen, da dies eine Voraussetzung für dieses Tutorial ist.If one does not exist, you must create it since this is a prerequisite for this tutorial. Entwicklerzertifikate können im Apple-Entwicklerportal über Xcode- oder in Visual Studio erstellt werden.Developer certificates can be created in the Apple Developer Portal, via Xcode or in Visual Studio.

  5. Wechseln Sie zurück zur Seite Zertifikate, Bezeichner und Profile, wählen Sie im Menü auf der linken Seite Profile und dann + aus, um ein neues Profil zu erstellen.Return to the Certificates, Identifiers & Profiles page, select Profiles from the left menu, and then select + to create a new profile. Der Bildschirm zum Registrieren eines neuen Bereitstellungsprofils wird angezeigt.The Register a New Provisioning Profile screen appears.

  6. Wählen Sie im Fenster Zertifikate auswählen das erstellte Entwicklungszertifikat aus.In the Select certificates window, select the development certificate that you created. Klicken Sie anschließend auf Weiter.Then select Continue.

  7. Wählen Sie nun die Geräte aus, die zum Testen verwendet werden sollen, und wählen Sie dann Weiter aus.Next, select the devices to use for testing, and select Continue.

  8. Wählen Sie schließlich im Feld Provisioning Profile Name (Name des Bereitstellungsprofils) einen Namen für das Profil, und wählen Sie Generate (Generieren) aus.Finally, choose a name for the profile in Provisioning Profile Name, and select Generate.

    Auswählen eines Bereitstellungsprofilnamens

  9. Nachdem das neue Bereitstellungsprofil erstellt wurde, wählen Sie Herunterladen aus.When the new provisioning profile is created, select Download. Merken Sie sich den Speicherort des Profils.Remember the location to which it's saved.

  10. Navigieren Sie zum Speicherort des Bereitstellungsprofils, und doppelklicken Sie darauf, um es auf dem Entwicklungscomputer zu installieren.Browse to the location of the provisioning profile, and then double-click it to install it on your development machine.

Erstellen eines Notification HubsCreate a Notification Hub

In diesem Abschnitt erstellen Sie einen Benachrichtigungshub und konfigurieren die Authentifizierung mit APNS.In this section, you create a notification hub and configure authentication with APNS. Sie können ein P12-Push-Zertifikat oder eine tokenbasierte Authentifizierung verwenden.You can use a p12 push certificate or token-based authentication. Wenn Sie einen bereits erstellten Notification Hub verwenden möchten, können Sie mit Schritt 5 fortfahren.If you want to use a notification hub that you've already created, you can skip to step 5.

  1. Melden Sie sich bei Azure an.Sign in to Azure.

  2. Klicken Sie auf Ressource erstellen, suchen und wählen Sie Benachrichtigungshub aus, und klicken Sie dann auf Erstellen.Click Create a resource, then search for and choose Notification Hub, then click Create.

  3. Aktualisieren Sie die folgenden Felder, und klicken Sie auf Erstellen:Update the following fields, then click Create:

    GRUNDLEGENDE INFORMATIONENBASIC DETAILS

    Abonnement: Wählen Sie das Zielabonnement aus der Dropdown-Liste aus.Subscription: Choose the target Subscription from the drop-down list
    Ressourcengruppe: Erstellen Sie eine neue Ressourcengruppe (oder verwenden Sie eine bereits vorhandene).Resource Group: Create a new Resource Group (or pick an existing one)

    DETAILS ZUM NAMESPACENAMESPACE DETAILS

    Benachrichtigungshub-Namespace: Geben Sie einen global eindeutigen Namen für den Namespace Benachrichtigungshub ein.Notification Hub Namespace: Enter a globally unique name for the Notification Hub namespace

    Hinweis

    Stellen Sie sicher, dass die Option Neu erstellen für dieses Feld ausgewählt ist.Ensure the Create new option is selected for this field.

    DETAILS ZUM BENACHRICHTIGUNGSHUBNOTIFICATION HUB DETAILS

    Benachrichtigungshub: Geben Sie einen Namen für den Benachrichtigungshub ein.Notification Hub: Enter a name for the Notification Hub
    Standort: Wählen Sie einen passenden Standort aus der Dropdownliste aus.Location: Choose a suitable location from the drop-down list
    Tarif: Behalten Sie die Standardoption Free bei,Pricing Tier: Keep the default Free option

    Hinweis

    es sei denn, Sie haben die maximale Anzahl von Hubs im Free-Tarif erreicht.Unless you have reached the maximum number of hubs on the free tier.

  4. Sobald der Benachrichtigungshub bereitgestellt wurde, navigieren Sie zu dieser Ressource.Once the Notification Hub has been provisioned, navigate to that resource.

  5. Navigieren Sie zu Ihrem neuen Benachrichtigungshub.Navigate to your new Notification Hub.

  6. Wählen Sie die Option Zugriffsrichtlinien aus der Liste aus (unter VERWALTEN).Select Access Policies from the list (under MANAGE).

  7. Notieren Sie sich den Wert von Richtlinienname zusammen mit den entsprechenden Verbindungszeichenfolge-Werten.Make note of the Policy Name values along with their corresponding Connection String values.

Konfigurieren Ihrer Notification Hubs-Instanz mit APNs-InformationenConfigure your Notification Hub with APNS information

Wählen Sie unter Notification Services die Option Apple aus, und führen Sie dann je nach der Methode, die Sie im Abschnitt Erstellen eines Zertifikats für Notification Hubs ausgewählt haben, die entsprechenden Schritte aus.Under Notification Services, select Apple then follow the appropriate steps based on the approach you chose previously in the Creating a Certificate for Notification Hubs section.

Hinweis

Verwenden Sie Produktion nur dann als Anwendungsmodus, wenn Sie Pushbenachrichtigungen an Benutzer senden möchten, die Ihre App im Store erworben haben.Use the Production for Application Mode only if you want to send push notifications to users who purchased your app from the store.

OPTION 1: Verwenden eines P12-ZertifikatsOPTION 1: Using a .p12 push certificate

  1. Wählen Sie Certificateaus.Select Certificate.

  2. Wählen Sie das Dateisymbol aus.Select the file icon.

  3. Wählen Sie die zuvor exportierte P12-Datei aus, und wählen Sie dann Öffnen.Select the .p12 file that you exported earlier, and then select Open.

  4. Geben Sie bei Bedarf das richtige Kennwort an.If necessary, specify the correct password.

  5. Wählen Sie den Modus Sandbox aus.Select Sandbox mode.

  6. Wählen Sie Speichern aus.Select Save.

OPTION 2: Verwenden der tokenbasierten AuthentifizierungOPTION 2: Using token-based authentication

  1. Wählen Sie Token aus.Select Token.

  2. Geben Sie die folgenden Werte ein, die Sie zuvor abgerufen haben:Enter the following values that you acquired earlier:

    • Schlüssel-IDKey ID
    • Bundle-IDBundle ID
    • Team-IDTeam ID
    • TokenToken
  3. Wählen Sie Sandbox aus.Choose Sandbox.

  4. Wählen Sie Speichern aus.Select Save.

Konfigurieren Ihres Benachrichtigungshubs mit FCM-InformationenConfigure your notification hub with FCM information

  1. Wählen Sie im linken Menü im Abschnitt Einstellungen die Option Google (GCM/FCM) aus.Select Google (GCM/FCM) in the Settings section on the left menu.
  2. Geben Sie den Serverschlüssel ein, den Sie in der Google Firebase-Konsole notiert haben.Enter the server key you noted down from the Google Firebase Console.
  3. Wählen Sie auf der Symbolleiste Speichern aus.Select Save on the toolbar.

Erstellen einer Anwendung für das ASP.NET Core-Web-API-Back-EndCreate an ASP.NET Core Web API backend application

In diesem Abschnitt erstellen Sie das ASP.NET Core-Web-API-Back-End für die Geräteregistrierung und das Senden von Benachrichtigungen an die mobile Xamarin.Forms-App.In this section, you create the ASP.NET Core Web API backend to handle device registration and the sending of notifications to the Xamarin.Forms mobile app.

Erstellen eines WebprojektsCreate a web project

  1. Wählen Sie in Visual Studio die Optionen Datei > Neue Lösung aus.In Visual Studio , select File > New Solution.

  2. Wählen Sie .NET Core > App > ASP.NET Core > API > Weiter aus.Select .NET Core > App > ASP.NET Core > API > Next.

  3. Wählen Sie im Dialogfeld Neue ASP.NET Core-Web-API konfigurieren die Option Zielframework von .NET Core 3.1 aus.In the Configure your new ASP.NET Core Web API dialog, select Target Framework of .NET Core 3.1.

  4. Geben Sie PushDemoApi als Projektnamen ein, und wählen Sie dann Erstellen aus.Enter PushDemoApi for the Project Name and then select Create.

  5. Starten Sie den Debugvorgang ( BEFEHL + EINGABE ), um die vorlagenbasierte App zu testen.Start debugging ( Command + Enter ) to test the templated app.

    Hinweis

    Die vorlagenbasierte App ist so konfiguriert, dass WeatherForecastController- als launchUrl verwendet wird.The templated app is configured to use the WeatherForecastController as the launchUrl. Dies wird unter Eigenschaften > launchSettings.json festgelegt.This is set in Properties > launchSettings.json.

    Wenn die Meldung Ungültiges Entwicklungszertifikat gefunden angezeigt wird:If you are prompted with an Invalid development certificate found message:

    1. Klicken Sie auf Ja , um zu bestätigen, dass das Tool „dotnet dev-certs https“ zum Korrigieren dieses Fehlers ausgeführt wird.Click Yes to agree to running the 'dotnet dev-certs https' tool to fix this. Vom Tool „dotnet dev-certs https“ werden Sie dann aufgefordert, ein Kennwort für das Zertifikat und das Kennwort für Ihren Schlüsselbund einzugeben.The 'dotnet dev-certs https' tool then prompt you to enter a password for the certificate and the password for your Keychain.

    2. Klicken Sie auf Ja , wenn Sie aufgefordert werden, das neue Zertifikat zu installieren und ihm zu vertrauen , und geben Sie dann das Kennwort für Ihren Schlüsselbund ein.Click Yes when prompted to Install and trust the new certificate , then enter the password for your Keychain.

  6. Erweitern Sie den Ordner Controller , und löschen Sie dann WeatherForecastController.cs.Expand the Controllers folder, then delete WeatherForecastController.cs.

  7. Löschen Sie WeatherForecast.cs.Delete WeatherForecast.cs.

  8. Richten Sie mit dem Geheimnis-Manager-Tool lokale Konfigurationswerte ein.Set up local configuration values using the Secret Manager tool. Indem Sie die Kopplung der geheimen Schlüssel mit der Lösung aufheben, wird sichergestellt, dass sie nicht in die Quellcodeverwaltung geraten.Decoupling the secrets from the solution ensures that they don't end up in source control. Öffnen Sie Terminal , wechseln Sie dann zum Verzeichnis der Projektdatei, und führen Sie die folgenden Befehle aus:Open Terminal then go to the directory of the project file and run the following commands:

    dotnet user-secrets init
    dotnet user-secrets set "NotificationHub:Name" <value>
    dotnet user-secrets set "NotificationHub:ConnectionString" <value>
    

    Ersetzen Sie die Platzhalterwerte durch den Namen ihres eigenen Benachrichtigungshubs und die Werte der Verbindungszeichenfolge.Replace the placeholder values with your own notification hub name and connection string values. Diese haben Sie sich im Abschnitt Erstellen eines Benachrichtigungshubs notiert.You made a note of them in the create a notification hub section. Andernfalls können Sie sie in Azure nachschlagen.Otherwise, you can look them up in Azure.

    NotificationsHub:Name :NotificationsHub:Name :
    Weitere Informationen finden Sie unter Name in der Zusammenfassung Essentials am Anfang der Übersicht.See Name in the Essentials summary at the top of Overview.

    NotificationHub:ConnectionString :NotificationHub:ConnectionString :
    Weitere Informationen finden Sie unter DefaultFullSharedAccessSignature- in ZugriffsrichtlinienSee DefaultFullSharedAccessSignature in Access Policies

    Hinweis

    In Produktionsszenarien können Sie Optionen wie Azure KeyVault in Betracht ziehen, um die Verbindungszeichenfolge sicher zu speichern.For production scenarios, you can look at options such as Azure KeyVault to securely store the connection string. Der Einfachheit halber werden die geheimen Schlüssel den Anwendungseinstellungen von Azure App Service hinzugefügt.For simplicity, the secrets will be added to the Azure App Service application settings.

Authentifizieren von Clients mit einem API-Schlüssel (optional)Authenticate clients using an API Key (Optional)

API-Schlüssel sind nicht so sicher wie Token, sind aber für die Zwecke dieses Tutorials ausreichend.API keys aren't as secure as tokens, but will suffice for the purposes of this tutorial. Ein API-Schlüssel kann problemlos über die ASP.NET-Middleware konfiguriert werden.An API key can be configured easily via the ASP.NET Middleware.

  1. Fügen Sie den API-Schlüssel zu den lokalen Konfigurationswerten hinzu.Add the API key to the local configuration values.

    dotnet user-secrets set "Authentication:ApiKey" <value>
    

    Hinweis

    Ersetzen Sie den Platzhalterwert durch ihren eigenen Wert, und notieren Sie ihn.You should replace the placeholder value with your own and make a note of it.

  2. CONTROL + Klicken Sie auf das Projekt PushDemoApi , wählen Sie Neuer Ordner aus dem Menü Hinzufügen aus, und klicken Sie dann auf Hinzufügen. Verwenden Sie dabei Authentifizierung als Ordnernamen.Control + Click on the PushDemoApi project, choose New Folder from the Add menu, then click Add using Authentication as the Folder Name.

  3. CONTROL + Klicken Sie auf den Ordner Authentication , und wählen Sie dann Neue Datei... aus dem Menü Hinzufügen aus.Control + Click on the Authentication folder, then choose New File... from the Add menu.

  4. Wählen Sie Allgemein > Leere Klassen aus, geben Sie ApiKeyAuthOptions.cs als Namen ein, und klicken Sie dann auf Neu unter Hinzufügung der folgenden Implementierung.Select General > Empty Class , enter ApiKeyAuthOptions.cs for the Name , then click New adding the following implementation.

    using Microsoft.AspNetCore.Authentication;
    
    namespace PushDemoApi.Authentication
    {
        public class ApiKeyAuthOptions : AuthenticationSchemeOptions
        {
            public const string DefaultScheme = "ApiKey";
            public string Scheme => DefaultScheme;
            public string ApiKey { get; set; }
        }
    }
    
  5. Fügen Sie dem Ordner Authentication mit dem Namen ApiKeyAuthHandler.cs eine weitere leere Klasse hinzu, und fügen Sie dann die folgende Implementierung hinzu.Add another Empty Class to the Authentication folder called ApiKeyAuthHandler.cs , then add the following implementation.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Security.Claims;
    using System.Text.Encodings.Web;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Authentication;
    using Microsoft.Extensions.Logging;
    using Microsoft.Extensions.Options;
    
    namespace PushDemoApi.Authentication
    {
        public class ApiKeyAuthHandler : AuthenticationHandler<ApiKeyAuthOptions>
        {
            const string ApiKeyIdentifier = "apikey";
    
            public ApiKeyAuthHandler(
                IOptionsMonitor<ApiKeyAuthOptions> options,
                ILoggerFactory logger,
                UrlEncoder encoder,
                ISystemClock clock)
                : base(options, logger, encoder, clock) {}
    
            protected override Task<AuthenticateResult> HandleAuthenticateAsync()
            {
                string key = string.Empty;
    
                if (Request.Headers[ApiKeyIdentifier].Any())
                {
                    key = Request.Headers[ApiKeyIdentifier].FirstOrDefault();
                }
                else if (Request.Query.ContainsKey(ApiKeyIdentifier))
                {
                    if (Request.Query.TryGetValue(ApiKeyIdentifier, out var queryKey))
                        key = queryKey;
                }
    
                if (string.IsNullOrWhiteSpace(key))
                    return Task.FromResult(AuthenticateResult.Fail("No api key provided"));
    
                if (!string.Equals(key, Options.ApiKey, StringComparison.Ordinal))
                    return Task.FromResult(AuthenticateResult.Fail("Invalid api key."));
    
                var identities = new List<ClaimsIdentity> {
                    new ClaimsIdentity("ApiKeyIdentity")
                };
    
                var ticket = new AuthenticationTicket(
                    new ClaimsPrincipal(identities), Options.Scheme);
    
                return Task.FromResult(AuthenticateResult.Success(ticket));
            }
        }
    }
    

    Hinweis

    Ein Authentifizierungs-Handler ist ein Typ, der das Verhalten eines Schemas implementiert, in diesem Fall ein benutzerdefiniertes API-Schlüssel-Schema.An Authentication Handler is a type that implements the behavior of a scheme, in this case a custom API Key scheme.

  6. Fügen Sie dem Ordner Authentication mit dem Namen ApiKeyAuthenticationBuilderExtensions.cs eine weitere leere Klasse hinzu, und fügen Sie dann die folgende Implementierung hinzu.Add another Empty Class to the Authentication folder called ApiKeyAuthenticationBuilderExtensions.cs , then add the following implementation.

    using System;
    using Microsoft.AspNetCore.Authentication;
    
    namespace PushDemoApi.Authentication
    {
        public static class AuthenticationBuilderExtensions
        {
            public static AuthenticationBuilder AddApiKeyAuth(
                this AuthenticationBuilder builder,
                Action<ApiKeyAuthOptions> configureOptions)
            {
                return builder
                    .AddScheme<ApiKeyAuthOptions, ApiKeyAuthHandler>(
                        ApiKeyAuthOptions.DefaultScheme,
                        configureOptions);
            }
        }
    }
    

    Hinweis

    Diese Erweiterungsmethode vereinfacht den Konfigurationscode der Middleware in Startup.cs damit Sie besser lesbar und allgemein leichter zu finden ist.This extension method simplifies the middleware configuration code in Startup.cs making it more readable and generally easier to follow.

  7. Aktualisieren Sie in Startup.cs die Methode ConfigureServices , um die API-Schlüsselauthentifizierung unterhalb des Aufrufs der Methode services.AddControllers.In Startup.cs , update the ConfigureServices method to configure the API Key authentication below the call to the services.AddControllers method.

    using PushDemoApi.Authentication;
    using PushDemoApi.Models;
    using PushDemoApi.Services;
    
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
    
        services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = ApiKeyAuthOptions.DefaultScheme;
            options.DefaultChallengeScheme = ApiKeyAuthOptions.DefaultScheme;
        }).AddApiKeyAuth(Configuration.GetSection("Authentication").Bind);
    }
    
  8. Aktualisieren Sie, immer noch in Startup.cs , die Methode Configure , um die Erweiterungsmethoden UseAuthentication und UseAuthorization für das IApplicationBuilder -Objekt der App aufzurufen.Still in Startup.cs , update the Configure method to call the UseAuthentication and UseAuthorization extension methods on the app's IApplicationBuilder. Stellen Sie sicher, dass diese Methoden nach UseRouting und vor app.UseEndpoints aufgerufen werden.Ensure those methods are called after UseRouting and before app.UseEndpoints.

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
    
        app.UseHttpsRedirection();
    
        app.UseRouting();
    
        app.UseAuthentication();
    
        app.UseAuthorization();
    
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
    

    Hinweis

    Durch Aufrufen von UseAuthentication wird die Middleware registriert, die die zuvor registrierten Authentifizierungsschemas (von ConfigureServices ) verwendet.Calling UseAuthentication registers the middleware which uses the previously registered authentication schemes (from ConfigureServices ). Diese Methode muss vor jeglicher anderen Middleware aufgerufen werden, die von der Authentifizierung der Benutzer abhängig ist.This must be called before any middleware that depends on users being authenticated.

Hinzufügen von Abhängigkeiten und Konfigurieren von DienstenAdd dependencies and configure services

ASP.NET Core unterstützt das Softwareentwurfsmuster Abhängigkeitsinjektion (Dependency Injection, DI). Mit dieser Technik kann eine Umkehrung der Steuerung (Inversion of Control, IoC) zwischen Klassen und ihren Abhängigkeiten erreicht werden.ASP.NET Core supports the dependency injection (DI) software design pattern, which is a technique for achieving Inversion of Control (IoC) between classes and their dependencies.

Die Verwendung des Benachrichtigungshubs und des Notification Hubs SDK für Back-End-Vorgänge ist innerhalb eines Diensts gekapselt.Use of the notification hub and the Notification Hubs SDK for backend operations is encapsulated within a service. Der Dienst wird durch eine geeignete Abstraktion registriert und verfügbar gemacht.The service is registered and made available through a suitable abstraction.

  1. CONTROL + Klicken Sie auf den Ordner Abhängigkeiten , und wählen Sie dann NuGet-Pakete verwalten... aus.Control + Click on the Dependencies folder, then choose Manage NuGet Packages....

  2. Suchen Sie nach Microsoft.Azure.NotificationHubs , und stellen Sie sicher, dass diese Option aktiviert ist.Search for Microsoft.Azure.NotificationHubs and ensure it's checked.

  3. Klicken Sie auf Pakete hinzufügen dann auf Zustimmen , wenn Sie aufgefordert werden, die Lizenzbedingungen zu akzeptieren.Click Add Packages , then click Accept when prompted to accept the license terms.

  4. CONTROL + Klicken Sie auf das Projekt PushDemoApi , wählen Sie Neuer Ordner aus dem Menü Hinzufügen aus, und klicken Sie dann auf Hinzufügen. Verwenden Sie dabei Modelle als Ordnernamen.Control + Click on the PushDemoApi project, choose New Folder from the Add menu, then click Add using Models as the Folder Name.

  5. CONTROL + Klicken Sie auf den Ordner Modelle , und wählen Sie dann Neue Datei... aus dem Menü Hinzufügen aus.Control + Click on the Models folder, then choose New File... from the Add menu.

  6. Wählen Sie Allgemein > Leere Klassen aus, geben Sie PushTemplates.cs als Namen ein, und klicken Sie dann auf Neu unter Hinzufügung der folgenden Implementierung.Select General > Empty Class , enter PushTemplates.cs for the Name , then click New adding the following implementation.

    namespace PushDemoApi.Models
    {
        public class PushTemplates
        {
            public class Generic
            {
                public const string Android = "{ \"notification\": { \"title\" : \"PushDemo\", \"body\" : \"$(alertMessage)\"}, \"data\" : { \"action\" : \"$(alertAction)\" } }";
                public const string iOS = "{ \"aps\" : {\"alert\" : \"$(alertMessage)\"}, \"action\" : \"$(alertAction)\" }";
            }
    
            public class Silent
            {
                public const string Android = "{ \"data\" : {\"message\" : \"$(alertMessage)\", \"action\" : \"$(alertAction)\"} }";
                public const string iOS = "{ \"aps\" : {\"content-available\" : 1, \"apns-priority\": 5, \"sound\" : \"\", \"badge\" : 0}, \"message\" : \"$(alertMessage)\", \"action\" : \"$(alertAction)\" }";
            }
        }
    }
    

    Hinweis

    Diese Klasse enthält die tokenisierten Benachrichtigungsnutzlasten für die für dieses Szenario erforderlichen generischen und automatischen Benachrichtigungen.This class contains the tokenized notification payloads for the generic and silent notifications required by this scenario. Die Nutzlasten werden außerhalb der Installation definiert, um Experimente zuzulassen, ohne vorhandene Installationen über den Dienst aktualisieren zu müssen.The payloads are defined outside of the Installation to allow experimentation without having to update existing installations via the service. Die Verarbeitung von Änderungen an Installationen auf diese Weise ist nicht Gegenstand dieses Tutorials.Handling changes to installations in this way is out of scope for this tutorial. Ziehen Sie für die Produktion benutzerdefinierte Vorlagen in Betracht.For production, consider custom templates.

  7. Fügen Sie dem Ordner Modelle mit dem Namen DeviceInstallation.cs eine weitere leere Klasse hinzu, und fügen Sie dann die folgende Implementierung hinzu.Add another Empty Class to the Models folder called DeviceInstallation.cs , then add the following implementation.

    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    
    namespace PushDemoApi.Models
    {
        public class DeviceInstallation
        {
            [Required]
            public string InstallationId { get; set; }
    
            [Required]
            public string Platform { get; set; }
    
            [Required]
            public string PushChannel { get; set; }
    
            public IList<string> Tags { get; set; } = Array.Empty<string>();
        }
    }
    
  8. Fügen Sie dem Ordner Modelle mit dem Namen NotificationRequest.cs eine weitere leere Klasse hinzu, und fügen Sie dann die folgende Implementierung hinzu.Add another Empty Class to the Models folder called NotificationRequest.cs , then add the following implementation.

    using System;
    
    namespace PushDemoApi.Models
    {
        public class NotificationRequest
        {
            public string Text { get; set; }
            public string Action { get; set; }
            public string[] Tags { get; set; } = Array.Empty<string>();
            public bool Silent { get; set; }
        }
    }
    
  9. Fügen Sie dem Ordner Modelle mit dem Namen NotificationHubOptions.cs eine weitere leere Klasse hinzu, und fügen Sie dann die folgende Implementierung hinzu.Add another Empty Class to the Models folder called NotificationHubOptions.cs , then add the following implementation.

    using System.ComponentModel.DataAnnotations;
    
    namespace PushDemoApi.Models
    {
        public class NotificationHubOptions
        {
            [Required]
            public string Name { get; set; }
    
            [Required]
            public string ConnectionString { get; set; }
        }
    }
    
  10. Fügen Sie dem Projekt PushDemoApi einen neuen Ordner mit dem Namen Dienste hinzu.Add a new folder to the PushDemoApi project called Services.

  11. Fügen Sie zum Ordner Dienste eine leere Schnittstelle namens INotificationService.cs hinzu, und fügen Sie dann die folgende Implementierung hinzu.Add an Empty Interface to the Services folder called INotificationService.cs , then add the following implementation.

    using System.Threading;
    using System.Threading.Tasks;
    using PushDemoApi.Models;
    
    namespace PushDemoApi.Services
    {
        public interface INotificationService
        {
            Task<bool> CreateOrUpdateInstallationAsync(DeviceInstallation deviceInstallation, CancellationToken token);
            Task<bool> DeleteInstallationByIdAsync(string installationId, CancellationToken token);
            Task<bool> RequestNotificationAsync(NotificationRequest notificationRequest, CancellationToken token);
        }
    }
    
  12. Fügen Sie zum Ordner Dienste eine leere Klasse namens NotificationHubsService.cs hinzu, und fügen Sie dann den folgenden Code hinzu, um die Schnittstelle INotificationService zu implementieren:Add an Empty Class to the Services folder called NotificationHubsService.cs , then add the following code to implement the INotificationService interface:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.Azure.NotificationHubs;
    using Microsoft.Extensions.Logging;
    using Microsoft.Extensions.Options;
    using PushDemoApi.Models;
    
    namespace PushDemoApi.Services
    {
        public class NotificationHubService : INotificationService
        {
            readonly NotificationHubClient _hub;
            readonly Dictionary<string, NotificationPlatform> _installationPlatform;
            readonly ILogger<NotificationHubService> _logger;
    
            public NotificationHubService(IOptions<NotificationHubOptions> options, ILogger<NotificationHubService> logger)
            {
                _logger = logger;
                _hub = NotificationHubClient.CreateClientFromConnectionString(
                    options.Value.ConnectionString,
                    options.Value.Name);
    
                _installationPlatform = new Dictionary<string, NotificationPlatform>
                {
                    { nameof(NotificationPlatform.Apns).ToLower(), NotificationPlatform.Apns },
                    { nameof(NotificationPlatform.Fcm).ToLower(), NotificationPlatform.Fcm }
                };
            }
    
            public async Task<bool> CreateOrUpdateInstallationAsync(DeviceInstallation deviceInstallation, CancellationToken token)
            {
                if (string.IsNullOrWhiteSpace(deviceInstallation?.InstallationId) ||
                    string.IsNullOrWhiteSpace(deviceInstallation?.Platform) ||
                    string.IsNullOrWhiteSpace(deviceInstallation?.PushChannel))
                    return false;
    
                var installation = new Installation()
                {
                    InstallationId = deviceInstallation.InstallationId,
                    PushChannel = deviceInstallation.PushChannel,
                    Tags = deviceInstallation.Tags
                };
    
                if (_installationPlatform.TryGetValue(deviceInstallation.Platform, out var platform))
                    installation.Platform = platform;
                else
                    return false;
    
                try
                {
                    await _hub.CreateOrUpdateInstallationAsync(installation, token);
                }
                catch
                {
                    return false;
                }
    
                return true;
            }
    
            public async Task<bool> DeleteInstallationByIdAsync(string installationId, CancellationToken token)
            {
                if (string.IsNullOrWhiteSpace(installationId))
                    return false;
    
                try
                {
                    await _hub.DeleteInstallationAsync(installationId, token);
                }
                catch
                {
                    return false;
                }
    
                return true;
            }
    
            public async Task<bool> RequestNotificationAsync(NotificationRequest notificationRequest, CancellationToken token)
            {
                if ((notificationRequest.Silent &&
                    string.IsNullOrWhiteSpace(notificationRequest?.Action)) ||
                    (!notificationRequest.Silent &&
                    (string.IsNullOrWhiteSpace(notificationRequest?.Text)) ||
                    string.IsNullOrWhiteSpace(notificationRequest?.Action)))
                    return false;
    
                var androidPushTemplate = notificationRequest.Silent ?
                    PushTemplates.Silent.Android :
                    PushTemplates.Generic.Android;
    
                var iOSPushTemplate = notificationRequest.Silent ?
                    PushTemplates.Silent.iOS :
                    PushTemplates.Generic.iOS;
    
                var androidPayload = PrepareNotificationPayload(
                    androidPushTemplate,
                    notificationRequest.Text,
                    notificationRequest.Action);
    
                var iOSPayload = PrepareNotificationPayload(
                    iOSPushTemplate,
                    notificationRequest.Text,
                    notificationRequest.Action);
    
                try
                {
                    if (notificationRequest.Tags.Length == 0)
                    {
                        // This will broadcast to all users registered in the notification hub
                        await SendPlatformNotificationsAsync(androidPayload, iOSPayload, token);
                    }
                    else if (notificationRequest.Tags.Length <= 20)
                    {
                        await SendPlatformNotificationsAsync(androidPayload, iOSPayload, notificationRequest.Tags, token);
                    }
                    else
                    {
                        var notificationTasks = notificationRequest.Tags
                            .Select((value, index) => (value, index))
                            .GroupBy(g => g.index / 20, i => i.value)
                            .Select(tags => SendPlatformNotificationsAsync(androidPayload, iOSPayload, tags, token));
    
                        await Task.WhenAll(notificationTasks);
                    }
    
                    return true;
                }
                catch (Exception e)
                {
                    _logger.LogError(e, "Unexpected error sending notification");
                    return false;
                }
            }
    
            string PrepareNotificationPayload(string template, string text, string action) => template
                .Replace("$(alertMessage)", text, StringComparison.InvariantCulture)
                .Replace("$(alertAction)", action, StringComparison.InvariantCulture);
    
            Task SendPlatformNotificationsAsync(string androidPayload, string iOSPayload, CancellationToken token)
            {
                var sendTasks = new Task[]
                {
                    _hub.SendFcmNativeNotificationAsync(androidPayload, token),
                    _hub.SendAppleNativeNotificationAsync(iOSPayload, token)
                };
    
                return Task.WhenAll(sendTasks);
            }
    
            Task SendPlatformNotificationsAsync(string androidPayload, string iOSPayload, IEnumerable<string> tags, CancellationToken token)
            {
                var sendTasks = new Task[]
                {
                    _hub.SendFcmNativeNotificationAsync(androidPayload, tags, token),
                    _hub.SendAppleNativeNotificationAsync(iOSPayload, tags, token)
                };
    
                return Task.WhenAll(sendTasks);
            }
        }
    }
    

    Hinweis

    Der für SendTemplateNotificationAsync bereitgestellte Tagausdruck ist auf 20 Tags beschränkt.The tag expression provided to SendTemplateNotificationAsync is limited to 20 tags. Er ist für die meisten Operatoren auf 6 begrenzt, aber der Ausdruck enthält in diesem Fall nur ORs (||).It is limited to 6 for most operators but the expression contains only ORs (||) in this case. Wenn die Anforderung mehr als 20 Tags enthält, muss sie in mehrere Anforderungen aufgeteilt werden.If there are more than 20 tags in the request then they must be split into multiple requests. Weitere Details finden Sie in der Dokumentation Weiterleitung und Tagausdrücke.See the Routing and Tag Expressions documentation for more detail.

  13. Aktualisieren Sie die Methode ConfigureServices in Startup.cs , um NotificationHubsService als Singleton-Implementierung von INotificationService hinzuzufügen.In Startup.cs , update the ConfigureServices method to add the NotificationHubsService as a singleton implementation of INotificationService.

    
    using PushDemoApi.Models;
    using PushDemoApi.Services;
    
    public void ConfigureServices(IServiceCollection services)
    {
        ...
    
        services.AddSingleton<INotificationService, NotificationHubService>();
    
        services.AddOptions<NotificationHubOptions>()
            .Configure(Configuration.GetSection("NotificationHub").Bind)
            .ValidateDataAnnotations();
    }
    

Erstellen der Benachrichtigungen-APICreate the notifications API

  1. CONTROL + Klicken Sie auf den Ordner Controller , und wählen Sie dann Neue Datei... aus dem Menü Hinzufügen aus.Control + Click on the Controllers folder, then choose New File... from the Add menu.

  2. Wählen Sie ASP.NET Core > Web-API-Controller-Klasse aus, geben Sie NotificationsController als Namen ein, und klicken Sie dann auf Neu.Select ASP.NET Core > Web API Controller Class , enter NotificationsController for the Name , then click New.

    Hinweis

    Wenn Sie mit Visual Studio 2019 arbeiten, wählen Sie die Vorlage API-Controller mit Lese-/Schreibaktionen aus.If you're following with Visual Studio 2019, choose the API Controller with read/write actions template.

  3. Fügen Sie am Anfang der Datei die folgenden Namespaces hinzu.Add the following namespaces to the top of the file.

    using System.ComponentModel.DataAnnotations;
    using System.Net;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;
    using PushDemoApi.Models;
    using PushDemoApi.Services;
    
  4. Aktualisieren Sie den vordefinierten Controller so, dass er von ControllerBase abgeleitet und mit dem Attribut ApiController ergänzt wird.Update the templated controller so it derives from ControllerBase and is decorated with the ApiController attribute.

    [ApiController]
    [Route("api/[controller]")]
    public class NotificationsController : ControllerBase
    {
        // Templated methods here
    }
    

    Hinweis

    Die Basisklasse Controller bietet Unterstützung für Ansichten, aber dies ist in diesem Fall nicht erforderlich, sodass stattdessen ControllerBase verwendet werden kann.The Controller base class provides support support for views but this is not needed in this case and so ControllerBase can be used instead. Wenn Sie mit Visual Studio 2019 arbeiten, können Sie diesen Schritt überspringen.If you're following with Visual Studio 2019, you can skip this step.

  5. Wenn Sie entschieden haben, die Schritte im Abschnitt Authentifizieren von Clients mit einem API-Schlüssel durchzuführen, sollten Sie NotificationsController auch mit dem Authorize -Attribut ergänzen.If you chose to complete the Authenticate clients using an API Key section, you should decorate the NotificationsController with the Authorize attribute as well.

    [Authorize]
    
  6. Aktualisieren Sie den Konstruktor so, dass er die registrierte Instanz von INotificationService als Argument akzeptiert, und weisen Sie ihn einem readonly-Member zu.Update the constructor to accept the registered instance of INotificationService as an argument and assign it to a readonly member.

    readonly INotificationService _notificationService;
    
    public NotificationsController(INotificationService notificationService)
    {
        _notificationService = notificationService;
    }
    
  7. Ändern Sie in launchSettings.json (im Ordner Eigenschaften ) die launchUrl von weatherforecast in api/notifications , damit sie mit der im Route -Attribut von RegistrationsController angegebenen URL übereinstimmt.In launchSettings.json (within the Properties folder), change the launchUrl from weatherforecast to api/notifications to match the URL specified in the RegistrationsController Route attribute.

  8. Starten Sie das Debugging ( BEFEHL + EINGABE ), um zu überprüfen, ob die App mit dem neuen NotificationsController funktioniert und den Status 401 – Nicht autorisiert zurückgibt.Start debugging ( Command + Enter ) to validate the app is working with the new NotificationsController and returns a 401 Unauthorized status.

    Hinweis

    Visual Studio startet die App möglicherweise nicht automatisch im Browser.Visual Studio may not automatically launch the app in the browser. Sie verwenden Postman, um die API von diesem Punkt an zu testen.You will use Postman to test the API from this point on.

  9. Legen Sie auf einer neuen Postman -Registerkarte die Anforderung auf GET fest.On a new Postman tab, set the request to GET. Geben Sie die folgende Adresse ein, und ersetzen Sie dabei den Platzhalter <ApplicationUrl> durch die HTTPS- ApplicationUrl unter Eigenschaften > launchSettings.json.Enter the address below replacing the placeholder <applicationUrl> with the https applicationUrl found in Properties > launchSettings.json.

    <applicationUrl>/api/notifications
    

    Hinweis

    Die ApplicationUrl muss für das Standardprofil „https://localhost:5001“ sein.The applicationUrl should be 'https://localhost:5001' for the default profile. Wenn Sie IIS verwenden (Standard in Visual Studio 2019 unter Windows), sollten Sie stattdessen die ApplicationUrl verwenden, die im Element iisSettings angegeben wird.If you're using IIS (default in Visual Studio 2019 on Windows), you should use the applicationUrl specified in the iisSettings item instead. Sie erhalten eine Antwort vom Typ 404, wenn die Adresse falsch ist.You will receive a 404 response if the address is incorrect.

  10. Wenn Sie sich entschieden haben, die Schritte im Abschnitt Authentifizieren von Clients mit einem API-Schlüssel durchzuführen, stellen Sie sicher, dass die Anforderungsheader Ihren apikey -Wert enthalten.If you chose to complete the Authenticate clients using an API Key section, be sure to configure the request headers to include your apikey value.

    SchlüsselKey WertValue
    apikeyapikey <your_api_key><your_api_key>
  11. Klicken Sie auf die Schaltfläche Senden.Click the Send button.

    Hinweis

    Sie sollten einen 200 OK -Status mit einigen JSON -Inhalten erhalten.You should receive a 200 OK status with some JSON content.

    Wenn Sie eine Warnung der SSL-Zertifikatüberprüfung erhalten, können Sie die Postman -Einstellung zum Anfordern der SSL-Zertifikatüberprüfung unter Einstellungen deaktivieren.If you receive an SSL certificate verification warning, you can switch the request SSL certificate verification Postman setting off in the Settings.

  12. Ersetzen Sie die vorlagenbasierten Klassenmethoden in NotificationsController.cs durch den folgenden Code:Replace the templated class methods in NotificationsController.cs with the following code.

    [HttpPut]
    [Route("installations")]
    [ProducesResponseType((int)HttpStatusCode.OK)]
    [ProducesResponseType((int)HttpStatusCode.BadRequest)]
    [ProducesResponseType((int)HttpStatusCode.UnprocessableEntity)]
    public async Task<IActionResult> UpdateInstallation(
        [Required]DeviceInstallation deviceInstallation)
    {
        var success = await _notificationService
            .CreateOrUpdateInstallationAsync(deviceInstallation, HttpContext.RequestAborted);
    
        if (!success)
            return new UnprocessableEntityResult();
    
        return new OkResult();
    }
    
    [HttpDelete()]
    [Route("installations/{installationId}")]
    [ProducesResponseType((int)HttpStatusCode.OK)]
    [ProducesResponseType((int)HttpStatusCode.BadRequest)]
    [ProducesResponseType((int)HttpStatusCode.UnprocessableEntity)]
    public async Task<ActionResult> DeleteInstallation(
        [Required][FromRoute]string installationId)
    {
        var success = await _notificationService
            .DeleteInstallationByIdAsync(installationId, CancellationToken.None);
    
        if (!success)
            return new UnprocessableEntityResult();
    
        return new OkResult();
    }
    
    [HttpPost]
    [Route("requests")]
    [ProducesResponseType((int)HttpStatusCode.OK)]
    [ProducesResponseType((int)HttpStatusCode.BadRequest)]
    [ProducesResponseType((int)HttpStatusCode.UnprocessableEntity)]
    public async Task<IActionResult> RequestPush(
        [Required]NotificationRequest notificationRequest)
    {
        if ((notificationRequest.Silent &&
            string.IsNullOrWhiteSpace(notificationRequest?.Action)) ||
            (!notificationRequest.Silent &&
            string.IsNullOrWhiteSpace(notificationRequest?.Text)))
            return new BadRequestResult();
    
        var success = await _notificationService
            .RequestNotificationAsync(notificationRequest, HttpContext.RequestAborted);
    
        if (!success)
            return new UnprocessableEntityResult();
    
        return new OkResult();
    }
    

Erstellen der API-AppCreate the API app

Sie erstellen jetzt eine API-App in Azure App Service zum Hosten des Back-End-Diensts.You now create an API App in Azure App Service for hosting the backend service.

  1. Melden Sie sich beim Azure-Portal an.Sign in to the Azure portal.

  2. Klicken Sie auf Ressource erstellen , suchen und wählen Sie API-App aus, und klicken Sie dann auf Erstellen.Click Create a resource , then search for and choose API App , then click Create.

  3. Aktualisieren Sie die folgenden Felder, und klicken Sie auf Erstellen.Update the following fields, then click Create.

    App-Name:App name:
    Geben Sie einen global eindeutigen Namen für die API-App ein.Enter a globally unique name for the API App

    Abonnement:Subscription:
    Wählen Sie dasselbe Zielabonnement aus, in dem Sie den Benachrichtigungshub erstellt haben.Choose the same target Subscription you created the notification hub in.

    Ressourcengruppe:Resource Group:
    Wählen Sie dieselbe Ressourcengruppe aus, in der Sie den Benachrichtigungshub erstellt haben.Choose the same Resource Group you created the notification hub in.

    App Service-Plan/Standort:App Service Plan/Location:
    Erstellen Sie einen neuen App Services-PlanCreate a new App Service Plan

    Hinweis

    Wechseln Sie von der Standardoption zu einem Plan, der SSL -Unterstützung umfasst.Change from the default option to a plan that includes SSL support. Andernfalls müssen Sie bei Verwendung der mobilen App die entsprechenden Schritte ausführen, um zu verhindern, dass http -Anforderungen blockiert werden.Otherwise, you will need to take the appropriate steps when working with the mobile app to prevent http requests from getting blocked.

    Application Insights:Application Insights:
    Behalten Sie die vorgeschlagene Option bei (eine neue Ressource wird unter diesem Namen erstellt), oder wählen Sie eine vorhandene Ressource aus.Keep the suggested option (a new resource will be created using that name) or pick an existing resource.

  4. Sobald die API-App bereitgestellt wurde, navigieren Sie zu dieser Ressource.Once the API App has been provisioned, navigate to that resource.

  5. Notieren Sie sich die Eigenschaft URL in der Zusammenfassung Essentials oben in der Übersicht.Make note of the URL property in the Essentials summary at the top of the Overview. Diese URL ist Ihr Back-End-Endpunkt , der später in diesem Tutorial verwendet wird.This URL is your backend endpoint that will be used later in this tutorial.

    Hinweis

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

  6. Wählen Sie die Option Konfiguration aus der Liste aus (unter Einstellungen ).Select Configuration from the list (under Settings ).

  7. Klicken Sie für jede der folgenden Einstellungen auf Neue Anwendungseinstellung , um den Namen und einen Wert einzugeben, und klicken Sie dann auf OK.For each of the settings below, click New application setting to enter the Name and a Value , then click OK.

    NameName WertValue
    Authentication:ApiKey <api_key_value><api_key_value>
    NotificationHub:Name <hub_name_value><hub_name_value>
    NotificationHub:ConnectionString <hub_connection_string_value><hub_connection_string_value>

    Hinweis

    Dies sind die gleichen Einstellungen, die Sie zuvor in den Benutzereinstellungen definiert haben.These are the same settings you defined previously in the user settings. Sie sollten Sie diese kopieren und übernehmen können.You should be able to copy these over. Die Einstellung Authentication:ApiKey ist nur erforderlich, wenn Sie die Schritte im Abschnitt Authentifizieren von Clients mit einem API-Schlüssel durchgeführt haben.The Authentication:ApiKey setting is required only if you chose to to complete the Authenticate clients using an API Key section. In Produktionsszenarien können Sie Optionen wie Azure KeyVault in Betracht ziehen.For production scenarios, you can look at options such as Azure KeyVault. Diese wurden in diesem Fall der Einfachheit halber als Anwendungseinstellungen hinzugefügt.These have been added as application settings for simplicity in this case.

  8. Sobald alle Anwendungseinstellungen hinzugefügt wurden, klicken Sie auf Speichern und dann auf Fortsetzen.Once all application settings have been added click Save , then Continue.

Veröffentlichen des Back-End-DienstsPublish the backend service

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

Hinweis

Die folgenden Schritte gelten speziell für Visual Studio für Mac.The following steps are specific to Visual Studio for Mac. Wenn Sie mit Visual Studio 2019 unter Windows arbeiten, ist der Veröffentlichungsfluss anders.If you're following with Visual Studio 2019 on Windows, the publishing flow will be different. Weitere Informationen dazu finden Sie unter Veröffentlichen in Azure App Service unter Windows.See Publish to Azure App Service on Windows.

  1. Ändern Sie die Konfiguration von Debuggen in Release , wenn Sie dies noch nicht getan haben.Change your configuration from Debug to Release if you haven't already done so.

  2. CONTROL + Klicken Sie auf das Projekt PushDemoApi , und wählen Sie dann In Azure veröffentlichen... aus dem Menü Veröffentlichen aus.Control + Click the PushDemoApi project, and then choose Publish to Azure... from the Publish menu.

  3. Befolgen Sie den Authentifizierungsflow, wenn Sie dazu aufgefordert werden.Follow the auth flow if prompted to do so. Verwenden Sie das Konto, das Sie im vorigen Abschnitt Erstellen der API-App verwendet haben.Use the account that you used in the previous create the API App section.

  4. Wählen Sie die zuvor erstellte Azure App Service-API-App aus der Liste als Ihr Veröffentlichungsziel aus, und klicken Sie dann auf Veröffentlichen.Select the Azure App Service API App you created previously from the list as your publish target, and then click Publish.

Nach Abschluss des Assistenten wird die App in Azure veröffentlicht und anschließend geöffnet.After you've completed the wizard, it publishes the app to Azure and then opens the app. Notieren Sie sich die URL , wenn Sie dies noch nicht getan haben.Make a note of the URL if you haven't done so already. Diese URL ist Ihr Back-End-Endpunkt , der später in diesem Tutorial verwendet wird.This URL is your backend endpoint that is used later in this tutorial.

Überprüfen der veröffentlichten APIValidating the published API

  1. Öffnen Sie auf der Registerkarte Postman eine neue Registerkarte, legen Sie die Anforderung auf PUT fest, und geben Sie die Adresse unten ein.In Postman open a new tab, set the request to PUT and enter the address below. Ersetzen Sie den Platzhalter durch die Basisadresse, die Sie im vorherigen Abschnitt Veröffentlichung des Back-End-Diensts notiert haben.Replace the placeholder with the base address you made note of in the previous publish the backend service section.

    https://<app_name>.azurewebsites.net/api/notifications/installations
    

    Hinweis

    Die Basisadresse muss das Format folgende aufweisen: https://<app_name>.azurewebsites.net/The base address should be in the format https://<app_name>.azurewebsites.net/

  2. Wenn Sie sich entschieden haben, die Schritte im Abschnitt Authentifizieren von Clients mit einem API-Schlüssel durchzuführen, stellen Sie sicher, dass die Anforderungsheader Ihren apikey -Wert enthalten.If you chose to complete the Authenticate clients using an API Key section, be sure to configure the request headers to include your apikey value.

    SchlüsselKey WertValue
    apikeyapikey <your_api_key><your_api_key>
  3. Wählen Sie die Option raw für den Text aus, wählen Sie dann JSON aus der Liste der Formatoptionen aus, und fügen Sie anschließend JSON -Platzhalterinhalt ein:Choose the raw option for the Body , then choose JSON from the list of format options, and then include some placeholder JSON content:

    {}
    
  4. Klicken Sie auf Send.Click Send.

    Hinweis

    Sie sollten eine Statusmeldung 422 UnprocessableEntity vom Dienst erhalten.You should receive a 422 UnprocessableEntity status from the service.

  5. Führen Sie die Schritte 1 bis 4 noch einmal aus, aber dieses Mal erhalten Sie bei Angabe des zu validierenden Anforderungsendpunkts eine Antwort 400 Bad Request (Ungültige Anforderung).Do steps 1-4 again but this time specifying the requests endpoint to validate you receive a 400 Bad Request response.

    https://<app_name>.azurewebsites.net/api/notifications/requests
    

Hinweis

Es ist noch nicht möglich, die API mit gültigen Anforderungsdaten zu testen, da hierfür plattformspezifische Informationen von der mobilen Client-App erforderlich sind.It is not yet possible to test the API using valid request data since this will require platform-specific information from the client mobile app.

Erstellen einer plattformübergreifenden Xamarin.Forms-AnwendungCreate a cross-platform Xamarin.Forms application

In diesem Abschnitt erstellen Sie eine mobile Xamarin.Forms-Anwendung, die Pushbenachrichtigungen plattformübergreifend implementiert.In this section, you build a Xamarin.Forms mobile application implementing push notifications in a cross-platform manner.

Es ermöglicht Ihnen die Registrierung und die Aufhebung der Registrierung von einem Benachrichtigungshub über den von Ihnen erstellten Back-End-Dienst.It enables you to register and deregister from a notification hub via the backend service that you created.

Wird eine Aktion angegeben, und befindet sich die Anwendung im Vordergrund, wird ein Alarm angezeigt.An alert is displayed when an action is specified and the app is in the foreground. Andernfalls erscheinen die Benachrichtigungen in der Mitteilungszentrale.Otherwise, notifications appear in notification center.

Hinweis

Normalerweise würden Sie die Aktionen zur Registrierung und Aufhebung der Registrierung während des entsprechenden Zeitpunkts im Lebenszyklus der Anwendung (oder vielleicht als Teil Ihres Eindrucks beim ersten Ausführen der Anwendung) ohne explizite Eingaben zur Registrierung/Aufhebung der Registrierung des Benutzers durchführen.You would typically perform the registration (and deregistration) actions during the appropriate point in the application lifecycle (or as part of your first-run experience perhaps) without explicit user register/deregister inputs. Dieses Beispiel erfordert jedoch eine explizite Benutzereingabe, damit diese Funktionalität leichter untersucht und getestet werden kann.However, this example will require explicit user input to allow this functionality to be explored and tested more easily.

Erstellen der Xamarin.Forms-LösungCreate the Xamarin.Forms solution

  1. Erstellen Sie in Visual Studio eine neue Xamarin.Forms-Lösung, wobei Sie die Leere Forms-App als Vorlage verwenden und PushDemo als Projektnamen eingeben.In Visual Studio, create a new Xamarin.Forms solution using Blank Forms App as the template and entering PushDemo for the Project Name.

    Hinweis

    Vergewissern Sie sich im Dialogfeld Leere Forms-App konfigurieren, dass der Organisationsbezeichner mit dem zuvor verwendeten Wert übereinstimmt und dass sowohl Android als auch iOS als Ziele aktiviert sind.In the Configure your Blank Forms App dialog, ensure the Organization Identifier matches the value you used previously and that both Android and iOS targets are checked.

  2. CONTROL + Klicken Sie auf die PushDemo-Lösung, und wählen Sie dann NuGet-Pakete aktualisieren aus.Control + Click on the PushDemo solution, then choose Update NuGet Packages.

  3. CONTROL + Klicken Sie auf die PushDemo-Lösung, und wählen Sie dann NuGet-Pakete verwalten aus.Control + Click on the PushDemo solution, then choose Manage NuGet Packages...

  4. Suchen Sie nach Newtonsoft.Json, und stellen Sie sicher, dass es aktiviert ist.Search for Newtonsoft.Json and ensure it's checked.

  5. Klicken Sie auf Pakete hinzufügen und dann auf Zustimmen, wenn Sie aufgefordert werden, die Lizenzbedingungen zu akzeptieren.Click Add Packages, then click Accept when prompted to accept the license terms.

  6. Erstellen Sie die App, und führen Sie sie auf jeder Zielplattform aus (BEFEHL + EINGABE), um zu testen, ob die auf der Vorlage basierende App auf Ihren Geräten ausgeführt wird.Build and run the app on each target platform (Command + Enter) to test the templated app runs on your device(s).

Implementieren der plattformübergreifenden KomponentenImplement the cross-platform components

  1. CONTROL + Klicken Sie auf das Projekt PushDemo, wählen Sie Neuer Ordner aus dem Menü Hinzufügen aus, und klicken Sie dann auf Hinzufügen. Verwenden Sie dabei Modelle als Ordnernamen.Control + Click on the PushDemo project, choose New Folder from the Add menu, then click Add using Models as the Folder Name.

  2. CONTROL + Klicken Sie auf den Ordner Modelle, und wählen Sie dann Neue Datei... aus dem Menü Hinzufügen aus.Control + Click on the Models folder, then choose New File... from the Add menu.

  3. Wählen Sie Allgemein > Leere Klasse aus, geben Sie DeviceInstallation.cs ein, und fügen Sie dann die folgende Implementierung hinzu.Select General > Empty Class, enter DeviceInstallation.cs, then add the following implementation.

    using System.Collections.Generic;
    using Newtonsoft.Json;
    
    namespace PushDemo.Models
    {
        public class DeviceInstallation
        {
            [JsonProperty("installationId")]
            public string InstallationId { get; set; }
    
            [JsonProperty("platform")]
            public string Platform { get; set; }
    
            [JsonProperty("pushChannel")]
            public string PushChannel { get; set; }
    
            [JsonProperty("tags")]
            public List<string> Tags { get; set; } = new List<string>();
        }
    }
    
  4. Fügen Sie eine leere Aufzählung namens PushDemoAction.cs mit der folgenden Implementierung zum Ordner Modelle hinzu.Add an Empty Enumeration to the Models folder called PushDemoAction.cs with the following implementation.

    namespace PushDemo.Models
    {
        public enum PushDemoAction
        {
            ActionA,
            ActionB
        }
    }
    
  5. Fügen Sie einen neuen Ordner mit dem Namen Dienste zum Projekt PushDemo hinzu, und fügen Sie diesem Ordner dann eine leere Klasse namens ServiceContainer.cs mit der folgenden Implementierung hinzu.Add a new folder to the PushDemo project called Services then add an Empty Class to that folder called ServiceContainer.cs with the following implementation.

    using System;
    using System.Collections.Generic;
    
    namespace PushDemo.Services
    {
       public static class ServiceContainer
       {
           static readonly Dictionary<Type, Lazy<object>> services
               = new Dictionary<Type, Lazy<object>>();
    
           public static void Register<T>(Func<T> function)
               => services[typeof(T)] = new Lazy<object>(() => function());
    
           public static T Resolve<T>()
               => (T)Resolve(typeof(T));
    
           public static object Resolve(Type type)
           {
               {
                   if (services.TryGetValue(type, out var service))
                       return service.Value;
    
                   throw new KeyNotFoundException($"Service not found for type '{type}'");
               }
           }
       }
    }
    

    Hinweis

    Dies ist eine abgespeckte Version der Klasse ServiceContainer aus dem XamCAT-Repository.This is a trimmed-down version of the ServiceContainer class from the XamCAT repository. Sie wird als ein Lightweight-IoC-Container (Inversion of Control) verwendet.It will be used as a light-weight IoC (Inversion of Control) container.

  6. Fügen Sie zum Ordner Dienste eine leere Schnittstelle namens IDeviceInstallationService.cs hinzu, und fügen Sie dann den folgenden Code hinzu.Add an Empty Interface to the Services folder called IDeviceInstallationService.cs, then add the following code.

    using PushDemo.Models;
    
    namespace PushDemo.Services
    {
        public interface IDeviceInstallationService
        {
            string Token { get; set; }
            bool NotificationsSupported { get; }
            string GetDeviceId();
            DeviceInstallation GetDeviceInstallation(params string[] tags);
        }
    }
    

    Hinweis

    Diese Schnittstelle wird später von jedem Ziel implementiert und über Bootstrapping geladen, um die plattformspezifische Funktionalität und die erforderlichen DeviceInstallation-Informationen bereitzustellen, die vom Back-End-Dienst benötigt werden.This interface will be implemented and bootstrapped by each target later to provide the platform-specific functionality and DeviceInstallation information required by the backend service.

  7. Fügen Sie zum Ordner Dienste eine weitere leere Schnittstelle namens INotificationRegistrationService.cs hinzu, und fügen Sie dann den folgenden Code hinzu.Add another Empty Interface to the Services folder called INotificationRegistrationService.cs, then add the following code.

    using System.Threading.Tasks;
    
    namespace PushDemo.Services
    {
        public interface INotificationRegistrationService
        {
            Task DeregisterDeviceAsync();
            Task RegisterDeviceAsync(params string[] tags);
            Task RefreshRegistrationAsync();
        }
    }
    

    Hinweis

    Dadurch wird die Interaktion zwischen dem Client und dem Back-End-Dienst behandelt.This will handle the interaction between the client and backend service.

  8. Fügen Sie zum Ordner Dienste eine weitere leere Schnittstelle namens INotificationActionService.cs hinzu, und fügen Sie dann den folgenden Code hinzu.Add another Empty Interface to the Services folder called INotificationActionService.cs, then add the following code.

    namespace PushDemo.Services
    {
        public interface INotificationActionService
        {
            void TriggerAction(string action);
        }
    }
    

    Hinweis

    Dieser einfache Mechanismus dient dazu, die Behandlung von Benachrichtigungsaktionen zu zentralisieren.This is used as a simple mechanism to centralize the handling of notification actions.

  9. Fügen Sie dem Ordner Dienste eine leere Schnittstelle namens IPushDemoNotificationActionService.cs hinzu, die von INotificationActionService abgeleitet ist, mit der folgenden Implementierung.Add an Empty Interface to the Services folder called IPushDemoNotificationActionService.cs that derives from the INotificationActionService, with the following implementation.

    using System;
    using PushDemo.Models;
    
    namespace PushDemo.Services
    {
        public interface IPushDemoNotificationActionService : INotificationActionService
        {
            event EventHandler<PushDemoAction> ActionTriggered;
        }
    }
    

    Hinweis

    Dieser Typ ist für die Anwendung PushDemo spezifisch und verwendet die PushDemoAction-Enumeration, um die Aktion zu identifizieren, die in stark typisierter Weise ausgelöst wird.This type is specific to the PushDemo application and uses the PushDemoAction enumeration to identify the action that is being triggered in a strongly-typed manner.

  10. Fügen Sie zum Ordner Dienste eine leere Klasse namens NotificationRegistrationService.cs hinzu, und implementieren Sie INotificationRegistrationService mit dem folgenden Code.Add an Empty Class to the Services folder called NotificationRegistrationService.cs implementing the INotificationRegistrationService with the following code.

    using System;
    using System.Net.Http;
    using System.Text;
    using System.Threading.Tasks;
    using Newtonsoft.Json;
    using PushDemo.Models;
    using Xamarin.Essentials;
    
    namespace PushDemo.Services
    {
        public class NotificationRegistrationService : INotificationRegistrationService
        {
            const string RequestUrl = "api/notifications/installations";
            const string CachedDeviceTokenKey = "cached_device_token";
            const string CachedTagsKey = "cached_tags";
    
            string _baseApiUrl;
            HttpClient _client;
            IDeviceInstallationService _deviceInstallationService;
    
            public NotificationRegistrationService(string baseApiUri, string apiKey)
            {
                _client = new HttpClient();
                _client.DefaultRequestHeaders.Add("Accept", "application/json");
                _client.DefaultRequestHeaders.Add("apikey", apiKey);
    
                _baseApiUrl = baseApiUri;
            }
    
            IDeviceInstallationService DeviceInstallationService
                => _deviceInstallationService ??
                    (_deviceInstallationService = ServiceContainer.Resolve<IDeviceInstallationService>());
    
            public async Task DeregisterDeviceAsync()
            {
                var cachedToken = await SecureStorage.GetAsync(CachedDeviceTokenKey)
                    .ConfigureAwait(false);
    
                if (cachedToken == null)
                    return;
    
                var deviceId = DeviceInstallationService?.GetDeviceId();
    
                if (string.IsNullOrWhiteSpace(deviceId))
                    throw new Exception("Unable to resolve an ID for the device.");
    
                await SendAsync(HttpMethod.Delete, $"{RequestUrl}/{deviceId}")
                    .ConfigureAwait(false);
    
                SecureStorage.Remove(CachedDeviceTokenKey);
                SecureStorage.Remove(CachedTagsKey);
            }
    
            public async Task RegisterDeviceAsync(params string[] tags)
            {
                var deviceInstallation = DeviceInstallationService?.GetDeviceInstallation(tags);
    
                await SendAsync<DeviceInstallation>(HttpMethod.Put, RequestUrl, deviceInstallation)
                    .ConfigureAwait(false);
    
                await SecureStorage.SetAsync(CachedDeviceTokenKey, deviceInstallation.PushChannel)
                    .ConfigureAwait(false);
    
                await SecureStorage.SetAsync(CachedTagsKey, JsonConvert.SerializeObject(tags));
            }
    
            public async Task RefreshRegistrationAsync()
            {
                var cachedToken = await SecureStorage.GetAsync(CachedDeviceTokenKey)
                    .ConfigureAwait(false);
    
                var serializedTags = await SecureStorage.GetAsync(CachedTagsKey)
                    .ConfigureAwait(false);
    
                if (string.IsNullOrWhiteSpace(cachedToken) ||
                    string.IsNullOrWhiteSpace(serializedTags) ||
                    string.IsNullOrWhiteSpace(DeviceInstallationService.Token) ||
                    cachedToken == DeviceInstallationService.Token)
                    return;
    
                var tags = JsonConvert.DeserializeObject<string[]>(serializedTags);
    
                await RegisterDeviceAsync(tags);
            }
    
            async Task SendAsync<T>(HttpMethod requestType, string requestUri, T obj)
            {
                string serializedContent = null;
    
                await Task.Run(() => serializedContent = JsonConvert.SerializeObject(obj))
                    .ConfigureAwait(false);
    
                await SendAsync(requestType, requestUri, serializedContent);
            }
    
            async Task SendAsync(
                HttpMethod requestType,
                string requestUri,
                string jsonRequest = null)
            {
                var request = new HttpRequestMessage(requestType, new Uri($"{_baseApiUrl}{requestUri}"));
    
                if (jsonRequest != null)
                    request.Content = new StringContent(jsonRequest, Encoding.UTF8, "application/json");
    
                var response = await _client.SendAsync(request).ConfigureAwait(false);
    
                response.EnsureSuccessStatusCode();
            }
        }
    }
    

    Hinweis

    Das Argument apiKey ist nur erforderlich, wenn Sie sich entschieden haben, die Schritte im Abschnitt Authentifizieren von Clients mit einem API-Schlüssel durchzuführen.The apiKey argument is only required if you chose to complete the Authenticate clients using an API Key section.

  11. Fügen Sie zum Ordner Dienste eine leere Klasse namens PushDemoNotificationActionService.cs hinzu, und implementieren Sie IPushDemoNotificationActionService mit dem folgenden Code.Add an Empty Class to the Services folder called PushDemoNotificationActionService.cs implementing the IPushDemoNotificationActionService with the following code.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using PushDemo.Models;
    
    namespace PushDemo.Services
    {
        public class PushDemoNotificationActionService : IPushDemoNotificationActionService
        {
            readonly Dictionary<string, PushDemoAction> _actionMappings = new Dictionary<string, PushDemoAction>
            {
                { "action_a", PushDemoAction.ActionA },
                { "action_b", PushDemoAction.ActionB }
            };
    
            public event EventHandler<PushDemoAction> ActionTriggered = delegate { };
    
            public void TriggerAction(string action)
            {
                if (!_actionMappings.TryGetValue(action, out var pushDemoAction))
                    return;
    
                List<Exception> exceptions = new List<Exception>();
    
                foreach (var handler in ActionTriggered?.GetInvocationList())
                {
                    try
                    {
                        handler.DynamicInvoke(this, pushDemoAction);
                    }
                    catch (Exception ex)
                    {
                        exceptions.Add(ex);
                    }
                }
    
                if (exceptions.Any())
                    throw new AggregateException(exceptions);
            }
        }
    }
    
  12. Fügen Sie zum Projekt PushDemo eine leere Klasse namens Config.cs mit der folgenden Implementierung hinzu.Add an Empty Class to the PushDemo project called Config.cs with the following implementation.

    namespace PushDemo
    {
        public static partial class Config
        {
            public static string ApiKey = "API_KEY";
            public static string BackendServiceEndpoint = "BACKEND_SERVICE_ENDPOINT";
        }
    }
    

    Hinweis

    Diese einfache Methode dient dazu, geheime Schlüssen aus der Quellcodeverwaltung herauszuhalten.This is used as a simple way to keep secrets out of source control. Sie können diese Werte als Teil eines automatisierten Builds ersetzen oder durch eine lokale Teilklasse überschreiben.You can replace these values as part of an automated build or override them using a local partial class. Dieses Verfahren wird im nächsten Schritt behandelt.You will do this in the next step.

    Das Feld ApiKey ist nur erforderlich, wenn Sie sich entschieden haben, die Schritte im Abschnitt Authentifizieren von Clients mit einem API-Schlüssel durchzuführen.The ApiKey field is only required if you chose to complete the Authenticate clients using an API Key section.

  13. Fügen Sie zum Projekt PushDemo eine weitere leere Klasse, dieses Mal mit dem Namen Config.local_secrets.cs und der folgenden Implementierung hinzu.Add another Empty Class to the PushDemo project this time called Config.local_secrets.cs with the following implementation.

    namespace PushDemo
    {
        public static partial class Config
        {
            static Config()
            {
                ApiKey = "<your_api_key>";
                BackendServiceEndpoint = "<your_api_app_url>";
            }
        }
    }
    

    Hinweis

    Ersetzen Sie die Platzhalterwerte durch eigene Werte.Replace the placeholder values with your own. Sie sollten sich diese bei der Erstellung des Back-End-Diensts notiert haben.You should have made a note of these when you built the backend service. Die API-App-URL sollte https://<api_app_name>.azurewebsites.net/ lauten.The API App URL should be https://<api_app_name>.azurewebsites.net/. Denken Sie daran, ihrer gitignore-Datei *.local_secrets.* hinzuzufügen, um das Committen dieser Datei zu vermeiden.Remember to add *.local_secrets.* to your gitignore file to avoid committing this file.

    Das Feld ApiKey ist nur erforderlich, wenn Sie sich entschieden haben, die Schritte im Abschnitt Authentifizieren von Clients mit einem API-Schlüssel durchzuführen.The ApiKey field is only required if you chose to complete the Authenticate clients using an API Key section.

  14. Fügen Sie zum Projekt PushDemo eine leere Klasse namens Bootstrap.cs mit der folgenden Implementierung hinzu.Add an Empty Class to the PushDemo project called Bootstrap.cs with the following implementation.

    using System;
    using PushDemo.Services;
    
    namespace PushDemo
    {
        public static class Bootstrap
        {
            public static void Begin(Func<IDeviceInstallationService> deviceInstallationService)
            {
                ServiceContainer.Register(deviceInstallationService);
    
                ServiceContainer.Register<IPushDemoNotificationActionService>(()
                    => new PushDemoNotificationActionService());
    
                ServiceContainer.Register<INotificationRegistrationService>(()
                    => new NotificationRegistrationService(
                        Config.BackendServiceEndpoint,
                        Config.ApiKey));
            }
        }
    }
    

    Hinweis

    Die Methode Begin wird von jeder Plattform aufgerufen, wenn die App unter Übergabe einer plattformspezifischen Implementierung von IDeviceInstallationService gestartet wird.The Begin method will be called by each platform when the app launches passing in a platform-specific implementation of IDeviceInstallationService.

    Das NotificationRegistrationService apiKey-Konstruktorargument ist nur erforderlich, wenn Sie sich entschieden haben, die Schritte im Abschnitt Authentifizieren von Clients mit einem API-Schlüssel durchzuführen.The NotificationRegistrationService apiKey constructor argument is only required if you chose to complete the Authenticate clients using an API Key section.

Implementieren der plattformübergreifenden BenutzeroberflächeImplement the cross-platform UI

  1. Öffnen Sie im Projekt PushDemo die Datei MainPage.xaml, und ersetzen Sie das Steuerelement StackLayout durch Folgendes.In the PushDemo project, open MainPage.xaml and replace the StackLayout control with the following.

    <StackLayout VerticalOptions="EndAndExpand"  
                 HorizontalOptions="FillAndExpand"
                 Padding="20,40">
        <Button x:Name="RegisterButton"
                Text="Register"
                Clicked="RegisterButtonClicked" />
        <Button x:Name="DeregisterButton"
                Text="Deregister"
                Clicked="DeregisterButtonClicked" />
    </StackLayout>
    
  2. Fügen Sie nun in MainPage.xaml.cs ein readonly-Unterstützungsfeld zum Speichern eines Verweises auf die Implementierung INotificationRegistrationService hinzu.Now in MainPage.xaml.cs, add a readonly backing field to store a reference to the INotificationRegistrationService implementation.

    readonly INotificationRegistrationService _notificationRegistrationService;
    
  3. Lösen Sie im MainPage-Konstruktor die INotificationRegistrationService-Implementierung unter Verwendung von ServiceContainer auf, und weisen Sie sie dem notificationRegistrationService-Unterstützungsfeld zu.In the MainPage constructor, resolve the INotificationRegistrationService implementation using the ServiceContainer and assign it to the notificationRegistrationService backing field.

    public MainPage()
    {
        InitializeComponent();
    
        _notificationRegistrationService =
            ServiceContainer.Resolve<INotificationRegistrationService>();
    }
    
  4. Implementieren Sie die Ereignishandler für die Clicked-Ereignisse der Schaltflächen RegisterButton und DeregisterButton, die die entsprechenden Register/Deregister-Methoden aufrufen.Implement the event handlers for the RegisterButton and DeregisterButton buttons Clicked events calling the corresponding Register/Deregister methods.

    void RegisterButtonClicked(object sender, EventArgs e)
        => _notificationRegistrationService.RegisterDeviceAsync().ContinueWith((task)
            => { ShowAlert(task.IsFaulted ?
                    task.Exception.Message :
                    $"Device registered"); });
    
    void DeregisterButtonClicked(object sender, EventArgs e)
        => _notificationRegistrationService.DeregisterDeviceAsync().ContinueWith((task)
            => { ShowAlert(task.IsFaulted ?
                    task.Exception.Message :
                    $"Device deregistered"); });
    
    void ShowAlert(string message)
        => MainThread.BeginInvokeOnMainThread(()
            => DisplayAlert("PushDemo", message, "OK").ContinueWith((task)
                => { if (task.IsFaulted) throw task.Exception; }));
    
  5. Stellen Sie nun sicher, dass in App.xaml.cs auf die folgenden Namespaces verwiesen wird.Now in App.xaml.cs, ensure the following namespaces are referenced.

    using PushDemo.Models;
    using PushDemo.Services;
    using Xamarin.Essentials;
    using Xamarin.Forms;
    
  6. Implementieren Sie den Ereignishandler für das ActionTriggered-Ereignis von IPushDemoNotificationActionService.Implement the event handler for the IPushDemoNotificationActionService ActionTriggered event.

    void NotificationActionTriggered(object sender, PushDemoAction e)
        => ShowActionAlert(e);
    
    void ShowActionAlert(PushDemoAction action)
        => MainThread.BeginInvokeOnMainThread(()
            => MainPage?.DisplayAlert("PushDemo", $"{action} action received", "OK")
                .ContinueWith((task) => { if (task.IsFaulted) throw task.Exception; }));
    
  7. Lösen Sie im App-Konstruktor die IPushNotificationActionService-Implementierung mithilfe von ServiceContainer auf, und abonnieren Sie das ActionTriggered-Ereignis von IPushDemoNotificationActionService.In the App constructor, resolve the IPushNotificationActionService implementation using the ServiceContainer and subscribe to the IPushDemoNotificationActionService ActionTriggered event.

    public App()
    {
        InitializeComponent();
    
        ServiceContainer.Resolve<IPushDemoNotificationActionService>()
            .ActionTriggered += NotificationActionTriggered;
    
        MainPage = new MainPage();
    }
    

    Hinweis

    Dies soll lediglich den Empfang und die Weitergabe von Pushbenachrichtigungsaktionen veranschaulichen.This is simply to demonstrate the receipt and propagation of push notification actions. Diese werden in der Regel im Hintergrund behandelt, z. B. wenn Sie zu einer bestimmten Ansicht navigieren oder einige Daten aktualisieren, anstatt eine Warnung über die Stammseite (in diesem Fall MainPage) anzuzeigen.Typically, these would be handled silently for example navigating to a specific view or refreshing some data rather than displaying an alert via the root Page, MainPage in this case.

Konfigurieren des nativen Android-Projekts für PushbenachrichtigungenConfigure the native Android project for push notifications

Überprüfen von Paketname und BerechtigungenValidate package name and permissions

  1. Öffnen Sie in PushDemo.Android die Projektoptionen und dann Android-Anwendung aus dem Abschnitt Build.In PushDemo.Android, open the Project Options then Android Application from the Build section.

  2. Überprüfen Sie, ob der Paketname mit dem Wert übereinstimmt, den Sie im PushDemo-Projekt der Firebase-Konsole verwendet haben.Check that the Package name matches the value you used in the Firebase Console PushDemo project. Der Paketname wies das Format com.<organization>.pushdemo auf.The Package name was in the format com.<organization>.pushdemo.

  3. Legen Sie die Minimale Android-Version auf Android 8.0 (API-Ebene 26) und die Android-Zielversion auf die neueste API-Ebene fest.Set the Minimum Android Version to Android 8.0 (API level 26) and the Target Android Version to the latest API level.

    Hinweis

    Für die Zwecke dieses Tutorials werden nur Geräte mit API-Ebene 26 und höher unterstützt. Sie können diese Einstellung jedoch erweitern, um Geräte mit älteren Versionen zu unterstützen.Only those devices running API level 26 and above are supported for the purposes of this tutorial however you can extend it to support devices running older versions.

  4. Stellen Sie sicher, dass die Berechtigungen INTERNET und READ_PHONE_STATE unter Erforderliche Berechtigungen aktiviert sind.Ensure the INTERNET and READ_PHONE_STATE permissions are enabled under Required permissions.

  5. Klicken Sie auf OKClick OK

Hinzufügen der Pakete „Xamarin Google Play Services Base“ und „Xamarin.Firebase.Messaging“Add the Xamarin Google Play Services base and Xamarin.Firebase.Messaging packages

  1. CONTROL + Klicken Sie in PushDemo.Android auf den Ordner Pakete, und wählen Sie dann NuGet-Pakete verwalten... aus.In PushDemo.Android, Control + Click on the Packages folder, then choose Manage NuGet Packages....

  2. Suchen Sie nach Xamarin.GooglePlayServices.Base (nicht Basement), und stellen Sie sicher, dass es aktiviert ist.Search for Xamarin.GooglePlayServices.Base (not Basement) and ensure it's checked.

  3. Suchen Sie nach Xamarin.Firebase.Messaging, und stellen Sie sicher, dass es aktiviert ist.Search for Xamarin.Firebase.Messaging and ensure it's checked.

  4. Klicken Sie auf Pakete hinzufügen dann auf Zustimmen, wenn Sie aufgefordert werden, die Lizenzbedingungen zu akzeptieren.Click Add Packages, then click Accept when prompted to accept the license terms.

Hinzufügen der JSON-Datei von Google ServicesAdd the Google Services JSON file

  1. CONTROL + Klicken Sie auf das Projekt PushDemo.Android, und wählen Sie dann Vorhandene Datei... aus dem Menü Hinzufügen aus.Control + Click on the PushDemo.Android project, then choose Existing File... from the Add menu.

  2. Wählen Sie die Datei google-services.json aus, die Sie zuvor beim Einrichten des PushDemo-Projekts in der Firebase-Konsole heruntergeladen haben, und klicken Sie dann auf Öffnen.Choose the google-services.json file you downloaded earlier when you set up the PushDemo project in the Firebase Console then click Open.

  3. Wenn Sie dazu aufgefordert werden, kopieren Sie die Datei in das Verzeichnis.When prompted, choose to Copy the file to the directory.

  4. CONTROL + Klicken Sie aus dem PushDemo.Android-Projekt heraus auf die Datei google-services.json, und stellen Sie dann sicher, dass GoogleServicesJson als Build-Aktion festgelegt ist.Control + Click on the google-services.json file from within the PushDemo.Android project, then ensure GoogleServicesJson is set as the Build Action.

Behandeln von Pushbenachrichtigungen für AndroidHandle push notifications for Android

  1. CONTROL + Klicken Sie auf das Projekt PushDemo.Android, wählen Sie Neuer Ordner aus dem Menü Hinzufügen aus, und klicken Sie dann auf Hinzufügen. Verwenden Sie dabei Dienste als Ordnernamen.Control + Click on the PushDemo.Android project, choose New Folder from the Add menu, then click Add using Services as the Folder Name.

  2. CONTROL + Klicken Sie auf den Ordner Dienste, und wählen Sie dann Neue Datei... aus dem Menü Hinzufügen aus.Control + Click on the Services folder, then choose New File... from the Add menu.

  3. Wählen Sie Allgemein > Leere Klassen aus, geben Sie DeviceInstallationService.cs als Namen ein, und klicken Sie dann auf Neu unter Hinzufügung der folgenden Implementierung.Select General > Empty Class, enter DeviceInstallationService.cs for the Name, then click New adding the following implementation.

    using System;
    using Android.App;
    using Android.Gms.Common;
    using PushDemo.Models;
    using PushDemo.Services;
    using static Android.Provider.Settings;
    
    namespace PushDemo.Droid.Services
    {
        public class DeviceInstallationService : IDeviceInstallationService
        {
            public string Token { get; set; }
    
            public bool NotificationsSupported
                => GoogleApiAvailability.Instance
                    .IsGooglePlayServicesAvailable(Application.Context) == ConnectionResult.Success;
    
            public string GetDeviceId()
                => Secure.GetString(Application.Context.ContentResolver, Secure.AndroidId);
    
            public DeviceInstallation GetDeviceInstallation(params string[] tags)
            {
                if (!NotificationsSupported)
                    throw new Exception(GetPlayServicesError());
    
                if (string.isNullOrWhitespace(Token))
                    throw new Exception("Unable to resolve token for FCM");
    
                var installation = new DeviceInstallation
                {
                    InstallationId = GetDeviceId(),
                    Platform = "fcm",
                    PushChannel = Token
                };
    
                installation.Tags.AddRange(tags);
    
                return installation;
            }
    
            string GetPlayServicesError()
            {
                int resultCode = GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(Application.Context);
    
                if (resultCode != ConnectionResult.Success)
                    return GoogleApiAvailability.Instance.IsUserResolvableError(resultCode) ?
                               GoogleApiAvailability.Instance.GetErrorString(resultCode) :
                               "This device is not supported";
    
                return "An error occurred preventing the use of push notifications";
            }
        }
    }
    

    Hinweis

    Diese Klasse bietet eine eindeutige ID (unter Verwendung von Secure.AndroidId) als Teil der Nutzlast der Benachrichtigungshubregistrierung.This class provides a unique ID (using Secure.AndroidId) as part of the notification hub registration payload.

  4. Fügen Sie dem Ordner Dienste mit dem Namen PushNotificationFirebaseMessagingService.cs eine weitere leere Klasse hinzu, und fügen Sie dann die folgende Implementierung hinzu.Add another Empty Class to the Services folder called PushNotificationFirebaseMessagingService.cs, then add the following implementation.

    using Android.App;
    using Android.Content;
    using Firebase.Messaging;
    using PushDemo.Services;
    
    namespace PushDemo.Droid.Services
    {
        [Service]
        [IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
        public class PushNotificationFirebaseMessagingService : FirebaseMessagingService
        {
            IPushDemoNotificationActionService _notificationActionService;
            INotificationRegistrationService _notificationRegistrationService;
            IDeviceInstallationService _deviceInstallationService;
    
            IPushDemoNotificationActionService NotificationActionService
                => _notificationActionService ??
                    (_notificationActionService =
                    ServiceContainer.Resolve<IPushDemoNotificationActionService>());
    
            INotificationRegistrationService NotificationRegistrationService
                => _notificationRegistrationService ??
                    (_notificationRegistrationService =
                    ServiceContainer.Resolve<INotificationRegistrationService>());
    
            IDeviceInstallationService DeviceInstallationService
                => _deviceInstallationService ??
                    (_deviceInstallationService =
                    ServiceContainer.Resolve<IDeviceInstallationService>());
    
            public override void OnNewToken(string token)
            {
                DeviceInstallationService.Token = token;
    
                NotificationRegistrationService.RefreshRegistrationAsync()
                    .ContinueWith((task) => { if (task.IsFaulted) throw task.Exception; });
            }
    
            public override void OnMessageReceived(RemoteMessage message)
            {
                if(message.Data.TryGetValue("action", out var messageAction))
                    NotificationActionService.TriggerAction(messageAction);
            }
        }
    }
    
  5. Stellen Sie in MainActivity.cs sicher, dass am Anfang der Datei die folgenden Namespaces hinzugefügt wurden.In MainActivity.cs, ensure the following namespaces have been added to the top of the file.

    using System;
    using Android.App;
    using Android.Content;
    using Android.Content.PM;
    using Android.OS;
    using Android.Runtime;
    using Firebase.Iid;
    using PushDemo.Droid.Services;
    using PushDemo.Services;
    
  6. Legen Sie in MainActivity.cs das LaunchMode-Element auf SingleTop fest, damit MainActivity beim Öffnen nicht erneut erstellt wird.In MainActivity.cs, set the LaunchMode to SingleTop so MainActivity won't get created again when opened.

    [Activity(
        Label = "PushDemo",
        LaunchMode = LaunchMode.SingleTop,
        Icon = "@mipmap/icon",
        Theme = "@style/MainTheme",
        MainLauncher = true,
        ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    
  7. Fügen Sie private Eigenschaften und entsprechende Unterstützungsfelder hinzu, um einen Verweis auf die IPushNotificationActionService- und IDeviceInstallationService-Implementierungen zu speichern.Add private properties and corresponding backing fields to store a reference to the IPushNotificationActionService and IDeviceInstallationService implementations.

    IPushDemoNotificationActionService _notificationActionService;
    IDeviceInstallationService _deviceInstallationService;
    
    IPushDemoNotificationActionService NotificationActionService
        => _notificationActionService ??
            (_notificationActionService =
            ServiceContainer.Resolve<IPushDemoNotificationActionService>());
    
    IDeviceInstallationService DeviceInstallationService
        => _deviceInstallationService ??
            (_deviceInstallationService =
            ServiceContainer.Resolve<IDeviceInstallationService>());
    
  8. Implementieren Sie die IOnSuccessListener-Schnittstelle zum Abrufen und Speichern des Firebase-Tokens.Implement the IOnSuccessListener interface to retrieve and store the Firebase token.

    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity, Android.Gms.Tasks.IOnSuccessListener
    {
        ...
    
        public void OnSuccess(Java.Lang.Object result)
            => DeviceInstallationService.Token =
                result.Class.GetMethod("getToken").Invoke(result).ToString();
    }
    
  9. Fügen Sie eine neue Methode namens ProcessNotificationActions hinzu, die prüft, ob eine gegebene Absicht einen zusätzlichen Wert namens Aktion ausweist.Add a new method called ProcessNotificationActions that will check whether a given Intent has an extra value named action. Führen Sie eine bedingte Auslösung dieser Aktion unter Verwendung der Implementierung IPushDemoNotificationActionService aus.Conditionally trigger that action using the IPushDemoNotificationActionService implementation.

    void ProcessNotificationActions(Intent intent)
    {
        try
        {
            if (intent?.HasExtra("action") == true)
            {
                var action = intent.GetStringExtra("action");
    
                if (!string.IsNullOrEmpty(action))
                    NotificationActionService.TriggerAction(action);
            }
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine(ex.Message);
        }
    }
    
  10. Überschreiben Sie die Methode OnNewIntent, um die Methode ProcessNotificationActions aufzurufen.Override the OnNewIntent method to call ProcessNotificationActions method.

    protected override void OnNewIntent(Intent intent)
    {
        base.OnNewIntent(intent);
        ProcessNotificationActions(intent);
    }
    

    Hinweis

    Da das LaunchMode-Element für die Aktivität auf SingleTop festgelegt ist, wird eine Absicht an die bestehende Activity-Instanz über die OnNewIntent-Methode statt über die OnCreate-Methode gesendet, daher müssen Sie eine eingehende Absicht sowohl in der OnCreate- als auch in der OnNewIntent-Methode behandeln.Since the LaunchMode for the Activity is set to SingleTop, an Intent will be sent to the existing Activity instance via the OnNewIntent method rather than the OnCreate method and so you must handle an incoming intent in both OnCreate and OnNewIntent methods.

  11. Aktualisieren Sie die OnCreate-Methode, um Bootstrap.Begin direkt nach dem Aufruf von base.OnCreate aufzurufen, wobei Sie die plattformspezifische Implementierung von IDeviceInstallationService übergeben.Update the OnCreate method to call Bootstrap.Begin right after the call to base.OnCreate passing in the platform-specific implementation of IDeviceInstallationService.

    Bootstrap.Begin(() => new DeviceInstallationService());
    
  12. In derselben Methode erfolgt ein bedingter Aufruf von GetInstanceId- in der FirebaseApp-Instanz unmittelbar nach dem Aufrufen von Bootstrap.Begin, wobei MainActivity als IOnSuccessListener hinzugefügt wird.In the same method, conditionally call GetInstanceId on the FirebaseApp instance, right after the call to Bootstrap.Begin, adding MainActivity as the IOnSuccessListener.

    if (DeviceInstallationService.NotificationsSupported)
    {
        FirebaseInstanceId.GetInstance(Firebase.FirebaseApp.Instance)
            .GetInstanceId()
            .AddOnSuccessListener(this);
    }
    
  13. Rufen Sie, immer noch in OnCreate, die ProcessNotificationActions-Methode unmittelbar nach dem Aufruf von LoadApplication auf, wobei Sie die aktuelle Absicht übergeben.Still in OnCreate, call ProcessNotificationActions immediately after the call to LoadApplication passing in the current Intent.

    ...
    
    LoadApplication(new App());
    
    ProcessNotificationActions(Intent);
    

Hinweis

Sie müssen die App jedes Mal, wenn Sie sie von einer Debugsitzung aus ausführen und beenden, neu registrieren, um weiterhin Pushbenachrichtigungen zu erhalten.You must re-register the app each time you run it and stop it from a debug session to continue receiving push notifications.

Konfigurieren des nativen iOS-Projekts für PushbenachrichtigungenConfigure the native iOS project for push notifications

Konfigurieren von „Info.plist“ und „Entitlements.plist“Configure Info.plist and Entitlements.plist

  1. Stellen Sie sicher, dass Sie sich bei Ihrem Apple-Entwicklerkonto unter Visual Studio > Einstellungen... > Veröffentlichen > Apple-Entwicklerkonten angemeldet haben, und dass das entsprechende Zertifikat und Bereitstellungsprofil heruntergeladen wurden.Ensure you've signed in to your Apple Developer Account in Visual Studio > Preferences... > Publishing > Apple Developer Accounts and the appropriate Certificate and Provisioning Profile has been downloaded. Sie sollten diese Ressourcen im Rahmen der vorherigen Schritte erstellt haben.You should have created these assets as part of the previous steps.

  2. Öffnen Sie in PushDemo.iOS die Datei Info.plist, und stellen Sie sicher, dass BundleIdentifier mit dem Wert übereinstimmt, der für das jeweilige Bereitstellungsprofil im Apple-Entwicklerportal verwendet wurde.In PushDemo.iOS, open Info.plist and ensure that the BundleIdentifier matches the value that was used for the respective provisioning profile in the Apple Developer Portal. BundleIdentifier hatte das Format com.<organization>.PushDemo.The BundleIdentifier was in the format com.<organization>.PushDemo.

  3. Legen Sie in derselben Datei Minimale Systemversion auf 13.0 fest.In the same file, set Minimum system version to 13.0.

    Hinweis

    Für die Zwecke dieses Tutorials werden nur Geräte mit iOS 13.0 und höher unterstützt. Sie können diese Einstellung jedoch erweitern, um Geräte mit älteren Versionen zu unterstützen.Only those devices running iOS 13.0 and above are supported for the purposes of this tutorial however you can extend it to support devices running older versions.

  4. Öffnen Sie die Projektoptionen für PushDemo.iOS (durch Doppelklicken auf das Projekt).Open the Project Options for PushDemo.iOS (double-click on the project).

  5. Vergewissern Sie sich in Projektoptionen unter Build > iOS-Bundlesignierung, dass unter Team Ihr Entwicklerkonto ausgewählt ist.In Project Options, under Build > iOS Bundle Signing, ensure that your Developer account is selected under Team. Vergewissern Sie sich dann, dass das Kontrollkästchen für die automatische Signierungsverwaltung aktiviert ist und dass Ihr Signaturzertifikat und Ihr Bereitstellungsprofil automatisch ausgewählt wurden.Then, ensure "Automatically manage signing" is selected and your Signing Certificate and Provisioning Profile are automatically selected.

    Hinweis

    Wenn Ihr Signaturzertifikat und Bereitstellungsprofil nicht automatisch ausgewählt wurden, wählen Sie Manuelle Bereitstellung aus, und klicken Sie dann auf signierungsoptionen.If your Signing Certificate and Provisioning Profile have not been automatically selected, choose Manual Provisioning, then click on Bundle Signing Options. Stellen Sie sicher, dass Ihr Team als Signierungsidentität und Ihr PushDemo-spezifisches Bereitstellungsprofil als Bereitstellungsprofil sowohl für Debug- als auch für Freigabe-Konfigurationen ausgewählt ist, und dass iPhone in beiden Fällen als Plattform ausgewählt ist.Ensure that your Team is selected for Signing Identity and your PushDemo specific provisioning profile is selected for Provisioning Profile for both Debug and Release configurations ensuring that iPhone is selected for the Platform in both cases.

  6. Öffnen Sie in PushDemo.iOS die Datei Entitlements.plist, und stellen Sie sicher, dass Push-Benachrichtigungen aktivieren bei der Ansicht auf der Registerkarte Berechtigungen aktiviert ist. Vergewissern Sie sich anschließend, dass die Einstellung APS-Umgebung bei der Ansicht auf der Registerkarte Quelle auf Entwicklung festgelegt ist.In PushDemo.iOS, open Entitlements.plist and ensure that Enable Push Notifications is checked when viewed in the Entitlements tab. Then, ensure the APS Environment setting is set to development when viewed in the Source tab.

Behandeln von Pushbenachrichtigungen für iOSHandle push notifications for iOS

  1. CONTROL + Klicken Sie auf das Projekt PushDemo.iOS, wählen Sie Neuer Ordner aus dem Menü Hinzufügen aus, und klicken Sie dann auf Hinzufügen. Verwenden Sie dabei Dienste als Ordnernamen.Control + Click on the PushDemo.iOS project, choose New Folder from the Add menu, then click Add using Services as the Folder Name.

  2. CONTROL + Klicken Sie auf den Ordner Dienste, und wählen Sie dann Neue Datei... aus dem Menü Hinzufügen aus.Control + Click on the Services folder, then choose New File... from the Add menu.

  3. Wählen Sie Allgemein > Leere Klassen aus, geben Sie DeviceInstallationService.cs als Namen ein, und klicken Sie dann auf Neu unter Hinzufügung der folgenden Implementierung.Select General > Empty Class, enter DeviceInstallationService.cs for the Name, then click New adding the following implementation.

    using System;
    using PushDemo.Models;
    using PushDemo.Services;
    using UIKit;
    
    namespace PushDemo.iOS.Services
    {
        public class DeviceInstallationService : IDeviceInstallationService
        {
            const int SupportedVersionMajor = 13;
            const int SupportedVersionMinor = 0;
    
            public string Token { get; set; }
    
            public bool NotificationsSupported
                => UIDevice.CurrentDevice.CheckSystemVersion(SupportedVersionMajor, SupportedVersionMinor);
    
            public string GetDeviceId()
                => UIDevice.CurrentDevice.IdentifierForVendor.ToString();
    
            public DeviceInstallation GetDeviceInstallation(params string[] tags)
            {
                if (!NotificationsSupported)
                    throw new Exception(GetNotificationsSupportError());
    
                if (string.isNullOrWhitespace(Token))
                    throw new Exception("Unable to resolve token for APNS");
    
                var installation = new DeviceInstallation
                {
                    InstallationId = GetDeviceId(),
                    Platform = "apns",
                    PushChannel = Token
                };
    
                installation.Tags.AddRange(tags);
    
                return installation;
            }
    
            string GetNotificationsSupportError()
            {
                if (!NotificationsSupported)
                    return $"This app only supports notifications on iOS {SupportedVersionMajor}.{SupportedVersionMinor} and above. You are running {UIDevice.CurrentDevice.SystemVersion}.";
    
                if (Token == null)
                    return $"This app can support notifications but you must enable this in your settings.";
    
    
                return "An error occurred preventing the use of push notifications";
            }
        }
    }
    

    Hinweis

    Diese Klasse bietet eine eindeutige ID (unter Verwendung des Werts UIDevice.IdentifierForVendor) und die Nutzlast der Benachrichtigungshubregistrierung.This class provides a unique ID (using the UIDevice.IdentifierForVendor value) and the notification hub registration payload.

  4. Fügen Sie einen neuen Ordner mit dem Namen Erweiterungen zum Projekt PushDemo.iOS hinzu, und fügen Sie diesem Ordner dann eine leere Klasse namens NSDataExtensions.cs mit der folgenden Implementierung hinzu.Add a new folder to the PushDemo.iOS project called Extensions then add an Empty Class to that folder called NSDataExtensions.cs with the following implementation.

    using System.Text;
    using Foundation;
    
    namespace PushDemo.iOS.Extensions
    {
        internal static class NSDataExtensions
        {
            internal static string ToHexString(this NSData data)
            {
                var bytes = data.ToArray();
    
                if (bytes == null)
                    return null;
    
                StringBuilder sb = new StringBuilder(bytes.Length * 2);
    
                foreach (byte b in bytes)
                    sb.AppendFormat("{0:x2}", b);
    
                return sb.ToString().ToUpperInvariant();
            }
        }
    }
    
  5. Stellen Sie in AppDelegate.cs sicher, dass am Anfang der Datei die folgenden Namespaces hinzugefügt wurden.In AppDelegate.cs, ensure the following namespaces have been added to the top of the file.

    using System;
    using System.Diagnostics;
    using System.Threading.Tasks;
    using Foundation;
    using PushDemo.iOS.Extensions;
    using PushDemo.iOS.Services;
    using PushDemo.Services;
    using UIKit;
    using UserNotifications;
    using Xamarin.Essentials;
    
  6. Fügen Sie private Eigenschaften und die entsprechenden Unterstützungsfelder hinzu, um einen Verweis auf die IPushDemoNotificationActionService-, INotificationRegistrationService- und IDeviceInstallationService-Implementierungen zu speichern.Add private properties and their respective backing fields to store a reference to the IPushDemoNotificationActionService, INotificationRegistrationService, and IDeviceInstallationService implementations.

    IPushDemoNotificationActionService _notificationActionService;
    INotificationRegistrationService _notificationRegistrationService;
    IDeviceInstallationService _deviceInstallationService;
    
    IPushDemoNotificationActionService NotificationActionService
        => _notificationActionService ??
            (_notificationActionService =
            ServiceContainer.Resolve<IPushDemoNotificationActionService>());
    
    INotificationRegistrationService NotificationRegistrationService
        => _notificationRegistrationService ??
            (_notificationRegistrationService =
            ServiceContainer.Resolve<INotificationRegistrationService>());
    
    IDeviceInstallationService DeviceInstallationService
        => _deviceInstallationService ??
            (_deviceInstallationService =
            ServiceContainer.Resolve<IDeviceInstallationService>());
    
  7. Fügen Sie die RegisterForRemoteNotifications-Methode hinzu, um Benutzerbenachrichtigungseinstellungen und dann Remotebenachrichtigungen mit APNS zu registrieren.Add the RegisterForRemoteNotifications method to register user notification settings and then for remote notifications with APNS.

    void RegisterForRemoteNotifications()
    {
        MainThread.BeginInvokeOnMainThread(() =>
        {
            var pushSettings = UIUserNotificationSettings.GetSettingsForTypes(
                UIUserNotificationType.Alert |
                UIUserNotificationType.Badge |
                UIUserNotificationType.Sound,
                new NSSet());
    
            UIApplication.SharedApplication.RegisterUserNotificationSettings(pushSettings);
            UIApplication.SharedApplication.RegisterForRemoteNotifications();
        });
    }
    
  8. Fügen Sie die CompleteRegistrationAsync-Methode hinzu, um den IDeviceInstallationService.Token-Eigenschaftswert festzulegen.Add the CompleteRegistrationAsync method to set the IDeviceInstallationService.Token property value. Aktualisieren Sie die Registrierung, und speichern Sie das Gerätetoken zwischen, wenn es seit der letzten Speicherung aktualisiert wurde.Refresh the registration and cache the device token if it has been updated since it was last stored.

    Task CompleteRegistrationAsync(NSData deviceToken)
    {
        DeviceInstallationService.Token = deviceToken.ToHexString();
        return NotificationRegistrationService.RefreshRegistrationAsync();
    }
    
  9. Fügen Sie die ProcessNotificationActions-Methode zur Verarbeitung der NSDictionary-Benachrichtigungsdaten und zum bedingten Aufruf von NotificationActionService.TriggerAction hinzu.Add the ProcessNotificationActions method for processing the NSDictionary notification data and conditionally calling NotificationActionService.TriggerAction.

    void ProcessNotificationActions(NSDictionary userInfo)
    {
        if (userInfo == null)
            return;
    
        try
        {
            var actionValue = userInfo.ObjectForKey(new NSString("action")) as NSString;
    
            if (!string.IsNullOrWhiteSpace(actionValue?.Description))
                NotificationActionService.TriggerAction(actionValue.Description);
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.Message);
        }
    }
    
  10. Überschreiben Sie die RegisteredForRemoteNotifications-Methode, wobei Sie das deviceToken-Argument an die CompleteRegistrationAsync-Methode übergeben.Override the RegisteredForRemoteNotifications method passing the deviceToken argument to the CompleteRegistrationAsync method.

    public override void RegisteredForRemoteNotifications(
        UIApplication application,
        NSData deviceToken)
        => CompleteRegistrationAsync(deviceToken).ContinueWith((task)
            => { if (task.IsFaulted) throw task.Exception; });
    
  11. Überschreiben Sie die ReceivedRemoteNotification-Methode, wobei Sie das userInfo-Argument an die ProcessNotificationActions-Methode übergeben.Override the ReceivedRemoteNotification method passing the userInfo argument to the ProcessNotificationActions method.

    public override void ReceivedRemoteNotification(
        UIApplication application,
        NSDictionary userInfo)
        => ProcessNotificationActions(userInfo);
    
  12. Überschreiben Sie die FailedToRegisterForRemoteNotifications-Methode, um den Fehler zu protokollieren.Override the FailedToRegisterForRemoteNotifications method to log the error.

    public override void FailedToRegisterForRemoteNotifications(
        UIApplication application,
        NSError error)
        => Debug.WriteLine(error.Description);
    

    Hinweis

    Dies dient als Platzhalter.This is very much a placeholder. Für Produktionsszenarien werden Sie eine ordnungsgemäße Protokollierung und Fehlerbehandlung implementieren wollen.You will want to implement proper logging and error handling for production scenarios.

  13. Aktualisieren Sie die FinishedLaunching-Methode, um Bootstrap.Begin direkt nach dem Aufruf von Forms.Init aufzurufen, wobei Sie die plattformspezifische Implementierung von IDeviceInstallationService übergeben.Update the FinishedLaunching method to call Bootstrap.Begin right after the call to Forms.Init passing in the platform-specific implementation of IDeviceInstallationService.

    Bootstrap.Begin(() => new DeviceInstallationService());
    
  14. Fordern Sie in der gleichen Methode eine bedingte Autorisierung an, und registrieren Sie sich unmittelbar nach Bootstrap.Begin für Remotebenachrichtigungen.In the same method, conditionally request authorization and register for remote notifications immediately after Bootstrap.Begin.

    if (DeviceInstallationService.NotificationsSupported)
    {
        UNUserNotificationCenter.Current.RequestAuthorization(
                UNAuthorizationOptions.Alert |
                UNAuthorizationOptions.Badge |
                UNAuthorizationOptions.Sound,
                (approvalGranted, error) =>
                {
                    if (approvalGranted && error == null)
                        RegisterForRemoteNotifications();
                });
    }
    
  15. Rufen Sie, immer noch in der FinishedLaunching-Methode, die ProcessNotificationActions-Methode unmittelbar nach dem Aufruf von LoadApplication auf, wenn das Argument options das UIApplication.LaunchOptionsRemoteNotificationKey-Element enthält, wobei Sie das resultierende userInfo-Objekt übergeben.Still in FinishedLaunching, call ProcessNotificationActions immediately after the call to LoadApplication if the options argument contains the UIApplication.LaunchOptionsRemoteNotificationKey passing in the resulting userInfo object.

    using (var userInfo = options?.ObjectForKey(
        UIApplication.LaunchOptionsRemoteNotificationKey) as NSDictionary)
            ProcessNotificationActions(userInfo);
    

Testen der LösungTest the solution

Sie können jetzt das Senden von Benachrichtigungen über den Back-End-Dienst testen.You can now test sending notifications via the backend service.

Senden einer TestbenachrichtigungSend a test notification

  1. Öffnen Sie in Postman eine neue Registerkarte.Open a new tab in Postman.

  2. Legen Sie die Anforderung auf POST fest, und geben Sie die folgende Adresse ein:Set the request to POST, and enter the following address:

    https://<app_name>.azurewebsites.net/api/notifications/requests
    
  3. Wenn Sie sich entschieden haben, die Schritte im Abschnitt Authentifizieren von Clients mit einem API-Schlüssel durchzuführen, stellen Sie sicher, dass die Anforderungsheader Ihren apikey-Wert enthalten.If you chose to complete the Authenticate clients using an API Key section, be sure to configure the request headers to include your apikey value.

    SchlüsselKey WertValue
    apikeyapikey <your_api_key><your_api_key>
  4. Wählen Sie die Option raw für den Text aus, wählen Sie dann JSON aus der Liste der Formatoptionen aus, und fügen Sie anschließend JSON-Platzhalterinhalt ein:Choose the raw option for the Body, then choose JSON from the list of format options, and then include some placeholder JSON content:

    {
        "text": "Message from Postman!",
        "action": "action_a"
    }
    
  5. Klicken Sie auf die Schaltfläche Code oben rechts im Fenster unter der Schaltfläche Speichern.Select the Code button, which is under the Save button on the upper right of the window. Die Anforderung sollte ähnlich wie im folgenden Beispiel aussehen, wenn sie für HTML angezeigt wird (je nachdem, ob Sie einen apikey-Header eingefügt haben):The request should look similar to the following example when displayed for HTML (depending on whether you included an apikey header):

    POST /api/notifications/requests HTTP/1.1
    Host: https://<app_name>.azurewebsites.net
    apikey: <your_api_key>
    Content-Type: application/json
    
    {
        "text": "Message from backend service",
        "action": "action_a"
    }
    
  6. Führen Sie die Anwendung PushDemo auf einer oder beiden Zielplattformen (Android und iOS) aus.Run the PushDemo application on one or both of the target platforms (Android and iOS).

    Hinweis

    Wenn Sie auf Android testen, stellen Sie sicher, dass Sie nicht in Debug ausgeführt werden, oder wenn die Anwendung durch Ausführen der Anwendung bereitgestellt wurde, erzwingen Sie das Schließen der Anwendung, und starten Sie sie erneut vom Startprogramm aus.If you are testing on Android ensure that you are not running in Debug, or if the app has been deployed by running the application then force close the app and start it again from the launcher.

  7. Tippen Sie in der PushDemo-App auf die Schaltfläche Registrieren.In the PushDemo app, tap on the Register button.

  8. Kehren Sie zu Postmann zurück, schließen Sie das Fenster Codeausschnitt generieren (falls Sie dies noch nicht getan haben). und klicken Sie dann auf die Schaltfläche Senden.Back in Postman, close the Generate Code Snippets window (if you haven't done so already) then click the Send button.

  9. Vergewissern Sie sich, dass Sie eine 200 OK-Antwort in Postmann erhalten, und dass die Warnung -Aktion empfangen in der App angezeigt wird.Validate that you get a 200 OK response in Postman and the alert appears in the app showing ActionA action received.

  10. Schließen Sie die PushDemo-App, und klicken Sie dann erneut auf die Schaltfläche Senden in Postmann .Close the PushDemo app, then click the Send button again in Postman.

  11. Überprüfen Sie, dass Sie wieder eine 200 OK-Antwort in Postmann erhalten.Validate that you get a 200 OK response in Postman again. Vergewissern Sie sich, dass im Benachrichtigungsbereich für die PushDemo-App eine Benachrichtigung mit der richtigen Meldung angezeigt wird.Validate that a notification appears in the notification area for the PushDemo app with the correct message.

  12. Tippen Sie auf die Benachrichtigung, um zu bestätigen, dass die App geöffnet und die Warnung ActionA-Aktion empfangen angezeigt wurde.Tap on the notification to confirm that it opens the app and displayed the ActionA action received alert.

  13. Kehren Sie zu Postmann zurück, und ändern Sie den vorherigen Anforderungstext so, dass eine Hintergrundbenachrichtigung gesendet wird, die action_b statt action_a als Wert für action angibt.Back in Postman, modify the previous request body to send a silent notification specifying action_b instead of action_a for the action value.

    {
        "action": "action_b",
        "silent": true
    }
    
  14. Klicken Sie, während die App noch geöffnet ist, auf die Schaltfläche Senden in Postman .With the app still open, click the Send button in Postman.

  15. Vergewissern Sie sich, dass Sie eine 200 OK-Antwort in Postmann erhalten, und dass die Warnung ActionB-Aktion empfangen anstelle von ActionA-Aktion empfangen in der App angezeigt wird.Validate that you get a 200 OK response in Postman and that the alert appears in the app showing ActionB action received instead of ActionA action received.

  16. Schließen Sie die PushDemo-App, und klicken Sie dann erneut auf die Schaltfläche Senden in Postmann .Close the PushDemo app, then click the Send button again in Postman.

  17. Vergewissern Sie sich, dass Sie eine 200 OK-Antwort in Postmann erhalten, und dass die Hintergrundbenachrichtigung nicht im Benachrichtigungsbereich angezeigt wird.Validate that you get a 200 OK response in Postman and that the silent notification doesn't appear in the notification area.

ProblembehandlungTroubleshooting

Keine Antwort vom Back-End-DienstNo response from the backend service

Vergewissern Sie sich beim lokalen Testen, dass der Back-End-Dienst ausgeführt wird und den richtigen Port verwendet.When testing locally, ensure that the backend service is running and is using the correct port.

Wenn Sie den Text gegen die Azure-API-App ausführen, überprüfen Sie, ob der Dienst läuft und ohne Fehler bereitgestellt und gestartet wurde.If testing against the Azure API App, check the service is running and has been deployed and has started without error.

Vergewissern Sie sich, dass Sie die Basisadresse in Postman oder in der Konfiguration der mobilen Anwendung richtig angegeben haben, wenn Sie über den Client testen.Be sure to check you've specified the base address correctly in Postman or in the mobile app configuration when testing via the client. Die Basisadresse sollte bei lokalen Tests in etwa so aussehen: https://<api_name>.azurewebsites.net/ oder https://localhost:5001/.The base address should indicatively be https://<api_name>.azurewebsites.net/ or https://localhost:5001/ when testing locally.

Kein Empfang von Benachrichtigungen unter Android nach dem Starten oder Beenden einer DebugsitzungNot receiving notifications on Android after starting or stopping a debug session

Stellen Sie sicher, dass Sie sich nach dem Starten oder Beenden einer Debugsitzung erneut registrieren.Ensure you register again after starting or stopping a debug session. Der Debugger bewirkt, dass ein neues Firebase-Token generiert wird.The debugger will cause a new Firebase token to be generated. Die Benachrichtigungshubinstallation muss ebenfalls aktualisiert werden.The notification hub installation must be updated as well.

Empfangen eines 401-Statuscodes vom Back-End-DienstReceiving a 401 status code from the backend service

Vergewissern Sie sich, dass Sie den apikey-Anforderungsheader festlegen und dieser Wert mit dem übereinstimmt, den Sie für den Back-End-Dienst konfiguriert haben.Validate that you're setting the apikey request header and this value matches the one you had configured for the backend service.

Wenn dieser Fehler beim lokalen Testen auftritt, stellen Sie sicher, dass der Schlüsselwert, den Sie in der Clientkonfiguration definiert haben, mit dem von der API verwendeten Benutzereinstellungswert Authentication:ApiKey übereinstimmt.If you receive this error when testing locally, ensure the key value you defined in the client config, matches the Authentication:ApiKey user-setting value used by the API.

Wenn Sie mit einer API-App testen, stellen Sie sicher, dass der Schlüsselwert in der Clientkonfigurationsdatei mit der Authentication:ApiKey-Anwendungseinstellung übereinstimmt, die Sie in der API-App verwenden.If you're testing with an API App, ensure the key value in the client config file matches the Authentication:ApiKey application setting you're using in the API App.

Hinweis

Wenn Sie diese Einstellung erstellt oder geändert haben, nachdem Sie den Back-End-Dienst bereitgestellt haben, müssen Sie den Dienst neu starten, damit sie wirksam wird.If you had created or changed this setting after you had deployed the backend service then you must restart the service in order for it take effect.

Wenn Sie entschieden haben, die Schritte im Abschnitt Authentifizieren von Clients mit einem API-Schlüssel durchzuführen, stellen Sie sicher, dass Sie das Authorize-Attribut nicht auf die NotificationsController-Klasse angewendet haben.If you chose not to complete the Authenticate clients using an API Key section, ensure that you didn't apply the Authorize attribute to the NotificationsController class.

Empfangen eines 404-Statuscodes vom Back-End-DienstReceiving a 404 status code from the backend service

Überprüfen Sie, ob der Endpunkt und die HTTP-Anforderungsmethode korrekt sind.Validate that the endpoint and HTTP request method is correct. Die Endpunkte sollten z. B. wie folgt lauten:For example, the endpoints should indicatively be:

  • [PUT] https://<api_name>.azurewebsites.net/api/notifications/installations[PUT] https://<api_name>.azurewebsites.net/api/notifications/installations
  • [DELETE] https://<api_name>.azurewebsites.net/api/notifications/installations/<installation_id>[DELETE] https://<api_name>.azurewebsites.net/api/notifications/installations/<installation_id>
  • [POST] https://<api_name>.azurewebsites.net/api/notifications/requests[POST] https://<api_name>.azurewebsites.net/api/notifications/requests

Oder beim lokalen Testen:Or when testing locally:

  • [PUT] https://localhost:5001/api/notifications/installations[PUT] https://localhost:5001/api/notifications/installations
  • [DELETE] https://localhost:5001/api/notifications/installations/<installation_id>[DELETE] https://localhost:5001/api/notifications/installations/<installation_id>
  • [POST] https://localhost:5001/api/notifications/requests[POST] https://localhost:5001/api/notifications/requests

Wenn Sie die Basisadresse in der Client-App angeben, stellen Sie sicher, dass sie mit einem / endet.When specifying the base address in the client app, ensure it ends with a /. Die Basisadresse sollte bei lokalen Tests in etwa so aussehen: https://<api_name>.azurewebsites.net/ oder https://localhost:5001/.The base address should indicatively be https://<api_name>.azurewebsites.net/ or https://localhost:5001/ when testing locally.

Registrierung kann nicht ausgeführt werden, und eine Benachrichtigungshub-Fehlermeldung wird angezeigtUnable to register and a notification hub error message is displayed

Stellen Sie sicher, dass das Testgerät über Netzwerkkonnektivität verfügt.Verify that the test device has network connectivity. Legen Sie dann den Statuscode der HTTP-Antwort fest, indem Sie einen Breakpoint festlegen, um den Wert der Eigenschaft StatusCode im HttpResponse-Objekt zu überprüfen.Then, determine the Http response status code by setting a breakpoint to inspect the StatusCode property value in the HttpResponse.

Prüfen Sie gegebenenfalls die früheren Vorschläge zur Problembehandlung basierend auf dem Statuscode.Review the previous troubleshooting suggestions where applicable based on the status code.

Legen Sie einen Breakpoint für die Zeilen fest, die diese spezifischen Statuscodes für die jeweilige API zurückgeben.Set a breakpoint on the lines that return these specific status codes for the respective API. Versuchen Sie dann, beim lokalen Debuggen den Back-End-Dienst aufzurufen.Then try calling the backend service when debugging locally.

Überprüfen Sie über Postman unter Verwendung der entsprechenden Nutzlast, ob der Back-End-Dienst wie erwartet funktioniert.Validate the backend service is working as expected via Postman using the appropriate payload. Verwenden Sie die tatsächliche Nutzlast, die vom Clientcode für die betreffende Plattform erstellt wurde.Use the actual payload created by the client code for the platform in question.

Überprüfen Sie die plattformspezifischen Konfigurationsabschnitte, um sicherzustellen, dass keine Schritte ausgelassen wurden.Review the platform-specific configuration sections to ensure that no steps have been missed. Vergewissern Sie sich, dass für die Variablen installation id und token geeignete Werte für die entsprechende Plattform aufgelöst werden.Check that suitable values are being resolved for installation id and token variables for the appropriate platform.

Fehlermeldung „Eine ID für das Gerät kann nicht aufgelöst werden“Unable to resolve an ID for the device error message is displayed

Überprüfen Sie die plattformspezifischen Konfigurationsabschnitte, um sicherzustellen, dass keine Schritte ausgelassen wurden.Review the platform-specific configuration sections to ensure that no steps have been missed.

Nächste SchritteNext steps

Sie verfügen nun über eine einfache Xamarin.Forms-App, die über einen Back-End-Dienst mit einem Notification Hub verbunden ist und Benachrichtigungen senden und empfangen kann.You should now have a basic Xamarin.Forms app connected to a notification hub via a backend service and can send and receive notifications.

Wahrscheinlich werden Sie das in diesem Tutorial verwendete Beispiel an Ihr eigenes Szenario anpassen müssen.You'll likely need to adapt the example used in this tutorial to fit your own scenario. Auch wird die Implementierung einer robusteren Fehlerbehandlung, Wiederholungslogik und Protokollierung empfohlen.Implementing more robust error handling, retry logic, and logging is also recommended.

Visual Studio App Center kann schnell in mobile Anwendungen integriert werden und bietet Analyse und Diagnose zur Unterstützung der Problembehandlung.Visual Studio App Center can be quickly incorporated into mobile apps providing analytics and diagnostics to aid in troubleshooting.