푸시 알림 사용

푸시 알림은 원격 알림 공급자가 모바일 장치에서 실행되고 있는 응용 프로그램에 알림을 전송하도록 합니다. AIR 3.4에서는 APNs(Apple Push Notification service)를 사용하여 iOS 장치에 대해 푸시 알림을 지원합니다.

참고: AIR에서 Android 응용 프로그램에 대해 푸시 알림을 사용하려면 Adobe 전문가 Piotr Walczyszyn씨가 개발한 as3c2dm 과 같은 기본 확장을 사용하십시오.

이 섹션의 나머지 부분에서는 AIR에서 iOS 응용 프로그램에 대해 푸시 알림을 활성화하는 방법을 설명합니다.

참고: 이 단원에서는 사용자가 Apple 개발자 ID를 가지고 있고 iOS 개발 작업 과정에 익숙하며, iOS 장치에 하나 이상의 응용 프로그램을 배포한 경험이 있다고 가정합니다.

푸시 알림 개요

APNs(Apple Push Notification service)는 원격 알림 공급자가 iOS 장치에서 실행되고 있는 응용 프로그램에 알림을 전송하도록 합니다. APNs에서 지원하는 알림 유형은 다음과 같습니다.

  • 경고

  • 배지

  • 사운드

APNs에 대한 자세한 내용은 developer.apple.com 을 참조하십시오.

응용 프로그램에서 푸시 알림을 사용하는 작업은 다음 여러 요소로 이루어집니다.

  • 클라이언트 응용 프로그램 - 푸시 알림에 등록하고, 원격 알림 공급자와 통신하며, 푸시 알림을 수신합니다.

  • iOS - 클라이언트 응용 프로그램과 APNs 간의 상호 작용을 관리합니다.

  • APNs - 클라이언트 등록 과정에서 tokenID를 제공하고 원격 알림 공급자에서 iOS로 알림을 전달합니다.

  • 원격 알림 공급자 - tokenId-클라이언트 응용 프로그램 정보를 저장하고 APNs로 알림을 푸시합니다.

등록 작업 과정

서버 측 서비스에 푸시 알림을 등록하는 작업 과정은 다음과 같습니다.

  1. 클라이언트 응용 프로그램은 iOS에서 푸시 알림을 활성화하도록 요청합니다.

  2. iOS에서 해당 요청을 APNs로 전달합니다.

  3. APNs 서버에서 tokenId를 iOS에 반환합니다.

  4. iOS에서 tokenId를 클라이언트 응용 프로그램에 반환합니다.

  5. 클라이언트 응용 프로그램에서 응용 프로그램별 메커니즘을 통해 원격 알림 공급자에 tokenId를 제공하며, 원격 알림 공급자는 푸시 알림용으로 해당 tokenId를 저장합니다.

알림 작업 과정

알림 작업 과정은 다음과 같습니다.

  1. 원격 알림 공급자에서 알림을 생성하고 해당 알림 페이로드를 tokenId와 함께 APNs에 전달합니다.

  2. APNs에서 알림을 장치에 있는 iOS에 전달합니다.

  3. iOS에서 알림 페이로드를 응용 프로그램에 푸시합니다.

푸시 알림 API

AIR 3.4에는 iOS 푸시 알림을 지원하는 API 세트가 추가되었습니다. 이 API는 flash.notifications 패키지에 들어 있으며 다음과 같은 클래스를 포함하고 있습니다.

  • NotificationStyle - 알림 유형 ALERT , BADGE SOUND .C에 대한 상수를 정의합니다.

  • RemoteNotifier - 푸시 알림에 구독하거나 구독 해제하도록 합니다.

  • RemoteNotifierSubscribeOptions - 수신할 알림 유형을 선택하도록 합니다. notificationStyles 속성을 사용하면 여러 알림 유형에 대해 등록할 문자열 벡터를 정의할 수 있습니다.

AIR 3.4에는 다음과 같이 RemoteNotifier 에 의해 전달되는 flash.events.RemoteNotificationEvent 도 포함되어 있습니다.

  • 응용 프로그램의 구독이 성공적으로 작성되면 APNs로부터 새로운 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 파일에서 푸시 알림 활성화

응용 프로그램에서 푸시 알림을 사용하려면 iphone 태그 아래의 Entitlements 태그 내용을 다음과 같이 입력합니다.

<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 푸시 서비스를 활성화하는 프로비저닝 프로파일과 인증서 만들기

응용 프로그램 및 APNs 간 통신을 활성화하려면 해당 응용 프로그램을 iOS 푸시 서비스를 활성화하는 프로비저닝 프로파일 및 인증서와 함께 패키지화해야 합니다.

  1. Apple 개발자 계정으로 로그인합니다.

  2. Provisioning Portal로 이동합니다.

  3. [응용 프로그램 ID] 탭을 클릭합니다.

  4. [새 응용 프로그램 ID] 버튼을 클릭합니다.

  5. 설명 및 번들 식별자를 지정합니다. 번들 식별자에는 * 기호를 사용하지 않습니다.

  6. [전송]을 클릭합니다. Provisioning Portal에서 응용 프로그램 ID를 생성하고 응용 프로그램 ID 페이지를 다시 표시합니다.

  7. 응용 프로그램 ID 오른쪽에 있는 [구성]을 클릭합니다. [응용 프로그램 ID 구성] 페이지가 표시됩니다.

  8. [Apple 푸시 알림 서비스 사용] 체크 상자를 선택합니다. 푸시 SSL 인증서에는 각각 개발/테스트용과 실제 업무용으로 두 가지 유형이 있습니다.

  9. 개발용 푸시 SSL 인증서의 오른쪽에 있는 [구성] 버튼을 클릭합니다. [인증서 서명 요청(CSR) 생성] 페이지가 표시됩니다.

  10. 페이지의 지침에 따라 키체인 접근 유틸리티를 사용하여 CSR을 생성합니다.

  11. SSL 인증서를 생성합니다.

  12. SSL 인증서를 다운로드하여 설치합니다.

  13. (선택 사항) 실제 업무용 푸시 SSL 인증서에 대해 9~12단계를 반복합니다.

  14. [완료]를 클릭합니다. [응용 프로그램 ID 구성] 페이지가 표시됩니다.

  15. [완료]를 클릭합니다. [응용 프로그램 ID] 페이지가 표시됩니다. 해당 응용 프로그램 ID에 대한 푸시 알림 옆에 있는 녹색 원을 주목하십시오.

  16. SSL 인증서를 저장합니다. 이 인증서는 나중에 응용 프로그램 및 공급자 간 통신에 사용됩니다.

  17. [프로비저닝] 탭을 클릭하여 [프로비저닝 프로파일] 페이지를 표시합니다.

  18. 새 응용 프로그램 ID에 대한 프로비저닝 프로파일을 작성한 후 다운로드합니다.

  19. [인증서] 탭을 클릭하여 새 프로비저닝 프로파일에 대한 새 인증서를 다운로드합니다.

푸시 알림에 사운드 사용

응용 프로그램에서 사운드 알림을 사용하려면 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 파일 형태)은 다음과 같습니다.

  • Linear PCM

  • MA4(IMA/ADPCM)

  • uLaw

  • aLaw

지역화된 경고 알림 사용

응용 프로그램에서 지역화된 경고 알림을 사용하려면 지역화된 문자열을 lproj 폴더의 형식으로 번들하십시오. 예를 들어 경고를 스페인어로 지원하려면 다음과 같이 합니다.

  1. 프로젝트 안에 app-xml 파일과 같은 수준에서 es.lproj 폴더를 만듭니다.

  2. es.lproj 폴더 안에서 Localizable.Strings라는 이름으로 텍스트 파일을 만듭니다.

  3. 텍스트 편집기에서 Localizable.Strings를 열고 메시지 키와 해당되는 지역화된 문자열을 추가합니다. 예를 들면 다음과 같습니다.

    "PokeMessageFormat" = "La notificación de alertas en español."
  4. 파일을 저장합니다.

  5. 응용 프로그램에서 이 키 값을 갖는 경고 알림을 수신하고 장치 언어가 스페인어인 경우 변환된 경고 텍스트가 표시됩니다.

원격 알림 공급자 구성

응용 프로그램에 푸시 알림을 보내려면 원격 알림 공급자가 필요합니다. 이 서버 응용 프로그램은 사용자의 푸시 입력을 허용하고 알림 및 알림 데이터를 APNs에 전달하는 공급자로 작동하며, 곧이어 APNs에서는 푸시 알림을 클라이언트 응용 프로그램에 전송합니다.

원격 알림 공급자에서 알림을 푸시하는 방식에 대한 자세한 내용은 Apple 개발자 라이브러리에서 공급자와 APNs(Apple Push Notification service) 간 통신 을 참조하십시오.

원격 알림 공급자 옵션

원격 알림 공급자에 대한 옵션은 다음과 같습니다.

  • APNS-php 오픈 소스 서버를 기반으로 사용자 고유의 공급자를 만듭니다. http://code.google.com/p/apns-php/ 의 내용을 참고하여 PHP 서버를 설정할 수 있습니다. 이 Google 코드 프로젝트를 활용하면 사용자의 특정 요구 사항을 충족하는 인터페이스를 설계할 수 있습니다.

  • 서비스 공급자를 사용합니다. 예를 들어 http://urbanairship.com/ 에서는 미리 준비된 APNs 공급자를 제공합니다. 이 서비스에 등록한 후에는 가장 먼저 다음과 비슷한 코드를 사용하여 장치 토큰을 제공합니다.

    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 인증서와 이전에 생성된 개인 키를 복사해 놓아야 합니다. 이 두 파일은 하나의 .pem 파일로 통합하는 것이 일반적입니다. 이렇게 하려면 다음 단계를 수행하십시오.

  1. 터미널 윈도우를 엽니다.

  2. 다음 명령을 입력하여 SSL 인증서로부터 .pem 파일을 생성합니다.

    openssl x509 -in aps_developer_identity.cer -inform der -out TestPushDev.pem
  3. 다음 명령을 입력하여 개인 키 파일의 .pem 파일을 생성( .p12 )합니다.

    openssl pkcs12 -nocerts -out TestPushPrivateKey.pem -in certificates.p12
  4. 다음 명령을 입력하여 두 .pem 파일을 단일 파일로 결합합니다.

    cat TestPushDev.pem TestPushPrivateKey.pem > FinalTestPush.pem
  5. 서버 측 푸시 응용 프로그램을 만들 때, 결합된 .pem 파일을 서버 공급자에 제공합니다.

자세한 내용은 Apple 로컬 및 푸시 알림 프로그래밍 안내서에서 서버에 SSL 인증서 및 키 설치 를 참조하십시오.

응용 프로그램 내 푸시 알림 처리

응용 프로그램 내의 푸시 알림 처리는 다음 작업으로 이루어집니다.

  • 전역 사용자 구성 및 푸시 알림의 허용

  • 개별 푸시 알림에 대한 사용자의 허용

  • 푸시 알림 및 알림 페이로드 데이터의 처리

구성 및 푸시 알림의 허용

iOS에서는 사용자가 푸시 알림 지원 응용 프로그램을 처음으로 시작할 때 [허용 안 함] 및 [확인] 버튼이 포함된 appname 푸시 알림 전송 대화 상자를 표시합니다. 사용자가 [확인]을 선택하면 응용 프로그램에서 구독하는 모든 스타일의 알림을 수신할 수 있습니다. [허용 안 함]을 선택하면 아무런 알림도 수신되지 않습니다.

참고: [설정] > [알림]으로 이동하면 각 푸시 지원 응용 프로그램과 관련해 수신할 수 있는 특정 알림 유형을 제어할 수 있습니다.

Apple에서는 응용 프로그램이 활성화될 때마다 푸시 알림에 구독하도록 설정할 것을 권장하고 있습니다. 응용 프로그램에서 RemoteNotifier.subscribe() 를 호출하면 token 유형의 RemoteNotificationEvent 를 수신하게 되며, 여기에는 장치에서 해당 응용 프로그램을 고유하게 식별하는 32바이트 고유 숫자 tokenId가 포함되어 있습니다.

장치에서 푸시 알림을 수신하면 [닫기] 및 [시작] 버튼이 포함된 팝업이 표시됩니다. 사용자가 [닫기]를 터치하면 아무런 동작도 발생하지 않습니다. [시작]을 터치하면 iOS에서는 해당 응용 프로그램을 호출하고 이 응용 프로그램은 아래에 설명된 것처럼 notification 유형의 flash.events.RemoteNotificationEvent 를 수신합니다.

푸시 알림 및 페이로드 데이터의 처리

원격 알림 공급자에서 tokenID를 사용하여 장치에 알림을 전송하면 응용 프로그램에서는 현재 실행 여부에 관계없이 notification 유형의 flash.events.RemoteNotificationEvent 를 수신하게 됩니다. 응용 프로그램은 이 시점에서 응용 프로그램별 알림 처리를 수행합니다. 응용 프로그램에서 알림 데이터를 처리할 경우 사용자는 해당 데이터를 JSON 형식의 RemoteNotificationEvent.data 속성을 통해 액세스할 수 있습니다.