2012年1月20日 星期五

push notification - step by step

所謂萬事起頭難
Push notification更是如此
由於Push notification因為牽扯到iOS app, provider server跟APNS三方溝通
provider server又跟APNS中間溝通要透過SSL
再加上有些東西需要在provisioning portal做設定
所以我覺得對初學者來講第一步真的很困難的

最近在搞這個,我就把我實驗出可以work的方法記錄下來
除了當做自己的備忘以外
也同時提供也有同樣需求的做參考

主要有幾個步驟,測試請一定要在device上做,push notification無法在模擬器上模擬
1. 在xcode新增一個App,並且在AppDelegate加上以下的code
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.mainViewController = [[MainViewController alloc] initWithNibName:@"MainViewController" bundle:nil];
    self.window.rootViewController = self.mainViewController;
    [self.window makeKeyAndVisible];
   
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert];
    return YES;
}


- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    NSLog(@"receive deviceToken: %@", deviceToken);
}

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
    NSLog(@"Remote notification error:%@", [error localizedDescription]);
}


先來執行看看..
當然,不可能這樣就ok。你應該會在Debug訊息中得到這個error
Remote notification error:找不到應用程式的有效“aps-environment”授權字串
不用擔心,那是因為你還有些事情還沒做

2.
到iOS Provisioning Portal,
首先你要先產生一個app id
而這個app id的bundle id要跟你前面產生的app的bundle id一致。
(所謂的bundle id就是類似com.example.APNTest)

3.
產生完app id之後,點進這個app id
我們可以看到這個畫面..
請打開push notification的功能。
因為我們是測試,所以先以development為例。
按下"Development Push SSL Certificate"的Configure按鈕
此時會看到下面的畫面,按照裡面的動作產生Certificate Signing Request


他告訴我們要使用keychain access這個app
並且在選單上找到這個選項

點了之後,輸入你的email跟certification name

產生之後save to disk,並且回到ios provisioning portal
按continue之後會看到這個畫面

指定剛剛的CSR則可以得到這個畫面

之後就把這個Certification抓下來

抓下來記得點兩下安裝,這時候你的Keychain access應該會出現新的Cert.跟Private Key

4.
好了之後,回到iOS provisioning portal
切到Provisioning的Development,按下New Profile
產生一個新的Provision Profile是對應到你的bundle id的
產生完之後,抓下來點兩下,就可以安裝到你的xcode

5.
回到XCode
重新run你的app
應該就會成功的取得device token
receive deviceToken: <c87c312f 1efc...>
如果還是不行,請手動指定你的provision profile到你剛剛產生download下來的那個profile..

6.
上面是已經成功的把device跟app註冊到APNS了
接下來我們要做的是去讓Server上的程式去notify我們的app
因為要用SSL
我們要先產生p12檔才可以建立SSL
回到keychain access
選擇你剛剛的certification按右鍵
選擇export就可以輸出成p12了

7.
由於跟provider server跟APNS溝通的部分跟iOS無關
所以我寫了一個簡單的java程式去測試
細節就不講了
大家可以從這邊抓下來去使用
解開後,把剛剛輸出的.p12檔也放在該目錄之中
打開Console,到這個解開的目錄
並且打下下面的command
java -cp apns-0.1.5.jar:. APNTest "APNTest.p12" "APNTest" "c87c..." "Hello APN"
最後四個參數分別是
(1) 你的.p12的檔名
(2) 你的.p12的密碼
(3) 你的device token。從你上面印出來的token除掉中間空格就是了
(4) 你要送的message。

如果你看到下面的畫面
恭喜你,你踏出push notification的第一步了








8 則留言:

  1. 嘩,有空再看
    我連基本東西都沒開始寫(登入登出傳資料)(汗

    回覆刪除
  2. 受益良多的教學,
    不過我在執行Java程式時
    出現"javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure"這一類的訊息
    請問是我給的參數有問題嗎?

    回覆刪除
  3. 非常有用的教學文~遵照步驟就可成功~
    唯一卡住一下子的地方是:第2點中,產生完新的APP ID後,要重新載入網頁,不然也許憑證丟進去會沒反應。
    另外,provider server跟APNS溝通的部分,就沒有用版主的來測試了~

    回覆刪除
  4. 非常棒,這是個 workable 的範例教學。

    回覆刪除
  5. 從你的blog知道很多東西

    回覆刪除
  6. 請問如何能把取得的devicetoken存入資料庫

    回覆刪除
  7. 感謝教學~步驟很詳盡,
    不過第一步Remote Notification的授權允許,
    因為iOS 8之後的方式有變,所以會出現:
    registerForRemoteNotificationTypes: is not supported in iOS 8.0 and later.
    但已經找到解法了 可以交流交流
    http://derjohng.doitwell.tw/?p=6178

    回覆刪除
  8. 文章中提到的 https://dl.dropboxusercontent.com/u/12450729/APNS/APNTest_java.zip 目前已無法存取, 您能提供給我嗎 ? 謝謝您.

    回覆刪除