[titanium] Apple Push Notification Services & Titanium SDK 2.0

LINEで送る
[`evernote` not found]

在Titanium SDK 2.0之前,要在Titanium實現「Apple Push Notification Service」是一件很麻煩的事(我還沒有成功@@),但是,前幾天Titanium sdk升級到2.0.1.GA2後,一切就可愛了很多。

首先可以更新一下KitchenSink,會發現多了不少的範例檔案。其中就包括push_notification.js。原來是多了Titanium.Network.registerForPushNotifications這個api可以用!

找一個喜歡的地方把程式碼貼上去後,可以在畫面上看到「Attempting to register with Apple for Push Notifications…」這一行字。所以,就來跟APNS註冊一下app吧!!

不過其實註冊的文章很多人都寫過了,這一篇我覺得還蠻詳細的,可以參考看看,一步一步照做就可以實現Apple Push Notification Services了。

本來我是打算用appcelerator的ACS來push的,只是,我不懂要怎麼在ACS註冊客戶端,所以在push_notification的畫面就一直卡在「You currently have 0 iOS clients, 0 Android clients subscribed to push notifications.」這個訊息@@。好在這一篇連push用的php都幫我們準備好了,看看他的原始碼也不難。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?php
 
// Put your device token here (without spaces):
$deviceToken = 'xxxxxxx........................xxxxxxxxxxxxxx';
 
// Put your private key's passphrase here:
$passphrase = 'passphrase';
 
// Put your alert message here:
$message = 'my message';
 
////////////////////////////////////////////////////////////////////////////////
 
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
 
// Open a connection to the APNS server
$fp = stream_socket_client(
	'ssl://gateway.sandbox.push.apple.com:2195', $err,
	$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
 
if (!$fp)
	exit("Failed to connect: $err $errstr" . PHP_EOL);
 
echo 'Connected to APNS' . PHP_EOL;
 
// Create the payload body
$body['aps'] = array(
	'alert' => $message,
	'sound' => 'default'
	);
 
// Encode the payload as JSON
$payload = json_encode($body);
 
// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;
 
// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));
 
if (!$result)
	echo 'Message not delivered' . PHP_EOL;
else
	echo 'Message successfully delivered' . PHP_EOL;
 
// Close the connection to the server
fclose($fp);

所以如果我們可以在titanium中在用Titanium.Network.createHTTPClient呼叫的話,應該可以多出更多的用法了吧~

44 則迴響於《[titanium] Apple Push Notification Services & Titanium SDK 2.0

  1. 您好,約在3/10後,push notification在android都會收到原本應是中文字,卻變成英文的問號,使用ACS的console去送也是,iOS則是正常,請問有遇到同樣的情形?

  2. 請問我在使用ACS for android時
    留言有個 註冊(新增) ACS User 部分,
    email: ’email’,
    first_name: ‘push’,
    last_name: ‘service’,
    password: ‘password’,
    password_confirmation: ‘password’
    這個部分是要填入什麼資訊呢?
    開發者的應該是填在
    //必須登入ACS
    Ti.Cloud.Users.login({
    login: ‘ login id’,
    password: ‘password ‘,
    },
    謝謝板主

    • Ti.Network.registerForPushNotifications({
              types:[
                      Ti.Network.NOTIFICATION_TYPE_BADGE,
                      Ti.Network.NOTIFICATION_TYPE_ALERT,
                      Ti.Network.NOTIFICATION_TYPE_SOUND
              ],
              success: successCallback,
              error: errorCallback,
              callback: messageCallback
      });
       
      function successCallback(e) {
              alert('Push successCallback');
              alert('LOL:' + e.deviceToken);
              alert('myID:' + myID);
              var deviceToken = e.deviceToken;
      }
       
      // error callBack
      function errorCallback(e) {
              Ti.API.info("Error during registration: " + e.error);
              alert('Push errorCallback' + e.error);
      }
       
      // message callBack
      function messageCallback(e) {
              alert('Push messageCallback');
      }

      試試看吧

      • 謝謝你,
        所以事先用titanium抓到deviceToken後,
        再把這個deviceToken貼到php內的$deviceToken 嗎?

        謝謝

          • 您好
            我使用您提供的程式於titanium發布至手機,
            手機執行後會要求我開通知的設定,當我案下’好’之後,
            手機視窗卻沒有跳出alert顯示deviceToken的訊息,
            請問我有哪個步驟出問題嗎?
            手機Titanium抓deviceToken有要先做什麼其他前置作業嗎?
            感謝你

          • 試試看用一個按鈕

            btn.addEventListener('click', function(e) {
                    CloudPush.retrieveDeviceToken({
                            success: function deviceTokenSuccess(e) {
                                    alert('Device Token: ' + e.deviceToken);
                                    deviceToken = e.deviceToken
                            },
                            error: function deviceTokenError(e) {
                                    alert('Failed to register for push! ' + e.error);
                            }
                    });
            });
          • 您好,我知道原因了
            因為e.deviceToken要轉成string 就會顯示deviceToken了,
            不過請問我在執行php會出現

            Warning: stream_socket_client() [function.stream-socket-client]: unable to connect to ssl://gateway.sandbox.push.apple.com:2195 (Unable to find the socket transport “ssl” – did you forget to enable it when you configured PHP?) in C:\AppServ\www\apns.php on line 18
            request failed

            是不是我們在發訊息時,一定也要有https的網址才可以?謝謝你

            ps:我下 telnet gateway.sandbox.push.apple.com 2195 是有連通的

          • phpinfo openssl我enabled後
            目前一直卡在

            Warning: stream_socket_client() [function.stream-socket-client]: Unable to set local cert chain file `ck.pem’; Check that your cafile/capath settings include details of your certificate and its issuer in C:\AppServ\www\apns.php on line 18

            Warning: stream_socket_client() [function.stream-socket-client]: failed to create an SSL handle in C:\AppServ\www\apns.php on line 18

            Warning: stream_socket_client() [function.stream-socket-client]: Failed to enable crypto in C:\AppServ\www\apns.php on line 18

            Warning: stream_socket_client() [function.stream-socket-client]: unable to connect to ssl://gateway.sandbox.push.apple.com:2195 (Unknown error) in C:\AppServ\www\apns.php on line 18
            request failed

            我試著 重新再照一次(http://www.raywenderlich.com/3443/apple-push-notification-services-tutorial-part-12)
            去產生pem
            結果一直出現這個問題
            pem路徑應該也沒錯 ,因為我也是放在與php相同的資料夾內@~@
            請問你有遇過這個問題嗎
            感謝你

          • 我嘗試把 simplepush.php內

            ck.pem改成

            $apnsCert = dirname(__FILE__) . ‘/’ . ‘ck.pem’;

            所以那一段程式會變成
            $apnsCert = dirname(__FILE__) . ‘/’ . ‘ck.pem’;
            $ctx = stream_context_create();
            stream_context_set_option($ctx, ‘ssl’, ‘local_cert’, $apnsCert );
            stream_context_set_option($ctx, ‘ssl’, ‘passphrase’, $passphrase);

            這樣去run php檔 可以成功的看見
            Connected to APNS Message successfully delivered

            不過尷尬的是 手機沒有收到 notification = =+
            不知這樣該怎抓問題

          • 我換一隻手機嘗試
            iphone 4s sdk ios 5.1.1
            titanium sdk 2.1.3v20120927181611 發佈ios sdk 6 去安裝 是可以順利收到 push notification的
            (這點還滿奇怪的,手機ios 5.1.1 確可以裝titanium發佈ios sdk6的版本程式@@?)

            而原本iphone 3 sdk ios4.2.1
            titanium sdk 1.8.2 發佈ios sdk 4.2 這樣確無法順利收到push notification

            我記得文件有提過push notification是從ios 3.0開始就可以使用的押
            請問您知道原因嗎?
            謝謝

          • 我沒有碰過這樣的情況耶!「titanium sdk 2.1.3v20120927181611 發佈ios sdk 6 」的程式在「iphone 3 sdk ios4.2.1」上可以收到push嗎?

          • 我使用iphone 3無法收到push的 ,不知原因為何?

            請問push notification可以傳中文字到手機嗎,我若在message改為中文字好像就收不到了,是編碼的關係嗎?

            謝謝

          • 我後來發現是 php傳中文字要先轉UTF-8就可以送中文了!
            謝謝板主的回應讓我能順利是出來~感謝你~
            接下來要嘗試Android的了

  3. Hi:
    想請問一下android的前置
    因為我是用titanium寫的
    所以太了解Application Package,這個是自己取還是填入已寫好程式的名子
    AndroidManifest.xml,這個檔案是要自己創建在titanium的android的資料夾裡面嗎?

    謝謝

      • 如果不是要特別客製化的話,titanium應該是不用自己創建AndroidManifest.xml阿!
        至於Application Packagem,應該也是用java開發時需要填寫的項目。在titanium中,不是填寫application Id就好嗎?

        我都是用domain加上app name,類似「tw.idv.justfly.testapp」這樣。

  4. iPhone 部份只有一個部份不同:
    //retrieveDeviceTokenApple 實做 – 跟APNS 取得Token
    Ti.Network.registerForPushNotifications({
    types:[Ti.Network.NOTIFICATION_TYPE_ALERT, Ti.Network.NOTIFICATION_TYPE_BADGE, Ti.Network.NOTIFICATION_TYPE_NEWSSTAND, Ti.Network.NOTIFICATION_TYPE_SOUND],
    success: function(e) {
    deviceToken = e.deviceToken;
    },
    error: function(e) {
    alert(e.error);
    },
    callback: function(e) {
    Ti.API.info(JSON.stringify(e.data));
    }
    });

    其他前置請參考這兩處吧
    https://cloud.appcelerator.com/docs/android#push
    https://cloud.appcelerator.com/docs/ios#push

  5. Client Device Sucribe 簡易流程:
    Android:
    Ti.CloudPush.enable = true //讓裝置可以接收push
    Ti.CloudPush.enabled = true;
    Ti.CloudPush.showTrayNotification = true;
    Ti.CloudPush.showTrayNotificationsWhenFocused = true;
    Ti.CloudPush.showAppOnTrayClick = true;
    //取得裝置token
    Ti.CloudPush.retrieveDeviceToken({
    error:function(e){
    alert(e.error);
    },
    success:function(e){
    deviceToken = e.deviceToken;
    subscribe(); //請看訂閱實做
    }
    });

    //必須登入ACS
    Ti.Cloud.Users.login({
    login: ‘username_or_email’,
    password: ‘yourpassword’,
    }, function(e) {
    if (e.success) {
    if(osname == ‘android’)
    retrieveDeviceTokenAndroid(); //上面為Android實做
    else
    retrieveDeviceTokenApple(); //另一篇為Apple實做
    } else {
    signup(); //請看註冊實做
    }
    });

    //註冊(新增) ACS User
    Ti.Cloud.Users.create({
    email: ’email’,
    first_name: ‘push’,
    last_name: ‘service’,
    password: ‘password’,
    password_confirmation: ‘password’
    }, function(e) {
    if(!e.success) {
    alert(‘Error:\\n’ +
    ((e.error && e.message) || JSON.stringify(e)));
    } else { //同上新增後自動為登入狀態
    if(osname == ‘android’)
    retrieveDeviceTokenAndroid();
    else
    retrieveDeviceTokenApple();
    }
    });

    //訂閱
    Ti.Cloud.PushNotifications.subscribe({
    channel: ‘friend_request’,
    device_token: deviceToken,
    type: Ti.Platform.osname
    }, function (e) {
    if (e.success) {
    Ti.API.info(‘Success’);
    } else {
    alert(‘Error:\\n’ +
    ((e.error && e.message) || JSON.stringify(e)));
    }
    });

    ==================================
    以上完成後你會發現 device 數量增加

回應已關閉。