Aracılığıyla paylaş


Öğretici: Arka uç hizmeti aracılığıyla Azure Notification Hubs kullanarak .NET MAUI uygulamalarına anında iletme bildirimleri gönderme

Örneğe göz atın. Örneğe göz atın

Anında iletme bildirimleri, bir arka uç sisteminden istemci uygulamasına bilgi sağlar. Apple, Google ve diğer platformların her birinin kendi Anında İletme Bildirimi Hizmeti (PNS) vardır. Azure Notification Hubs, arka uç uygulamanızın tek bir hub ile iletişim kurabilmesi için bildirimleri platformlar arasında merkezi hale getirebilmenizi sağlar ve bu sayede her PNS'ye bildirim dağıtımıyla ilgilenir.

Azure Notification Hubs, uygulamaların hub'a kaydolmasını ve isteğe bağlı olarak şablonları tanımlamasını ve/veya etiketlere abone olmasını gerektirir:

  • Cihaz yüklemesi gerçekleştirmek, PNS tutamacını Azure Notification Hub'daki bir tanımlayıcıya bağlar. Kayıtlar hakkında daha fazla bilgi için bkz . Kayıt yönetimi.
  • Şablonlar, cihazların parametreli ileti şablonlarını belirtmesine olanak tanır. Gelen iletiler cihaz başına özelleştirilebilir. Daha fazla bilgi için bkz . Bildirim hub'ları şablonları.
  • Etiketler haber, spor ve hava durumu gibi ileti kategorilerine abone olmak için kullanılabilir. Daha fazla bilgi için bkz . Yönlendirme ve etiket ifadeleri.

Bu öğreticide, Android ve iOS'yi hedefleyen bir .NET Çok Platformlu Uygulama Kullanıcı Arabirimi (.NET MAUI) uygulamasına anında iletme bildirimleri göndermek için Azure Notification Hubs'ı kullanacaksınız. İstemcinin cihaz kaydını işlemek ve anında iletme bildirimi başlatmak için ASP.NET Core Web API arka ucu kullanılır. Bu işlemler Microsoft.Azure.NotificationHubs NuGet paketi kullanılarak işlenir. Genel yaklaşım hakkında daha fazla bilgi için bkz . Arka uçtan kayıt yönetimi.

Bu öğreticide şunları yaptınız:

  • Anında iletme bildirimi hizmetlerini ve Azure Notification Hub'ı ayarlayın.
  • ASP.NET Core WebAPI arka uç uygulaması oluşturun.
  • .NET MAUI uygulaması oluşturun.
  • Android uygulamasını anında iletme bildirimleri için yapılandırın.
  • iOS uygulamasını anında iletme bildirimleri için yapılandırın.
  • Uygulamayı test etme.
  • Tüm kurulum ve yapılandırma sorunlarını giderin.

Önkoşullar

Bu öğreticiyi tamamlamak için şunlar gerekir:

  • Etkin aboneliği olan bir Azure hesabı.
  • .NET Çok Platformlu Uygulama Kullanıcı Arabirimi geliştirme iş yükü ve ASP.NET ve web geliştirme iş yüklerinin yüklü olduğu Visual Studio/Visual Studio Code'un en son sürümünü çalıştıran bir PC veya Mac.

Android için sahip olmanız gerekenler:

  • Google Play Services yüklü api 26+ çalıştıran bir geliştirici fiziksel cihazın veya öykünücünün kilidini açtı.

iOS için sahip olmanız gerekenler:

  • Etkin bir Apple geliştirici hesabı.
  • Anahtar zincirinize yüklenmiş geçerli bir geliştirici sertifikasının yanı sıra Xcode çalıştıran bir Mac.

Ardından, iOS'ta aşağıdakilerden birini yapmalısınız:

  • Apple silikon veya T2 işlemcili Mac bilgisayarlarda macOS 13+ sürümünde çalışan bir iOS 16+ simülatörü.

    VEYA

  • Geliştirici hesabınıza kayıtlı fiziksel bir iOS cihazı (iOS 13.0+ çalıştıran).

  • Fiziksel cihazınız Apple geliştirici hesabınıza kayıtlı ve sertifikanızla ilişkilendirilmiş.

Önemli

iOS simülatörü, Apple silikon veya T2 işlemcili Mac bilgisayarlarda macOS 13+ sürümünde çalışırken iOS 16+'da uzaktan bildirimleri destekler. Bu donanım gereksinimlerini karşılamıyorsanız etkin bir Apple geliştirici hesabı ve fiziksel bir cihaz gerekir.

Bu öğreticiyi takip etmek için şu konuda bilgi sahibi olmanız gerekir:

Bu öğretici Visual Studio'yu hedeflese de, PC veya Mac'te Visual Studio Code kullanarak bunu takip etmek mümkündür. Ancak, mutabakat gerektiren bazı farklılıklar olacaktır. Örneğin, kullanıcı arabiriminin ve iş akışlarının, şablon adlarının ve ortam yapılandırmasının açıklamaları.

Anında iletme bildirimi hizmetlerini ve Azure Notification Hub'ı ayarlama

Bu bölümde Firebase Cloud Messaging ve Apple Anında İletme Bildirim Hizmetleri'ni (APNS) kuracaksınız. Ardından bu hizmetlerle çalışmak için bir Azure Notification Hub oluşturup yapılandıracaksınız.

Firebase projesi oluşturma

Firebase projesi oluşturmak için:

  1. Web tarayıcısında Firebase konsolunda oturum açın.

  2. Firebase konsolunda Proje ekle düğmesini seçin ve proje adı olarak PushDemo girerek yeni bir Firebase projesi oluşturun.

    Not

    Sizin için benzersiz bir ad oluşturulur. Varsayılan olarak bu, sağladığınız adın küçük harfli bir değişkenini ve tireyle ayrılmış olarak oluşturulan bir sayıyı içerir. Düzenlemelerinizin hala genel olarak benzersiz olması koşuluyla, isterseniz bunu değiştirebilirsiniz.

  3. Projeniz oluşturulduktan sonra Bir Android uygulamasına Firebase eklemek için Android logosunu seçin:

    Firebase Cloud Messaging konsolunda bir Android uygulamasına Firebase ekleme işleminin ekran görüntüsü.

  4. Android uygulamanıza Firebase ekle sayfasında paketiniz için isteğe bağlı olarak bir uygulama takma adı girin ve Uygulamayı kaydet düğmesini seçin:

    Android uygulamanızı Firebase'e kaydetme işleminin ekran görüntüsü.

  5. Android uygulamanıza Firebase ekle sayfasında, İndir google-services.json düğmesini seçin ve İleri düğmesini seçmeden önce dosyayı yerel bir klasöre kaydedin:

    google services JSON dosyasını indirme işleminin ekran görüntüsü.

  6. Android uygulamanıza Firebase ekle sayfasında İleri düğmesini seçin.

  7. Android uygulamanıza Firebase ekle sayfasında Konsola devam et düğmesini seçin.

  8. Firebase konsolunda Projeye Genel Bakış simgesini ve ardından Proje ayarları'nı seçin:

    Firebase Cloud Messaging konsolunda proje ayarlarını seçme işleminin ekran görüntüsü.

  9. Proje ayarlarında Bulut Mesajlaşması sekmesini seçin. Firebase Cloud Messaging API'sini (V1) etkinleştirmiş olduğunu göreceksiniz:

    Firebase Cloud Messaging V1'in etkinleştirildiğini onaylayan ekran görüntüsü.

  10. Proje ayarlarında Hizmet hesapları sekmesini ve ardından Yeni özel anahtar oluştur düğmesini seçin.

  11. Yeni özel anahtar oluştur iletişim kutusunda Anahtar oluştur düğmesini seçin:

    Firebase Cloud Messaging konsolunda yeni bir özel anahtar oluşturma işleminin ekran görüntüsü.

    Azure Notification Hub'ınıza gireceğiniz değerleri içeren bir JSON dosyası indirilir.

iOS uygulamanızı anında iletme bildirimleri için kaydetme

Bir iOS uygulamasına anında iletme bildirimleri göndermek için uygulamanızı Apple'a kaydetmeniz ve anında iletme bildirimlerine kaydolmanız gerekir. Bu, aşağıdaki Azure Notification Hub belgelerindeki adımlar gerçekleştirilerek gerçekleştirilebilir:

Fiziksel bir cihazda anında iletme bildirimleri almak istiyorsanız bir sağlama profili de oluşturmanız gerekir.

Önemli

iOS'ta arka plan bildirimleri almak için uygulamanıza uzak bildirimler arka plan modunu eklemeniz gerekir. Daha fazla bilgi için bkz . developer.apple.com uzaktan bildirim özelliğini etkinleştirme.

Azure Notification Hub oluşturma

Azure portalında bildirim hub'ı oluşturmak için:

  1. Web tarayıcısında Azure portalında oturum açın.
  2. Azure portalında Kaynak oluştur düğmesine tıklayın ve oluştur düğmesini seçmeden önce Bildirim Hub'ını arayıp seçin.
  3. Bildirim Hub'ı sayfasında aşağıdaki adımları gerçekleştirin:
    1. Abonelik alanında, kullanmak istediğiniz Azure aboneliğinin adını seçin ve ardından mevcut bir kaynak grubunu seçin veya yeni bir kaynak grubu oluşturun.

    2. Ad Alanı Ayrıntıları alanına yeni ad alanı için benzersiz bir ad girin.

    3. Bildirim Hub'ı Ayrıntıları alanına bildirim hub'ı için bir ad yazın. Ad alanı bir veya daha fazla bildirim hub'ı içerdiği için bu gereklidir.

    4. Konum açılan listesinde, bildirim hub'ını oluşturmak istediğiniz konumu belirten bir değer seçin.

    5. Kullanılabilirlik Alanları seçeneğini gözden geçirin. Kullanılabilirlik alanları olan bir bölge seçtiyseniz, onay kutusu varsayılan olarak seçilidir.

      Not

      Kullanılabilirlik alanları ücretli bir özellik olduğundan katmanınıza ek ücret eklenir.

    6. Olağanüstü durum kurtarma seçeneğini belirleyin: yok, eşleştirilmiş kurtarma bölgesi veya esnek kurtarma bölgesi. Eşleştirilmiş kurtarma bölgesi'ni seçerseniz yük devretme bölgesi görüntülenir. Esnek kurtarma bölgesi'ni seçerseniz, kurtarma bölgeleri listesinden seçim yapmak için açılan listeyi kullanın.

    7. Oluştur düğmesini seçin. Bildirim hub'ı oluşturulur.

  4. Azure portalında yeni oluşturduğunuz bildirim hub'ınıza ve ardından Erişim İlkelerini Yönet > dikey penceresine gidin.
  5. Erişim İlkeleri dikey penceresinde, ilkenin bağlantı dizesi DefaultFullSharedAccessSignature not edin. Bunu daha sonra bildirim hub'ınızla iletişim kuran bir arka uç hizmeti oluştururken gerekecektir.

Bildirim hub'ı oluşturma hakkında daha fazla bilgi için bkz . Azure portalında Azure bildirim hub'ı oluşturma.

Bildirim hub'ında Firebase Cloud Messaging'i yapılandırma

Bildirim hub'ınızı Firebase Cloud Messaging ile iletişim kuracak şekilde yapılandırmak için:

  1. Azure portalında bildirim hub'ınıza göz atın ve Ayarlar > Google (FCM v1) dikey penceresini seçin.

  2. Google (FCM v1) dikey penceresinde Özel Anahtar, İstemci E-postası ve Proje Kimliği alanlarının değerlerini girin. Bu değerler Firebase Cloud Messaging'ten indirdiğiniz özel anahtar JSON dosyasında bulunabilir:

    Azure alanı JSON anahtarı JSON değeri örneği
    Özel Anahtar private_key Bu değer ile -----BEGIN PRIVATE KEY-----\n başlayıp ile -----END PRIVATE KEY-----\nbitmelidir.
    İstemci E-postası client_email firebase-adminsdk-55sfg@pushdemo-d6ab2.iam.gserviceaccount.com
    Proje kodu project_id pushdemo-d6ab2
  3. Google (FCM v1) dikey penceresinde Kaydet düğmesini seçin.

Bildirim hub'ında Apple Anında İletme Bildirimi Hizmetini yapılandırma

Azure portalında bildirim hub'ınıza göz atın ve Ayarlar > Apple (APNS) dikey penceresini seçin. Ardından, bildirim hub'ı için bir sertifika oluştururken daha önce seçtiğiniz yaklaşıma göre uygun adımları izleyin.

Önemli

Uygulama Modu'nu ayarlarken, yalnızca uygulamanızı mağazadan satın alan kullanıcılara anında iletme bildirimleri göndermek istiyorsanız Üretim'i seçin.

Seçenek 1 - .p12 anında iletme sertifikası kullanma

  1. Apple (APNS) dikey penceresinde Sertifika kimlik doğrulama modunu seçin.
  2. Apple (APNS) dikey penceresinde Sertifikayı Karşıya Yükle alanının yanındaki dosya simgesini seçin. Ardından daha önce dışarı aktardığınız .p12 dosyasını seçin ve karşıya yükleyin.
  3. Apple (APNS) dikey penceresinde, gerekirse Parola alanına sertifika parolasını girin.
  4. Apple (APNS) dikey penceresinde Korumalı alan uygulama modunu seçin.
  5. Apple (APNS) dikey penceresinde Kaydet düğmesini seçin.

Seçenek 2 - Belirteç tabanlı kimlik doğrulamayı kullanma

  1. Apple (APNS) dikey penceresinde Belirteç kimlik doğrulama modunu seçin.
  2. Apple (APNS) dikey penceresinde Anahtar Kimliği, Paket Kimliği, Ekip Kimliği ve Belirteç alanları için daha önce aldığınız değerleri girin.
  3. Apple (APNS) dikey penceresinde Korumalı alan uygulama modunu seçin.
  4. Apple (APNS) dikey penceresinde Kaydet düğmesini seçin.

ASP.NET Core Web API arka uç uygulaması oluşturma

Bu bölümde, cihaz yüklemesini işlemek ve .NET MAUI uygulamasına bildirim göndermek için bir ASP.NET Core Web API arka ucu oluşturacaksınız.

Web API'si projesi oluşturma

Web API'si projesi oluşturmak için:

  1. Visual Studio'da bir ASP.NET Core Web API'si projesi oluşturun:

    Visual Studio'da yeni ASP.NET Core Web API projesi oluşturma işleminin ekran görüntüsü.

  2. Yeni projenizi yapılandırın iletişim kutusunda projeyi PushNotificationsAPI olarak adlandırın.

  3. Ek bilgiler iletişim kutusunda HTTPS için yapılandır ve Denetleyicileri kullan onay kutularının etkinleştirildiğinden emin olun:

    Visual Studio'da ASP.NET Core Web API projesini yapılandırma işleminin ekran görüntüsü.

  4. Proje oluşturulduktan sonra F5 tuşuna basarak projeyi çalıştırın.

    Uygulama şu anda Properties\launchSettings.json dosyasında ayarlanan olarak öğesini kullanacak launchUrlWeatherForecastController şekilde yapılandırılmıştır. Uygulama bir web tarayıcısında başlatılır ve bazı JSON verilerini görüntüler.

    Önemli

    HTTPS kullanan bir ASP.NET Core projesi çalıştırdığınızda Visual Studio, ASP.NET Core HTTPS geliştirme sertifikasının yerel kullanıcı sertifika deponuza yüklenip yüklenmediğini algılar ve eksikse yüklemeyi ve güvenmeyi önerir.

  5. Web tarayıcısını kapatın.

  6. Çözüm Gezgini Denetleyiciler klasörünü genişletin ve WeatherForecastController.cs silin.

  7. Çözüm Gezgini,projenin kökünde WeatherForecast.cs silin.

  8. Bir komut penceresi açın ve proje dosyasını içeren dizine gidin. Sonra şu komutları çalıştırın:

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

    Yer tutucu değerlerini kendi Azure Notification Hub adınızla ve bağlantı dizesi değerleriyle değiştirin. Bunlar Azure Notification Hub'ınızın aşağıdaki konumlarında bulunabilir:

    Yapılandırma değeri Konum
    NotificationHub:Name Genel Bakış sayfasının üst kısmındaki Temel Bilgiler özetindeki Ad bölümüne bakın.
    NotificationHub:ConnectinString Erişim İlkeleri sayfasında DefaultFullSharedAccessSignature* bölümüne bakın.

    Bu, Gizli Dizi Yöneticisi aracını kullanarak yerel yapılandırma değerlerini ayarlar. Bu, Azure Notification Hub gizli dizilerinizi Visual Studio çözümünden ayrıştırarak bunların kaynak denetimine dahil olmamasını sağlar.

    İpucu

    Üretim senaryolarında, bağlantı dizesi güvenli bir şekilde depolamak için Azure KeyVault gibi bir hizmeti göz önünde bulundurun.

API anahtarıyla istemcilerin kimliğini doğrulama

İstemcilerin kimliğini bir API anahtarıyla doğrulamak için:

  1. Bir komut penceresi açın ve proje dosyasını içeren dizine gidin. Sonra şu komutları çalıştırın:

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

    Yer tutucu değerini HERHANGI bir değer olabilecek API anahtarınız ile değiştirin.

  2. Visual Studio'da projenize Authentication adlı yeni bir klasör ekleyin ve ardından Authentication klasörüne adlı ApiKeyAuthOptions yeni bir sınıf ekleyin ve kodunu aşağıdaki kodla değiştirin:

    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; }
    }
    
  3. Visual Studio'da, Authentication klasörüne adlı ApiKeyAuthHandler yeni bir sınıf ekleyin ve kodunu aşağıdaki kodla değiştirin:

    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));
        }
    }
    

    Kimlik doğrulama işleyicisi, bir düzenin davranışını uygulayan bir türdür ve bu durumda özel bir API anahtar düzenidir.

  4. Visual Studio'da, Authentication klasörüne adlı AuthenticationBuilderExtensions yeni bir sınıf ekleyin ve kodunu aşağıdaki kodla değiştirin:

    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);
        }
    }
    

    Bu uzantı yöntemi, Program.cs ara yazılım yapılandırma kodunu basitleştirmek için kullanılır.

  5. Visual Studio'da Program.cs açın ve yönteminin çağrısının altındaki API anahtarı kimlik doğrulamasını yapılandırmak için kodu güncelleştirinbuilder.Services.AddControllers:

    using PushNotificationsAPI.Authentication;
    
    builder.Services.AddControllers();
    
    builder.Services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = ApiKeyAuthOptions.DefaultScheme;
        options.DefaultChallengeScheme = ApiKeyAuthOptions.DefaultScheme;
    }).AddApiKeyAuth(builder.Configuration.GetSection("Authentication").Bind);
    
  6. Program.cs, açıklamasının altındaki // Configure the HTTP request pipeline kodu güncelleştirerek , UseAuthenticationve MapControllers uzantı yöntemlerini çağırınUseRouting:

    // Configure the HTTP request pipeline.
    
    app.UseHttpsRedirection();
    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();
    app.MapControllers();
    
    app.Run();
    

    uzantı yöntemi, UseAuthentication önceden kaydedilmiş kimlik doğrulama düzenini kullanan ara yazılımı kaydeder. UseAuthentication kullanıcıların kimliğinin doğrulanmasını gerektiren herhangi bir ara yazılımdan önce çağrılmalıdır.

    Not

    BIR API anahtarı belirteç kadar güvenli olmasa da, bu öğretici için yeterlidir ve ASP.NET Ara Yazılımı aracılığıyla kolayca yapılandırılabilir.

Hizmet ekleme ve yapılandırma

Web API arka uç uygulamanıza hizmet eklemek ve yapılandırmak için:

  1. Visual Studio'da Microsoft.Azure.NotificationHubs NuGet paketini projenize ekleyin. Bu NuGet paketi, bir hizmet içinde kapsüllenmiş bildirim hub'ınıza erişmek için kullanılır.

  2. Visual Studio'da projenize Models adlı yeni bir klasör ekleyin, ardından Models klasörüne adlı PushTemplates yeni bir sınıf ekleyin ve kodunu aşağıdaki kodla değiştirin:

    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)\" }";
        }
    }
    

    sınıfı, PushTemplates genel ve sessiz anında iletme bildirimleri için belirteçli bildirim yükleri içerir. Bu yükler, hizmet aracılığıyla mevcut yüklemeleri güncelleştirmek zorunda kalmadan denemelere izin vermek için yüklemenin dışında tanımlanır. Yüklemelerdeki değişiklikleri bu şekilde işlemek, bu makalenin kapsamı dışındadır. Ürün senaryolarında özel şablonlar kullanmayı göz önünde bulundurun.

  3. Visual Studio'da Models klasörüne adlı DeviceInstallation yeni bir sınıf ekleyin ve kodunu aşağıdaki kodla değiştirin:

    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>();
    }
    
  4. Visual Studio'da Models klasörüne adlı NotificationRequest yeni bir sınıf ekleyin ve kodunu aşağıdaki kodla değiştirin:

    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; }
    }
    
  5. Visual Studio'da Models klasörüne adlı NotificationHubOptions yeni bir sınıf ekleyin ve kodunu aşağıdaki kodla değiştirin:

    using System.ComponentModel.DataAnnotations;
    
    namespace PushNotificationsAPI.Models;
    
    public class NotificationHubOptions
    {
        [Required]
        public string Name { get; set; }
    
        [Required]
        public string ConnectionString { get; set; }
    }
    
  6. Visual Studio'da projenize Services adlı yeni bir klasör ekleyin ve ardından Services klasörüne adlı INotificationService yeni bir arabirim ekleyin ve kodunu aşağıdaki kodla değiştirin:

    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);
    }
    
  7. Visual Studio'da Services klasörüne adlı NotificationHubService yeni bir sınıf ekleyin ve kodunu aşağıdaki kodla değiştirin:

    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);
        }
    }
    

    yöntemine SendTemplateNotificationsAsync sağlanan etiket ifadesi, yalnızca OR'ler içeriyorsa 20 etiketle sınırlıdır. Aksi takdirde 6 etiketle sınırlıdır. Daha fazla bilgi için bkz . Yönlendirme ve Etiket İfadeleri.

  8. Visual Studio'da Program.cs açın ve yönteminin altındaki tekil uygulaması INotificationService olarak eklemek NotificationHubService için kodu güncelleştirinbuilder.Services.AddAuthentication:

    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();
    

Bildirimler REST API'sini oluşturma

Bildirimler REST API'sini oluşturmak için:

  1. Visual Studio'da Controllers klasörüne adlı NotificationsController yeni bir Denetleyici ekleyin.

    İpucu

    Okuma/yazma eylemleriyle API Denetleyicisi şablonunu seçin.

  2. NotificationsController.cs dosyasında, dosyanın en üstüne aşağıdaki using deyimleri ekleyin:

    using System.ComponentModel.DataAnnotations;
    using System.Net;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;
    using PushNotificationsAPI.Models;
    using PushNotificationsAPI.Services;
    
  3. NotificationsController.cs dosyasında özniteliğini Authorize sınıfına NotificationsController ekleyin:

    [Authorize]
    [ApiController]
    [Route("api/[controller]")]
    public class NotificationsController : ControllerBase
    
  4. NotificationsController.cs dosyasında oluşturucuyuNotificationsContoller, kayıtlı örneğini INotificationService bağımsız değişken olarak kabul etmek üzere güncelleştirin ve salt okunur bir üyeye atayın:

    readonly INotificationService _notificationService;
    
    public NotificationsController(INotificationService notificationService)
    {
        _notificationService = notificationService;
    }
    
  5. NotificationsContoller.cs dosyasında, tüm yöntemleri aşağıdaki kodla değiştirin:

    [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();
    }
    
  6. Özellikler/launchSettings.json dosyasında, her profilin launchUrl özelliğini olarak weatherforecast api/notificationsdeğiştirin.

API uygulaması oluşturma

Şimdi arka uç hizmetinizi barındırmak için Azure Uygulaması Hizmeti'nde bir API uygulaması oluşturacaksınız. Bu doğrudan Visual Studio veya Visual Studio Code'dan, Azure CLI, Azure PowerShell, Azure Geliştirici CLI ile ve Azure Portal aracılığıyla gerçekleştirilebilir. Daha fazla bilgi için bkz . Web uygulamanızı yayımlama.

Azure portalında api uygulaması oluşturmak için:

  1. Web tarayıcısında Azure portalında oturum açın.

  2. Azure portalında Kaynak oluştur düğmesine tıklayın ve oluştur düğmesini seçmeden önce API Uygulaması'nı arayıp seçin.

  3. API Uygulaması Oluştur sayfasında Oluştur düğmesini seçmeden önce aşağıdaki alanları güncelleştirin:

    Alan Eylem
    Abonelik Bildirim hub'ını oluşturduğunuz hedef aboneliği seçin.
    Kaynak Grubu Bildirim hub'ını oluşturduğunuz kaynak grubunu seçin.
    Veri Akışı Adı Genel olarak benzersiz bir ad girin.
    Çalışma zamanı yığını .NET'in en son sürümünün seçildiğinden emin olun.
  4. API Uygulaması sağlandıktan sonra kaynağa gidin.

  5. Genel Bakış sayfasında, varsayılan etki alanı değerini not edin. Bu URL, .NET MAUI uygulamanızdan kullanılacak arka uç uç noktanızdır. URL, biçimiyle https://<app_name>.azurewebsites.netbelirttiğiniz API uygulama adını kullanır.

  6. Azure portalında Ayarlar > Ortam değişkenleri dikey penceresine gidin ve Uygulama ayarları sekmesinin seçili olduğundan emin olun. Ardından Ekle düğmesini kullanarak aşağıdaki ayarları ekleyin:

    Veri Akışı Adı Değer
    Kimlik Doğrulaması:ApiKey <api_key_value>
    NotificationHub:Name <hub_name_value>
    NotificationHub:ConnectionString <hub_connection_string_value>

    Önemli

    Kolaylık Authentication:ApiKey olması için uygulama ayarı eklendi. Üretim senaryolarında, bağlantı dizesi güvenli bir şekilde depolamak için Azure KeyVault gibi bir hizmeti göz önünde bulundurun.

    Bu ayarların tümü girildikten sonra Uygula düğmesini ve ardından Onayla düğmesini seçin.

Arka uç hizmetini yayımlama

Arka uç hizmetinizi Azure Uygulaması Hizmeti'ne yayımlamak için:

  1. Visual Studio'da projenize sağ tıklayın ve Yayımla'yı seçin.
  2. Yayımla sihirbazında Azure'ı ve ardından İleri düğmesini seçin.
  3. Yayımla sihirbazında Azure Uygulaması Hizmeti (Windows) ve ardından İleri düğmesini seçin.
  4. Yayımla sihirbazında, Visual Studio'yu Azure aboneliğinize bağlamak ve uygulamayı yayımlamak için kimlik doğrulama akışını izleyin.

Visual Studio uygulamayı oluşturur, paketler ve Azure'da yayımlar ve ardından uygulamayı varsayılan tarayıcınızda başlatır. Daha fazla bilgi için bkz . ASP.NET web uygulaması yayımlama.

İpucu

Azure portalındaki API uygulamanızın Genel Bakış dikey penceresinden uygulamanız için bir yayımlama profili indirebilir ve ardından visual studio'daki profili kullanarak uygulamanızı yayımlayabilirsiniz.

Yayımlanan API'yi doğrulama

API uygulamasının doğru yayımlandığını denetlemek için, aşağıdaki adrese istek POST göndermek için tercih ettiğiniz REST araçlarını kullanmanız gerekir:

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

Not

Temel adres şeklindedir https://<app_name>.azurewebsites.net.

İstek üst bilgilerini anahtarı apikey ve değerini içerecek şekilde yapılandırdığınızdan, gövdeyi ham olarak ayarladığınızdan ve aşağıdaki yer tutucu JSON içeriğini kullandığınızdan emin olun:

{}

Hizmetten bir 400 Bad Request yanıt almanız gerekir.

Not

Bu işlem .NET MAUI uygulamasından platforma özgü bilgiler gerektireceğinden, geçerli istek verilerini kullanarak API'yi test etmek henüz mümkün değildir.

REST API'lerini çağırma hakkında daha fazla bilgi için bkz . Visual Studio'da .http dosyalarını kullanma ve Http Repl ile web API'lerini test edin. Visual Studio Code'da REST İstemcisi, REST API'lerini test etmek için kullanılabilir.

.NET MAUI uygulaması oluşturma

Bu bölümde, arka uç hizmeti aracılığıyla bir bildirim hub'ından anında iletme bildirimleri almak üzere kaydolmanızı ve kaydını kaldırmanızı sağlayan bir .NET Çok Platformlu Uygulama Kullanıcı Arabirimi (.NET MAUI) uygulaması oluşturacaksınız.

.NET MAUI uygulamanızı oluşturmak için:

  1. Visual Studio'da.NET MAUI Uygulaması proje şablonunu kullanarak PushNotificationsDemo adlı yeni bir .NET MAUI uygulaması oluşturun.

  2. Visual Studio'da. .NET MAUI projesine Models adlı yeni bir klasör ekleyin ve ardından Models klasörüne adlı DeviceInstallation yeni bir sınıf ekleyin ve kodunu aşağıdaki kodla değiştirin:

    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>();
    }
    
  3. Visual Studio'da Models klasörüne adlı PushDemoAction bir numaralandırma ekleyin ve kodunu aşağıdaki kodla değiştirin:

    namespace PushNotificationsDemo.Models;
    
    public enum PushDemoAction
    {
        ActionA,
        ActionB
    }
    
  4. Visual Studio'da. .NET MAUI projesine Services adlı yeni bir klasör ekleyin, ardından Services klasörüne adlı IDeviceInstallationService yeni bir arabirim ekleyin ve kodunu aşağıdaki kodla değiştirin:

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

    Bu arabirim, arka uç hizmetinin gerektirdiği bilgileri sağlamak DeviceInstallation için daha sonra her platformda uygulanacaktır.

  5. Visual Studio'da Services klasörüne adlı INotificationRegistrationService bir arabirim ekleyin ve kodunu aşağıdaki kodla değiştirin:

    namespace PushNotificationsDemo.Services;
    
    public interface INotificationRegistrationService
    {
        Task DeregisterDeviceAsync();
        Task RegisterDeviceAsync(params string[] tags);
        Task RefreshRegistrationAsync();
    }
    

    Bu arabirim, istemci ile arka uç hizmeti arasındaki etkileşimi işler.

  6. Visual Studio'da Services klasörüne adlı INotificationActionService bir arabirim ekleyin ve kodunu aşağıdaki kodla değiştirin:

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

    Bu arabirim, bildirim eylemlerinin işlenmesini merkezileştirmek için basit bir mekanizma olarak kullanılacaktır.

  7. Visual Studio'da Services klasörüne adlı IPushDemoNotificationActionService bir arabirim ekleyin ve kodunu aşağıdaki kodla değiştirin:

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

    Türü IPushDemoNotificationActionService bu uygulamaya özgüdür ve sabit listesi, kesin olarak belirlenmiş bir yaklaşım kullanılarak tetiklenen eylemi tanımlamak için numaralandırmayı kullanır PushDemoAction .

  8. Visual Studio'da Services klasörüne adlı NotificationRegistrationService bir sınıf ekleyin ve kodunu aşağıdaki kodla değiştirin:

    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();
        }
    }
    
  9. Visual Studio'da Services klasörüne adlı PushDemoNotificationActionService bir sınıf ekleyin ve kodunu aşağıdaki kodla değiştirin:

    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);
        }
    }
    
  10. Visual Studio'da, projenin köküne adlı Config bir sınıf ekleyin ve kodunu aşağıdaki kodla değiştirin:

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

    Config sınıfı, gizli dizilerinizi kaynak denetiminden uzak tutmak için basit bir yol olarak kullanılır. Bu değerleri otomatik bir derlemenin parçası olarak değiştirebilir veya yerel bir kısmi sınıf kullanarak geçersiz kılabilirsiniz.

    Önemli

    .NET MAUI uygulamasında temel adresi belirtirken ile sona erdiğinden /emin olun.

  11. Visual Studio'da, projenin köküne adlı Config.local_secrets bir sınıf ekleyin. Ardından Config.local_secrets.cs dosyasındaki kodu aşağıdaki kodla değiştirin:

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

    Yer tutucu değerlerini arka uç hizmetini oluştururken seçtiğiniz değerlerle değiştirin. BackendServiceEndpoint URL biçimini https://<api_app_name>.azurewebsites.net/kullanmalıdır.

    İpucu

    Bu dosyanın kaynak denetimine işlenmesini önlemek için dosyanıza .gitignore eklemeyi *.local_secrets.* unutmayın.

Kullanıcı arabirimini oluşturma

Uygulamanın kullanıcı arabirimini oluşturmak için:

  1. Visual Studio'da MainPage.xaml dosyasını açın ve ve alt öğelerini aşağıdaki XAML ile değiştirinVerticalStackLayout:

    <VerticalStackLayout Margin="20"
                         Spacing="6">
        <Button x:Name="registerButton"
                Text="Register"
                Clicked="OnRegisterButtonClicked" />
        <Button x:Name="deregisterButton"
                Text="Deregister"
                Clicked="OnDeregisterButtonClicked" />
    </VerticalStackLayout>
    
  2. Visual Studio'da MainPage.xaml.cs açın ve ad alanı için PushNotificationsDemo.Services bir using deyim ekleyin:

    using PushNotificationsDemo.Services;
    
  3. MainPage.xaml.cs'da, uygulamaya yönelik bir readonly başvuruyu depolamak için INotificationRegistrationService bir yedekleme alanı ekleyin:

    readonly INotificationRegistrationService _notificationRegistrationService;
    
  4. Oluşturucuda MainPage uygulamayı çözümleyin INotificationRegistrationService ve yedekleme alanına atayın _notificationRegistrationService :

    public MainPage(INotificationRegistrationService service)
    {
        InitializeComponent();
    
        _notificationRegistrationService = service;
    }
    
  5. MainPage sınıfında ve OnDeregisterButtonClicked olay işleyicilerini uygulayarak OnRegisterButtonClicked nesnede karşılık gelen yazmaç ve kayıt silme yöntemlerini çağırınINotificationRegistrationService:

    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;
                });
        });
    }
    

    Önemli

    Uygulamada, bu işlevselliğin daha kolay keşfedilmesine ve test edilmesine izin vermek için kullanıcı girişine yanıt olarak kayıt ve kayıt kaldırma gerçekleştirilir. Üretim uygulamasında genellikle kayıt ve kayıt kaldırma eylemlerini uygulama yaşam döngüsünde uygun bir noktada, açık kullanıcı girişi gerektirmeden gerçekleştirirsiniz.

  6. Visual Studio'da App.xaml.cs açın ve aşağıdaki using deyimleri ekleyin:

    using PushNotificationsDemo.Models;
    using PushNotificationsDemo.Services;
    
  7. App.xaml.cs'da, uygulamaya başvuruyu depolamak için IPushDemoNotificationActionService bir yedekleme alanı ekleyinreadonly:

    readonly IPushDemoNotificationActionService _actionService;
    
  1. Oluşturucuda App uygulamayı çözümleyip IPushDemoNotificationActionService yedekleme alanına atayın _actionService ve olaya abone olun IPushDemoNotificationActionService.ActionTriggered :

    public App(IPushDemoNotificationActionService service)
    {
        InitializeComponent();
    
        _actionService = service;
        _actionService.ActionTriggered += NotificationActionTriggered;
    
        MainPage = new AppShell();
    }
    
  1. Oluşturucuda App uygulamayı çözümleyip IPushDemoNotificationActionService yedekleme alanına atayın _actionService ve olaya abone olun IPushDemoNotificationActionService.ActionTriggered :

    public App(IPushDemoNotificationActionService service)
    {
        InitializeComponent();
    
        _actionService = service;
        _actionService.ActionTriggered += NotificationActionTriggered;
    }
    
  1. App sınıfında, olay için olay işleyicisini IPushDemoNotificationActionService.ActionTriggered uygulayın:

    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;
                });
        });
    }
    

    Olayın olay işleyicisi ActionTriggered , anında iletme bildirimi eylemlerinin alınmasını ve yayılmasını gösterir. Bunlar genellikle sessizce işlenir, örneğin belirli bir görünüme gitmek veya bir uyarı görüntülemek yerine bazı verileri yenilemek.

Android uygulamasını yapılandırma

Android'de .NET MAUI uygulamanızı anında iletme bildirimleri alacak ve işecek şekilde yapılandırmak için:

  1. Visual Studio'da Xamarin.Firebase.Messaging NuGet paketini .NET MAUI uygulama projenize ekleyin.

  2. Visual Studio'da google-services.json dosyanızı .NET MAUI uygulama projenizin Platforms/Android klasörüne ekleyin. Dosya projenize eklendikten sonra derleme eylemiyle GoogleServicesJsoneklenmelidir:

    <ItemGroup Condition="'$(TargetFramework)' == 'net8.0-android'">
      <GoogleServicesJson Include="Platforms\Android\google-services.json" />
    </ItemGroup>
    

    İpucu

    Bu dosyanın kaynak denetimine işlenmesini önlemek için dosyanıza .gitignore eklemeyi google-services.json unutmayın.

  3. Visual Studio'da proje dosyasını (*.csproj) düzenleyin ve Android için değerini 26.0 olarak ayarlayın SupportedOSPlatformVersion :

    <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">26.0</SupportedOSPlatformVersion>
    

    Google, API 26'da Android bildirim kanallarında değişiklikler yaptı. Daha fazla bilgi için bkz . developer.android.com bildirim kanalları .

  4. Projenin Platforms/Android klasörüne adlı DeviceInstallationService yeni bir sınıf ekleyin ve kodunu aşağıdaki kodla değiştirin:

    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.";
        }
    }
    

    Bu sınıf, değerini ve bildirim hub'ı Secure.AndroidId kayıt yükünü kullanarak benzersiz bir kimlik sağlar.

  5. Projenin Platforms/Android klasörüne adlı PushNotificationFirebaseMessagingService yeni bir sınıf ekleyin ve kodunu aşağıdaki kodla değiştirin:

    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);
        }
    }
    

    Bu sınıf, filtreyi içeren bir IntentFilter özniteliğine com.google.firebase.MESSAGING_EVENT sahiptir. Bu filtre, Android'in işlenmek üzere gelen iletileri bu sınıfa geçirmesini sağlar.

    Firebase Cloud Messaging ileti biçimi hakkında bilgi için bkz . developer.android.com'da FCM iletileri hakkında.

  6. Visual Studio'da Platformlar/Android klasöründe MainActivity.cs dosyasını açın ve aşağıdaki using deyimleri ekleyin:

    using Android.App;
    using Android.Content;
    using Android.Content.PM;
    using Android.OS;
    using PushNotificationsDemo.Services;
    using Firebase.Messaging;
    
  7. MainActivity sınıfında öğesini olarak ayarlayın LaunchMode SingleTop, böylece MainActivity açıldığında yeniden oluşturulmaz:

    [Activity(
        Theme = "@style/Maui.SplashTheme",
        MainLauncher = true,
        LaunchMode = LaunchMode.SingleTop,
        ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
    
  8. MainActivity sınıfında, ve IDeviceInstallationService uygulamalarına başvuruları depolamak için IPushDemoNotificationActionService yedekleme alanları ekleyin:

    IPushDemoNotificationActionService _notificationActionService;
    IDeviceInstallationService _deviceInstallationService;
    
  9. MainActivity sınıfında, uygulamanın bağımlılık ekleme kapsayıcısından somut uygulamalarını alan ve DeviceInstallationService özel özellikleri ekleyinNotificationActionService:

    IPushDemoNotificationActionService NotificationActionService =>
        _notificationActionService ?? (_notificationActionService = IPlatformApplication.Current.Services.GetService<IPushDemoNotificationActionService>());
    
    IDeviceInstallationService DeviceInstallationService =>
        _deviceInstallationService ?? (_deviceInstallationService = IPlatformApplication.Current.Services.GetService<IDeviceInstallationService>());
    
  10. MainActivity sınıfında Firebase belirtecini Android.Gms.Tasks.IOnSuccessListener almak ve depolamak için arabirimini uygulayın:

    public class MainActivity : MauiAppCompatActivity, Android.Gms.Tasks.IOnSuccessListener
    {
        public void OnSuccess(Java.Lang.Object result)
        {
            DeviceInstallationService.Token = result.ToString();
        }
    }
    
  11. MainActivity sınıfında, belirli Intent bir değerin ProcessNotificationActions adlı actionek bir değere sahip olup olmadığını denetleyecek yöntemini ekleyin ve ardından uygulamayı kullanarak bunu action koşullu olarak tetikleyinIPushDemoNotificationActionService:

    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);
        }
    }
    
  12. MainActivity sınıfında yöntemini geçersiz kılarak OnNewIntent yöntemini çağırınProcessNotificationActions:

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

    LaunchMode için Activity değeri olarak ayarlandığındanSingleTop, yöntemi yerine OnCreate geçersiz kılma yoluyla OnNewIntent mevcut Activity örneğe bir Intent gönderilir. Bu nedenle, hem OnCreatehem de OnNewIntent içinde gelen bir amacı işlemeniz gerekir.

  13. MainActivity sınıfında yöntemini geçersiz kılarak OnCreate yöntemini çağırın ProcessNotificationActions ve firebase'den belirteci almak için öğesini olarak IOnSuccessListenerekleyinMainActivity:

    protected override void OnCreate(Bundle? savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
    
        if (DeviceInstallationService.NotificationsSupported)
            FirebaseMessaging.Instance.GetToken().AddOnSuccessListener(this);
    
        ProcessNotificationsAction(Intent);
    }
    

    Not

    Anında iletme bildirimleri almaya devam etmek için uygulamanın her çalıştırdığınızda yeniden kaydedilmesi ve hata ayıklama oturumundan durdurulması gerekir.

  14. Visual Studio'da, Platformlar/Android klasöründeki AndroidManifest.xml dosyasına izni ekleyinPOST_NOTIFICATIONS:

    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
    

    Bu izin hakkında daha fazla bilgi için bkz . developer.android.com üzerinde bildirim çalışma zamanı izni .

  15. Visual Studio'da MainPage.xaml.cs açın ve sınıfına MainPage aşağıdaki kodu ekleyin:

    #if ANDROID
            protected override async void OnAppearing()
            {
                base.OnAppearing();
    
                PermissionStatus status = await Permissions.RequestAsync<Permissions.PostNotifications>();
            }
    #endif
    

    Bu kod görüntülendiğinde MainPage Android'de çalışır ve kullanıcıdan izni vermesini POST_NOTIFICATIONS istemektedir. .NET MAUI izinleri hakkında daha fazla bilgi için bkz . İzinler.

iOS uygulamasını yapılandırma

iOS simülatörü, Apple silikon veya T2 işlemcili Mac bilgisayarlarda macOS 13+ sürümünde çalışırken iOS 16+'da uzaktan bildirimleri destekler. Her simülatör, bu simülatörün ve üzerinde çalıştığı Mac donanımının birleşimine özgü kayıt belirteçleri oluşturur.

Önemli

Simülatör, Apple Anında İletme Bildirimi Hizmeti korumalı alan ortamını destekler.

Aşağıdaki yönergelerde, bir iOS simülatöründe uzak bildirimleri almayı destekleyen bir donanım kullandığınız varsayılır. Bu durumda iOS uygulamasını fiziksel bir cihazda çalıştırmanız gerekir. Bu, uygulamanız için Anında İletme Bildirimleri özelliğini içeren bir sağlama profili oluşturmanızı gerektirir. Ardından uygulamanızın sertifikanız ve sağlama profiliniz kullanılarak derlendiğinden emin olmanız gerekir. Bunun nasıl yapacağı hakkında daha fazla bilgi için bkz . iOS uygulamanızı Azure Notification Hubs ile çalışacak şekilde ayarlama ve ardından aşağıdaki yönergeleri izleyin.

iOS'ta .NET MAUI uygulamanızı anında iletme bildirimleri alacak ve işecek şekilde yapılandırmak için:

  1. Visual Studio'da proje dosyasını (*.csproj) düzenleyin ve iOS için değerini 13.0 olarak ayarlayın SupportedOSPlatformVersion :

    <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">13.0</SupportedOSPlatformVersion>
    

    Apple, iOS 13'teki gönderim servisinde değişiklikler yaptı. Daha fazla bilgi için bkz . iOS 13 için Azure Notification Hubs güncelleştirmeleri.

  2. Visual Studio'da projenin Platforms/iOS klasörüne bir Entitlements.plist dosyası ekleyin ve dosyaya aşağıdaki XML'yi ekleyin:

    <?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>
    

    Bu, APS ortam yetkilendirmesini ayarlar ve geliştirme Apple Anında İletme Bildirimi hizmeti ortamının kullanılacağını belirtir. Üretim uygulamalarında bu yetkilendirme değeri olarak productionayarlanmalıdır. Bu yetkilendirme hakkında daha fazla bilgi için bkz . developer.apple.com üzerinde APS Ortam Yetkilendirmesi .

    Yetkilendirme dosyası ekleme hakkında daha fazla bilgi için bkz . iOS yetkilendirmeleri.

  3. Visual Studio'da, projenin Platforms/iOS klasörüne adlı DeviceInstallationService yeni bir sınıf ekleyin ve dosyaya aşağıdaki kodu ekleyin:

    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";
        }
    }
    

    Bu sınıf, değerini ve bildirim hub'ı UIDevice.IdentifierForVendor kayıt yükünü kullanarak benzersiz bir kimlik sağlar.

  4. Visual Studio'da, projenin Platforms/iOS klasörüne adlı NSDataExtensions yeni bir sınıf ekleyin ve dosyaya aşağıdaki kodu ekleyin:

    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();
        }
    }
    

    ToHexString Uzantı yöntemi, alınan cihaz belirtecini ayrıştıran ekleyeceğiniz kod tarafından kullanılır.

  5. Visual Studio'da Platformlar/iOS klasöründe AppDelegate.cs dosyasını açın ve aşağıdaki using deyimleri ekleyin:

    using System.Diagnostics;
    using Foundation;
    using PushNotificationsDemo.Platforms.iOS;
    using PushNotificationsDemo.Services;
    using UIKit;
    using UserNotifications;
    
  6. AppDelegate sınıfında, , INotificationRegistrationServiceve IDeviceInstallationService uygulamalarına başvuruları depolamak için IPushDemoNotificationActionServiceyedekleme alanları ekleyin:

    IPushDemoNotificationActionService _notificationActionService;
    INotificationRegistrationService _notificationRegistrationService;
    IDeviceInstallationService _deviceInstallationService;
    
  7. AppDelegate sınıfında, uygulamanın bağımlılık ekleme kapsayıcısından somut uygulamalarını alan , NotificationRegistrationServiceve DeviceInstallationService özel özellikleri ekleyinNotificationActionService:

    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>());
    
  8. AppDelegate sınıfında, özellik değerini ayarlamak IDeviceInstallationService.Token için yöntemini ekleyinCompleteRegistrationAsync:

    Task CompleteRegistrationAsync(NSData deviceToken)
    {
        DeviceInstallationService.Token = deviceToken.ToHexString();
        return NotificationRegistrationService.RefreshRegistrationAsync();
    }
    

    Bu yöntem ayrıca kaydı yeniler ve cihaz belirtecini son depolandığından beri güncelleştirildiyse önbelleğe alır.

  9. AppDelegate sınıfında, bildirim verilerini işlemek NSDictionary ve koşullu olarak çağırmak NotificationActionService.TriggerActioniçin yöntemini ekleyinProcessNotificationActions:

    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);
        }
    }
    
  10. AppDelegate sınıfında, bağımsız değişkenini RegisteredForRemoteNotifications yöntemine deviceToken CompleteRegistrationAsync geçirerek yöntemini ekleyin:

    [Export("application:didRegisterForRemoteNotificationsWithDeviceToken:")]
    public void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
    {
        CompleteRegistrationAsync(deviceToken)
            .ContinueWith((task) =>
            {
                if (task.IsFaulted)
                    throw task.Exception;
            });
    }
    

    Bu yöntem, uygulama uzaktan bildirim almak üzere kaydedildiğinde çağrılır ve cihazdaki uygulamanızın adresi olan benzersiz cihaz belirtecini istemek için kullanılır.

  11. AppDelegate sınıfında, bağımsız değişkenini ReceivedRemoteNotification yöntemine userInfo ProcessNotificationActions geçirerek yöntemini ekleyin:

    [Export("application:didReceiveRemoteNotification:")]
    public void ReceivedRemoteNotification(UIApplication application, NSDictionary userInfo)
    {
        ProcessNotificationActions(userInfo);
    }
    

    Bu yöntem, uygulama bir uzak bildirim aldığında çağrılır ve bildirimi işlemek için kullanılır.

  12. AppDelegate sınıfında, hataları günlüğe kaydetmek için yöntemini ekleyinFailedToRegisterForRemoteNotifications:

    [Export("application:didFailToRegisterForRemoteNotificationsWithError:")]
    public void FailedToRegisterForRemoteNotifications(UIApplication application, NSError error)
    {
        Debug.WriteLine(error.Description);
    }
    

    Uygulama uzak bildirimleri almak için kaydolamadığında bu yöntem çağrılır. Cihaz ağa bağlı değilse, APNS sunucusuna ulaşılamıyorsa veya uygulama yanlış yapılandırılmışsa kayıt başarısız olabilir.

    Not

    Üretim senaryoları için yönteminde FailedToRegisterForRemoteNotifications düzgün günlük ve hata işleme uygulamak isteyeceksiniz.

  13. AppDelegate sınıfında, bildirimleri kullanmak ve uzak bildirimlere kaydolmak için koşullu olarak izin istemek için yöntemini ekleyinFinishedLaunching:

    [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);
    }
    

    Bildirimleri kullanmak için izin isteme hakkında bilgi için bkz . developer.apple.com bildirimleri kullanmak için izin isteme.

iOS'taki bildirimler hakkında bilgi için bkz . developer.apple.com'de Kullanıcı Bildirimleri .

Türleri uygulamanın bağımlılık ekleme kapsayıcısıyla kaydetme

  1. Visual Studio'da MauiProgram.cs açın ve ad alanı için PushNotificationsDemo.Services bir using deyim ekleyin:

    using PushNotificationsDemo.Services;
    
  2. MauiProgram sınıfında, her platforma RegisterServices ve platformlar DeviceInstallationService arası PushDemoNotificationActionService NotificationRegistrationService hizmetlere kaydeden ve bir MauiAppBuilder nesnesi döndüren uzantı yöntemi için kod ekleyin:

    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;
    }
    
  3. MauiProgram sınıfında, türü tekil olarak kaydeden MainPage ve bir MauiAppBuilder nesne döndüren uzantı yöntemi için RegisterViews kod ekleyin:

    public static MauiAppBuilder RegisterViews(this MauiAppBuilder builder)
    {
        builder.Services.AddSingleton<MainPage>();
        return builder;
    }
    

    Tür MainPage , bağımlılık INotificationRegistrationService gerektirdiğinden ve bağımlılık gerektiren tüm türlerin bağımlılık ekleme kapsayıcısıyla kaydedilmesi gerektiğinden kaydedilir.

  4. MauiProgram sınıfında yöntemini değiştirerek CreateMauiApp ve RegisterViews uzantı yöntemlerini çağırmasını RegisterServices sağlar:

    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();
    }
    

.NET MAUI'de bağımlılık ekleme hakkında daha fazla bilgi için bkz . Bağımlılık ekleme.

Uygulamayı test etme

Arka uç hizmetini kullanarak veya Azure portalı aracılığıyla uygulamaya anında iletme bildirimleri göndererek uygulamanızı test edebilirsiniz.

iOS simülatörü, Apple silikon veya T2 işlemcili Mac bilgisayarlarda macOS 13+ sürümünde çalışırken iOS 16+'da uzaktan bildirimleri destekler. Bu donanım gereksinimlerini karşılamıyorsanız iOS uygulamanızı fiziksel bir cihazda test etmek zorunda olursunuz. Android'de uygulamanızı geliştirici kilidi açılmış bir fiziksel cihazda veya öykünücüde test edebilirsiniz.

Android ve iOS, arka planda çalışırken uygulama adına anında iletme bildirimleri görüntüler. Bildirim alındığında uygulama ön planda çalışıyorsa, davranışı uygulama kodu belirler. Örneğin, uygulamanızın arabirimini bildirimde yer alan yeni bilgileri yansıtacak şekilde güncelleştirebilirsiniz.

Arka uç hizmetini kullanarak test edin

Azure Uygulaması Hizmeti'ne yayımlanan arka uç hizmeti aracılığıyla uygulamanıza bir test anında iletme bildirimi göndermek için:

  1. Visual Studio'da Android veya iOS'ta PushNotificationsDemo uygulamasını çalıştırın ve Kaydet düğmesini seçin.

    Not

    Android'de test ediyorsanız hata ayıklama yapılandırmasını kullanarak çalışmadığınızdan emin olun. Alternatif olarak, uygulama daha önce dağıtıldıysa zorla kapatıldığından emin olun ve ardından başlatıcıdan yeniden başlatın.

  2. Seçtiğiniz REST aracında aşağıdaki adrese bir POST istek gönderin:

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

    İstek üst bilgilerini anahtarı apikey ve değerini içerecek şekilde yapılandırdığınızdan, gövdeyi ham olarak ayarladığınızdan ve aşağıdaki JSON içeriğini kullandığınızdan emin olun:

    {
        "text": "Message from REST tooling!",
        "action": "action_a"
    }
    

    Genel istek aşağıdaki örneğe benzer olmalıdır:

    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"
    }
    
  3. Seçtiğiniz REST araçlarında 200 Tamam yanıtı aldığınızı doğrulayın.

  4. Android veya iOS'taki uygulamada, alınan ActionA eylemini gösteren bir uyarı görünmelidir.

REST API'lerini çağırma hakkında daha fazla bilgi için bkz . Visual Studio'da .http dosyalarını kullanma ve Http Repl ile web API'lerini test edin. Visual Studio Code'da REST İstemcisi, REST API'lerini test etmek için kullanılabilir.

Azure portalını kullanarak test edin

Azure Notification Hubs, uygulamanızın anında iletme bildirimleri alıp almadığını denetlemenizi sağlar.

Azure portalı aracılığıyla uygulamanıza test anında iletme bildirimi göndermek için:

  1. Visual Studio'da Android veya iOS'ta PushNotificationsDemo uygulamasını çalıştırın ve Kaydet düğmesini seçin.

    Not

    Android'de test ediyorsanız hata ayıklama yapılandırmasını kullanarak çalışmadığınızdan emin olun. Alternatif olarak, uygulama daha önce dağıtıldıysa zorla kapatıldığından emin olun ve ardından başlatıcıdan yeniden başlatın.

  2. Azure portalında bildirim hub'ınıza göz atın ve Genel Bakış dikey penceresinde Göndermeyi Sına düğmesini seçin.

  3. Göndermeyi Test Et dikey penceresinde gerekli Platformunuzu seçin ve yükü değiştirin.

    Apple için aşağıdaki yükü kullanın:

    {
      "aps": {
        "alert": "Message from Notification Hub!"
      },
      "action": "action_a"
    }
    

    Android için aşağıdaki yükü kullanın:

    {
      "message": {
        "notification": {
          "title": "PushDemo",
          "body": "Message from Notification Hub!"
        },
        "data": {
          "action": "action_a"
        }
      }
    }
    

    Azure portalı, bildirimin başarıyla gönderildiğini belirtmelidir.

    Firebase Cloud Messaging ileti biçimi hakkında bilgi için bkz . developer.android.com'da FCM iletileri hakkında.

  4. Android veya iOS'taki uygulamada, alınan ActionA eylemini gösteren bir uyarı görünmelidir.

Sorun giderme

Aşağıdaki bölümlerde, istemci uygulamasında anında iletme bildirimleri tüketilirken karşılaşılan yaygın sorunlar açıklanmıştır.

Arka uç hizmetinden yanıt yok

Yerel olarak test ederken arka uç hizmetinin çalıştığından ve doğru bağlantı noktasını kullandığından emin olun.

Azure API uygulamasıyla test ediyorsanız hizmetin çalışıp çalışmadığını ve dağıtıldığını ve hatasız olarak başlatıldığını denetleyin.

REST araçlarınızda veya .NET MAUI uygulama yapılandırmanızda temel adresi doğru belirttiğinizden emin olun. Temel adres veya https://localhost:7020 yerel olarak test ederken olmalıdırhttps://<api_name>.azurewebsites.net.

Arka uç hizmetinden 401 durum kodu alma

İstek üst bilgisini doğru ayarladığınızı apikey ve bu değerin arka uç hizmeti için yapılandırdığınız değerle eşleşip eşleşmediğini doğrulayın.

Yerel olarak test ederken bu hatayı alırsanız, .NET MAUI uygulamanızda tanımladığınız anahtar değerinin Authentication:ApiKey arka uç hizmeti tarafından kullanılan kullanıcı gizli dizileri değeriyle eşleştiğinden emin olun.

Bir Azure API uygulamasıyla test ediyorsanız.NET MAUI uygulamanızda tanımlanan anahtar değerinin Authentication:ApiKey Azure portalında tanımlanan uygulama ayarı değeriyle eşleştiğinden emin olun. Arka uç hizmetini dağıttıktan sonra bu uygulama ayarını oluşturduysanız veya değiştirdiyseniz, değerin geçerli olması için hizmeti yeniden başlatmanız gerekir.

Arka uç hizmetinden 404 durum kodu alma

Uç nokta ve HTTP istek yönteminin doğru olduğunu doğrulayın:

  • KOYMAK- https://<api_name>.azurewebsites.net/api/notifications/installations
  • SİLMEK- https://<api_name>.azurewebsites.net/api/notifications/installations/<installation_id>
  • YAYINLA- https://<api_name>.azurewebsites.net/api/notifications/requests

Veya yerel olarak test ederken:

  • KOYMAK- https://localhost:7020/api/notifications/installations
  • SİLMEK- https://localhost:7020/api/notifications/installations/<installation_id>
  • YAYINLA- https://localhost:7020/api/notifications/requests

Önemli

.NET MAUI uygulamasında temel adresi belirtirken ile sona erdiğinden /emin olun. Temel adres veya https://localhost:7020/ yerel olarak test ederken olmalıdırhttps://<api_name>.azurewebsites.net.

Hata ayıklama oturumunu başlattıktan veya durdurduktan sonra Android'de bildirim alınmıyor

Her hata ayıklama oturumu başlattığınızda kaydettiğinizden emin olun. Hata ayıklayıcı yeni bir Firebase belirtecinin oluşturulmasına neden olur ve bu nedenle bildirim hub'ı yüklemesinin güncelleştirilmesi gerekir.

Kaydedilemiyor ve bir bildirim hub'ı hata iletisi görüntüleniyor

Test cihazının ağ bağlantısı olduğunu doğrulayın. Ardından, içindeki özelliğini HttpResponseincelemek StatusCode için bir kesme noktası ayarlayarak HTTP yanıt durum kodunu belirleyin.

Durum koduna bağlı olarak, uygun olduğunda önceki sorun giderme önerilerini gözden geçirin.

İlgili API için belirli durum kodları döndüren satırlarda bir kesme noktası ayarlayın. Ardından yerel olarak hata ayıklarken arka uç hizmetini çağırmayı deneyin.

Arka uç hizmetinin seçtiğiniz REST araçları tarafından beklendiği gibi çalıştığını doğrulayın ve seçtiğiniz platform için .NET MAUI uygulaması tarafından oluşturulan yükü kullanın.

Hiçbir adımın kaçırılmadığından emin olmak için platforma özgü yapılandırma bölümlerini gözden geçirin. Seçtiğiniz platform için ve Token değişkenleri için InstallationId uygun değerlerin çözümlenip çözümlenmediğini denetleyin.

Cihaz kimliği çözümlenemiyor hata iletisi

Hiçbir adımın kaçırılmadığından emin olmak için platforma özgü yapılandırma bölümlerini gözden geçirin.