webネタ

Webエンジニアが業務に関係することをメモしていく

iPhoneプッシュ通知まとめ

2011/11/14 : 追記
moruguさんに指摘頂いてdeviceTokenのPOST処理を追記しました。
連絡手段がなかったのでここにお礼として書いておきます。どもです! m(_ _)m


iPhoneアプリ開発でプッシュ通知を使ったので、まとめ。

仕組み

f:id:R-H:20110923115354j:image

1、APNsにPush通知許可の登録する。
2、APNsからデバイストークンが帰ってくる。
3、そのデバイストークンをサーバー(これは自分で用意します)に送ってDBなりに保存する。
4、サーバーからAPNsにPush通知依頼を出す。
5、APNsは登録済みの指定デバイスにPush通知を出す。
6、受け取ってAlert出すなり色々する。

実装前に準備

Push通知を行うには、iOSDeveloperCenterでPush通知用の証明書をインストールしたりしなければならない。
このフェーズは自分ではやってないので省略orz
参考サイトだけ載せておく。

実装

ここのメソッドは全てプロジェクトのdelegateクラス。

1、APNsにPush通知許可の登録する。

registerForRemoteNotificationTypesを叩くと『プッシュ送信を許可しますか?』のアラートが出て、APNsにリクエストが送られ登録される。

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
    
[[UIApplication sharedApplication] 
     registerForRemoteNotificationTypes:
     (UIRemoteNotificationTypeBadge| 
      UIRemoteNotificationTypeSound|
      UIRemoteNotificationTypeAlert)];
    
return YES;
}
2、APNsからデバイストークンが帰ってくる。

レスポンスが返ってくると、didRegisterForRemoteNotificationsWithDeviceTokenメソッドがコールされる。
引数にデバイストークンがついてくる。

 - (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)devToken{ 
    NSLog(@"Success : Regist device token to APNS. (%@)", devToken);
    [self postDeviceToken:deviceTokenString]; // POST
}

APNSへのデバイス登録失敗時

 - (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)err{ 
    NSLog(@"Error : Fail Regist to APNS. (%@)", err);
}
3、そのデバイストークンをサーバー(これは自分で用意します)に送ってDBなりに保存する。
 - (void)postDeviceToken:(NSString *)deviceToken {
    
    // prepare url.
    NSString* content = [NSString stringWithFormat:@"deviceToken=%@", deviceToken];
    NSURL* url = [NSURL URLWithString:@"http://192.168.1.5:8080/registDeviceServelt"];
    
    // create instance.
    NSMutableURLRequest* urlRequest = [[NSMutableURLRequest alloc]initWithURL:url];
    [urlRequest setHTTPMethod:@"POST"];
    [urlRequest setHTTPBody:[content dataUsingEncoding:NSUTF8StringEncoding]];
    
    // post.
    NSURLResponse* response;
    NSError* error = nil;
    NSData* result = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&error];
    if(error) NSLog(@"error = %@", error);
    
    // get result.
    NSString* resultString = [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];
    NSLog(@"%@", resultString);
    
    // release.
    [resultString release];
    [urlRequest release];
}

サーバー側でdeviceTokenを受け取り、DBに保存します。

4、サーバーからAPNsにPush通知依頼を出す。

PHPでやる場合
php-apnsというライブラリを使う。
使う前に証明書を作ったり、ルート証明書をダウンロードしないといけない。ここにやり方が載ってる。
何も考えずにコマンドを叩く^^;

Javaでやる場合
java-apnsというライブラリを使う。
証明書は、キーチェーンからPush通知用にインストールした証明書をエクスポートして使う。
サンプルコード

ApnsService service =
APNS.newService()
.withCert("/Users/*******.p12", "*****")
 .withSandboxDestination()
 .build();

String payload = APNS.newPayload().alertBody("Can't be simpler than this!").build();
String token = "638d09063fe6a73a6cb4*******************ab084e5ea8b0b390d1480f";
service.push(token, payload);
5、APNsは登録済みの指定デバイスにPush通知を出す。

ここはAPNsが勝手にやります。

6、受け取ってAlert出すなり色々する。
 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
    for (id key in userInfo) {
        NSLog(@"key: %@, value: %@", key, [userInfo objectForKey:key]);
    }
}

まとめ

Push通知の仕組み自体がシンプルな上に、ライブラリも各種言語あるので簡単。
やっぱりappleはスゴイ。