2014年3月12日 星期三

iOS 開發筆記 - 使用 Apple Push Notification service (APNs)

Apple 官方詳細的文件:Local Notifications and Push Notifications,漂亮的流程圖:

Service-to-Device Connection Trust:



Provider-to-Service Connection Trust:


Token Generation and Dispersal:

Token Trust (Notification):


心得:
  • 透過 Apple Push Notification service (APNs) 時,可以有提醒使用者來使用 app 的效果,無論使用者是否正在使用、背景使用、關閉使用都可以,就只要不要刪掉 app 都可以
  • APNs 只是讓 Service Provider 透過 Gateway 主動丟訊息給使用者,也不保證丟的到,除了訊息也可以設定 expiry date 外,也可以從 Feedback service 來取得傳送失敗的資訊
  • APNs 是單向傳訊息,所以,其實就像打聲招呼而已,等使用者使用 app 時,需額外處理連回自家 server 的部分,才能完成互動
Service Provider 進行 Push Notification 流程:
  1. 在 iOS Developer Center 對指定的 APP ID 設定好 Push Notifications 的憑證等
  2. 在 OSX 上,將憑證輸出成 P12 檔
  3. 透過 openssl 將 *.P12 檔轉成 PEM 格式
    $ openssl pkcs12 -in 憑證.p12 -out CertificateName.pem -nodes
    Enter Import Password:
    MAC verified OK
  4. Server 使用 PEM 檔案與 Apple server 進行 SSL/TLS 溝通
  5. 資料格式需依照 The Binary Interface and Notification Format 編碼,簡易程式:github.com/changyy/ios-apple-push-notification-service/php/send.php
iOS app 設定:
  1. 在程式啟動處,進行 APNs 註冊流程
  2. 判斷是否註冊成功,成功後要將 deviceToken 傳給 Service Provider
    - (NSString *)getHEX:(NSData *)data
    {
        const unsigned char *dataBytes = [data bytes];
        NSMutableString *ret = [NSMutableString stringWithCapacity:[data length] * 2];
        for (int i=0; i<[data length]; ++i)
            [ret appendFormat:@"%02X", (NSUInteger)dataBytes[i]];
        return ret;
    }
    - (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {
        NSLog(@"didRegisterForRemoteNotificationsWithDeviceToken: %@", [self getHEX:devToken]);
    }

    - (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
        NSLog(@"didFailToRegisterForRemoteNotificationsWithError: %@", err);
    }
  3. 若程式在使用中,可以監控是否有通知
    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
        NSLog(@"didReceiveRemoteNotification: %@",userInfo);
        if (application.applicationState == UIApplicationStateActive)
        {
            // use UIAlertView
        }
        else
        {
            //application.applicationIconBadgeNumber =[[[userInfo objectForKey:@"aps"] objectForKey: @"badge"] integerValue];
            //NSInteger badgeNumber = [application applicationIconBadgeNumber];
            //[application setApplicationIconBadgeNumber:++badgeNumber];
        }
    }

沒有留言:

張貼留言