Samouczek: wysyłanie powiadomień wypychanych do aplikacji MAUI platformy .NET przy użyciu usługi Azure Notification Hubs za pośrednictwem usługi zaplecza
Powiadomienia wypychane dostarczają informacje z systemu zaplecza do aplikacji klienckiej. Firmy Apple, Google i inne platformy mają własną usługę powiadomień wypychanych (PNS). Usługa Azure Notification Hubs umożliwia scentralizowanie powiadomień na różnych platformach, dzięki czemu aplikacja zaplecza może komunikować się z jednym koncentratorem, który zajmuje się dystrybucją powiadomień do poszczególnych systemów powiadomień.
Usługa Azure Notification Hubs wymaga od aplikacji zarejestrowania się w centrum i opcjonalnie definiowania szablonów i/lub subskrybowania tagów:
- Wykonanie instalacji urządzenia łączy dojście pnS do identyfikatora w usłudze Azure Notification Hub. Aby uzyskać więcej informacji na temat rejestracji, zobacz Zarządzanie rejestracją.
- Szablony umożliwiają urządzeniom określanie sparametryzowanych szablonów komunikatów. Komunikaty przychodzące można dostosować na urządzenie. Aby uzyskać więcej informacji, zobacz Szablony usługi Notification Hubs.
- Tagi mogą służyć do subskrybowania kategorii wiadomości, takich jak wiadomości, sport i pogoda. Aby uzyskać więcej informacji, zobacz Routing i wyrażenia tagów.
W tym samouczku użyjesz usługi Azure Notification Hubs do wysyłania powiadomień wypychanych do aplikacji wieloplatformowej interfejsu użytkownika aplikacji platformy .NET (.NET MAUI) przeznaczonej dla systemów Android i iOS. Zaplecze internetowego interfejsu API platformy ASP.NET Core służy do obsługi rejestracji urządzeń dla klienta i inicjowania powiadomień wypychanych. Te operacje są obsługiwane przy użyciu pakietu NuGet Microsoft.Azure.NotificationHubs . Aby uzyskać więcej informacji na temat ogólnego podejścia, zobacz Zarządzanie rejestracją z zaplecza.
W tym samouczku zostały wykonane następujące czynności:
- Konfigurowanie usług powiadomień wypychanych i usługi Azure Notification Hub.
- Utwórz aplikację zaplecza interfejsu WebAPI platformy ASP.NET Core.
- Utwórz aplikację .NET MAUI.
- Skonfiguruj aplikację systemu Android na potrzeby powiadomień wypychanych.
- Skonfiguruj aplikację systemu iOS na potrzeby powiadomień wypychanych.
- Testowanie aplikacji.
- Rozwiąż wszelkie problemy z konfiguracją i konfiguracją.
Wymagania wstępne
Do ukończenia tego samouczka wymagane są następujące elementy:
- Konto platformy Azure z aktywną subskrypcją.
- Komputer PC lub Mac z najnowszą wersją programu Visual Studio/Visual Studio Code z obciążeniem tworzenia aplikacji wieloplatformowych platformy .NET oraz zainstalowanymi obciążeniami tworzenia aplikacji ASP.NET i aplikacji internetowych.
W przypadku systemu Android musisz mieć następujące elementy:
- Odblokowane przez dewelopera urządzenie fizyczne lub emulator z zainstalowanym interfejsem API 26 lub nowszym z zainstalowanymi usługami Google Play.
W przypadku systemu iOS musisz mieć następujące elementy:
- Aktywne konto dewelopera firmy Apple.
- Komputer Mac z uruchomionym programem Xcode wraz z prawidłowym certyfikatem dewelopera zainstalowanym w pęku kluczy.
Następnie w systemie iOS należy mieć:
Symulator systemu iOS 16+ działający w systemie macOS 13 lub nowszym na komputerach Mac z procesorami krzemowymi firmy Apple lub T2.
LUB
Fizyczne urządzenie z systemem iOS zarejestrowane na koncie dewelopera (z systemem iOS 13.0 lub nowszym).
Urządzenie fizyczne zarejestrowane na koncie dewelopera firmy Apple i skojarzone z certyfikatem.
Ważne
Symulator systemu iOS obsługuje powiadomienia zdalne w systemie iOS 16 lub nowszym podczas uruchamiania w systemie macOS 13 lub nowszym na komputerach Mac z procesorami krzemowymi firmy Apple lub T2. Jeśli nie spełniasz tych wymagań sprzętowych, musisz mieć aktywne konto dewelopera firmy Apple i urządzenie fizyczne.
Aby wykonać czynności opisane w tym samouczku, musisz zapoznać się z następującymi tematami:
- Portal dla deweloperów firmy Apple
- ASP.NET Core i internetowe interfejsy API
- Usługa Firebase Cloud Messaging
- Microsoft Azure
Chociaż ten samouczek jest przeznaczony dla programu Visual Studio, można go wykonać przy użyciu programu Visual Studio Code na komputerze PC lub Mac. Jednak będą istnieć pewne różnice, które wymagają uzgadniania. Na przykład opisy interfejsu użytkownika i przepływów pracy, nazw szablonów i konfiguracji środowiska.
Konfigurowanie usług powiadomień wypychanych i usługi Azure Notification Hub
W tej sekcji skonfigurujesz usługę Firebase Cloud Messaging i Apple Push Notification Services (APNS). Następnie utworzysz i skonfigurujesz usługę Azure Notification Hub do pracy z tymi usługami.
Tworzenie projektu Firebase
Aby utworzyć projekt Firebase:
W przeglądarce internetowej zaloguj się do konsoli firebase.
W konsoli Firebase wybierz przycisk Dodaj projekt i utwórz nowy projekt Firebase, wprowadzając wartość PushDemo jako nazwę projektu.
Uwaga
Zostanie wygenerowana unikatowa nazwa. Domyślnie składa się z małego wariantu podanej nazwy oraz wygenerowanej liczby rozdzielonej kreską. Możesz to zmienić, jeśli chcesz, pod warunkiem, że zmiany są nadal unikatowe globalnie.
Po utworzeniu projektu wybierz logo systemu Android, aby dodać aplikację Firebase do aplikacji systemu Android:
Na stronie Dodawanie aplikacji Firebase do aplikacji systemu Android wprowadź nazwę pakietu, opcjonalnie pseudonim aplikacji i wybierz przycisk Zarejestruj aplikację :
Na stronie Dodawanie programu Firebase do aplikacji systemu Android wybierz przycisk Pobierz google-services.json i zapisz plik w folderze lokalnym przed wybraniem przycisku Dalej :
Na stronie Dodawanie aplikacji Firebase do aplikacji systemu Android wybierz przycisk Dalej.
Na stronie Dodawanie bazy danych Firebase do aplikacji systemu Android wybierz przycisk Kontynuuj w konsoli.
W konsoli Firebase wybierz ikonę Przegląd projektu, a następnie wybierz pozycję Ustawienia projektu:
W ustawieniach projektu wybierz kartę Cloud Messaging (Obsługa komunikatów w chmurze). Zobaczysz, że interfejs API usługi Firebase Cloud Messaging (V1) jest włączony:
W ustawieniach projektu wybierz kartę Konta usług, a następnie wybierz przycisk Generuj nowy klucz prywatny.
W oknie dialogowym Generowanie nowego klucza prywatnego wybierz przycisk Generuj klucz:
Zostanie pobrany plik JSON, który będzie zawierać wartości wprowadzone w usłudze Azure Notification Hub.
Rejestrowanie aplikacji systemu iOS na potrzeby powiadomień wypychanych
Aby wysyłać powiadomienia wypychane do aplikacji systemu iOS, musisz zarejestrować aplikację w usłudze Apple i zarejestrować się w celu otrzymywania powiadomień wypychanych. Można to zrobić, wykonując kroki opisane w następującej dokumentacji usługi Azure Notification Hub:
- Generowanie pliku żądania podpisania certyfikatu
- Rejestrowanie aplikacji na potrzeby powiadomień wypychanych
- Tworzenie certyfikatu dla centrum powiadomień
Jeśli chcesz otrzymywać powiadomienia wypychane na urządzeniu fizycznym, musisz również utworzyć profil aprowizacji.
Ważne
Aby otrzymywać powiadomienia w tle w systemie iOS, musisz dodać tryb tła powiadomień zdalnych do aplikacji. Aby uzyskać więcej informacji, zobacz Włączanie możliwości powiadomień zdalnych w developer.apple.com.
Tworzenie centrum powiadomień platformy Azure
Aby utworzyć centrum powiadomień w witrynie Azure Portal:
- W przeglądarce internetowej zaloguj się do witryny Azure Portal.
- W witrynie Azure Portal kliknij przycisk Utwórz zasób , a następnie wyszukaj i wybierz pozycję Centrum powiadomień przed wybraniem przycisku Utwórz .
- Na stronie Centrum powiadomień wykonaj następujące kroki:
W polu Subskrypcja wybierz nazwę subskrypcji platformy Azure, której chcesz użyć, a następnie wybierz istniejącą grupę zasobów lub utwórz nową.
W polu Szczegóły przestrzeni nazw wprowadź unikatową nazwę nowej przestrzeni nazw.
W polu Szczegóły centrum powiadomień wpisz nazwę centrum powiadomień. Jest to wymagane, ponieważ przestrzeń nazw zawiera co najmniej jedno centrum powiadomień.
Z listy rozwijanej Lokalizacja wybierz wartość określającą lokalizację, w której chcesz utworzyć centrum powiadomień.
Przejrzyj opcję Strefy dostępności. Jeśli wybrano region ze strefami dostępności, pole wyboru jest zaznaczone domyślnie.
Uwaga
Strefy dostępności to funkcja płatna, więc dodatkowa opłata jest dodawana do warstwy.
Wybierz opcję Odzyskiwania po awarii: brak, sparowany region odzyskiwania lub elastyczny region odzyskiwania. Jeśli wybierzesz region odzyskiwania sparowanego, zostanie wyświetlony region trybu failover. Jeśli wybierzesz pozycję Elastyczny region odzyskiwania, użyj listy rozwijanej, aby wybrać z listy regionów odzyskiwania.
Zaznacz przycisk Utwórz. Zostanie utworzone centrum powiadomień.
- W witrynie Azure Portal przejdź do nowo utworzonego centrum powiadomień, a następnie w bloku Zarządzanie zasadami > dostępu.
- W bloku Zasady dostępu zanotuj parametry połączenia zasad
DefaultFullSharedAccessSignature
. Będzie to wymagane później podczas tworzenia usługi zaplecza, która komunikuje się z centrum powiadomień.
Aby uzyskać więcej informacji na temat tworzenia centrum powiadomień, zobacz Tworzenie centrum powiadomień platformy Azure w witrynie Azure Portal.
Konfigurowanie usługi Firebase Cloud Messaging w centrum powiadomień
Aby skonfigurować centrum powiadomień do komunikowania się z usługą Firebase Cloud Messaging:
W witrynie Azure Portal przejdź do centrum powiadomień i wybierz blok Ustawienia > Google (FCM v1).
W bloku Google (FCM v1) wprowadź wartości pól Klucz prywatny, Adres e-mail klienta i Identyfikator projektu. Te wartości można znaleźć w pliku JSON klucza prywatnego pobranym z usługi Firebase Cloud Messaging:
Pole platformy Azure Klucz JSON Przykład wartości JSON Klucz prywatny private_key
Ta wartość powinna zaczynać się od -----BEGIN PRIVATE KEY-----\n
i kończyć ciągiem-----END PRIVATE KEY-----\n
.Adres e-mail klienta client_email
firebase-adminsdk-55sfg@pushdemo-d6ab2.iam.gserviceaccount.com
Identyfikator projektu project_id
pushdemo-d6ab2
W bloku Google (FCM v1) wybierz przycisk Zapisz.
Konfigurowanie usługi Apple Push Notification Service w centrum powiadomień
W witrynie Azure Portal przejdź do centrum powiadomień i wybierz blok Ustawienia > Apple (APNS). Następnie wykonaj odpowiednie kroki na podstawie podejścia wybranego wcześniej podczas tworzenia certyfikatu dla centrum powiadomień.
Ważne
Podczas ustawiania trybu aplikacji wybierz pozycję Produkcja tylko wtedy, gdy chcesz wysyłać powiadomienia wypychane do użytkowników, którzy kupili aplikację ze sklepu.
Opcja 1 — używanie certyfikatu wypychania p12
- W bloku Apple (APNS) wybierz tryb uwierzytelniania certyfikatu.
- W bloku Apple (APNS) wybierz ikonę pliku obok pola Przekaż certyfikat. Następnie wybierz wyeksportowany wcześniej plik p12 i przekaż go.
- W bloku Apple (APNS) wprowadź hasło certyfikatu w polu Hasło, jeśli jest to wymagane.
- W bloku Apple (APNS) wybierz tryb aplikacji piaskownicy.
- W bloku Apple (APNS) wybierz przycisk Zapisz.
Opcja 2 — używanie uwierzytelniania opartego na tokenach
- W bloku Apple (APNS) wybierz tryb uwierzytelniania tokenu.
- W bloku Apple (APNS) wprowadź wartości uzyskane wcześniej dla pól Identyfikator klucza, Identyfikator pakietu, Identyfikator zespołu i Token.
- W bloku Apple (APNS) wybierz tryb aplikacji piaskownicy.
- W bloku Apple (APNS) wybierz przycisk Zapisz.
Tworzenie aplikacji zaplecza internetowego interfejsu API platformy ASP.NET Core
W tej sekcji utworzysz zaplecze internetowego interfejsu API platformy ASP.NET Core do obsługi instalacji urządzenia i wysyłania powiadomień do aplikacji .NET MAUI.
Tworzenie projektu internetowego interfejsu API
Aby utworzyć projekt internetowego interfejsu API:
W programie Visual Studio utwórz projekt internetowego interfejsu API platformy ASP.NET Core:
W oknie dialogowym Konfigurowanie nowego projektu nadaj projektowi nazwę PushNotificationsAPI.
W oknie dialogowym Dodatkowe informacje upewnij się, że pole wyboru Konfiguruj dla protokołu HTTPS i Użyj kontrolerów jest włączone:
Po utworzeniu projektu naciśnij F5 , aby uruchomić projekt.
Aplikacja jest obecnie skonfigurowana do używania
WeatherForecastController
elementu jakolaunchUrl
, który jest ustawiony w pliku Properties\launchSettings.json . Aplikacja zostanie uruchomiona w przeglądarce internetowej i wyświetli niektóre dane JSON.Ważne
Po uruchomieniu projektu ASP.NET Core korzystającego z protokołu HTTPS program Visual Studio wykryje, czy certyfikat dewelopera ASP.NET Core HTTPS jest zainstalowany w magazynie certyfikatów użytkownika lokalnego i będzie oferować jego zainstalowanie i zaufanie, jeśli go brakuje.
Zamknij przeglądarkę internetową.
W Eksplorator rozwiązań rozwiń folder Controllers i usuń WeatherForecastController.cs.
W Eksplorator rozwiązań w katalogu głównym projektu usuń WeatherForecast.cs.
Otwórz okno polecenia i przejdź do katalogu zawierającego plik projektu. Użyj następujących poleceń:
dotnet user-secrets init dotnet user-secrets set "NotificationHub:Name" <value> dotnet user-secrets set "NotificationHub:ConnectionString" "<value>"
Zastąp wartości symboli zastępczych własną nazwą usługi Azure Notification Hub i wartościami parametry połączenia. Można je znaleźć w następujących lokalizacjach w usłudze Azure Notification Hub:
Wartość konfiguracji Lokalizacja NotificationHub:Name
Zobacz Nazwę w podsumowaniu Podstawy w górnej części strony Przegląd . NotificationHub:ConnectinString
Zobacz DefaultFullSharedAccessSignature* na stronie Zasady dostępu. Spowoduje to skonfigurowanie lokalnych wartości konfiguracji przy użyciu narzędzia Secret Manager. Spowoduje to oddzielenie wpisów tajnych usługi Azure Notification Hub z rozwiązania Visual Studio, aby upewnić się, że nie są one w kontroli źródła.
Napiwek
W przypadku scenariuszy produkcyjnych rozważ usługę, taką jak Azure KeyVault, aby bezpiecznie przechowywać parametry połączenia.
Uwierzytelnianie klientów przy użyciu klucza interfejsu API
Aby uwierzytelnić klientów przy użyciu klucza interfejsu API:
Otwórz okno polecenia i przejdź do katalogu zawierającego plik projektu. Użyj następujących poleceń:
dotnet user-secrets set "Authentication:ApiKey" <value>
Zastąp wartość symbolu zastępczego kluczem interfejsu API, który może być dowolną wartością.
W programie Visual Studio dodaj nowy folder o nazwie Authentication do projektu, a następnie dodaj nową klasę o nazwie
ApiKeyAuthOptions
do folderu Authentication i zastąp jego kod następującym kodem:using Microsoft.AspNetCore.Authentication; namespace PushNotificationsAPI.Authentication; public class ApiKeyAuthOptions : AuthenticationSchemeOptions { public const string DefaultScheme = "ApiKey"; public string Scheme => DefaultScheme; public string ApiKey { get; set; } }
W programie Visual Studio dodaj nową klasę o nazwie
ApiKeyAuthHandler
do folderu Authentication i zastąp jego kod następującym kodem:using Microsoft.AspNetCore.Authentication; using Microsoft.Extensions.Options; using System.Security.Claims; using System.Text.Encodings.Web; namespace PushNotificationsAPI.Authentication; public class ApiKeyAuthHandler : AuthenticationHandler<ApiKeyAuthOptions> { const string ApiKeyIdentifier = "apikey"; public ApiKeyAuthHandler( IOptionsMonitor<ApiKeyAuthOptions> options, ILoggerFactory logger, UrlEncoder encoder) : base(options, logger, encoder) { } 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)); } }
Procedura obsługi uwierzytelniania to typ implementujący zachowanie schematu, który w tym przypadku jest niestandardowym schematem kluczy interfejsu API.
W programie Visual Studio dodaj nową klasę o nazwie
AuthenticationBuilderExtensions
do folderu Authentication i zastąp jego kod następującym kodem:using Microsoft.AspNetCore.Authentication; namespace PushNotificationsAPI.Authentication; public static class AuthenticationBuilderExtensions { public static AuthenticationBuilder AddApiKeyAuth( this AuthenticationBuilder builder, Action<ApiKeyAuthOptions> configureOptions) { return builder .AddScheme<ApiKeyAuthOptions, ApiKeyAuthHandler>( ApiKeyAuthOptions.DefaultScheme, configureOptions); } }
Ta metoda rozszerzenia zostanie użyta do uproszczenia kodu konfiguracji oprogramowania pośredniczącego w Program.cs.
W programie Visual Studio otwórz Program.cs i zaktualizuj kod, aby skonfigurować uwierzytelnianie klucza interfejsu API poniżej wywołania
builder.Services.AddControllers
metody :using PushNotificationsAPI.Authentication; builder.Services.AddControllers(); builder.Services.AddAuthentication(options => { options.DefaultAuthenticateScheme = ApiKeyAuthOptions.DefaultScheme; options.DefaultChallengeScheme = ApiKeyAuthOptions.DefaultScheme; }).AddApiKeyAuth(builder.Configuration.GetSection("Authentication").Bind);
W Program.cs zaktualizuj kod poniżej komentarza
// Configure the HTTP request pipeline
, aby wywołaćUseRouting
metody ,UseAuthentication
iMapControllers
rozszerzenia:// Configure the HTTP request pipeline. app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();
Metoda
UseAuthentication
rozszerzenia rejestruje oprogramowanie pośredniczące, które używa wcześniej zarejestrowanego schematu uwierzytelniania.UseAuthentication
należy wywołać przed każdym oprogramowaniem pośredniczącym, które zależy od uwierzytelnienia użytkowników.
Dodawanie i konfigurowanie usług
Aby dodać i skonfigurować usługi w aplikacji zaplecza internetowego interfejsu API:
W programie Visual Studio dodaj pakiet NuGet Microsoft.Azure.NotificationHubs do projektu. Ten pakiet NuGet służy do uzyskiwania dostępu do centrum powiadomień, hermetyzowanego w usłudze.
W programie Visual Studio dodaj nowy folder o nazwie Models do projektu, a następnie dodaj nową klasę o nazwie
PushTemplates
do folderu Models i zastąp jego kod następującym kodem:namespace PushNotificationsAPI.Models; public class PushTemplates { public class Generic { public const string Android = "{ \"message\" : { \"notification\" : { \"title\" : \"PushDemo\", \"body\" : \"$(alertMessage)\"}, \"data\" : { \"action\" : \"$(alertAction)\" } } }"; public const string iOS = "{ \"aps\" : {\"alert\" : \"$(alertMessage)\"}, \"action\" : \"$(alertAction)\" }"; } public class Silent { public const string Android = "{ \"message\" : { \"data\" : {\"message\" : \"$(alertMessage)\", \"action\" : \"$(alertAction)\"} } }"; public const string iOS = "{ \"aps\" : {\"content-available\" : 1, \"apns-priority\": 5, \"sound\" : \"\", \"badge\" : 0}, \"message\" : \"$(alertMessage)\", \"action\" : \"$(alertAction)\" }"; } }
Klasa
PushTemplates
zawiera tokenizowane ładunki powiadomień dla ogólnych i dyskretnych powiadomień wypychanych. Te ładunki są definiowane poza instalacją, aby umożliwić eksperymentowanie bez konieczności aktualizowania istniejących instalacji za pośrednictwem usługi. Obsługa zmian w instalacjach w ten sposób jest poza zakresem tego artykułu. W scenariuszach produktów rozważ użycie szablonów niestandardowych.W programie Visual Studio dodaj nową klasę o nazwie
DeviceInstallation
do folderu Models i zastąp kod następującym kodem:using System.ComponentModel.DataAnnotations; namespace PushNotificationsAPI.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>(); }
W programie Visual Studio dodaj nową klasę o nazwie
NotificationRequest
do folderu Models i zastąp kod następującym kodem:namespace PushNotificationsAPI.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; } }
W programie Visual Studio dodaj nową klasę o nazwie
NotificationHubOptions
do folderu Models i zastąp kod następującym kodem:using System.ComponentModel.DataAnnotations; namespace PushNotificationsAPI.Models; public class NotificationHubOptions { [Required] public string Name { get; set; } [Required] public string ConnectionString { get; set; } }
W programie Visual Studio dodaj nowy folder o nazwie Services do projektu, a następnie dodaj nowy interfejs o nazwie
INotificationService
do folderu Services i zastąp jego kod następującym kodem:using PushNotificationsAPI.Models; namespace PushNotificationsAPI.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); }
W programie Visual Studio dodaj nową klasę o nazwie
NotificationHubService
do folderu Services i zastąp jego kod następującym kodem:using Microsoft.Extensions.Options; using Microsoft.Azure.NotificationHubs; using PushNotificationsAPI.Models; namespace PushNotificationsAPI.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.FcmV1).ToLower(), NotificationPlatform.FcmV1 } }; } 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.SendFcmV1NativeNotificationAsync(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.SendFcmV1NativeNotificationAsync(androidPayload, tags, token), _hub.SendAppleNativeNotificationAsync(iOSPayload, tags, token) }; return Task.WhenAll(sendTasks); } }
Wyrażenie tagu dostarczone do
SendTemplateNotificationsAsync
metody jest ograniczone do 20 tagów, jeśli zawierają tylko jednostki ORS. W przeciwnym razie są one ograniczone do 6 tagów. Aby uzyskać więcej informacji, zobacz Routing i wyrażenia tagów.W programie Visual Studio otwórz Program.cs i zaktualizuj kod, aby dodać
NotificationHubService
element jako pojedynczą implementacjęINotificationService
poniżej wywołaniabuilder.Services.AddAuthentication
metody :using PushNotificationsAPI.Authentication; using PushNotificationsAPI.Services; using PushNotificationsAPI.Models; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); builder.Services.AddAuthentication(options => { options.DefaultAuthenticateScheme = ApiKeyAuthOptions.DefaultScheme; options.DefaultChallengeScheme = ApiKeyAuthOptions.DefaultScheme; }).AddApiKeyAuth(builder.Configuration.GetSection("Authentication").Bind); builder.Services.AddSingleton<INotificationService, NotificationHubService>(); builder.Services.AddOptions<NotificationHubOptions>() .Configure(builder.Configuration.GetSection("NotificationHub").Bind) .ValidateDataAnnotations(); var app = builder.Build();
Tworzenie interfejsu API REST powiadomień
Aby utworzyć interfejs API REST powiadomień:
W programie Visual Studio dodaj nowy kontroler o nazwie
NotificationsController
do folderu Controllers .Napiwek
Wybierz szablon Kontroler interfejsu API z akcjami odczytu/zapisu.
W pliku NotificationsController.cs dodaj następujące
using
instrukcje w górnej części pliku:using System.ComponentModel.DataAnnotations; using System.Net; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using PushNotificationsAPI.Models; using PushNotificationsAPI.Services;
W pliku NotificationsController.cs dodaj
Authorize
atrybut doNotificationsController
klasy:[Authorize] [ApiController] [Route("api/[controller]")] public class NotificationsController : ControllerBase
W pliku NotificationsController.cs zaktualizuj
NotificationsContoller
konstruktor, aby akceptował zarejestrowane wystąpienieINotificationService
jako argument i przypisz go do elementu członkowskiego tylko do odczytu:readonly INotificationService _notificationService; public NotificationsController(INotificationService notificationService) { _notificationService = notificationService; }
W pliku NotificationsContoller.cs zastąp wszystkie metody następującym kodem:
[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) { // Probably want to ensure deletion even if the connection is broken 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(); }
W pliku Właściwości/launchSettings.json zmień
launchUrl
właściwość dla każdego profilu zweatherforecast
naapi/notifications
.
Tworzenie aplikacji interfejsu API
Teraz utworzysz aplikację interfejsu API w usłudze aplikacja systemu Azure, aby hostować usługę zaplecza. Można to zrobić bezpośrednio z poziomu programu Visual Studio lub Visual Studio Code przy użyciu interfejsu wiersza polecenia platformy Azure, programu Azure PowerShell, interfejsu wiersza polecenia dla deweloperów platformy Azure i witryny Azure Portal. Aby uzyskać więcej informacji, zobacz Publikowanie aplikacji internetowej.
Aby utworzyć aplikację interfejsu API w witrynie Azure Portal:
W przeglądarce internetowej zaloguj się do witryny Azure Portal.
W witrynie Azure Portal kliknij przycisk Utwórz zasób , a następnie wyszukaj i wybierz pozycję Aplikacja interfejsu API przed wybraniem przycisku Utwórz .
Na stronie Tworzenie aplikacji interfejsu API zaktualizuj następujące pola przed wybraniem przycisku Utwórz:
Pole Akcja Subskrypcja Wybierz tę samą subskrypcję docelową, w której utworzono centrum powiadomień. Grupa zasobów Wybierz tę samą grupę zasobów, w której utworzono centrum powiadomień. Nazwisko Podaj globalnie unikatową nazwę. Stos środowiska uruchomieniowego Upewnij się, że wybrano najnowszą wersję platformy .NET. Po aprowizacji aplikacji interfejsu API przejdź do zasobu.
Na stronie Przegląd zanotuj domyślną wartość domeny. Ten adres URL to punkt końcowy zaplecza, który będzie używany z poziomu aplikacji .NET MAUI. Adres URL będzie używać określonej nazwy aplikacji interfejsu API z formatem
https://<app_name>.azurewebsites.net
.W witrynie Azure Portal przejdź do bloku Ustawienia > Zmienne środowiskowe , a następnie upewnij się, że wybrano kartę Ustawienia aplikacji. Następnie użyj przycisku Dodaj , aby dodać następujące ustawienia:
Nazwa/nazwisko Wartość Authentication:ApiKey <api_key_value> NotificationHub:Name <hub_name_value> NotificationHub:ConnectionString <hub_connection_string_value> Ważne
Dla
Authentication:ApiKey
uproszczenia dodano ustawienie aplikacji. W przypadku scenariuszy produkcyjnych rozważ usługę, taką jak Azure KeyVault, aby bezpiecznie przechowywać parametry połączenia.Po wprowadzeniu wszystkich tych ustawień wybierz przycisk Zastosuj , a następnie przycisk Potwierdź .
Publikowanie usługi zaplecza
Aby opublikować usługę zaplecza w usłudze aplikacja systemu Azure:
- W programie Visual Studio kliknij prawym przyciskiem myszy projekt i wybierz polecenie Publikuj.
- W kreatorze Publikowanie wybierz pozycję Azure, a następnie przycisk Dalej.
- W kreatorze Publikowanie wybierz pozycję usługa aplikacja systemu Azure (Windows), a następnie przycisk Dalej.
- W kreatorze Publikowanie postępuj zgodnie z przepływem uwierzytelniania, aby połączyć program Visual Studio z subskrypcją platformy Azure i opublikować aplikację.
Program Visual Studio kompiluje, pakuje i publikuje aplikację na platformie Azure, a następnie uruchamia aplikację w domyślnej przeglądarce. Aby uzyskać więcej informacji, zobacz Publikowanie ASP.NET aplikacji internetowej.
Napiwek
Profil publikowania aplikacji można pobrać z bloku Przegląd aplikacji interfejsu API w witrynie Azure Portal, a następnie opublikować aplikację przy użyciu profilu w programie Visual Studio.
Weryfikowanie opublikowanego interfejsu API
Aby sprawdzić, czy aplikacja interfejsu API została poprawnie opublikowana, należy użyć wybranego narzędzia REST, aby wysłać POST
żądanie do następującego adresu:
https://<app_name>.azurewebsites.net/api/notifications/requests
Uwaga
Adres podstawowy to https://<app_name>.azurewebsites.net
.
Upewnij się, że nagłówki żądań są skonfigurowane tak, aby zawierały klucz apikey
i jego wartość, ustaw treść na nieprzetworzoną i użyj następującej zawartości zastępczej JSON:
{}
Powinna zostać odebrana 400 Bad Request
odpowiedź z usługi.
Uwaga
Nie można jeszcze przetestować interfejsu API przy użyciu prawidłowych danych żądania, ponieważ będzie to wymagało informacji specyficznych dla platformy z aplikacji .NET MAUI.
Aby uzyskać więcej informacji na temat wywoływania interfejsów API REST, zobacz Use .http files in Visual Studio and Test web APIs with the Http Repl (Używanie plików HTTP w programie Visual Studio i testowanie internetowych interfejsów API za pomocą protokołu Http Repl). W programie Visual Studio Code klient REST może służyć do testowania interfejsów API REST.
Tworzenie aplikacji MAUI platformy .NET
W tej sekcji utworzysz aplikację interfejsu użytkownika aplikacji wieloplatformowej platformy .NET (.NET MAUI), która umożliwia zarejestrowanie się w celu otrzymywania powiadomień wypychanych z centrum powiadomień za pośrednictwem usługi zaplecza i anulowania rejestracji.
Aby utworzyć aplikację .NET MAUI:
W programie Visual Studio utwórz nową aplikację .NET MAUI o nazwie PushNotificationsDemo przy użyciu szablonu projektu .NET MAUI App .
W programie Visual Studio dodaj nowy folder o nazwie Models do projektu .NET MAUI, a następnie dodaj nową klasę o nazwie
DeviceInstallation
do folderu Models i zastąp jego kod następującym kodem:using System.Text.Json.Serialization; namespace PushNotificationsDemo.Models; public class DeviceInstallation { [JsonPropertyName("installationId")] public string InstallationId { get; set; } [JsonPropertyName("platform")] public string Platform { get; set; } [JsonPropertyName("pushChannel")] public string PushChannel { get; set; } [JsonPropertyName("tags")] public List<string> Tags { get; set; } = new List<string>(); }
W programie Visual Studio dodaj wyliczenie o nazwie
PushDemoAction
do folderu Models i zastąp jego kod następującym kodem:namespace PushNotificationsDemo.Models; public enum PushDemoAction { ActionA, ActionB }
W programie Visual Studio dodaj nowy folder o nazwie Services do projektu .NET MAUI, a następnie dodaj nowy interfejs o nazwie
IDeviceInstallationService
do folderu Services i zastąp jego kod następującym kodem:using PushNotificationsDemo.Models; namespace PushNotificationsDemo.Services; public interface IDeviceInstallationService { string Token { get; set; } bool NotificationsSupported { get; } string GetDeviceId(); DeviceInstallation GetDeviceInstallation(params string[] tags); }
Ten interfejs zostanie zaimplementowany na każdej platformie później, aby udostępnić
DeviceInstallation
informacje wymagane przez usługę zaplecza.W programie Visual Studio dodaj interfejs o nazwie
INotificationRegistrationService
do folderu Services i zastąp jego kod następującym kodem:namespace PushNotificationsDemo.Services; public interface INotificationRegistrationService { Task DeregisterDeviceAsync(); Task RegisterDeviceAsync(params string[] tags); Task RefreshRegistrationAsync(); }
Ten interfejs będzie obsługiwać interakcję między klientem a usługą zaplecza.
W programie Visual Studio dodaj interfejs o nazwie
INotificationActionService
do folderu Services i zastąp jego kod następującym kodem:namespace PushNotificationsDemo.Services; public interface INotificationActionService { void TriggerAction(string action); }
Ten interfejs będzie używany jako prosty mechanizm umożliwiający scentralizowanie obsługi akcji powiadomień.
W programie Visual Studio dodaj interfejs o nazwie
IPushDemoNotificationActionService
do folderu Services i zastąp jego kod następującym kodem:using PushNotificationsDemo.Models; namespace PushNotificationsDemo.Services; public interface IPushDemoNotificationActionService : INotificationActionService { event EventHandler<PushDemoAction> ActionTriggered; }
Typ
IPushDemoNotificationActionService
jest specyficzny dla tej aplikacji i używaPushDemoAction
wyliczenia do identyfikowania akcji wyzwalanej przy użyciu podejścia silnie typizowanego.W programie Visual Studio dodaj klasę o nazwie
NotificationRegistrationService
do folderu Services i zastąp jego kod następującym kodem:using System.Text; using System.Text.Json; using PushNotificationsDemo.Models; namespace PushNotificationsDemo.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; IDeviceInstallationService DeviceInstallationService => _deviceInstallationService ?? (_deviceInstallationService = Application.Current.Windows[0].Page.Handler.MauiContext.Services.GetService<IDeviceInstallationService>()); public NotificationRegistrationService(string baseApiUri, string apiKey) { _client = new HttpClient(); _client.DefaultRequestHeaders.Add("Accept", "application/json"); _client.DefaultRequestHeaders.Add("apikey", apiKey); _baseApiUrl = baseApiUri; } 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, JsonSerializer.Serialize(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 = JsonSerializer.Deserialize<string[]>(serializedTags); await RegisterDeviceAsync(tags); } async Task SendAsync<T>(HttpMethod requestType, string requestUri, T obj) { string serializedContent = null; await Task.Run(() => serializedContent = JsonSerializer.Serialize(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(); } }
W programie Visual Studio dodaj klasę o nazwie
PushDemoNotificationActionService
do folderu Services i zastąp jego kod następującym kodem:using PushNotificationsDemo.Models; namespace PushNotificationsDemo.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); } }
W programie Visual Studio dodaj klasę o nazwie
Config
do katalogu głównego projektu i zastąp jego kod następującym kodem:namespace PushNotificationsDemo; public static partial class Config { public static string ApiKey = "API_KEY"; public static string BackendServiceEndpoint = "BACKEND_SERVICE_ENDPOINT"; }
Klasa
Config
jest używana jako prosty sposób, aby zachować wpisy tajne poza kontrolą źródła. Możesz zastąpić te wartości w ramach zautomatyzowanej kompilacji lub zastąpić je przy użyciu lokalnej klasy częściowej.Ważne
Podczas określania adresu podstawowego w aplikacji .NET MAUI upewnij się, że kończy się na .
/
W programie Visual Studio dodaj klasę o nazwie
Config.local_secrets
do katalogu głównego projektu. Następnie zastąp kod w pliku Config.local_secrets.cs następującym kodem:namespace PushNotificationsDemo; public static partial class Config { static Config() { ApiKey = "<your_api_key>"; BackendServiceEndpoint = "<your_api_app_url>"; } }
Zamień wartości symboli zastępczych na wartości wybrane podczas tworzenia usługi zaplecza. Adres
BackendServiceEndpoint
URL powinien używać formatuhttps://<api_app_name>.azurewebsites.net/
.Napiwek
Pamiętaj, aby dodać
*.local_secrets.*
plik do.gitignore
pliku, aby uniknąć zatwierdzania tego pliku do kontroli źródła.
Tworzenie interfejsu użytkownika
Aby utworzyć interfejs użytkownika aplikacji:
W programie Visual Studio otwórz plik MainPage.xaml i zastąp element
VerticalStackLayout
i jego elementami podrzędnymi następującym kodem XAML:<VerticalStackLayout Margin="20" Spacing="6"> <Button x:Name="registerButton" Text="Register" Clicked="OnRegisterButtonClicked" /> <Button x:Name="deregisterButton" Text="Deregister" Clicked="OnDeregisterButtonClicked" /> </VerticalStackLayout>
W programie Visual Studio otwórz MainPage.xaml.cs i dodaj instrukcję
using
dlaPushNotificationsDemo.Services
przestrzeni nazw:using PushNotificationsDemo.Services;
W MainPage.xaml.cs dodaj
readonly
pole zapasowe, aby zapisać odwołanie do implementacjiINotificationRegistrationService
:readonly INotificationRegistrationService _notificationRegistrationService;
W konstruktorze
MainPage
rozwiąż implementacjęINotificationRegistrationService
i przypisz ją do pola zapasowego_notificationRegistrationService
:public MainPage(INotificationRegistrationService service) { InitializeComponent(); _notificationRegistrationService = service; }
W klasie zaimplementuj
MainPage
OnRegisterButtonClicked
programy obsługi zdarzeń iOnDeregisterButtonClicked
, wywołując odpowiednie metody rejestru i wyrejestrowania wINotificationRegistrationService
obiekcie:void OnRegisterButtonClicked(object sender, EventArgs e) { _notificationRegistrationService.RegisterDeviceAsync() .ContinueWith((task) => { ShowAlert(task.IsFaulted ? task.Exception.Message : $"Device registered"); }); } void OnDeregisterButtonClicked(object sender, EventArgs e) { _notificationRegistrationService.DeregisterDeviceAsync() .ContinueWith((task) => { ShowAlert(task.IsFaulted ? task.Exception.Message : $"Device deregistered"); }); } void ShowAlert(string message) { MainThread.BeginInvokeOnMainThread(() => { DisplayAlert("Push notifications demo", message, "OK") .ContinueWith((task) => { if (task.IsFaulted) throw task.Exception; }); }); }
Ważne
W aplikacji rejestracja i anulowanie rejestracji jest wykonywana w odpowiedzi na dane wejściowe użytkownika, aby umożliwić łatwiejsze eksplorowanie i testowanie tej funkcji. W aplikacji produkcyjnej zazwyczaj wykonujesz akcje rejestracji i anulowania rejestracji w odpowiednim punkcie cyklu życia aplikacji bez konieczności jawnego wprowadzania danych przez użytkownika.
W programie Visual Studio otwórz App.xaml.cs i dodaj następujące
using
instrukcje:using PushNotificationsDemo.Models; using PushNotificationsDemo.Services;
W App.xaml.cs dodaj
readonly
pole zapasowe, aby zapisać odwołanie do implementacjiIPushDemoNotificationActionService
:readonly IPushDemoNotificationActionService _actionService;
W konstruktorze
App
rozwiąż implementacjęIPushDemoNotificationActionService
i przypisz ją do pola zapasowego_actionService
, a następnie zasubskrybujIPushDemoNotificationActionService.ActionTriggered
zdarzenie:public App(IPushDemoNotificationActionService service) { InitializeComponent(); _actionService = service; _actionService.ActionTriggered += NotificationActionTriggered; MainPage = new AppShell(); }
W konstruktorze
App
rozwiąż implementacjęIPushDemoNotificationActionService
i przypisz ją do pola zapasowego_actionService
, a następnie zasubskrybujIPushDemoNotificationActionService.ActionTriggered
zdarzenie:public App(IPushDemoNotificationActionService service) { InitializeComponent(); _actionService = service; _actionService.ActionTriggered += NotificationActionTriggered; }
W klasie zaimplementuj
App
program obsługi zdarzeń dlaIPushDemoNotificationActionService.ActionTriggered
zdarzenia:void NotificationActionTriggered(object sender, PushDemoAction e) { ShowActionAlert(e); } void ShowActionAlert(PushDemoAction action) { MainThread.BeginInvokeOnMainThread(() => { Windows[0].Page?.DisplayAlert("Push notifications demo", $"{action} action received.", "OK") .ContinueWith((task) => { if (task.IsFaulted) throw task.Exception; }); }); }
Procedura obsługi zdarzeń dla
ActionTriggered
zdarzenia demonstruje potwierdzenie i propagację akcji powiadomień wypychanych. Zazwyczaj są one obsługiwane w trybie dyskretnym, na przykład przechodzenie do określonego widoku lub odświeżanie niektórych danych zamiast wyświetlania alertu.
Konfigurowanie aplikacji systemu Android
Aby skonfigurować aplikację .NET MAUI w systemie Android w celu odbierania i przetwarzania powiadomień wypychanych:
W programie Visual Studio dodaj pakiet NuGet Xamarin.Firebase.Messaging do projektu aplikacji .NET MAUI.
W programie Visual Studio dodaj plik google-services.json do folderu Platformy/Android projektu aplikacji .NET MAUI. Po dodaniu pliku do projektu powinien zostać dodany z akcją kompilacji :
GoogleServicesJson
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0-android'"> <GoogleServicesJson Include="Platforms\Android\google-services.json" /> </ItemGroup>
Napiwek
Pamiętaj, aby dodać
google-services.json
plik do.gitignore
pliku, aby uniknąć zatwierdzania tego pliku do kontroli źródła.W programie Visual Studio edytuj plik projektu (*.csproj) i ustaw
SupportedOSPlatformVersion
dla systemu Android wartość 26.0:<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">26.0</SupportedOSPlatformVersion>
Google dokonało zmian w kanałach powiadomień systemu Android w interfejsie API 26. Aby uzyskać więcej informacji, zobacz Kanały powiadomień w developer.android.com.
W folderze Platformy/Android projektu dodaj nową klasę o nazwie
DeviceInstallationService
i zastąp jej kod następującym kodem:using Android.Gms.Common; using PushNotificationsDemo.Models; using PushNotificationsDemo.Services; using static Android.Provider.Settings; namespace PushNotificationsDemo.Platforms.Android; public class DeviceInstallationService : IDeviceInstallationService { public string Token { get; set; } public bool NotificationsSupported => GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(Platform.AppContext) == ConnectionResult.Success; public string GetDeviceId() => Secure.GetString(Platform.AppContext.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 FCMv1."); var installation = new DeviceInstallation { InstallationId = GetDeviceId(), Platform = "fcmv1", PushChannel = Token }; installation.Tags.AddRange(tags); return installation; } string GetPlayServicesError() { int resultCode = GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(Platform.AppContext); if (resultCode != ConnectionResult.Success) return GoogleApiAvailability.Instance.IsUserResolvableError(resultCode) ? GoogleApiAvailability.Instance.GetErrorString(resultCode) : "This device isn't supported."; return "An error occurred preventing the use of push notifications."; } }
Ta klasa udostępnia unikatowy identyfikator, używając
Secure.AndroidId
wartości i ładunku rejestracji centrum powiadomień.W folderze Platformy/Android projektu dodaj nową klasę o nazwie
PushNotificationFirebaseMessagingService
i zastąp jej kod następującym kodem:using Android.App; using Firebase.Messaging; using PushNotificationsDemo.Services; namespace PushNotificationsDemo.Platforms.Android; [Service(Exported = false)] [IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })] public class PushNotificationFirebaseMessagingService : FirebaseMessagingService { IPushDemoNotificationActionService _notificationActionService; INotificationRegistrationService _notificationRegistrationService; IDeviceInstallationService _deviceInstallationService; int _messageId; IPushDemoNotificationActionService NotificationActionService => _notificationActionService ?? (_notificationActionService = IPlatformApplication.Current.Services.GetService<IPushDemoNotificationActionService>()); INotificationRegistrationService NotificationRegistrationService => _notificationRegistrationService ?? (_notificationRegistrationService = IPlatformApplication.Current.Services.GetService<INotificationRegistrationService>()); IDeviceInstallationService DeviceInstallationService => _deviceInstallationService ?? (_deviceInstallationService = IPlatformApplication.Current.Services.GetService<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) { base.OnMessageReceived(message); if (message.Data.TryGetValue("action", out var messageAction)) NotificationActionService.TriggerAction(messageAction); } }
Ta klasa ma
IntentFilter
atrybut zawierającycom.google.firebase.MESSAGING_EVENT
filtr. Ten filtr umożliwia systemowi Android przekazywanie przychodzących komunikatów do tej klasy na potrzeby przetwarzania.Aby uzyskać informacje o formacie komunikatów firebase Cloud Messaging, zobacz About FCM messages on developer.android.com (Informacje o komunikatach FCM w developer.android.com).
W programie Visual Studio otwórz plik MainActivity.cs w folderze Platformy/Android i dodaj następujące
using
instrukcje:using Android.App; using Android.Content; using Android.Content.PM; using Android.OS; using PushNotificationsDemo.Services; using Firebase.Messaging;
MainActivity
W klasie ustawLaunchMode
wartość naSingleTop
, aby element nie został utworzony ponownie po otwarciuMainActivity
:[Activity( Theme = "@style/Maui.SplashTheme", MainLauncher = true, LaunchMode = LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
MainActivity
W klasie dodaj pola zapasowe do przechowywania odwołań doIPushDemoNotificationActionService
implementacji iIDeviceInstallationService
:IPushDemoNotificationActionService _notificationActionService; IDeviceInstallationService _deviceInstallationService;
MainActivity
W klasie dodajNotificationActionService
iDeviceInstallationService
właściwości prywatne, które pobierają konkretne implementacje z kontenera wstrzykiwania zależności aplikacji:IPushDemoNotificationActionService NotificationActionService => _notificationActionService ?? (_notificationActionService = IPlatformApplication.Current.Services.GetService<IPushDemoNotificationActionService>()); IDeviceInstallationService DeviceInstallationService => _deviceInstallationService ?? (_deviceInstallationService = IPlatformApplication.Current.Services.GetService<IDeviceInstallationService>());
W klasie zaimplementuj
MainActivity
Android.Gms.Tasks.IOnSuccessListener
interfejs w celu pobrania i zapisania tokenu Firebase:public class MainActivity : MauiAppCompatActivity, Android.Gms.Tasks.IOnSuccessListener { public void OnSuccess(Java.Lang.Object result) { DeviceInstallationService.Token = result.ToString(); } }
MainActivity
W klasie dodaj metodęProcessNotificationActions
, która sprawdzi, czy danaIntent
wartość ma dodatkową wartość o nazwieaction
, a następnie warunkowo wyzwalanaaction
przy użyciuIPushDemoNotificationActionService
implementacji:void ProcessNotificationsAction(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); } }
MainActivity
W klasie zastąpij metodęOnNewIntent
, aby wywołać metodęProcessNotificationActions
:protected override void OnNewIntent(Intent? intent) { base.OnNewIntent(intent); ProcessNotificationsAction(intent); }
LaunchMode
Ponieważ dla parametruActivity
jest ustawiona wartośćSingleTop
, elementIntent
zostanie wysłany do istniejącegoActivity
wystąpienia za pośrednictwemOnNewIntent
przesłonięcia, a nieOnCreate
metody. W związku z tym należy obsługiwać intencję przychodzącą zarówno w , jakOnNewIntent
iOnCreate
.MainActivity
W klasie zastąp metodęOnCreate
, aby wywołać metodęProcessNotificationActions
, i pobrać token z bazy firebase, dodającMainActivity
jako :IOnSuccessListener
protected override void OnCreate(Bundle? savedInstanceState) { base.OnCreate(savedInstanceState); if (DeviceInstallationService.NotificationsSupported) FirebaseMessaging.Instance.GetToken().AddOnSuccessListener(this); ProcessNotificationsAction(Intent); }
Uwaga
Aplikacja musi zostać ponownie zarejestrowana przy każdym uruchomieniu i zatrzymać ją z sesji debugowania, aby nadal otrzymywać powiadomienia wypychane.
W programie Visual Studio dodaj
POST_NOTIFICATIONS
uprawnienie do pliku AndroidManifest.xml w folderze Platformy/Android :<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
Aby uzyskać więcej informacji na temat tego uprawnienia, zobacz Uprawnienia środowiska uruchomieniowego powiadomień w developer.android.com.
W programie Visual Studio otwórz MainPage.xaml.cs i dodaj następujący kod do
MainPage
klasy:#if ANDROID protected override async void OnAppearing() { base.OnAppearing(); PermissionStatus status = await Permissions.RequestAsync<Permissions.PostNotifications>(); } #endif
Ten kod jest uruchamiany w systemie Android po
MainPage
wyświetleniu i żąda od użytkownika udzieleniaPOST_NOTIFICATIONS
uprawnienia. Aby uzyskać więcej informacji na temat uprawnień programu .NET MAUI, zobacz Uprawnienia.
Konfigurowanie aplikacji systemu iOS
Symulator systemu iOS obsługuje powiadomienia zdalne w systemie iOS 16 lub nowszym podczas uruchamiania w systemie macOS 13 lub nowszym na komputerach Mac z procesorami krzemowymi firmy Apple lub T2. Każdy symulator generuje tokeny rejestracji, które są unikatowe dla kombinacji tego symulatora i sprzętu mac, na którym działa.
Ważne
Symulator obsługuje środowisko piaskownicy usługi Apple Push Notification Service.
W poniższych instrukcjach założono, że używasz sprzętu obsługującego odbieranie powiadomień zdalnych w symulatorze systemu iOS. Jeśli tak nie jest, musisz uruchomić aplikację systemu iOS na urządzeniu fizycznym, co będzie wymagało utworzenia profilu aprowizacji dla aplikacji, która obejmuje możliwość powiadomień wypychanych. Następnie należy upewnić się, że aplikacja została skompilowana przy użyciu certyfikatu i profilu aprowizacji. Aby uzyskać więcej informacji na temat tego, jak to zrobić, zobacz Konfigurowanie aplikacji systemu iOS do pracy z usługą Azure Notification Hubs, a następnie postępuj zgodnie z poniższymi instrukcjami.
Aby skonfigurować aplikację .NET MAUI w systemie iOS w celu odbierania i przetwarzania powiadomień wypychanych:
W programie Visual Studio edytuj plik projektu (*.csproj) i ustaw
SupportedOSPlatformVersion
dla systemu iOS wartość 13.0:<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">13.0</SupportedOSPlatformVersion>
Firma Apple dokonała zmian w swojej usłudze wypychania w systemie iOS 13. Aby uzyskać więcej informacji, zobacz Aktualizacje usługi Azure Notification Hubs dla systemu iOS 13.
W programie Visual Studio dodaj plik Entitlements.plist do folderu Platforms/iOS projektu i dodaj następujący kod XML do pliku:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>aps-environment</key> <string>development</string> </dict> </plist>
Spowoduje to ustawienie uprawnień środowiska usługi APS i określa użycie środowiska deweloperskiego apple Push Notification Service. W aplikacjach produkcyjnych ta wartość uprawnień powinna być ustawiona na
production
wartość . Aby uzyskać więcej informacji na temat tego uprawnienia, zobacz Uprawnienia środowiska usługi APS w developer.apple.com.Aby uzyskać więcej informacji na temat dodawania pliku uprawnień, zobacz uprawnienia systemu iOS.
W programie Visual Studio dodaj nową klasę o nazwie
DeviceInstallationService
do folderu Platformy/iOS projektu i dodaj następujący kod do pliku:using PushNotificationsDemo.Services; using PushNotificationsDemo.Models; using UIKit; namespace PushNotificationsDemo.Platforms.iOS; 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"; } }
Ta klasa udostępnia unikatowy identyfikator, używając
UIDevice.IdentifierForVendor
wartości i ładunku rejestracji centrum powiadomień.W programie Visual Studio dodaj nową klasę o nazwie
NSDataExtensions
do folderu Platformy/iOS projektu i dodaj następujący kod do pliku:using Foundation; using System.Text; namespace PushNotificationsDemo.Platforms.iOS; 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(); } }
Metoda
ToHexString
rozszerzenia będzie zużywana przez kod, który analizuje pobrany token urządzenia.W programie Visual Studio otwórz plik AppDelegate.cs w folderze Platformy/iOS i dodaj następujące
using
instrukcje:using System.Diagnostics; using Foundation; using PushNotificationsDemo.Platforms.iOS; using PushNotificationsDemo.Services; using UIKit; using UserNotifications;
AppDelegate
W klasie dodaj pola zapasowe do przechowywania odwołań doIPushDemoNotificationActionService
implementacji ,INotificationRegistrationService
iIDeviceInstallationService
:IPushDemoNotificationActionService _notificationActionService; INotificationRegistrationService _notificationRegistrationService; IDeviceInstallationService _deviceInstallationService;
AppDelegate
W klasie dodajNotificationActionService
właściwości ,NotificationRegistrationService
iDeviceInstallationService
prywatne, które pobierają konkretne implementacje z kontenera wstrzykiwania zależności aplikacji:IPushDemoNotificationActionService NotificationActionService => _notificationActionService ?? (_notificationActionService = IPlatformApplication.Current.Services.GetService<IPushDemoNotificationActionService>()); INotificationRegistrationService NotificationRegistrationService => _notificationRegistrationService ?? (_notificationRegistrationService = IPlatformApplication.Current.Services.GetService<INotificationRegistrationService>()); IDeviceInstallationService DeviceInstallationService => _deviceInstallationService ?? (_deviceInstallationService = IPlatformApplication.Current.Services.GetService<IDeviceInstallationService>());
AppDelegate
W klasie dodaj metodęCompleteRegistrationAsync
, aby ustawićIDeviceInstallationService.Token
wartość właściwości:Task CompleteRegistrationAsync(NSData deviceToken) { DeviceInstallationService.Token = deviceToken.ToHexString(); return NotificationRegistrationService.RefreshRegistrationAsync(); }
Ta metoda odświeża również rejestrację i buforuje token urządzenia, jeśli został on zaktualizowany od czasu jego ostatniego przechowywania.
AppDelegate
W klasie dodaj metodęProcessNotificationActions
przetwarzaniaNSDictionary
danych powiadomień i warunkowo wywołując metodęNotificationActionService.TriggerAction
:void ProcessNotificationActions(NSDictionary userInfo) { if (userInfo == null) return; try { // If your app isn't in the foreground, the notification goes to Notification Center. // If your app is in the foreground, the notification goes directly to your app and you // need to process the notification payload yourself. 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); } }
AppDelegate
W klasie dodaj metodęRegisteredForRemoteNotifications
przekazującądeviceToken
argument doCompleteRegistrationAsync
metody :[Export("application:didRegisterForRemoteNotificationsWithDeviceToken:")] public void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken) { CompleteRegistrationAsync(deviceToken) .ContinueWith((task) => { if (task.IsFaulted) throw task.Exception; }); }
Ta metoda zostanie wywołana, gdy aplikacja zostanie zarejestrowana w celu odbierania powiadomienia zdalnego i będzie używana do żądania unikatowego tokenu urządzenia, który jest w rzeczywistości adresem aplikacji na urządzeniu.
AppDelegate
W klasie dodaj metodęReceivedRemoteNotification
przekazującąuserInfo
argument doProcessNotificationActions
metody :[Export("application:didReceiveRemoteNotification:")] public void ReceivedRemoteNotification(UIApplication application, NSDictionary userInfo) { ProcessNotificationActions(userInfo); }
Ta metoda będzie wywoływana, gdy aplikacja otrzymała powiadomienie zdalne i jest używana do przetwarzania powiadomienia.
AppDelegate
W klasie dodaj metodęFailedToRegisterForRemoteNotifications
, aby rejestrować błędy:[Export("application:didFailToRegisterForRemoteNotificationsWithError:")] public void FailedToRegisterForRemoteNotifications(UIApplication application, NSError error) { Debug.WriteLine(error.Description); }
Ta metoda zostanie wywołana, gdy aplikacja nie może zarejestrować się w celu odbierania powiadomień zdalnych. Rejestracja może zakończyć się niepowodzeniem, jeśli urządzenie nie jest połączone z siecią, jeśli serwer APNS jest niemożliwy do osiągnięcia lub jeśli aplikacja jest niepoprawnie skonfigurowana.
Uwaga
W przypadku scenariuszy produkcyjnych należy zaimplementować odpowiednie rejestrowanie i obsługę błędów w metodzie
FailedToRegisterForRemoteNotifications
.AppDelegate
W klasie dodaj metodęFinishedLaunching
, aby warunkowo zażądać uprawnień do korzystania z powiadomień i zarejestrować się w celu otrzymywania powiadomień zdalnych:[Export("application:didFinishLaunchingWithOptions:")] public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions) { if (DeviceInstallationService.NotificationsSupported) { UNUserNotificationCenter.Current.RequestAuthorization( UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge | UNAuthorizationOptions.Sound, (approvalGranted, error) => { if (approvalGranted && error == null) { MainThread.BeginInvokeOnMainThread(() => { UIApplication.SharedApplication.RegisterForRemoteNotifications(); }); } }); } using (var userInfo = launchOptions?.ObjectForKey(UIApplication.LaunchOptionsRemoteNotificationKey) as NSDictionary) { ProcessNotificationActions(userInfo); } return base.FinishedLaunching(application, launchOptions); }
Aby uzyskać informacje na temat monitowania o uprawnienie do korzystania z powiadomień, zobacz Monituj o uprawnienie do korzystania z powiadomień w developer.apple.com.
Aby uzyskać informacje o powiadomieniach w systemie iOS, zobacz Powiadomienia użytkowników w developer.apple.com.
Rejestrowanie typów w kontenerze wstrzykiwania zależności aplikacji
W programie Visual Studio otwórz MauiProgram.cs i dodaj instrukcję
using
dlaPushNotificationsDemo.Services
przestrzeni nazw:using PushNotificationsDemo.Services;
MauiProgram
W klasie dodaj kod dlaRegisterServices
metody rozszerzenia, która rejestrujeDeviceInstallationService
element na każdej platformie, oraz międzyplatformowePushDemoNotificationActionService
iNotificationRegistrationService
usługi, a następnie zwracaMauiAppBuilder
obiekt:public static MauiAppBuilder RegisterServices(this MauiAppBuilder builder) { #if IOS builder.Services.AddSingleton<IDeviceInstallationService, PushNotificationsDemo.Platforms.iOS.DeviceInstallationService>(); #elif ANDROID builder.Services.AddSingleton<IDeviceInstallationService, PushNotificationsDemo.Platforms.Android.DeviceInstallationService>(); #endif builder.Services.AddSingleton<IPushDemoNotificationActionService, PushDemoNotificationActionService>(); builder.Services.AddSingleton<INotificationRegistrationService>(new NotificationRegistrationService(Config.BackendServiceEndpoint, Config.ApiKey)); return builder; }
MauiProgram
W klasie dodaj kod dlaRegisterViews
metody rozszerzenia, która rejestrujeMainPage
typ jako pojedynczy i który zwracaMauiAppBuilder
obiekt:public static MauiAppBuilder RegisterViews(this MauiAppBuilder builder) { builder.Services.AddSingleton<MainPage>(); return builder; }
Typ
MainPage
jest zarejestrowany, ponieważ wymagaINotificationRegistrationService
zależności, a wszystkie typy wymagające zależności muszą być zarejestrowane w kontenerze wstrzykiwania zależności.W klasie zmodyfikuj
MauiProgram
metodęCreateMauiApp
, tak aby wywołałaRegisterServices
metody iRegisterViews
rozszerzenia:public static MauiApp CreateMauiApp() { var builder = MauiApp.CreateBuilder(); builder .UseMauiApp<App>() .ConfigureFonts(fonts => { fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); }) .RegisterServices() .RegisterViews(); #if DEBUG builder.Logging.AddDebug(); #endif return builder.Build(); }
Aby uzyskać więcej informacji na temat wstrzykiwania zależności w programie .NET MAUI, zobacz Wstrzykiwanie zależności.
Testowanie aplikacji
Aplikację można przetestować, wysyłając powiadomienia wypychane do aplikacji przy użyciu usługi zaplecza lub za pośrednictwem witryny Azure Portal.
Symulator systemu iOS obsługuje powiadomienia zdalne w systemie iOS 16 lub nowszym podczas uruchamiania w systemie macOS 13 lub nowszym na komputerach Mac z procesorami krzemowymi firmy Apple lub T2. Jeśli nie spełniasz tych wymagań sprzętowych, musisz przetestować aplikację systemu iOS na urządzeniu fizycznym. W systemie Android możesz przetestować aplikację na odblokowanym urządzeniu fizycznym dewelopera lub emulatorze.
Systemy Android i iOS wyświetlają powiadomienia wypychane w imieniu aplikacji, gdy są uruchomione w tle. Jeśli aplikacja jest uruchomiona na pierwszym planie po odebraniu powiadomienia, kod aplikacji określa zachowanie. Możesz na przykład zaktualizować interfejs aplikacji, aby odzwierciedlić nowe informacje zawarte w powiadomieniu.
Testowanie przy użyciu usługi zaplecza
Aby wysłać testowe powiadomienie wypychane do aplikacji za pośrednictwem usługi zaplecza opublikowanej w usłudze aplikacja systemu Azure Service:
W programie Visual Studio uruchom aplikację PushNotificationsDemo w systemie Android lub iOS i wybierz przycisk Zarejestruj .
Uwaga
Jeśli testujesz w systemie Android, upewnij się, że nie używasz konfiguracji debugowania. Alternatywnie, jeśli aplikacja została wcześniej wdrożona, upewnij się, że została zamknięta, a następnie uruchom ją ponownie z poziomu uruchamiania.
W wybranym narzędziu REST wyślij
POST
żądanie na następujący adres:https://<app_name>.azurewebsites.net/api/notifications/requests
Upewnij się, że nagłówki żądań są skonfigurowane tak, aby zawierały klucz
apikey
i jego wartość, ustawić treść na nieprzetworzoną i użyć następującej zawartości JSON:{ "text": "Message from REST tooling!", "action": "action_a" }
Ogólne żądanie powinno być podobne do następującego przykładu:
POST /api/notifications/requests HTTP/1.1 Host: https://<app_name>.azurewebsites.net apikey: <your_api_key> Content-Type: application/json { "text": "Message from REST tooling!", "action": "action_a" }
W wybranym narzędziu REST sprawdź, czy otrzymasz odpowiedź 200 OK .
W aplikacji w systemie Android lub iOS powinien zostać wyświetlony alert z odebraną akcją ActionA.
Aby uzyskać więcej informacji na temat wywoływania interfejsów API REST, zobacz Use .http files in Visual Studio and Test web APIs with the Http Repl (Używanie plików HTTP w programie Visual Studio i testowanie internetowych interfejsów API za pomocą protokołu Http Repl). W programie Visual Studio Code klient REST może służyć do testowania interfejsów API REST.
Testowanie przy użyciu witryny Azure Portal
Usługa Azure Notification Hubs umożliwia sprawdzenie, czy aplikacja może odbierać powiadomienia wypychane.
Aby wysłać testowe powiadomienie wypychane do aplikacji za pośrednictwem witryny Azure Portal:
W programie Visual Studio uruchom aplikację PushNotificationsDemo w systemie Android lub iOS i wybierz przycisk Zarejestruj .
Uwaga
Jeśli testujesz w systemie Android, upewnij się, że nie używasz konfiguracji debugowania. Alternatywnie, jeśli aplikacja została wcześniej wdrożona, upewnij się, że została zamknięta, a następnie uruchom ją ponownie z poziomu uruchamiania.
W witrynie Azure Portal przejdź do centrum powiadomień i wybierz przycisk Wyślij test w bloku Przegląd.
W bloku Wysyłanie testowe wybierz wymaganą platformę i zmodyfikuj ładunek.
W przypadku firmy Apple użyj następującego ładunku:
{ "aps": { "alert": "Message from Notification Hub!" }, "action": "action_a" }
W przypadku systemu Android użyj następującego ładunku:
{ "message": { "notification": { "title": "PushDemo", "body": "Message from Notification Hub!" }, "data": { "action": "action_a" } } }
Witryna Azure Portal powinna wskazywać, że powiadomienie zostało pomyślnie wysłane.
Aby uzyskać informacje o formacie komunikatów firebase Cloud Messaging, zobacz About FCM messages on developer.android.com (Informacje o komunikatach FCM w developer.android.com).
W aplikacji w systemie Android lub iOS powinien zostać wyświetlony alert z odebraną akcją ActionA.
Rozwiązywanie problemów
W poniższych sekcjach omówiono typowe problemy występujące podczas próby korzystania z powiadomień wypychanych w aplikacji klienckiej.
Brak odpowiedzi z usługi zaplecza
Podczas testowania lokalnego upewnij się, że usługa zaplecza jest uruchomiona i używa poprawnego portu.
W przypadku testowania aplikacji interfejsu API platformy Azure sprawdź, czy usługa jest uruchomiona i została wdrożona i została uruchomiona bez błędów.
Upewnij się, że adres podstawowy został poprawnie określony w narzędziu REST lub w konfiguracji aplikacji .NET MAUI. Adres podstawowy powinien być https://<api_name>.azurewebsites.net
lub https://localhost:7020
podczas testowania lokalnego.
Odbieranie kodu stanu 401 z usługi zaplecza
Sprawdź, czy poprawnie ustawiasz apikey
nagłówek żądania i czy ta wartość jest zgodna z wartością skonfigurowaną dla usługi zaplecza.
Jeśli ten błąd zostanie wyświetlony podczas testowania lokalnego, upewnij się, że wartość klucza zdefiniowana w aplikacji .NET MAUI odpowiada Authentication:ApiKey
wartości wpisów tajnych użytkownika używanych przez usługę zaplecza.
Jeśli testujesz przy użyciu aplikacji interfejsu API platformy Azure, upewnij się, że wartość klucza zdefiniowana w aplikacji .NET MAUI jest zgodna Authentication:ApiKey
z wartością ustawienia aplikacji zdefiniowaną w witrynie Azure Portal. Jeśli to ustawienie aplikacji zostało utworzone lub zmienione po wdrożeniu usługi zaplecza, musisz ponownie uruchomić usługę, aby wartość została wdrożona.
Odbieranie kodu stanu 404 z usługi zaplecza
Sprawdź, czy punkt końcowy i metoda żądania HTTP są poprawne:
- KŁAŚĆ-
https://<api_name>.azurewebsites.net/api/notifications/installations
- USUNĄĆ-
https://<api_name>.azurewebsites.net/api/notifications/installations/<installation_id>
- POST-
https://<api_name>.azurewebsites.net/api/notifications/requests
Lub podczas testowania lokalnego:
- KŁAŚĆ-
https://localhost:7020/api/notifications/installations
- USUNĄĆ-
https://localhost:7020/api/notifications/installations/<installation_id>
- POST-
https://localhost:7020/api/notifications/requests
Ważne
Podczas określania adresu podstawowego w aplikacji .NET MAUI upewnij się, że kończy się na ./
Adres podstawowy powinien być https://<api_name>.azurewebsites.net
lub https://localhost:7020/
podczas testowania lokalnego.
Nie otrzymuję powiadomień w systemie Android po uruchomieniu lub zatrzymaniu sesji debugowania
Upewnij się, że rejestrujesz się za każdym razem, gdy rozpoczynasz sesję debugowania. Debuger spowoduje wygenerowanie nowego tokenu programu Firebase, dlatego należy zaktualizować instalację centrum powiadomień.
Nie można zarejestrować i zostanie wyświetlony komunikat o błędzie centrum powiadomień
Sprawdź, czy urządzenie testowe ma łączność sieciową. Następnie określ kod stanu odpowiedzi HTTP, ustawiając punkt przerwania w celu sprawdzenia StatusCode
właściwości w obiekcie HttpResponse
.
Przejrzyj poprzednie sugestie dotyczące rozwiązywania problemów, jeśli ma to zastosowanie, na podstawie kodu stanu.
Ustaw punkt przerwania w wierszach, które zwracają określone kody stanu odpowiedniego interfejsu API. Następnie spróbuj wywołać usługę zaplecza podczas lokalnego debugowania.
Zweryfikuj, czy usługa zaplecza działa zgodnie z oczekiwaniami według wybranego narzędzia REST, i użyj ładunku utworzonego przez aplikację .NET MAUI dla wybranej platformy.
Przejrzyj sekcje konfiguracji specyficzne dla platformy, aby upewnić się, że nie pominięto żadnych kroków. Sprawdź, czy odpowiednie wartości są rozpoznawane jako InstallationId
zmienne i Token
dla wybranej platformy.
Nie można rozpoznać identyfikatora urządzenia w komunikacie o błędzie urządzenia
Przejrzyj sekcje konfiguracji specyficzne dla platformy, aby upewnić się, że nie pominięto żadnych kroków.