
この記事は GRIPHONE Advent Calendar 2020 9日目の記事です
こんにちは。Unityエンジニアの萩原です
今回はみんな実装しているはずのプッシュ通知周りの情報をまとめました
やりたいこと
iOSはプッシュ通知がオプトイン(許諾が必要)なので、なかなか許諾してくれませんね
でも、許諾しなかった人にもう一回設定してもらいたい!
ということで、やりたいことは以下のフローチャートです

やらなくちゃいけないことは
- ユーザのプッシュ通知の許諾設定を取得する
 - プッシュ通知設定画面に飛ばす
 
の2つです。
これをUnityでやるときに、どうすればいいんだろう
ユーザのプッシュ通知の許諾設定を取得する
iOSはUnityが用意してくれてるので簡単です
UnityEngine.iOS.NotificationServices.enabledNotificationTypes != UnityEngine.iOS.NotificationType.None;
簡単すぎたのでAndroidも用意してみましょう
Androidのネイティブプラグインを使う時はaarの記事が多いですが、面倒なのでここではJARプラグインを使いましょう
(https://docs.unity3d.com/ja/2018.4/Manual/PluginsForAndroid.html)
NotificationStatusChecker.java (プラグインフォルダに入れない)
package パッケージネームを入れる.notification;
import com.unity3d.player.UnityPlayer;
import android.content.Context;
import androidx.core.app.NotificationManagerCompat;
/* NotificationStatusChecker
    Androidのプッシュ通知許諾設定を取得するクラス
*/ 
public class NotificationStatusChecker{
 
    private Context context;
 
    public NotificationStatusChecker() {
 
        this.context = UnityPlayer.currentActivity;
    }
 
    public boolean areNotificationsEnabled() {
        boolean result = NotificationManagerCompat.from(this.context).areNotificationsEnabled();
        return result;
    }
}
使う側(Unity)の実装はこちら
iOSでも使えるようにしました
NotificationStatus.cs
/* NotificationStatus
	プッシュ通知の許諾状態の取得クラス
  NotificationStatus.Enabledで取得できる
*/
public static class NotificationStatus
{
    public static bool Enabled
    {
        get
        {
#if UNITY_IOS
            return UnityEngine.iOS.NotificationServices.enabledNotificationTypes != UnityEngine.iOS.NotificationType.None;
#elif UNITY_ANDROID
            const string notificationStatusClass = " パッケージネームを入れる.notification.NotificationStatusChecker";
            var notificationStatusChecker = new AndroidJavaObject(notificationStatusClass);
            var areNotificationsEnabled = notificationStatusChecker.Call<bool>("areNotificationsEnabled");
            return areNotificationsEnabled;
#endif
            return false;
        }
}
iOSのプッシュ通知設定画面に飛ばす
Androidはオプトアウトなので、iOSだけ紹介します
URLスキームを使うとリジェクトされるので、用意されたメソッドを叩いてあげましょう
OpenSettings.mm (プラグインフォルダに入れる)
@implementation OpenSettings
 
extern "C" {
    void Open();
}
 
void Open()
{
     NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
     [[UIApplication sharedApplication] openURL:url];
}
 
@end
使う側(Unity)の実装はこちら
OpenSettings.cs
using System.Runtime.InteropServices;
/* OpenSettings
	iOSのアプリ設定画面へ飛ばすクラス
*/
public class OpenSettings
{
#if !UNITY_EDITOR && UNITY_IOS
    [DllImport("__Internal")]
    public static extern void Open();
#else
    public static void Open()
    {
    }
#endif
  }
終わりに
ここらへんは実装方針が無限にあるので、あくまで一例ということでご容赦ください
実装担当者になった時はこの記事を思い出して参考にしてもらえたら幸いです
レッツプッシュ通知ライフ:D
