プッシュ通知の使用

プッシュ通知を使用すると、リモート通知プロバイダーから、モバイルデバイス上で実行されているアプリケーションへ、通知を送信できます。AIR 3.4 は、Apple Push Notification サービス(APN)を使用して、iOS デバイス用にプッシュ通知をサポートしています。

注意: AIR for Android アプリケーション向けのプッシュ通知を有効にするには、Adobe エバンジェリストの Piotr Walczyszyn 氏が開発した as3c2dm などのネイティブエクステンションを使用してください。

この節の残りの部分では、AIR for iOS アプリケーションでプッシュ通知を有効にする方法について説明します。

注意: この説明は、Apple のデベロッパー ID を持っていて、iOS の開発ワークフローに精通していて、iOS デバイスで 1 つ以上のアプリケーションを開発済みであることを前提としています。

プッシュ通知の概要

Apple Push Notification サービス(APN)を使用すると、リモート通知プロバイダーから、iOS デバイス上で実行されているアプリケーションへ、通知を送信できます。APN では次の通知タイプがサポートされています。

  • 警告

  • バッジ

  • サウンド

APN について詳しくは、developer.apple.com を参照してください。

アプリケーションでプッシュ通知を使用するには、次のような複数の要素が必要です。

  • クライアントアプリケーション - プッシュ通知の登録、リモート通知プロバイダーとの通信、プッシュ通知の受信を行います。

  • iOS - クライアントアプリケーションと APN の間の相互動作を管理します。

  • APN - クライアントの登録時に tokenID を提供し、リモート通知プロバイダーから iOS へ、通知を渡します。

  • リモート通知プロバイダー - tokenId クライアントアプリケーション情報を保存し、通知を APN にプッシュします。

登録のワークフロー

プッシュ通知をサーバー側のサービスに登録するワークフローは次のとおりです。

  1. クライアントアプリケーションが、プッシュ通知を有効にするように iOS に要求します。

  2. iOS が、この要求を APN に転送します。

  3. APN サーバーが tokenId を iOS に返します。

  4. iOS が tokenId をクライアントアプリケーションに返します。

  5. クライアントアプリケーション(アプリケーション固有のメカニズムを使用)が、tokenId をリモート通知プロバイダーに提供し、そこでプッシュ通知に使用する tokenId が保存されます。

通知のワークフロー

通知のワークフローは次のとおりです。

  1. リモート通知プロバイダーが通知を生成し、通知ペイロードを、tokenId と共に APN に渡します。

  2. APN がデバイス上の iOS に通知を転送します。

  3. iOS が通知ペイロードをアプリケーションにプッシュします。

プッシュ通知 API

AIR 3.4 では、iOS のプッシュ通知をサポートする一連の API が導入されました。これらの API は flash.notifications パッケージ内にあり、次のクラスが含まれています。

  • NotificationStyle - 通知タイプの定数、ALERTBADGE および SOUND を定義します。

  • RemoteNotifier - プッシュ通知をサブスクライブおよびアンサブスクライブすることができます。

  • RemoteNotifierSubscribeOptions - 受信する通知タイプを選択できます。複数の通知タイプに登録する文字列のベクトルを定義するには、notificationStyles プロパティを使用します。

AIR 3.4 には、flash.events.RemoteNotificationEvent も含まれています。これは、RemoteNotifier によって、次の場合に送出されます。

  • アプリケーションのサブスクリプションが正常に作成されて、APN から新しい tokenId を受信したとき。

  • 新しいリモート通知を受信したとき。

また、サブスクリプションプロセスでエラーが発生した場合、RemoteNotifier から flash.events.StatusEvent が送出されます。

アプリケーションでのプッシュ通知の管理

アプリケーションをプッシュ通知に登録するには、次の手順を実行する必要があります。

  • アプリケーションでコードを作成し、プッシュ通知をサブスクライブします。

  • アプリケーションの XML ファイルでプッシュ通知を有効にします。

  • iOS のプッシュサービスを有効にするプロビジョニングプロファイルと証明書を作成します。

次の注釈付きのサンプルコードは、プッシュ通知をサブスクライブし、プッシュ通知イベントを処理するためのものです。

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

アプリケーション XML ファイルでのプッシュ通知の有効化

アプリケーションでプッシュ通知を使用するには、Entitlements タグ(iphone タグの下)で、次のように指定します。

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

アプリケーションを App Store にプッシュする準備ができたら、<string> エレメントを development から production に変更します。

      <string>production</string>

ローカライズされた文字列に対応するアプリケーションの場合は、intialWindow タグの下の supportedLanguages タグで、次の例に従って言語を指定します。

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

iOS のプッシュサービスを有効にするプロビジョニングプロファイルと証明書の作成

アプリケーションと APN の通信を有効にするには、次のように、iOS のプッシュサービスを有効にするプロビジョニングプロファイルと証明書を含めてアプリケーションをパッケージ化する必要があります。

  1. Apple デベロッパーアカウントにログインします。

  2. Provisioning Portal に移動します。

  3. 「App IDs」タブをクリックします。

  4. 「New App ID」ボタンをクリックします。

  5. 説明とバンドル ID を指定します(バンドル ID には * は使用しないでください)。

  6. 「Submit」をクリックします。Provisioning Portal で App ID が生成され、App IDs ページが再度表示されます。

  7. 「Configure」(App ID の右側)をクリックします。Configure App ID ページが表示されます。

  8. 「Enable for Apple Push Notification service」チェックボックスを選択します。プッシュ SSL 証明書には、開発/テスト用と本番用の 2 種類があります。

  9. 「Development Push SSL Certificate」の右側にある「Configure」ボタンをクリックします。Generate Certificate Signing Request (CSR) ページが表示されます。

  10. ページの指示に従って、Keychain Access ユーティリティを使用して CSR を生成します。

  11. SSL 証明書を生成します。

  12. SSL 証明書をダウンロードしてインストールします。

  13. (オプション)本番用プッシュ SSL 証明書に関して、手順 9 から 12 を繰り返します。

  14. 「Done」をクリックします。Configure App ID ページが表示されます。

  15. 「Done」をクリックします。App IDs ページが表示されます。App ID のプッシュ通知の横に緑色の丸が付いていることを確認してください。

  16. SSL 証明書は、後でアプリケーションとプロバイダーの通信に使用するので、必ず保存してください。

  17. 「Provisioning」タブをクリックして Provisioning Profiles ページを表示します。

  18. 新しい App ID のプロビジョニングプロファイルを作成してダウンロードします。

  19. 「Certificates」タブをクリックして、新しいプロビジョニングプロファイル用の新しい証明書をダウンロードします。

プッシュ通知にサウンドを使用

アプリケーションでサウンド通知を有効にするには、サウンドファイルを他のアセットと同様に、ただし SWF ファイルや app-xml ファイルと同じディレクトリでバンドルします。次に、例を示します。

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 では、次のサウンドデータ形式をサポートしています(aiff、wav または caf ファイル)。

  • リニア PCM

  • MA4(IMA/ADPCM)

  • uLaw

  • aLaw

ローカライズされた警告通知の使用

ローカライズされた警告通知をアプリケーションで使用するには、ローカライズされた文字列を、lproj フォルダーの形式でバンドルします。例えば、スペイン語の警告をサポートするには、次の手順に従います。

  1. プロジェクト内で、es.lproj フォルダーを app-xml ファイルと同じレベルで作成します。

  2. es.lproj フォルダー内で、Localizable.Strings というテキストファイルを作成します。

  3. Localizable.Strings をテキストエディターで開き、メッセージキーおよび対応するローカライズ文字列を追加します。次に、例を示します。

    "PokeMessageFormat" = "La notificación de alertas en español."
  4. ファイルを保存します。

  5. アプリケーションがこのキー値の警告通知を受信したとき、デバイス言語がスペイン語であれば、翻訳された警告テキストが表示されます。

リモート通知プロバイダーの設定

プッシュ通知をアプリケーションに送信するには、リモート通知プロバイダーが必要です。このサーバーアプリケーションは、プロバイダーの役割を果たし、プッシュ入力を受け入れて、通知および通知データを APN に渡します。その後、APN がプッシュ通知をクライアントアプリケーションに送信します。

リモート通知プロバイダーからの通知のプッシュについて詳しくは、Apple Developer Library の「Provider Communication with Apple Push Notification Service」を参照してください。

リモート通知プロバイダーのオプション

リモート通知プロバイダーには、次のようなオプションがあります。

  • APNS-php オープンソースサーバーに基づいて独自のプロバイダーを作成。http://code.google.com/p/apns-php/ を使用して PHP サーバーを設定できます。この Google Code プロジェクトでは、特定の要件を満たすインターフェイスをデザインできます。

  • サービスプロバイダーを使用。例えば、http://urbanairship.com/ では、既製の APN プロバイダーが提供されています。このサービスに登録後、まず、次のようなコードを使用してデバイストークンを指定します。

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

    その後、Urban Airship のツールを使用して、テスト通知を送信できます。

リモート通知プロバイダーの証明書

SSL 証明書と秘密キー(生成済み)を、リモート通知プロバイダーのサーバー上の適切な場所にコピーする必要があります。通常は、これら 2 つのファイルを組み合わせて 1 つの .pem ファイルにします。これを行うには、次の手順を実行します。

  1. ターミナルウィンドウを開きます。

  2. 次のコマンドを入力して、SSL 証明書から .pem ファイルを作成します。

    openssl x509 -in aps_developer_identity.cer -inform der -out TestPushDev.pem
  3. 次のコマンドを入力して、秘密キー(.p12)ファイルの .pem ファイルを作成します。

    openssl pkcs12 -nocerts -out TestPushPrivateKey.pem -in certificates.p12
  4. 次のコマンドを入力して、2 つの .pem ファイルを組み合わせて 1 つのファイルにします。

    cat TestPushDev.pem TestPushPrivateKey.pem > FinalTestPush.pem
  5. サーバー側のプッシュアプリケーションを作成するときに、組み合わせた .pem ファイルをサーバープロバイダーに提供します。

詳しくは、Apple の『Local and Push Notification Programming Guide』の「Installing the SSL Certificate and Key on the Server」を参照してください。

アプリケーションでのプッシュ通知の処理

アプリケーションでのプッシュ通知の処理には、次の項目が含まれます。

  • グローバルユーザー設定とプッシュ通知の受け入れ

  • 個々のプッシュ通知のユーザーによる受け入れ

  • プッシュ通知および通知ペイロードデータの処理

プッシュ通知の設定と受け入れ

プッシュ通知が有効なアプリケーションを初めて起動すると、iOS に、"appname" はあなたにプッシュ通知を送信します。よろしいですか?ダイアログが表示されます。このダイアログには「許可しない」ボタンと「OK」ボタンがあります。「OK」を選択すると、アプリケーションは、サブスクライブしているすべてのスタイルの通知を受信します。「許可しない」を選択すると、通知はまったく受信されません。

注意: 設定/通知に移動して、プッシュが有効なアプリケーションごとに、受信できる通知タイプを制御することもできます。

Apple では、アプリケーションが起動するたびにプッシュ通知をサブスクライブすることを推奨しています。アプリケーションが RemoteNotifier.subscribe() を呼び出すと、token タイプの RemoteNotificationEvent を受信します。これには、そのデバイス上のアプリケーションを一意に識別する、32-byte の一意な数値の tokenId が含まれています。

プッシュ通知を受信したデバイスには、「閉じる」ボタンと「起動」ボタンを含むポップアップが表示されます。「閉じる」にタッチすると、何も起こりません。「起動」にタッチすると、iOS でアプリケーションが呼び出され、アプリケーションは、以下で説明するように、notification タイプの flash.events.RemoteNotificationEventnotification を受信します。

通知とペイロードデータの処理

リモート通知プロバイダーがデバイスに通知を送信すると(tokenID を使用)、アプリケーションは、実行中かどうかにかかわらず、notification タイプの flash.events.RemoteNotificationEvent を受信します。この時点で、アプリケーションでは、アプリケーションに固有の通知処理が実行されます。アプリケーションが通知データを処理する場合は、JSON 形式の RemoteNotificationEvent.data プロパティを使用してアクセスします。