目的

Push通知というとFirebaseなどのPush通知サービスで容易に設定するアプリも多いかと思いますが。
自社のJavaサーバなどで実現したい場合も出てきます。 その場合の対応メモを記載していきます。

ただここまで書いておいてなんですが、
無料のFirebaseを利用しない理由ってなんなんでしょうかね!?

一応、Firebaseは1,000通ずつしか通知出来ないようなので、繰り返す処理を作成する必要はあるようですが。
あとはデータ管理は自社でとかいう宗教上の理由ですかね。

環境

  • Xcode Version 12.1
  • Swift 5
  • Java

参照サイト

ほぼ以下のページの通りですが。
ちょっと分かりにくいのと、通知のタイトルとかの設定とかをこのページでは付加しています。
jchambers/pushy

対応メモ

Push通知には参照サイトに記載した、pushyというpush通知用のJavaライブラリを使います。
PHP版とかもあり、pushyという名前自体有名なようです。

push証明書の設定

まずAppleのpush通知証明書が必要です。
Apple Developerサイトより用意してください。
ここでは説明しません。

そして、サーバ上に設置してください。

push通知証明書にはp12とp8があり、それぞれ以下の設定です。
XXXXXは、開発者チームID(Xcode上でのDEVELOPMENT_TEAMのこと)
YYYYはp8ファイルのパスワードです。

p8ファイル設定
final ApnsClient apnsClient = new ApnsClientBuilder()
    .setApnsServer(ApnsClientBuilder.DEVELOPMENT_APNS_HOST)
    .setSigningKey(ApnsSigningKey.loadFromPkcs8File(new File("p8ファイルのパス"), "XXXXX", "YYYY"))
    .build();

zzzzはp12ファイルのパスワードです。

p12ファイル設定
final ApnsClient apnsClient = new ApnsClientBuilder()
    .setApnsServer(ApnsClientBuilder.DEVELOPMENT_APNS_HOST)
    .setClientCredentials(new File("p12ファイルのパス"), "zzzz")
    .build();

ペイロードとトークンの設定

次に以下の設定で通知の文言やトークンの設定を行います。
aaaaabbbbbはアプリの端末ごとのトークン
com.example.myAppはアプリのBundle Identifier

ペイロードとトークン設定
final ApnsPayloadBuilder payloadBuilder = new SimpleApnsPayloadBuilder();
payloadBuilder.setAlertBody("Example!");//本文
payloadBuilder.setAlertTitle("Title!");//タイトル
payloadBuilder.setSound("default");//サウンド設定

final String payload = payloadBuilder.build();
final String token = TokenUtil.sanitizeTokenString("aaaaabbbbb");

pushNotification = new SimpleApnsPushNotification(token, "com.example.myApp", payload);

push通知

以下でpush通知を行います。

ペイロードとトークン設定
final PushNotificationFuture<SimpleApnsPushNotification, PushNotificationResponse<SimpleApnsPushNotification>> sendNotificationFuture = apnsClient.sendNotification(pushNotification);
try {
    final PushNotificationResponse<SimpleApnsPushNotification> pushNotificationResponse =
            sendNotificationFuture.get();

    if (pushNotificationResponse.isAccepted()) {
        System.out.println("accepted");
    } else {
        System.out.println("rejected: " + pushNotificationResponse.getRejectionReason());

        pushNotificationResponse.getTokenInvalidationTimestamp().ifPresent(timestamp -> {
            System.out.println("\t…invalid " + timestamp);
        });
    }
} catch (final ExecutionException e) {
    System.err.println("Failed");
    e.printStackTrace();
}

以上を設定したクラスを実行すれば、簡単にpush通知行えると思います。
通知されない場合は、サーバ上のエラーログを見てください。
通知ファイルのパスが間違っているとかありました。

Javaだけなのか、、サーバ上でのファイルパス設定ってややこしい感じします。