Uso di Hub di notifica di Azure per inviare notifiche agli utenti per iOS con back-end .NETAzure Notification Hubs Notify Users for iOS with .NET backend

PanoramicaOverview

Il supporto per le notifiche push in Azure consente di accedere a un'infrastruttura push facile da usare, multipiattaforma e con scalabilità orizzontale, che semplifica considerevolmente l'implementazione delle notifiche push sia per le applicazioni consumer sia per quelle aziendali per piattaforme mobili.Push notification support in Azure enables you to access an easy-to-use, multiplatform, and scaled-out push infrastructure, which greatly simplifies the implementation of push notifications for both consumer and enterprise applications for mobile platforms. In questa esercitazione viene illustrato come usare Hub di notifica di Azure per inviare notifiche push a un utente specifico dell'app su un dispositivo specifico.This tutorial shows you how to use Azure Notification Hubs to send push notifications to a specific app user on a specific device. Per autenticare i client e generare le notifiche viene usato un back-end di API Web ASP.NET, come illustrato nell'argomento Registering from your app backend (Registrazione dal back-end dell'app).An ASP.NET WebAPI backend is used to authenticate clients and to generate notifications, as shown in the guidance topic Registering from your app backend.

Nota

In questa esercitazione si presuppone che l'utente abbia creato e configurato l'hub di notifica come descritto in Introduzione ad Hub di notifica (iOS).This tutorial assumes that you have created and configured your notification hub as described in Getting Started with Notification Hubs (iOS). È inoltre propedeutica all'esercitazione Push sicuro (iOS) .This tutorial is also the prerequisite to the Secure Push (iOS) tutorial. Se si desidera usare le app per dispositivi mobili come servizio back-end, vedere Introduzione alle app per dispositivi mobili con notifiche push.If you want to use Mobile Apps as your backend service, see the Mobile Apps Get Started with Push.

Creare il progetto WebAPICreate the WebAPI project

Le sezioni successive illustrano la creazione di un nuovo back-end WebAPI ASP.NET.The next sections discuss the creation of a new ASP.NET WebAPI back end. Questo processo ha tre obiettivi principali:This process has three main purposes:

  • Autenticare i client: si aggiungerà un gestore di messaggi per autenticare le richieste client e associare l'utente alla richiesta.Authenticate clients: You add a message handler later to authenticate client requests and associate the user with the request.

  • Eseguire la registrazione per le notifiche usando il back-end WebAPI: si aggiungerà un controller per gestire le nuove registrazioni e consentire a un dispositivo client di ricevere le notifiche.Register for notifications by using the WebAPI back end: You add a controller to handle new registrations for a client device to receive notifications. Il nome utente autenticato verrà aggiunto automaticamente alla registrazione come tag.The authenticated username is automatically added to the registration as a tag.

  • Inviare notifiche ai client: si aggiungerà anche un controller per consentire agli utenti di attivare un push sicuro per i dispositivi e i client associati al tag.Send notifications to clients: You also add a controller to provide a way for users to trigger a secure push to devices and clients associated with the tag.

Creare un nuovo back-end WebAPI ASP.NET seguendo questa procedura:Create the new ASP.NET WebAPI back end by doing the following:

Importante

Se si usa Visual Studio 2015 o una versione precedente, prima di procedere con l'esercitazione verificare di avere installato la versione più recente di Gestione pacchetti NuGet per Visual Studio.If you are using Visual Studio 2015 or earlier, before starting this tutorial, ensure that you have installed the latest version of NuGet Package Manager for Visual Studio.

A questo scopo, avviare Visual Studio.To check, start Visual Studio. Scegliere Estensioni e aggiornamenti dal menu Strumenti.On the Tools menu, select Extensions and Updates. Cercare Gestione pacchetti NuGet nella versione di Visual Studio e verificare che sia installata la versione più recente.Search for NuGet Package Manager in your version of Visual Studio, and make sure you have the latest version. Se la versione installata non è la più recente, disinstallarla e reinstallare Gestione pacchetti NuGet.If your version is not the latest version, uninstall it, and then reinstall the NuGet Package Manager.

Nota

Assicurarsi che sia installato Visual Studio Azure SDK per la distribuzione del sito Web.Make sure you have installed the Visual Studio Azure SDK for website deployment.

  1. Avviare Visual Studio o Visual Studio Express.Start Visual Studio or Visual Studio Express.

  2. Selezionare Esplora server e accedere all'account Azure.Select Server Explorer, and sign in to your Azure account. Per creare le risorse del sito Web nell'account è necessario eseguire l'accesso.To create the web site resources on your account, you must be signed in.

  3. In Visual Studio selezionare File > Nuovo > Progetto, espandere Modelli, espandere Visual C# e quindi selezionare Web e Applicazione Web ASP.NET.In Visual Studio, select File > New > Project, expand Templates, expand Visual C#, and then select Web and ASP.NET Web Application.

  4. Nella casella Nome digitare AppBackend e quindi selezionare OK.In the Name box, type AppBackend, and then select OK.

    Finestra Nuovo progetto

  5. Nella finestra Nuovo progetto ASP.NET selezionare la casella di controllo API Web e quindi selezionare OK.In the New ASP.NET Project window, select the Web API check box, and then select OK.

    Finestra Nuovo progetto ASP.NET

  6. Selezionare una sottoscrizione nella finestra Configura app Web di Microsoft Azure e nell'elenco Piano di Servizio app eseguire una di queste operazioni:In the Configure Microsoft Azure Web App window, select a subscription and then, in the App Service plan list, do either of the following:

    • Selezionare un piano di servizio app creato in precedenza.Select an app service plan that you've already created.
    • Selezionare Crea un nuovo piano di servizio app e quindi creare un piano.Select Create a new app service plan, and then create one.

    Per questa esercitazione non è necessario disporre di un database.You do not need a database for this tutorial. Dopo aver selezionato il piano di servizio app, fare clic su OK per creare il progetto.After you have selected your app service plan, select OK to create the project.

    Finestra Configura app Web di Microsoft Azure

Autenticare client con il back-end WebAPIAuthenticate clients to the WebAPI back end

In questa sezione si creerà una nuova classe del gestore di messaggi denominata AuthenticationTestHandler per il nuovo back-end.In this section, you create a new message-handler class named AuthenticationTestHandler for the new back end. Questa classe deriva da DelegatingHandler e viene aggiunta come gestore di messaggi per poter elaborare tutte le richieste in arrivo nel back-end.This class is derived from DelegatingHandler and added as a message handler so that it can process all requests that come into the back end.

  1. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto AppBackend, scegliere Aggiungi e quindi selezionare Classe.In Solution Explorer, right-click the AppBackend project, select Add, and then select Class.

  2. Assegnare alla nuova classe il nome AuthenticationTestHandler.cs e fare clic su Aggiungi per generarla.Name the new class AuthenticationTestHandler.cs, and then select Add to generate the class. Questa classe autentica gli utenti tramite l'autenticazione di base.This class authenticates users by using Basic Authentication for simplicity. L'app può usare qualsiasi schema di autenticazione.Your app can use any authentication scheme.

  3. In AuthenticationTestHandler.cs aggiungere le istruzioni using seguenti:In AuthenticationTestHandler.cs, add the following using statements:

     using System.Net.Http;
     using System.Threading;
     using System.Security.Principal;
     using System.Net;
     using System.Text;
     using System.Threading.Tasks;
    
  4. In AuthenticationTestHandler.cs sostituire la definizione di classe AuthenticationTestHandler con il codice seguente:In AuthenticationTestHandler.cs, replace the AuthenticationTestHandler class definition with the following code:

    Questo gestore autorizza la richiesta quando le tre condizioni seguenti sono vere:The handler will authorize the request when the following three conditions are true:

    • La richiesta include un'intestazione di autorizzazione.The request includes an Authorization header.
    • La richiesta usa l'autenticazione di base .The request uses basic authentication.
    • La stringa del nome utente corrisponde alla stringa della password.The user name string and the password string are the same string.

    In caso contrario, la richiesta verrà rifiutata.Otherwise, the request will be rejected. Non si tratta di un vero approccio di autenticazione e autorizzazione.This is not a true authentication and authorization approach. È solo un esempio molto semplice per questa esercitazione.It is only a very simple example for this tutorial.

    Se il messaggio di richiesta viene autenticato e autorizzato da AuthenticationTestHandler, l'utente dell'autenticazione di base viene associato alla richiesta corrente in HttpContext.If the request message is authenticated and authorized by AuthenticationTestHandler, the basic authentication user is attached to the current request on HttpContext. Le informazioni utente in HttpContext verranno usate da un altro controller (RegisterController) in un secondo momento per aggiungere un tag alla richiesta di registrazione per le notifiche.User information in HttpContext will be used by another controller (RegisterController) later to add a tag to the notification registration request.

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

    Nota

    Nota sulla sicurezza: la classe AuthenticationTestHandler non fornisce un'effettiva autenticazione.Security note: The AuthenticationTestHandler class does not provide true authentication. Viene usata solo per imitare l'autenticazione di base e non è sicura.It is used only to mimic basic authentication and is not secure. È necessario implementare un meccanismo di autenticazione sicuro nelle applicazioni e nei servizi di produzione.You must implement a secure authentication mechanism in your production applications and services.

  5. Per registrare il gestore di messaggi aggiungere il codice seguente alla fine del metodo Register nella classe App_Start/WebApiConfig.cs:To register the message handler, add the following code at the end of the Register method in the App_Start/WebApiConfig.cs class:

     config.MessageHandlers.Add(new AuthenticationTestHandler());
    
  6. Salvare le modifiche.Save your changes.

Eseguire la registrazione per le notifiche tramite il back-end WebAPIRegister for notifications by using the WebAPI back end

In questa sezione si aggiungerà un nuovo controller al back-end WebAPI per gestire le richieste di registrazione di un utente e un dispositivo per le notifiche tramite la libreria client per gli hub di notifica.In this section, you add a new controller to the WebAPI back end to handle requests to register a user and a device for notifications by using the client library for notification hubs. Il controller aggiunge un tag user per l'utente che è stato autenticato e collegato a HttpContext da AuthenticationTestHandler.The controller adds a user tag for the user that was authenticated and attached to HttpContext by AuthenticationTestHandler. Il tag avrà il formato della stringa, "username:<actual username>".The tag will have the string format, "username:<actual username>".

  1. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto AppBackend e quindi scegliere Gestisci pacchetti NuGet.In Solution Explorer, right-click the AppBackend project and then select Manage NuGet Packages.

  2. Nel riquadro sinistro selezionare Online e nella casella Cerca digitare Microsoft.Azure.NotificationHubs.In the left pane, select Online and then, in the Search box, type Microsoft.Azure.NotificationHubs.

  3. Nell'elenco dei risultati fare clic su Hub di notifica di Microsoft Azure e quindi selezionare Installa.In the results list, select Microsoft Azure Notification Hubs, and then select Install. Completare l'installazione e quindi chiudere la finestra di Gestione pacchetti NuGet.Complete the installation, and then close the NuGet Package Manager window.

    Questa azione aggiunge un riferimento ad Azure Notification Hubs SDK usando il pacchetto NuGet Microsoft.Azure.NotificationHubs.This action adds a reference to the Azure Notification Hubs SDK by using the Microsoft.Azure.Notification Hubs NuGet package.

  4. Creare un nuovo file di classe che rappresenta la connessione con l'hub di notifica usato per inviare le notifiche.Create a new class file that represents the connection with the notification hub that's used to send notifications. In Esplora soluzioni fare clic con il pulsante destro del mouse sulla cartella Modelli, scegliere Aggiungi e quindi fare clic su Classe.In Solution Explorer, right-click the Models folder, select Add, and then select Class. Assegnare alla nuova classe il nome Notifications.cs e quindi selezionare Aggiungi per generarla.Name the new class Notifications.cs, and then select Add to generate the class.

    Finestra Aggiungi nuovo elemento

  5. In Notifications.cs aggiungere l'istruzione using seguente all'inizio del file:In Notifications.cs, add the following using statement at the top of the file:

     using Microsoft.Azure.NotificationHubs;
    
  6. Sostituire la definizione di classe Notifications con il codice seguente e sostituire i due segnaposto con la stringa di connessione (con accesso completo) per l'hub di notifica e con il nome dell'hub disponibile nel portale di Azure classico:Replace the Notifications class definition with the following code, and replace the two placeholders with the connection string (with full access) for your notification hub and the hub name (available at Azure classic portal):

     public class Notifications
     {
         public static Notifications Instance = new Notifications();
    
         public NotificationHubClient Hub { get; set; }
    
         private Notifications() {
             Hub = NotificationHubClient.CreateClientFromConnectionString("<your hub's DefaultFullSharedAccessSignature>", 
                                                                          "<hub name>");
         }
     }
    
  7. Creare quindi un nuovo controller denominato RegisterController.Next, create a new controller named RegisterController. In Esplora soluzioni fare clic con il pulsante destro del mouse sulla cartella Controller, scegliere Aggiungi e quindi fare clic su Controller.In Solution Explorer, right-click the Controllers folder, select Add, and then select Controller.

  8. Fare clic su Controller Web API 2 - Vuoto e selezionare Aggiungi.Select Web API 2 Controller - Empty, and then select Add.

    Finestra Aggiungi scaffolding

  9. Nella casella Nome controller digitare RegisterController per assegnare un nome alla nuova classe, quindi selezionare Aggiungi.In the Controller name box, type RegisterController to name the new class, and then select Add.

    Finestra Aggiungi controller

  10. In RegisterController.cs aggiungere le istruzioni using seguenti:In RegisterController.cs, add the following using statements:

    using Microsoft.Azure.NotificationHubs;
    using Microsoft.Azure.NotificationHubs.Messaging;
    using AppBackend.Models;
    using System.Threading.Tasks;
    using System.Web;
    
  11. Aggiungere il codice seguente all'interno della definizione di classe RegisterController .Add the following code inside the RegisterController class definition. Si noti che in questo codice viene aggiunto un tag user per l'utente associato a HttpContext.Note that in this code, we add a user tag for the user that's attached to HttpContext. L'utente è stato autenticato e associato a HttpContext dal filtro messaggi aggiunto, AuthenticationTestHandler.The user was authenticated and attached to HttpContext by the message filter that we added, AuthenticationTestHandler. È anche possibile aggiungere controlli facoltativi per verificare che l'utente disponga dei diritti per la registrazione per i tag richiesti.You can also add optional checks to verify that the user has rights to register for the requested tags.

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

Inviare notifiche dal back-end WebAPISend notifications from the WebAPI back end

In questa sezione si aggiunge un nuovo controller che consente ai dispositivi client di inviare una notifica.In this section you add a new controller that exposes a way for client devices to send a notification. La notifica si basa sul tag username che usa la libreria di gestione del servizio Hub di notifica di Azure nel back-end WebAPI ASP.NET.The notification is based on the username tag that uses Azure Notification Hubs Service Management Library in the ASP.NET WebAPI back end.

  1. Creare un altro nuovo controller denominato NotificationsController seguendo la stessa procedura usata per creare RegisterController nella sezione precedente.Create another new controller named NotificationsController the same way you created RegisterController in the previous section.

  2. In NotificationsController.cs aggiungere le istruzioni using seguenti:In NotificationsController.cs, add the following using statements:

     using AppBackend.Models;
     using System.Threading.Tasks;
     using System.Web;
    
  3. Aggiungere il metodo seguente alla classe NotificationsController:Add the following method to the NotificationsController class:

    Questo codice invia un tipo di notifica basato sul parametro pns del servizio di notifica della piattaforma (PNS).This code sends a notification type that's based on the Platform Notification Service (PNS) pns parameter. Il valore to_tag viene usato per impostare il tag username nel messaggio.The value of to_tag is used to set the username tag on the message. Questo tag deve corrispondere a un tag username di una registrazione dell'hub di notifica attiva.This tag must match a username tag of an active notification hub registration. Il messaggio di notifica viene estratto dal corpo della richiesta POST ed è formattato per il PNS di destinazione.The notification message is pulled from the body of the POST request and formatted for the target PNS.

    A seconda del servizio di notifica della piattaforma (PNS) usato dai dispositivi supportati per ricevere le notifiche, sono supportate notifiche in una serie di formati.Depending on the PNS that your supported devices use to receive notifications, the notifications are supported by a variety of formats. Nei dispositivi Windows è ad esempio possibile usare una notifica di tipo avviso popup con WNS che non è supportata direttamente da un altro PNS.For example, on Windows devices, you might use a toast notification with WNS that isn't directly supported by another PNS. In tal caso, il back-end deve formattare la notifica come notifica supportata per il PNS dei dispositivi che si intende supportare.In such an instance, your back end needs to format the notification into a supported notification for the PNS of devices you plan to support. Usare quindi l'API di invio appropriata per la classe NotificationHubClient.Then use the appropriate send API on the NotificationHubClient class.

     public async Task<HttpResponseMessage> Post(string pns, [FromBody]string message, string to_tag)
     {
         var user = HttpContext.Current.User.Identity.Name;
         string[] userTag = new string[2];
         userTag[0] = "username:" + to_tag;
         userTag[1] = "from:" + user;
    
         Microsoft.Azure.NotificationHubs.NotificationOutcome outcome = null;
         HttpStatusCode ret = HttpStatusCode.InternalServerError;
    
         switch (pns.ToLower())
         {
             case "wns":
                 // Windows 8.1 / Windows Phone 8.1
                 var toast = @"<toast><visual><binding template=""ToastText01""><text id=""1"">" + 
                             "From " + user + ": " + message + "</text></binding></visual></toast>";
                 outcome = await Notifications.Instance.Hub.SendWindowsNativeNotificationAsync(toast, userTag);
                 break;
             case "apns":
                 // iOS
                 var alert = "{\"aps\":{\"alert\":\"" + "From " + user + ": " + message + "\"}}";
                 outcome = await Notifications.Instance.Hub.SendAppleNativeNotificationAsync(alert, userTag);
                 break;
             case "gcm":
                 // Android
                 var notif = "{ \"data\" : {\"message\":\"" + "From " + user + ": " + message + "\"}}";
                 outcome = await Notifications.Instance.Hub.SendGcmNativeNotificationAsync(notif, userTag);
                 break;
         }
    
         if (outcome != null)
         {
             if (!((outcome.State == Microsoft.Azure.NotificationHubs.NotificationOutcomeState.Abandoned) ||
                 (outcome.State == Microsoft.Azure.NotificationHubs.NotificationOutcomeState.Unknown)))
             {
                 ret = HttpStatusCode.OK;
             }
         }
    
         return Request.CreateResponse(ret);
     }
    
  4. Premere F5 per eseguire l'applicazione e verificare l'accuratezza del lavoro svolto sinora.To run the application and ensure the accuracy of your work so far, select the F5 key. L'app apre un Web browser e viene visualizzata nella home page di ASP.NET.The app opens a web browser, and it is displayed on the ASP.NET home page.

Pubblicare il nuovo back-end WebAPIPublish the new WebAPI back end

L'app verrà ora distribuita in un sito Web Azure per renderla accessibile da tutti i dispositivi.Next, you deploy the app to an Azure website to make it accessible from all devices.

  1. Fare clic con il pulsante destro del mouse sul progetto AppBackend e scegliere Pubblica.Right-click the AppBackend project, and then select Publish.

  2. Selezionare Servizio app di Microsoft Azure come destinazione di pubblicazione e quindi fare clic su Pubblica.Select Microsoft Azure App Service as your publish target, and then select Publish.
    Verrà visualizzata la finestra Crea servizio app.The Create App Service window opens. Qui è possibile creare tutte le risorse di Azure necessarie per eseguire l'app Web ASP.NET in Azure.Here you can create all the necessary Azure resources to run the ASP.NET web app in Azure.

    Riquadro Servizio app di Microsoft Azure

  3. Nella finestra Crea servizio app selezionare l'account Azure.In the Create App Service window, select your Azure account. Selezionare Modifica tipo > App Web.Select Change Type > Web App. Mantenere il valore di Nome app Web predefinito e selezionare la sottoscrizione, il gruppo di risorse e il piano di servizio app.Keep the default Web App Name, and then select the Subscription, Resource Group, and App Service Plan.

  4. Selezionare Crea.Select Create.

  5. Prendere nota della proprietà URL sito nella scheda Riepilogo.Make a note of the Site URL property in the Summary section. Questo URL sarà l'endpoint back-end più avanti nell'esercitazione.This URL is your back-end endpoint later in the tutorial.

  6. Selezionare Pubblica.Select Publish.

Al termine della procedura guidata, l'app Web ASP.NET viene pubblicata in Azure e aperta nel browser predefinito.After you've completed the wizard, it publishes the ASP.NET web app to Azure and then opens the app in the default browser. L'applicazione sarà visibile in Servizi app di Azure.Your application is viewable in Azure App Services.

L'URL usa il nome dell'app Web specificato in precedenza, con il formato http://<nome_app>.azurewebsites.net.The URL uses the web app name that you specified earlier, with the format http://<app_name>.azurewebsites.net.

Modificare l'app per iOSModify your iOS app

  1. Aprire l'app di visualizzazione Pagina singola creata nell'esercitazione Introduzione ad Hub di notifica (iOS) .Open the Single Page view app you created in the Getting Started with Notification Hubs (iOS) tutorial.

    Nota

    In questa sezione si presuppone che il progetto sia configurato con un nome di organizzazione vuoto.In this section we assume that your project is configured with an empty organization name. In caso contrario, sarà necessario anteporre il nome dell'organizzazione a tutti i nomi di classi.If not, you will need to prepend your organization name to all class names.

  2. In Main.storyboard aggiungere i componenti illustrati nella schermata seguente dalla libreria di oggetti.In your Main.storyboard add the components shown in the screenshot below from the object library.

    • Nome utente: oggetto UITextField con testo segnaposto, Enter Username, immediatamente sotto l'etichetta per l'invio dei risultati e limitato dai margini sinistro e destro.Username: A UITextField with placeholder text, Enter Username, immediately beneath the send results label and constrained to the left and right margins and beneath the send results label.
    • Password: oggetto UITextField con testo segnaposto, Enter Password, immediatamente sotto il campo di testo del nome utente e limitato dai margini sinistro e destro.Password: A UITextField with placeholder text, Enter Password, immediately beneath the username text field and constrained to the left and right margins and beneath the username text field. Selezionare l'opzione Secure Text Entry in Attribute Inspector sotto Return Key.Check the Secure Text Entry option in the Attribute Inspector, under Return Key.
    • Accesso: oggetto UIButton con etichetta immediatamente sotto il campo di testo della password; deselezionare l'opzione Abilitato in Attributes Inspector sotto Control-Content.Log in: A UIButton labeled immediately beneath the password text field and uncheck the Enabled option in the Attributes Inspector, under Control-Content
    • WNS: etichetta e opzione per consentire l'invio della notifica al servizio di notifica Windows se è stato configurato nell'hub.WNS: Label and switch to enable sending the notification Windows Notification Service if it has been setup on the hub. Vedere l'esercitazione Introduzione a Windows.See the Windows Getting Started tutorial.
    • GCM: etichetta e opzione per consentire l'invio della notifica a Google Cloud Messaging se è stato configurato nell'hub.GCM: Label and switch to enable sending the notification to Google Cloud Messaging if it has been setup on the hub. Vedere l'esercitazione Introduzione ad Android .See Android Getting Started tutorial.
    • APNS: etichetta e opzione per consentire l'invio della notifica al servizio di notifica della piattaforma di Apple.APNS: Label and switch to enable sending the notification to the Apple Platform Notification Service.
    • Nome utente del destinatario: oggetto UITextField con testo segnaposto, Recipient username tag, immediatamente sotto l'etichetta GCM e limitato dai margini sinistro e destro.Recipent Username:A UITextField with placeholder text, Recipient username tag, immediately beneath the GCM label and constrained to the left and right margins and beneath the GCM label.

      Alcuni componenti sono stati aggiunti nell'esercitazione Introduzione ad Hub di notifica (iOS) esercitazione.Some components were added in the Getting Started with Notification Hubs (iOS) tutorial.

  3. CTRL dai componenti nella visualizzazione a ViewController.h e aggiungere questi nuovi outlet.Ctrl drag from the components in the view to ViewController.h and add these new outlets.

     @property (weak, nonatomic) IBOutlet UITextField *UsernameField;
     @property (weak, nonatomic) IBOutlet UITextField *PasswordField;
     @property (weak, nonatomic) IBOutlet UITextField *RecipientField;
     @property (weak, nonatomic) IBOutlet UITextField *NotificationField;
    
     // Used to enable the buttons on the UI
     @property (weak, nonatomic) IBOutlet UIButton *LogInButton;
     @property (weak, nonatomic) IBOutlet UIButton *SendNotificationButton;
    
     // Used to enabled sending notifications across platforms
     @property (weak, nonatomic) IBOutlet UISwitch *WNSSwitch;
     @property (weak, nonatomic) IBOutlet UISwitch *GCMSwitch;
     @property (weak, nonatomic) IBOutlet UISwitch *APNSSwitch;
    
     - (IBAction)LogInAction:(id)sender;
    
  4. In ViewController.h aggiungere l'elemento #define seguente sotto le istruzioni di importazione.In ViewController.h, add the following #define just below your import statements. Sostituire il segnaposto > con l'URL di destinazione usato per distribuire il back-end dell'app nella sezione precedente.Substitute the <Enter Your Backend Endpoint> placeholder with the Destination URL you used to deploy your app backend in the previous section. Ad esempio, http://you_backend.azurewebsites.net.For example, http://you_backend.azurewebsites.net.

     #define BACKEND_ENDPOINT @"<Enter Your Backend Endpoint>"
    
  5. Nel progetto creare una nuova classe Cocoa Touch denominata RegisterClient da usare come interfaccia con il back-end ASP.NET creato.In your project, create a new Cocoa Touch class named RegisterClient to interface with the ASP.NET back-end you created. Creare la classe che eredita da NSObject.Create the class inheriting from NSObject. Aggiungere quindi il codice seguente in RegisterClient.h.Then add the following code in the RegisterClient.h.

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

     @interface RegisterClient ()
    
     @property (strong, nonatomic) NSURLSession* session;
     @property (strong, nonatomic) NSURLSession* endpoint;
    
     -(void) tryToRegisterWithDeviceToken:(NSData*)token tags:(NSSet*)tags retry:(BOOL)retry
                 andCompletion:(void(^)(NSError*))completion;
     -(void) retrieveOrRequestRegistrationIdWithDeviceToken:(NSString*)token
                 completion:(void(^)(NSString*, NSError*))completion;
     -(void) upsertRegistrationWithRegistrationId:(NSString*)registrationId deviceToken:(NSString*)token
                 tags:(NSSet*)tags andCompletion:(void(^)(NSURLResponse*, NSError*))completion;
    
     @end
    
  7. Sostituire la sezione @implementation in RegisterClient.m con il codice seguente.Replace the @implementation section in the RegisterClient.m with the following code.

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

    Il codice riportato sopra implementa la logica illustrata nell'articolo di istruzioni Registrazione dal back-end dell'app usando NSURLSession per eseguire chiamate REST al back-end dell'app e NSUserDefaults per archiviare in locale l'ID registrazione restituito dall'hub di notifica.The code above implements the logic explained in the guidance article Registering from your app backend using NSURLSession to perform REST calls to your app backend, and NSUserDefaults to locally store the registrationId returned by the notification hub.

    Si noti che per il corretto funzionamento di questa classe è necessario che sia impostata la relativa proprietà authorizationHeader .Note that this class requires its property authorizationHeader to be set in order to work properly. Questa proprietà viene impostata tramite la classe ViewController dopo l'accesso.This property is set by the ViewController class after the log in.

  8. In ViewController.h aggiungere un'istruzione #import per RegisterClient.h.In ViewController.h, add a #import statement for RegisterClient.h. Aggiungere quindi una dichiarazione per il token del dispositivo e fare riferimento a un'istanza di RegisterClient nella sezione @interface:Then add a declaration for the device token and reference to a RegisterClient instance in the @interface section:

     #import "RegisterClient.h"
    
     @property (strong, nonatomic) NSData* deviceToken;
     @property (strong, nonatomic) RegisterClient* registerClient;
    
  9. In ViewController.m aggiungere una dichiarazione di metodo privato nella sezione @interface :In ViewController.m, add a private method declaration in the @interface section:

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

Nota

Il frammento seguente non è uno schema di autenticazione sicuro. È consigliabile sostituire l'implementazione di createAndSetAuthenticationHeaderWithUsername:AndPassword: con il meccanismo di autenticazione specifico che genera un token di autenticazione che deve essere usato dalla classe client di registrazione, ad esempio OAuth o Active Directory.The following snippet is not a secure authentication scheme, you should substitute the implementation of the createAndSetAuthenticationHeaderWithUsername:AndPassword: with your specific authentication mechanism that generates an authentication token to be consumed by the register client class, e.g. OAuth, Active Directory.

  1. Aggiungere quindi nella sezione @implementation di ViewController.m il codice seguente che aggiunge l'implementazione per l'impostazione del token del dispositivo e dell'intestazione di autenticazione.Then in the @implementation section of ViewController.m add the following code which adds the implementation for setting the device token and authentication header.

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

    Si noti come impostando il token del dispositivo viene abilitato il pulsante di accesso.Note how setting the device token enables the log in button. Questo dipende dal fatto che, nell'ambito dell'azione di accesso, il controller di visualizzazione esegue la registrazione per le notifiche push con il back-end dell'app.This is becasue as a part of the login action, the view controller registers for push notifications with the app backend. L'azione di accesso deve quindi essere accessibile solo dopo che il token del dispositivo è stato correttamente configurato.Hence, we do not want Log In action to be accessible till the device token has been properly set up. È possibile separare l'accesso dalla registrazione push, purché la prima azione avvenga prima della seconda.You can decouple the log in from the push registration as long as the former happens before the latter.

  2. In ViewController.m usare i frammenti di codice seguenti per implementare il metodo di azione per il pulsante Log In e un metodo per inviare il messaggio di notifica con il back-end ASP.NET.In ViewController.m, use the following snippets to implement the action method for your Log In button and a method to send the notification message using the ASP.NET backend.

    - <span data-ttu-id="eeaed-150">(IBAction)LogInAction:(id)sender {   // create authentication header and set it in register client   NSString* username = self.UsernameField.text;   NSString* password = self.PasswordField.text;</span><span class="sxs-lookup"><span data-stu-id="eeaed-150">(IBAction)LogInAction:(id)sender {   // create authentication header and set it in register client   NSString* username = self.UsernameField.text;   NSString* password = self.PasswordField.text;</span></span>
    
        <span data-ttu-id="eeaed-151">[self createAndSetAuthenticationHeaderWithUsername:username AndPassword:password];</span><span class="sxs-lookup"><span data-stu-id="eeaed-151">[self createAndSetAuthenticationHeaderWithUsername:username AndPassword:password];</span></span>
    
        <span data-ttu-id="eeaed-152">__weak ViewController* selfie = self;   [self.registerClient registerWithDeviceToken:self.deviceToken tags:nil       andCompletion:^(NSError* error) {       if (!error) {           dispatch_async(dispatch_get_main_queue(),           ^{               selfie.SendNotificationButton.enabled = YES;               [self MessageBox:@"Success" message:@"Registered successfully!"];           });       }   }]; }</span><span class="sxs-lookup"><span data-stu-id="eeaed-152">__weak ViewController* selfie = self;   [self.registerClient registerWithDeviceToken:self.deviceToken tags:nil       andCompletion:^(NSError* error) {       if (!error) {           dispatch_async(dispatch_get_main_queue(),           ^{               selfie.SendNotificationButton.enabled = YES;               [self MessageBox:@"Success" message:@"Registered successfully!"];           });       }   }]; }</span></span>
    
     <span data-ttu-id="eeaed-153">- (void)SendNotificationASPNETBackend:(NSString*)pns UsernameTag:(NSString*)usernameTag            Message:(NSString*)message {    NSURLSession* session = [NSURLSession        sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:nil        delegateQueue:nil];</span><span class="sxs-lookup"><span data-stu-id="eeaed-153">- (void)SendNotificationASPNETBackend:(NSString*)pns UsernameTag:(NSString*)usernameTag            Message:(NSString*)message {    NSURLSession* session = [NSURLSession        sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:nil        delegateQueue:nil];</span></span>
    
         <span data-ttu-id="eeaed-154">// Pass the pns and username tag as parameters with the REST URL to the ASP.NET backend    NSURL* requestURL = [NSURL URLWithString:[NSString        stringWithFormat:@"%@/api/notifications?pns=%@&to_tag=%@", BACKEND_ENDPOINT, pns,        usernameTag]];</span><span class="sxs-lookup"><span data-stu-id="eeaed-154">// Pass the pns and username tag as parameters with the REST URL to the ASP.NET backend    NSURL* requestURL = [NSURL URLWithString:[NSString        stringWithFormat:@"%@/api/notifications?pns=%@&to_tag=%@", BACKEND_ENDPOINT, pns,        usernameTag]];</span></span>
    
         <span data-ttu-id="eeaed-155">NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:requestURL];    [request setHTTPMethod:@"POST"];</span><span class="sxs-lookup"><span data-stu-id="eeaed-155">NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:requestURL];    [request setHTTPMethod:@"POST"];</span></span>
    
         <span data-ttu-id="eeaed-156">// Get the mock authenticationheader from the register client    NSString* authorizationHeaderValue = [NSString stringWithFormat:@"Basic %@",        self.registerClient.authenticationHeader];    [request setValue:authorizationHeaderValue forHTTPHeaderField:@"Authorization"];</span><span class="sxs-lookup"><span data-stu-id="eeaed-156">// Get the mock authenticationheader from the register client    NSString* authorizationHeaderValue = [NSString stringWithFormat:@"Basic %@",        self.registerClient.authenticationHeader];    [request setValue:authorizationHeaderValue forHTTPHeaderField:@"Authorization"];</span></span>
    
         <span data-ttu-id="eeaed-157">//Add the notification message body    [request setValue:@"application/json;charset=utf-8" forHTTPHeaderField:@"Content-Type"];    [request setHTTPBody:[message dataUsingEncoding:NSUTF8StringEncoding]];</span><span class="sxs-lookup"><span data-stu-id="eeaed-157">//Add the notification message body    [request setValue:@"application/json;charset=utf-8" forHTTPHeaderField:@"Content-Type"];    [request setHTTPBody:[message dataUsingEncoding:NSUTF8StringEncoding]];</span></span>
    
         <span data-ttu-id="eeaed-158">// Execute the send notification REST API on the ASP.NET Backend    NSURLSessionDataTask* dataTask = [session dataTaskWithRequest:request        completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)    {        NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*) response;        if (error || httpResponse.statusCode != 200)        {            NSString* status = [NSString stringWithFormat:@"Error Status for %@: %d\nError: %@\n",                                pns, httpResponse.statusCode, error];            dispatch_async(dispatch_get_main_queue(),            ^{                // Append text because all 3 PNS calls may also have information to view                [self.sendResults setText:[self.sendResults.text stringByAppendingString:status]];            });            NSLog(status);        }</span><span class="sxs-lookup"><span data-stu-id="eeaed-158">// Execute the send notification REST API on the ASP.NET Backend    NSURLSessionDataTask* dataTask = [session dataTaskWithRequest:request        completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)    {        NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*) response;        if (error || httpResponse.statusCode != 200)        {            NSString* status = [NSString stringWithFormat:@"Error Status for %@: %d\nError: %@\n",                                pns, httpResponse.statusCode, error];            dispatch_async(dispatch_get_main_queue(),            ^{                // Append text because all 3 PNS calls may also have information to view                [self.sendResults setText:[self.sendResults.text stringByAppendingString:status]];            });            NSLog(status);        }</span></span>
    
             if (data != NULL)
             {
                 xmlParser = [[NSXMLParser alloc] initWithData:data];
                 [xmlParser setDelegate:self];
                 [xmlParser parse];
             }
         <span data-ttu-id="eeaed-159">}];    [dataTask resume]; }</span><span class="sxs-lookup"><span data-stu-id="eeaed-159">}];    [dataTask resume]; }</span></span>
    
  3. Aggiornare l'azione per il pulsante Send Notification per usare il back-end ASP.NET e inviare a qualsiasi PNS abilitato da un'opzione.Update the action for the Send Notification button to use the ASP.NET backend and send to any PNS enabled by a switch.

     - (IBAction)SendNotificationMessage:(id)sender
     {
         //[self SendNotificationRESTAPI];
         [self SendToEnabledPlatforms];
     }
    
    -(void)SendToEnabledPlatforms
    {
        NSString* json = [NSString stringWithFormat:@"\"%@\"",self.notificationMessage.text];

        [self.sendResults setText:@""];

        if ([self.WNSSwitch isOn])
            [self SendNotificationASPNETBackend:@"wns" UsernameTag:self.RecipientField.text Message:json];

        if ([self.GCMSwitch isOn])
            [self SendNotificationASPNETBackend:@"gcm" UsernameTag:self.RecipientField.text Message:json];

        if ([self.APNSSwitch isOn])
            [self SendNotificationASPNETBackend:@"apns" UsernameTag:self.RecipientField.text Message:json];
    }
  1. Nella funzione ViewDidLoadaggiungere quanto segue per creare l'istanza di RegisterClient e impostare il delegato per i campi di testo.In function ViewDidLoad, add the following to instantiate the RegisterClient instance and set the delegate for your text fields.

    self.UsernameField.delegate = self;
    self.PasswordField.delegate = self;
    self.RecipientField.delegate = self;
    self.registerClient = [[RegisterClient alloc] initWithEndpoint:BACKEND_ENDPOINT];
    
  2. In AppDelegate.m rimuovere tutto il contenuto del metodo application:didRegisterForPushNotificationWithDeviceToken: e sostituirlo con il seguente per assicurarsi che il controller di visualizzazione contenga il token del dispositivo più recente recuperato dagli APN:Now in AppDelegate.m, remove all the content of the method application:didRegisterForPushNotificationWithDeviceToken: and replace it with the following to make sure that the view controller contains the latest device token retrieved from APNs:

    // Add import to the top of the file
    #import "ViewController.h"
    
    - (void)application:(UIApplication *)application
                didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
    {
        ViewController* rvc = (ViewController*) self.window.rootViewController;
        rvc.deviceToken = deviceToken;
    }
    
  3. Infine in AppDelegate.mverificare che sia presente il metodo seguente:Finally in AppDelegate.m, make sure you have the following method:

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

Testare l'applicazioneTest the Application

  1. In XCode eseguire l'app su un dispositivo iOS fisico (le notifiche push non funzioneranno nel simulatore).In XCode, run the app on a physical iOS device (push notifications will not work in the simulator).
  2. Nell'interfaccia utente dell'app per iOS immettere un nome utente e una password.In the iOS app UI, enter a username and password. Può trattarsi di qualsiasi stringa, ma devono avere entrambi lo stesso valore di stringa.These can be any string, but they must both be the same string value. Quindi fare clic su Log In.Then click Log In.

  3. Verrà visualizzata una finestra popup che informa che la registrazione è stata completata.You should see a pop-up informing you of registration success. Fare clic su OK.Click OK.

  4. Nel campo di testo *Recipient username tag (Tag nome utente destinatario) immettere il tag del nome utente usato con la registrazione da un altro dispositivo.In the *Recipient username tag text field, enter the user name tag used with the registration from another device.
  5. Immettere un messaggio di notifica e fare clic su Send Notification.Enter a notification message and click Send Notification. Solo i dispositivi che hanno una registrazione con il tag del nome utente del destinatario riceveranno il messaggio di notifica.Only the devices that have a registration with the recipient user name tag receive the notification message. Viene inviato solo a tali utenti.It is only sent to those users.