2012年10月17日 星期三

Adobe AIR 與Push Notifications

為大家介紹Adobe AIR 原生支援的Push Notifications 功能, 配合apns-php 伺服器發出訊息給iOS 裝置.

簡單測試需要的準備:
  • Adobe AIR 3.4 或以上SDK (安裝SDK 於Flash Builder 請參考)
  • 一個iOS 裝置 (不能以XCode Simulator 來取代)
  • 需要.p12, .mobileprovision 與.pem 檔 (製作包含Push Notifications 功能請參考)
  • 一個執行Push Notification Provider 的伺服器, 我們可以使用apns-php


Push Notifications 的運作原理:

  • 使用Adobe AIR 提供的介面(RemoteNotifier) 並執行訂閱(subscribe), 取得一個Device Token (這是每個iOS 裝置獨一無異的記號)
  • 把Device Token 提交給伺服器記下
  • 利用Push Notification Provider 發放訊息給這些Device Token
  • 這個iOS 裝置會收到Push Notification
Push Notifications 基本工作流程


Adobe AIR 提供以下三種Push Notification 提示:
  • NotificationStyle.ALERT - 在收到通知時顯示警告方塊的通知
  • NotificationStyle.BADGE - 收到通知時會以數字/影像更新應用程式圖示的通知
  • NotificationStyle.SOUND - 在收到通知時播放聲音的通知
Adobe AIR 在iOS 接收Push Notifications

在Adobe AIR 程式編寫, 提供一個按鈕給用戶按下(clickHandler), 取得iOS 裝置的Device Token:
private function clickHandler(event:MouseEvent):void{
  trace("clickHandler: " + RemoteNotifier.supportedNotificationStyles.length);
  myTxt.appendText("clickHandler: " + RemoteNotifier.supportedNotificationStyles.length+"\n");
  
  if ( RemoteNotifier.supportedNotificationStyles.length > 0)
  {
    var preferredNotificationStyles:Vector.<string> = new Vector.<string>;
    
    preferredNotificationStyles.push(NotificationStyle.ALERT);
    preferredNotificationStyles.push(NotificationStyle.SOUND);
    preferredNotificationStyles.push(NotificationStyle.BADGE);
    
    var subscribeOptions:RemoteNotifierSubscribeOptions = new RemoteNotifierSubscribeOptions();
    subscribeOptions.notificationStyles = preferredNotificationStyles;
    
    rn = new RemoteNotifier();
    
    rn.addEventListener(RemoteNotificationEvent.TOKEN, sendDeviceTokenToServer);
    rn.addEventListener(StatusEvent.STATUS, subscriptionFailureCallback);
    
    rn.subscribe(subscribeOptions);
  }
}
protected function subscriptionFailureCallback(event:StatusEvent):void
{
  trace("Received Status event for registrationFailure with code:" + event.code + " and level:" + event.level + "\n");
  myTxt.appendText("Received Status event for registrationFailure with code:" + event.code + " and level:" + event.level + "\n");
}
protected function sendDeviceTokenToServer(event:RemoteNotificationEvent):void
{
  trace("Received " + event.type + " with tokenString:" + event.tokenId + "\n");
  myTxt.appendText("Received " + event.type + " with tokenString:" + event.tokenId + "\n");
}

在Adobe AIR 程式發佈設定:
  • Certificate 和Provisioning file 需要使用包含Push Notifications 功能的.p12 和 .mobileprovision 檔
  • 在XML 設定檔加入Entitlements 設定:
    <iPhone>
      <Entitlements><![CDATA[
        <key>get-task-allow</key>
        <true/>
        <key>aps-environment</key>
        <string>development</string>
        <key>keychain-access-groups</key>
        <array>
          <string>KEYCHAIN_ACCESS_GROUP</string>
        </array>
      ]]></Entitlements>
    </iPhone>
  • 在Flex Compiler > Additional compilder arguments: 更改成:
    -locale en_US -swf-version=17

架設apns-php 伺服器後, 我們更改sample_push.php 的內容作為發訊測試:
  • 更改.pem 檔名稱, 並把.pem 檔案複製至與sample_push.php 同一資料夾內
  • 加入iOS 裝置的Device Token
更改sample_push.php 內容

當執行sample_push.php 後, 測試對像的iOS 裝置會接收到Push Notification. 大家可以 [下載] 範例試試看.

參考資料: http://blogs.adobe.com/airodynamics/2012/05/29/push-notifications-support-in-ios/

2012年10月16日 星期二

製作p12, mobileprovision 與pem

製作p12 :  認證檔 iOS Certificate (包含Push Notifications 功能)
  1. 進入iOS Provisioning Portal, 在App IDsNew App ID

  2. 輸入新增程式的名稱 (NameApp ID)

  3. 找尋新增的程式, 按下Configure

  4. 啟動Enable for Apple Push Notification service, 並在Development Push SSL Certificate 按下Configure

  5. 然後按指示, 在MAC OS X 的Utilities 開啟Keychain Access, 選擇:
    Keychain > Certificate > Assistant > Request a Certificate from a Certificate Authority

  6. 產生一個csr 檔, 並儲存於桌面上

  7. 把桌面上的csr 檔上載給iOS Provisioning Portal 處理

  8. 處理完成後, 會產生一個cer 檔, 把它下載至桌面

  9. 在桌面執行cer 檔後, 在Keychain Access 會新增一個Certificate

  10. 在新增的Certificate 右按Export 產生p12 檔


製作mobileprovision :  描述檔 Provisioning Profile
  1. ProvisioningDistribution 選擇New Profile

  2. 輸入Profile Name 等資料

  3. 手動更新iOS Provisioning Portal 網頁(數秒時間便可), 直至新增的項目提供mobileprovision 檔下載按鈕


製作pem :  數位憑證 Push Certificate
  1. 開啟MAC OS X 的Terminal, 移至儲存p12 檔的桌面位置: (請更改為正確路徑)
    cd /Users/YOUR_USER_NAME/Desktop/
  2. 然後輸入以下指令產生pem 檔:
    openssl pkcs12 -in Certificates.p12 -out server_certificates_bundle_sandbox.pem -nodes -clcerts

若大家沒有開發者帳號, 可考慮暫時使用假認證檔(p12) 和描述檔(mobileprovision) 作測試. 待日後正式發佈時, 才購買開發者帳號.

2012年10月10日 星期三

as3dpad 操控桿介紹

as3dpad 是作者製作的一個類別庫, 目的在Adobe AIR mobile 提供一個虛擬操控桿, 於iOS 和Android 等流動裝置運作, 為遊戲提供一個輸入方法.

配合Starling 的 [範例] (請以鍵盤WASDm, 操控)

as3dpad 渲染部分參考SpriteSheetClip 的手法, 所以在stage3d 之上有效運作, 與Starling 等框架相容.
另外, 類別庫提供以鍵盤代替螢幕輸入(WASDm,), 給開發人員在電腦直接測試遊戲.

弧度(radians) 表示操控桿位置

以下是編寫的簡單步驟:
  1. 建立DPad 物件
    var dPad:DPad = new DPad();
    this.addChild(dPad);
    
  2. 接收X 軸與Y 軸回傳的數據
    dPad.leftPad.addEventListener(DPadEvent.TOUCH_PRESS, touchPressHandler);
    dPad.leftPad.addEventListener(DPadEvent.TOUCH_RELEASE, touchReleaseHandler);
    
    private function touchPressHandler(event:DPadEvent):void{
      var axisPad:AxisPad = event.target as AxisPad;
      trace("radians: " + axisPad.radians);
      trace("distance: " + axisPad.distance + "/" + axisPad.maxDistance);
      trace("press left:  " + (axisPad.value & AxisPad.LEFT));
      trace("press right: " + (axisPad.value & AxisPad.RIGHT));
      trace("press up:    " + (axisPad.value & AxisPad.UP));
      trace("press down:  " + (axisPad.value & AxisPad.DOWN));
    }
    private function touchReleaseHandler(event:DPadEvent):void{
      ...
    }
    
  3. 接收A 和B 按鈕回傳的數據
    dPad.rightPad.addEventListener(DPadEvent.TOUCH_PRESS_A, touchPressAHandler);
    dPad.rightPad.addEventListener(DPadEvent.TOUCH_PRESS_B, touchPressBHandler);
    dPad.rightPad.addEventListener(DPadEvent.TOUCH_RELEASE_A, touchReleaseAHandler);
    dPad.rightPad.addEventListener(DPadEvent.TOUCH_RELEASE_B, touchReleaseBHandler);
    
    private function touchPressAHandler(event:DPadEvent):void{
      var groupPad:GroupPad = event.target as GroupPad;
      trace("press A: " + (groupPad.value & GroupPad.A_BUTTON));
      trace("press B: " + (groupPad.value & GroupPad.B_BUTTON));
    }
    private function touchPressBHandler(event:DPadEvent):void{
        ...
    }
    private function touchReleaseAHandler(event:DPadEvent):void{
        ...
    }
    private function touchReleaseBHandler(event:DPadEvent):void{
        ...
    }

類別庫提供以下範例參考:
  • example01_basic - 基本用法 [demo]
  • example02_custom_UI - 自定介面 [demo]
  • example03_double_AxisPad - 雙操控桿 [demo]
  • example04_touch9Grid - 螢幕九格觸控 [demo]
  • example05_starling - 配合Starling [demo]

Launch Examples Launch Examples Launch Examples Launch Examples Launch Examples

大家可以 [下載] 範例試試看.