スマートフォンを使っていると当たり前の機能のうちに「プッシュ通知」があります。
たとえば、iPhoneやiPadでGmailアプリなどのメールアプリを使っていると、メールを受け取るとユーザーに向けて「メールを受信しました」とプッシュ通知されます。
プッシュ通知を送るための仕組みは、iOS(Apple)、Windows(Microsoft)、Android(Google)とプラットフォームごとに用意されています。当然、実装に必要のための手順がバラバラにも拘わらず、モバイルアプリは複数のプラットフォームでリリースするのも当たり前になっています。プッシュ通知を送るための実装が異なることで工数が増大して苦しんでいた方も多いと思います。
各プラットフォームでのプッシュ通知の実装をラッピングして、簡単にプッシュ通知とデバイスの管理ができるようにするサードパーティ製のサービスには「Parse」や「Amaozon SNS」というものがあります。それらのひとつに「Azure Mobile Service(モバイルサービス)」があります。*1
事前準備
Apple Push Notification Service(APNs)でプッシュ通知を送る場合の処理については、Appleからプログラミングガイドが出ていますのでこのドキュメントを読みます。
用語は異なりますが基本的には「Windows PhoneでAzure Mobile ServiceとNotification Hubを利用して2ステップでプッシュ通知機能を実装する #wpdev_jp - 酢ろぐ!」で説明しているイメージ図と同じです。APNsへプッシュ通知を送信するのにあたり、通知ハブの機能を利用するには「Azure Notification Hubs を使用して iOS アプリにプッシュ通知を送信する | Microsoft Docs」を参考にしてください。
プッシュ通知を受け取るための準備
アプリ側の実装
アプリ側では以下のように実装します。iOS 7.1以前とiOS 8以降で実装が異なります。
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // ... // プッシュ通知を受けるためにデバイストークンの要求 if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) { // iOS 8 以降 UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNotificationTypeAlert; UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil]; [application registerUserNotificationSettings:settings]; } else { // iOS 7.1 以前 UIRemoteNotificationType types = UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge; [application registerForRemoteNotificationTypes:types]; } return YES; } - (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings { [application registerForRemoteNotifications]; } - (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken { // サーバーにデバイストークンを設定する処理を実装する NSString* serviceUrl = @"https://{service_name}.azure-mobile.net/"; NSString* appKey = @"{your application key}"; MSClient* client = [MSClient clientWithApplicationURLString:serviceUrl applicationKey:appKey]; // 通知ハブを使う場合は以下のように実装する [self.client.push registerNativeWithDeviceToken:deviceToken tags:nil completion:nil]; }
iOSデバイスに向けてプッシュ通知する
バッチ処理等でiOSデバイスに向けてプッシュ通知を送る場合の処理です。
// 接続文字列 var connnectionString = "Endpoint=sb://example-ns.servicebus.windows.net/;SharedAccessKeyName=DefaultFullSharedAccessSignature;SharedAccessKey=<your key>"; // ハブ名 var hubName = "<your hub name>"; // テスト送信か? // Production(本番)にプッシュ通知を送信する場合は false // Development(開発)にプッシュ通知を送信する場合は true var enableTestSend = false; // 接続文字列からNotificationHubClientオブジェクトを生成する var hubClient = NotificationHubClient.CreateClientFromConnectionString( connnectionString, hubName, false); // 通知を送信!!!! var json = "{\"aps\":{\"alert\":\"hage\"},\"app\":{\"id\":\"kazuakix\"}}"; await client.SendAppleNativeNotificationAsync(json);
アプリで通知を受け取る
アプリでプッシュ通知を受け取った後の処理についてです。userInfoには送信されたプッシュ通知のペイロードがパースされた状態で格納されています。
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { if (application.applicationState == UIApplicationStateInactive) { // アプリプロセスがバックグラウンドで動作している状態 } else if (application.applicationState == UIApplicationStateActive) { // アプリプロセスがフォアグランドで動作している状態 } // pushのペイロードから読み取る NSDictionary *app = [userInfo objectForKey:@"app"]; NSString *userId = [app objectForKey:@"id"]; // 受け取ったよ!!!!!! UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"didReceiveRemoteNotification" message:@"received!" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alertView show]; }
*1:Windowsに関しては当事者