AWS SNS を使ってプッシュ通知してみた【Java】
AWSの管理画面からプッシュする記事だったり、SDKを使っていても断片的なコードしかない記事が多かったので、アプリからサーバーサイドまでの一連の流れをまとめたものを作ってみました。
今回の全体アーキテクチャ
・プッシュ通知のための証明書などの設定
各サイトを参考に設定
[AWS] Amazon SNS の新機能「Mobile Push」を iOS で使ってみた | Developers.IO
Apple Push Notification Service の使用開始 - Amazon Simple Notification Service
・SNSから通知される用のアプリの作成
Simple View Application を作成
AppDelegate.m
#import "AppDelegate.h" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSLog(@"Register for push notifications"); UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert) categories:nil]; [[UIApplication sharedApplication] registerUserNotificationSettings:setting]; [[UIApplication sharedApplication] registerForRemoteNotifications]; return YES; } // 「PUSH通知許可」の場合 - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { NSString *token = [NSString stringWithFormat:@"Device Token=%@",deviceToken]; NSLog(@"%@",token); token = [token stringByReplacingOccurrencesOfString:@"<" withString:@""]; token = [token stringByReplacingOccurrencesOfString:@">" withString:@""]; token = [token stringByReplacingOccurrencesOfString:@" " withString:@""]; NSURL *url = [NSURL URLWithString:@"http://xxx"]; // SNSに登録リクエスト NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:3.0]; NSHTTPURLResponse *resp; NSError *error; [NSURLConnection sendSynchronousRequest:req returningResponse:&resp error:&error]; } // 「PUSH通知拒否」の場合 - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)err { NSString *str = [NSString stringWithFormat: @"Error: %@", err]; NSLog(@"%@",str); } // プッシュ通知を受け取ったときの処理 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { NSLog(@"ReceiveRemoteNotification: %@", userInfo); } @end
・トークンを登録するプログラム
JavaとSpring MVCを使ってトークンを登録する受け口を作成
細かい設定ファイルなどプロジェクト全体はこちらに。
/** * Register the token requested from the device to publish later on. * * @author keichanzahorumon * */ @Controller public class RegisterController { private static final Logger logger = LoggerFactory.getLogger(RegisterController.class); @Autowired private String topicArn; @Autowired private String appArn; /** * Register the token to the SNS. * * @param locale * @param model * @param token */ @RequestMapping(value = "/register", method = RequestMethod.GET) public void register(Locale locale, Model model, @RequestParam("token") String token) { if (token == null || token.length() != 64) { logger.warn("token must be 64bit. token=" + token); } AmazonSNSClient snsClient = new AmazonSNSClient(new ClasspathPropertiesFileCredentialsProvider()); snsClient.setRegion(Region.getRegion(Regions.AP_NORTHEAST_1)); // Create endpoint from the requested token CreatePlatformEndpointRequest cpeReq = new CreatePlatformEndpointRequest(); cpeReq.setPlatformApplicationArn(appArn); cpeReq.setToken(token); CreatePlatformEndpointResult result = snsClient.createPlatformEndpoint(cpeReq); logger.info("Succeeded at creating Endpointarn.EndpointArn=" + result.getEndpointArn()); // Subscribe to Topic SubscribeRequest subscribeRequest = new SubscribeRequest(); subscribeRequest.setTopicArn(topicArn); subscribeRequest.setProtocol("application"); subscribeRequest.setEndpoint(result.getEndpointArn()); SubscribeResult subscribeResult = snsClient.subscribe(subscribeRequest); logger.info("Succeeded at subscribing to a Topic.SubscriptionArn=" + subscribeResult.getSubscriptionArn()); } }
流れ
1.事前にAWS管理画面で作成したApplicationに通知された端末を識別するトークンを登録
2.登録すると EndpointArn が返却される
3.事前にAWS管理画面で作成したTopicのarn(TopicArn)と上記EndpointArnをもとにTopicに端末情報を登録
・プッシュ通知をするプログラム
/** * Publish the requested message * * @author keichanzahorumon * */ @Controller public class PublishController { private static final Logger logger = LoggerFactory.getLogger(PublishController.class); @Autowired private String topicArn; /** * Publish the requested message * * @param locale * @param model * @param message */ @RequestMapping(value = "/publish", method = RequestMethod.GET) public void publish(Locale locale, Model model, @RequestParam("message") String message) { AmazonSNSClient snsClient = new AmazonSNSClient(new ClasspathPropertiesFileCredentialsProvider()); snsClient.setRegion(Region.getRegion(Regions.AP_NORTHEAST_1)); // Publish a message PublishRequest publishRequest = new PublishRequest(topicArn, message); snsClient.publish(publishRequest); logger.info("Published a message.Message=" + message); } }
流れ
1.事前にAWS管理画面で作成したTopicにプッシュしたいメッセージを設定、通知
結果、今までTopicに登録した端末達にメッセージがプッシュされる。