FJCT_ニフクラ mobile backend(mBaaS)お役立ちブログ

スマホアプリ開発にニフクラ mobile backend(mBaaS)。アプリ開発に役立つ情報をおとどけ!

React Native SDKを使ってiOSへプッシュ通知を送信する

f:id:mbaasdevrel:20210224180710p:plain

React NativeはiOS/Androidはもちろん、Web向けにもアプリが開発できるフレームワークです。そんなReact Native向けに、公式サポートはないもののReact Native SDKを開発しています。

今回はそのReact Native SDKを使ってiOS向けにプッシュ通知を送信するまでの方法を紹介します。

下準備

まずiOS向けの証明書を取得しなければなりません。この手順はチュートリアル (iOS) : mBaaSとAPNsの連携に必要な設定 | ニフクラ mobile backendに書いてある内容を実施し、最終的にアプリIDとプッシュ通知用の証明書ファイル(p12ファイル)を取得します。

React Nativeアプリでの準備

React Nativeでは以下の3つのライブラリが必要です。

それぞれインストールします。

npm install @react-native-community/push-notification-ios ncmb-react-native react-native-push-notification

Xcodeでの処理

次に ios フォルダ以下にあるXcodeプロジェクトファイルを開き、次の準備をします。

Signing & Capabilitiesの処理

Background Mode と Push Notificationsを追加します。また、Background ModeではRemote Notificationsも追加します。

f:id:mbaasdevrel:20210224180824p:plain

AppDelegate.hの更新

冒頭に下記を追記します。

#import <UserNotifications/UNUserNotificationCenter.h>

さらにAppDelegateのインタフェースを次のように変更します。

@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate, UNUserNotificationCenterDelegate>

AppDelegate.mの更新

冒頭に下記を追記します。

#import <UserNotifications/UserNotifications.h>
#import <RNCPushNotificationIOS.h>

さらに処理を追加します。

// デバイストークンを取得した際のイベント
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
 [RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}

// Required for the notification event. You must call the completion handler after handling the remote notification.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
  [RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}

// 登録エラー時のイベント
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
 [RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error];
}

// ローカル通知のイベント
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
         withCompletionHandler:(void (^)(void))completionHandler
{
  [RNCPushNotificationIOS didReceiveNotificationResponse:response];
}

-(void)userNotificationCenter:(UNUserNotificationCenter *)center
      willPresentNotification:(UNNotification *)notification
        withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
  // Still call the JS onNotification handler so it can display the new message right away
  NSDictionary *userInfo = notification.request.content.userInfo;
  [RNCPushNotificationIOS didReceiveRemoteNotification:userInfo
                                fetchCompletionHandler:^void (UIBackgroundFetchResult result){}];

  // allow showing foreground notifications
  completionHandler(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge);
  // or if you wish to hide all notification while in foreground replace it with 
  // completionHandler(UNNotificationPresentationOptionNone);
}

didFinishLaunchingWithOptions には UNUserNotificationCenter を追加します。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  // これを追加
  UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
  center.delegate = self;

  return YES;
}

JavaScriptのコード

ではいよいよJavaScriptのコードについてです。まず必要なライブラリをインポートします。

import PushNotificationIOS from '@react-native-community/push-notification-ios';
import PushNotification from "react-native-push-notification";
import NCMB, { NCMBInstallation } from 'ncmb-react-native';

処理内の適当なところでNCMBを初期化します。

new NCMB('YOUR_APPLICATION_KEY', 'YOUR_CLIENT_KEY');

そしてプッシュ通知周りの処理を書きます。デバイストークンが取得できたら、NCMBへの登録は簡単です(下記 onRegister イベントです)。

PushNotification.configure({
  // デバイストークンを取得した際の処理
  // NCMBへ登録します
  onRegister: async function (token) {
    if (!token) return;
    const installation = new NCMBInstallation();
    await installation
      .set('deviceToken', token.token)
      .set('deviceType', token.os)
      .save();
  },

  // プッシュ通知を受け取った時の処理
  onNotification: function (notification) {
    console.log("NOTIFICATION:", notification);
    notification.finish(PushNotificationIOS.FetchResult.NoData);
  },

  // デバイストークン取得エラー
  onRegistrationError: function(err) {
    console.error(err.message, err);
  },

  // iOSのみ(オプションです)
  // 利用するプッシュ通知について
  permissions: {
    alert: true,
    badge: true,
    sound: true,
  },

  popInitialNotification: true,
  requestPermissions: true,
});

プッシュ通知の受信

ではNCMBの管理画面でプッシュ通知を送信し、それを受け取った際の内容を紹介します。

f:id:mbaasdevrel:20210224180756p:plain

f:id:mbaasdevrel:20210224180710p:plain

ユーザが設定するJSONデータは data キーに対して設定されています。

{
  id: undefined,
  foreground: false,
  userInteraction: false,
  message: 'これはReact Nativeに対して配信しています。',
  data: {
    remote: true,
    notificationId: '11F9F1E8-06CA-45CB-89FF-E02D83B3A122',
    'com.nifcloud.mbaas.PushId': '6nPt5y2VydW6z6mR',
    a: 'b'
  },
  badge: undefined,
  title: 'テストのプッシュ通知',
  soundName: 'default',
  action: undefined,
  reply_text: undefined,
  finish: Function
}

foregroundか否かも取れるので、それによって処理を変えるのも簡単です。また、データ内を見て、表示する画面を変えたりするのも簡単に実装できるでしょう。

まとめ

React Native SDK本体ではデバイストークンの取得やプッシュ通知の受信処理は提供していません。ぜひこの内容を元にして、アプリの中にプッシュ通知機能を組み込んでください。

中津川 篤司

中津川 篤司

NCMBエヴァンジェリスト。プログラマ、エンジニアとしていくつかの企業で働き、28歳のときに独立。 2004年、まだ情報が少なかったオープンソースソフトの技術ブログ「MOONGIFT」を開設し、毎日情報を発信している。2013年に法人化、ビジネスとエンジニアを結ぶDXエージェンシー「DevRel」活動をスタート。