Uso delle notifiche push

Le notifiche push consentono a provider di notifiche remote di inviare notifiche ad applicazioni eseguite su dispositivi mobili. AIR 3.4 supporta le notifiche push per dispositivi iOS che impiegano il servizio APN (Apple Push Notification).

Nota: per abilitare le notifiche push in un'applicazione AIR for Android, utilizzate un'estensione nativa, quale as3c2dm , sviluppata dall'esperto Adobe Piotr Walczyszyn.

La restante parte di questa sezione spiega come abilitare le notifiche push in applicazioni AIR for iOS.

Nota: questa discussione presuppone che disponiate di un ID di sviluppatore Apple, che abbiate famigliarità con il flusso di lavoro di sviluppo iOS e che abbiate implementato almeno un'applicazione su un dispositivo iOS.

Panoramica delle notifiche push

Il servizio APN (Apple Push Notification service) consente a provider di notifiche remote di inviare notifiche ad applicazioni eseguite su dispositivi iOS. Il servizio APN supporta i seguenti tipi di notifiche:

  • Avvisi

  • Badge

  • Suoni

Per informazioni complete sul servizio APN, andate alla pagina developer.apple.com .

L'uso delle notifiche push in un'applicazione comporta una serie di attività correlate:

  • Applicazione client - Registrazione alle notifiche push, comunicazione con i provider di notifiche remote e ricezione delle notifiche push.

  • iOS - Gestione dell'interazione tra applicazione client e servizio APN.

  • Servizio APN - Fornitura di un tokenID durante la registrazione del client e trasferimento delle notifiche dai provider di notifiche remote a iOS.

  • Provider di notifiche remote - Memorizzazione delle informazioni relative a tokenID e applicazione client e invio delle notifiche push al servizio APN.

Flusso di lavoro di registrazione

Il flusso di lavoro per la registrazione delle notifiche push su un servizio lato server è il seguente:

  1. L'applicazione client richiede a iOS di abilitare le notifiche push.

  2. iOS inoltra la richiesta al servizio APN.

  3. Il server APN restituisce un tokenId a iOS.

  4. iOS invia il tokenId all'applicazione client.

  5. L'applicazione client (utilizzando un meccanismo specifico dell'applicazione) fornisce il tokenId al provider di notifiche remote, che lo memorizza per utilizzarlo per l'invio delle notifiche push.

Flusso di lavoro di notifica

Il flusso di lavoro di notifica è il seguente:

  1. Il provider di notifiche remoto genera una notifica e trasmette il payload della notifica al servizio APN, insieme al tokenId.

  2. Il servizio APN inoltra la notifica a iOS sul dispositivo.

  3. iOS trasmette il payload della notifica all'applicazione.

API delle notifiche push

In AIR 3.4 è stata introdotta una serie di API che supportano le notifiche push iOS. Queste API si trovano nel pacchetto flash.notifications e includono le classi seguenti:

  • NotificationStyle - Definisce le costanti per i tipi di notifiche: ALERT , BADGE e SOUND .

  • RemoteNotifier - Consente di sottoscrivere le notifiche push e di annullare la sottoscrizione.

  • RemoteNotifierSubscribeOptions - Consente di scegliere i tipi di notifiche che si desidera ricevere. Utilizzate la proprietà notificationStyles per definire un vettore di stringhe che consenta di registrarsi a più tipi di notifiche.

AIR 3.4 include anche la proprietà flash.events.RemoteNotificationEvent , che viene inviata da RemoteNotifier nei seguenti casi:

  • Quando la sottoscrizione di un'applicazione va a buon fine e un nuovo tokenId viene ricevuto dal servizio APN.

  • Al ricevimento di una nuova notifica remota.

Inoltre, RemoteNotifier trasmette flash.events.StatusEvent se riscontra un errore durante la procedura di sottoscrizione.

Gestione delle notifiche push in un'applicazione

Per registrare un'applicazione per le notifiche push, dovete procedere nel modo seguente:

  • Create un codice per la sottoscrizione alle notifiche push nella vostra applicazione.

  • Abilitate le notifiche push nel file XML dell'applicazione.

  • Create un profilo di provisioning e un certificato che abiliti i servizi push di iOS.

Il codice di esempio riportato di seguito consente di sottoscrivere le notifiche push e di gestire gli eventi di notifica push:

package 
                        { 
                        import flash.display.Sprite; 
                        import flash.display.StageAlign; 
                        import flash.display.StageScaleMode; 
                        import flash.events.*; 
                        import flash.events.Event; 
                        import flash.events.IOErrorEvent; 
                        import flash.events.MouseEvent; 
                        import flash.net.*; 
                        import flash.text.TextField; 
                        import flash.text.TextFormat; 
                        import flash.ui.Multitouch; 
                        import flash.ui.MultitouchInputMode; 
                        // Required packages for push notifications 
                        import flash.notifications.NotificationStyle; 
                        import flash.notifications.RemoteNotifier; 
                        import flash.notifications.RemoteNotifierSubscribeOptions; 
                        import flash.events.RemoteNotificationEvent; 
                        import flash.events.StatusEvent; 
                        [SWF(width="1280", height="752", frameRate="60")] 

                        public class TestPushNotifications extends Sprite 
                        { 
                        private var notiStyles:Vector.<String> = new Vector.<String>;; 
                        private var tt:TextField = new TextField(); 
                        private var tf:TextFormat = new TextFormat(); 
                        // Contains the notification styles that your app wants to receive 
                        private var preferredStyles:Vector.<String> = new Vector.<String>(); 
                        private var subscribeOptions:RemoteNotifierSubscribeOptions = new RemoteNotifierSubscribeOptions(); 
                        private var remoteNot:RemoteNotifier = new RemoteNotifier(); 

                        private var subsButton:CustomButton = new CustomButton("Subscribe"); 
                        private var unSubsButton:CustomButton = new CustomButton("UnSubscribe"); 
                        private var clearButton:CustomButton = new CustomButton("clearText"); 

                        private var urlreq:URLRequest; 
                        private var urlLoad:URLLoader = new URLLoader(); 
                        private var urlString:String; 

                        public function TestPushNotifications() 
                        { 
                        super(); 

                        Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT; 
                        stage.align = StageAlign.TOP_LEFT; 
                        stage.scaleMode = StageScaleMode.NO_SCALE; 

                        tf.size = 20; 
                        tf.bold = true; 


                        tt.x=0; 
                        tt.y =150; 
                        tt.height = stage.stageHeight; 
                        tt.width = stage.stageWidth; 
                        tt.border = true; 
                        tt.defaultTextFormat = tf; 

                        addChild(tt); 

                        subsButton.x = 150; 
                        subsButton.y=10; 
                        subsButton.addEventListener(MouseEvent.CLICK,subsButtonHandler); 
                        stage.addChild(subsButton); 

                        unSubsButton.x = 300; 
                        unSubsButton.y=10; 
                        unSubsButton.addEventListener(MouseEvent.CLICK,unSubsButtonHandler); 
                        stage.addChild(unSubsButton); 

                        clearButton.x = 450; 
                        clearButton.y=10; 
                        clearButton.addEventListener(MouseEvent.CLICK,clearButtonHandler); 
                        stage.addChild(clearButton); 

                        // 
                        tt.text += "\n SupportedNotification Styles: " + RemoteNotifier.supportedNotificationStyles.toString() + "\n"; 

                        tt.text += "\n Before Preferred notificationStyles: " + subscribeOptions.notificationStyles.toString() + "\n"; 

                        // Subscribe to all three styles of push notifications: 
                        // ALERT, BADGE, and SOUND. 
                        preferredStyles.push(NotificationStyle.ALERT ,NotificationStyle.BADGE,NotificationStyle.SOUND ); 

                        subscribeOptions.notificationStyles= preferredStyles; 

                        tt.text += "\n After Preferred notificationStyles:" + subscribeOptions.notificationStyles.toString() + "\n"; 


                        remoteNot.addEventListener(RemoteNotificationEvent.TOKEN,tokenHandler); 
                        remoteNot.addEventListener(RemoteNotificationEvent.NOTIFICATION,notificationHandler); 
                        remoteNot.addEventListener(StatusEvent.STATUS,statusHandler); 

                        this.stage.addEventListener(Event.ACTIVATE,activateHandler); 


                        } 
                        // Apple recommends that each time an app activates, it subscribe for 
                        // push notifications. 
                        public function activateHandler(e:Event):void{ 
                        // Before subscribing to push notifications, ensure the device supports it. 
                        // supportedNotificationStyles returns the types of notifications 
                        // that the OS platform supports 
                        if(RemoteNotifier.supportedNotificationStyles.toString() != "") 
                        {     
                        remoteNot.subscribe(subscribeOptions); 
                        } 
                        else{ 
                        tt.appendText("\n Remote Notifications not supported on this Platform !"); 
                        } 
                        } 
                        public function subsButtonHandler(e:MouseEvent):void{ 
                        remoteNot.subscribe(subscribeOptions); 
                        } 
                        // Optionally unsubscribe from push notfications at runtime. 
                        public function unSubsButtonHandler(e:MouseEvent):void{ 
                        remoteNot.unsubscribe(); 
                        tt.text +="\n UNSUBSCRIBED"; 
                        } 

                        public function clearButtonHandler(e:MouseEvent):void{ 
                        tt.text = " "; 
                        } 
                        // Receive notification payload data and use it in your app 
                        public function notificationHandler(e:RemoteNotificationEvent):void{ 
                        tt.appendText("\nRemoteNotificationEvent type: " + e.type + 
                        "\nbubbles: "+ e.bubbles + "\ncancelable " +e.cancelable); 

                        for (var x:String in e.data) { 
                        tt.text += "\n"+ x + ":  " + e.data[x]; 
                        } 
                        } 
                        // If the subscribe() request succeeds, a RemoteNotificationEvent of 
                        // type TOKEN is received, from which you retrieve e.tokenId, 
                        // which you use to register with the server provider (urbanairship, in 
                        // this example. 
                        public function tokenHandler(e:RemoteNotificationEvent):void 
                        { 
                        tt.appendText("\nRemoteNotificationEvent type: "+e.type +"\nBubbles: "+ e.bubbles + "\ncancelable " +e.cancelable +"\ntokenID:\n"+ e.tokenId +"\n"); 

                        urlString = new String("https://go.urbanairship.com/api/device_tokens/" + 
                        e.tokenId); 
                        urlreq = new URLRequest(urlString); 

                        urlreq.authenticate = true; 
                        urlreq.method = URLRequestMethod.PUT; 

                        URLRequestDefaults.setLoginCredentialsForHost 
                        ("go.urbanairship.com", 
                        "1ssB2iV_RL6_UBLiYMQVfg","t-kZlzXGQ6-yU8T3iHiSyQ"); 

                        urlLoad.load(urlreq); 
                        urlLoad.addEventListener(IOErrorEvent.IO_ERROR,iohandler); 
                        urlLoad.addEventListener(Event.COMPLETE,compHandler); 
                        urlLoad.addEventListener(HTTPStatusEvent.HTTP_STATUS,httpHandler); 

                        } 

                        private function iohandler(e:IOErrorEvent):void 
                        { 
                        tt.appendText("\n In IOError handler" + e.errorID +" " +e.type); 

                        } 
                        private function compHandler(e:Event):void{ 
                        tt.appendText("\n In Complete handler,"+"status: " +e.type + "\n"); 
                        } 

                        private function httpHandler(e:HTTPStatusEvent):void{ 
                        tt.appendText("\n in httpstatus handler,"+ "Status: " + e.status); 
                        } 

                        // If the subscription request fails, StatusEvent is dispatched with 
                        // error level and code. 
                        public function statusHandler(e:StatusEvent):void{ 
                        tt.appendText("\n statusHandler"); 
                        tt.appendText("event Level" + e.level +"\nevent code " + 
                        e.code + "\ne.currentTarget: " + e.currentTarget.toString()); 
                        } 
                        } 
                        }

Abilitazione delle notifiche push nel file XML dell'applicazione

Per poter utilizzare le notifiche push nella vostra applicazione, dovete specificare quanto segue nel tag Entitlements (sotto il tag iphone ):

<iphone> 
                            ... 
                               <Entitlements> 
                                  <![CDATA[ 
                                     <key>aps-environment</key> 
                                     <string>development</string> 
                                  ]]> 
                               </Entitlements> 
                            </iphone>

Quando siete pronti a eseguire il push dell'applicazione all'App Store, un elemento <string> per lo sviluppo alla produzione:

      <string>production</string>

Se la vostra applicazione supporta stringhe localizzate, specificate le lingue nel tag supportedLanguages , sotto al tag intialWindow , come nell'esempio seguente:

<supportedLanguages>en de cs es fr it ja ko nl pl pt</supportedLanguages>

Creazione di un profilo di provisioning e di un certificato per l'abilitazione dei servizi push di iOS

Per abilitare le comunicazioni tra l'applicazione e il servizio APN, dovete inserire nell'applicazione un profilo di provisioning e un certificato che abiliti i servizi push di iOS. Per farlo, procedete nel modo seguente:

  1. Accedete al vostro account di sviluppatore Apple.

  2. Navigate fino al Provisioning Portal.

  3. Fate clic sulla scheda App IDs.

  4. Fate clic sul pulsante New App ID.

  5. Specificate una descrizione e un identificatore pacchetto (non utilizzate l'asterisco (*) nell'identificatore pacchetto).

  6. Fate clic su Invia. Il Provisioning Portal genera l'ID applicazione e visualizza di nuovo la pagina App IDs.

  7. Fate clic su Configure, alla destra dell'ID applicazione. Viene visualizzata la pagina Configure App ID.

  8. Selezionate la casella di controllo Enable per il servizio APN. Noterete che vi sono due tipi di certificati SSL push: uno per lo sviluppo/test e un altro per la produzione.

  9. Fate clic sul pulsante Configure a destra di Development Push SSL Certificate. Viene visualizzata la pagina Generate Certificate Signing Request (CSR).

  10. Generate una CSR utilizzando l'utility Keychain Access, come spiegato nella pagina.

  11. Generate il certificato SSL.

  12. Scaricate e installate il certificato SSL.

  13. (Facoltativo) Ripetete i passaggi da 9 a 12 per il certificato SSL push per la produzione.

  14. Fate clic su Done. Viene visualizzata la pagina Configure App ID.

  15. Fate clic su Done. Viene visualizzata la pagina App IDs. Noterete il cerchio verde accanto a Push Notification per il vostro ID applicazione.

  16. Assicuratevi di salvare i vostri certificati SSL, in quanto vi serviranno successivamente per abilitare le comunicazioni tra l'applicazione e il provider.

  17. Fate clic sulla scheda Provisioning per visualizzare la pagina Provisioning Profiles.

  18. Create un profilo di provisioning per il vostro nuovo ID applicazione e scaricatelo.

  19. Fate clic sulla scheda Certificates e scaricate un nuovo certificato per il nuovo profilo di provisioning.

Uso dei suoni nelle notifiche push

Per abilitare le notifiche sonore nella vostra applicazione, dovete inserire i file audio come qualsiasi altra risorsa, ma nella stessa directory dei file SWF e app-xml. Ad esempio:

Build/adt -package -target ipa-app-store -provisioning-profile _-_.mobileprovision -storetype pkcs12 -keystore _-_.p12 test.ipa test-app.xml test.swf sound.caf sound1.caf

Apple supporta i seguenti formati di dati audio (su file aiff, wav o caf):

  • PCM lineare

  • MA4 (IMA/ADPCM)

  • uLaw

  • aLaw

Uso di notifiche di avviso localizzate

Per utilizzare le notifiche di avviso localizzate nella vostra applicazione, inserite stringhe localizzate sotto forma di cartelle lproj. Ad esempio, per supportare avvisi in spagnolo, procedete nel modo seguente:

  1. Create una cartella es.lproj all'interno del progetto, allo stesso livello del file app-xml.

  2. All'interno della cartella es.lproj, create un file di testo denominato Localizable.Strings.

  3. Aprite Localizable.Strings in un editor di testo e aggiungete le chiavi dei messaggi e le stringhe localizzate corrispondenti. Ad esempio:

    "PokeMessageFormat" = "La notificación de alertas en español."
  4. Salvate il file.

  5. Quando l'applicazione riceve una notifica di avviso con questo valore chiave e la lingua del dispositivo è lo spagnolo, viene visualizzato il testo dell'avviso tradotto.

Configurazione di un provider di notifiche remote

È necessario un provider di notifiche remote che invii le notifiche push alla vostra applicazione. Questa applicazione server funge da provider, accettando i vostri input di push e trasferendo la notifica con i relativi dati al servizio APN, che, a sua volta, invia la notifica push a un'applicazione client.

Per informazioni dettagliate sull'invio di notifiche push da un provider di notifiche remote, consultate l'articolo Provider Communication with Apple Push Notification Service della libreria per sviluppatori Apple.

Opzioni per provider di notifiche remote

Le opzioni disponibili per la configurazione di un provider di notifiche remote sono le seguenti:

  • Create un vostro provider, basato sul server open-source APNS-php. Per impostare un server PHP potete utilizzare http://code.google.com/p/apns-php/ . Questo progetto Google Code consente di progettare un'interfaccia in grado di soddisfare i vostri specifici requisiti.

  • Usate un provider di servizi. Ad esempio, http://urbanairship.com/ offre un provider di servizi APN pronto per l'uso. Dopo aver eseguito la registrazione al servizio, dovete iniziare a fornire il token del vostro dispositivo utilizzando codice simile al seguente:

    private var urlreq:URLRequest; 
                                        private var urlLoad:URLLoader = new URLLoader(); 
                                        private var urlString:String; 
    
                                        //When subscription is successful then only call the following code 
                                        urlString = new String("https://go.urbanairship.com/api/device_tokens/" + e.tokenId); 
                                        urlreq = new URLRequest(urlString); 
    
                                        urlreq.authenticate = true; 
                                        urlreq.method = URLRequestMethod.PUT; 
                                        URLRequestDefaults.setLoginCredentialsForHost("go.urbanairship.com", 
                                           "Application Key","Application Secret"); 
                                        urlLoad.load(urlreq); 
                                        urlLoad.addEventListener(IOErrorEvent.IO_ERROR,iohandler); 
                                        urlLoad.addEventListener(Event.COMPLETE,compHandler); 
                                        urlLoad.addEventListener(HTTPStatusEvent.HTTP_STATUS,httpHandler); 
    
                                        private function iohandler(e:IOErrorEvent):void{ 
                                           trace("\n In IOError handler" + e.errorID +" " +e.type); 
                                        } 
    
                                        private function compHandler(e:Event):void{ 
                                           trace("\n In Complete handler,"+"status: " +e.type + "\n"); 
                                        } 
    
                                        private function httpHandler(e:HTTPStatusEvent):void{ 
                                           tt.appendText("\n in httpstatus handler,"+ "Status: " + e.status); 
                                        }

    Per inviare notifiche di prova potete usare gli strumenti Urban Airship.

Certificati per il provider di notifiche remote

Dovete copiare il certificato SSL e il codice privato (precedentemente generato) nel percorso appropriato sul server del provider di notifiche remote. In genere, potete unire questi due file in un unico file .pem . Per farlo, procedete nel modo seguente:

  1. Aprite una finestra di terminale.

  2. Create un file .pem dal certificato SSL digitando il seguente comando:

    openssl x509 -in aps_developer_identity.cer -inform der -out TestPushDev.pem
  3. Create un file .pem a partire dalla chiave privata ( .p12 ) digitando il seguente comando:

    openssl pkcs12 -nocerts -out TestPushPrivateKey.pem -in certificates.p12
  4. Unite i due file .pem in un unico file digitando il comando seguente:

    cat TestPushDev.pem TestPushPrivateKey.pem > FinalTestPush.pem
  5. Fornite il file .pem creato al provider durante la creazione dell'applicazione push lato server.

Per maggiori informazioni, consultate l'articolo Installing the SSL Certificate and Key on the Server della guida Local and Push Notification Programming Guide di Apple.

Gestione delle notifiche push in un'applicazione

La gestione delle notifiche push in un'applicazione comporta quanto segue:

  • Configurazione e accettazione delle notifiche push da parte degli utenti a livello globale

  • Accettazione da parte degli utenti delle singole notifiche push

  • Gestione delle notifiche push e dei dati di payload delle notifiche

Configurazione e accettazione delle notifiche push

La prima volta che un utente avvia un'applicazione abilitata per le notifiche push, iOS visualizza la finestra di dialogo nome app desidera inviarti notifiche push , con i pulsanti Non consentire e OK. Se l'utente sceglie OK, l'applicazione potrà ricevere tutti i tipi di notifiche che ha sottoscritto. Se l'utente seleziona Non consentire, l'applicazione non riceverà alcuna notifica.

Nota: gli utenti possono inoltre selezionare Impostazioni > Notifiche per controllare i tipi specifici di notifiche che desiderano ricevere per ciascuna applicazione abilitata per le notifiche push.

Apple raccomanda di sottoscrivere le notifiche push per ogni applicazione che viene attivata. Quando la vostra applicazione richiama RemoteNotifier.subscribe() , essa riceve un RemoteNotificationEvent di tipo token contenente un tokenId numerico a 32 byte che identifica in modo univoco tale applicazione su un determinato dispositivo.

Ogni volta che il dispositivo riceve una notifica push, viene visualizzata una finestra a comparsa con i pulsanti Chiudi e Avvia. Se l'utente tocca Chiudi, non accade nulla; se invece seleziona Avvia, iOS richiama l'applicazione, che riceverà un flash.events.RemoteNotificationEvent di tipo notification , come descritto di seguito.

Gestione delle notifiche push e dei dati di payload

Quando il provider di notifiche remote invia una notifica a un dispositivo (usando il tokenID), la vostra applicazione riceverà un flash.events.RemoteNotificationEvent di tipo notification , indipendentemente dal fatto che l'applicazione sia o meno in esecuzione. A questo punto, l'applicazione eseguirà un'elaborazione della notifica specifica dell'applicazione. Se l'applicazione gestisce i dati delle notifiche, potrete accedervi mediante la proprietà RemoteNotificationEvent.data formattata con JSON.