iOSアプリにPush通知機能を実装するためには、まずApple Developer Centerで開発対象のアプリ用にPUSH通知(APNs)用の証明書を作成し、アプリに登録する必要があります。
また、PUSHを通知する側についても、自作のアプリやmBaaSに登録する作成した証明書を設定して、ようやく開発が始められるようになります。
慣れれば、簡単なのですが、久しぶりにアプリの開発をしたところ結構忘れていたので、手順をまとめておくことにしました。
この記事では、iOS 8.4、Xcodeは6.4で確認しています
また、手順は開発環境でAPNsによるPUSH通知の動作を確認することに絞って記述しています。
Push通知をアプリに実装するために用意するもの
まずは、Push通知を実装する前提条件として準備するものを整理しておきます
iOSアプリのビルドに必要なもの
- Push通知を有効にしたApp IDが指定されたプロビジョニングプロファイル
APNsへのPUSH通知送信に必要なもの
- Push通知用の証明書
App IDの作成
Apple Developer Centerにログインして以下の手順を実行します
開発用アプリケーションのApp IDを作成します
- [iOS App IDs]を開き、右上の[+](新規作成)をクリック
- [Registering an App ID]の画面は以下のように入力します
- [App ID Description] > [Name]にアプリの名前を入力
- [App ID Suffix]では[Explicit App ID]を選択して[Bundle ID]に
com.example
のようにドメインを逆にしたユニークな値を入力 - [App Services]で[Push Notifications]にチェックを入れます
- [Continue]をクリック
- [Confirm your App ID.]の画面で、[Push Notifications]が[Configurable]になっていることを確認して[Submit]をクリック
- [Registration complete.]の画面で[Done]をクリック
すでにApp IDを作成済みだった場合は、対象のApp IDを選択して[Edit]をクリック、[Push Notifications]にチェックを入れて[Done]をクリックして保存します
Apple Push Notification service (APNS)用証明書の作成
Apple Developer Centerで以下の手順を実行します
- [iOS Certificates]を開き、右上の[+](新規作成)をクリック
- [Development] の [Apple Push Notification service SSL (Sandbox)] を選択し[Continue]をクリック
- [App ID]で開発対象のを選択して[Continue]をクリック
- [About Creating a Certificate Signing Request (CSR)]の画面には、証明書要求 CSR ファイルの作成手順が書かれています。以下の手順でCSRファイルを作成します
- キーチェーンアクセスを開き、メニュー[キーチェーンアクセス] > [証明書アシスタント] > [認証局に証明書を要求]を選択します
- [ユーザーのメールアドレス]にメールアドレスを、[通称(Common Name)]には、秘密キー用のわかりやすい名前(例えば、遠藤の開発キーとか)を入力、[CAのメールアドレス]は空のまま、[要求の処理]で[ディスクに保存]を選択して[続ける]をクリックします
- ファイル名と保存先を指定してCSRファイルを保存します
- [完了]をクリックしてウィザードを閉じます
- [Upload CSR file.]で作成したCSRファイルを選択して、[Generate]をクリックします
- [Download]をクリックして証明書をダウンロードし、ダウンロードした証明書
aps_development.cer
をダブルクリックするとキーチェーンアクセスに登録されます(これをしておかないと、プロビジョニングプロファイルを追加してもXCodeで選択できませn) - [Done]をクリックして閉じます
キーチェーンアクセスの[証明書]を開くと、以下のように追加された証明書と秘密キーを確認できます
プロビジョニングプロファイルの作成
Apple Developer Centerで行う最後の手順はプロビジョニングプロファイルの作成です
- [iOS Provisioning Profiles]を開き、右上の[+](新規作成)をクリック
- [Development]の[iOS App Development]を選択して[Continue]をクリック
- [Select App ID]画面では、作成してPush通知を有効にしたApp IDを選択して[Continue]をクリック
- [Select certificates.]画面では、開発用の証明書”iOS Development”のものを選択します( ※1 )。[Continue]をクリック
- [Select devices.]画面では、ビルドしたアプリケーションをインストールする開発用の実機を選択します。[Continue]をクリック
- [Name this profile and generate.]画面では、[Profile Name]に適当な名前を入力して[Continue]をクリック
- [Your provisioning profile is ready.]の画面で[Download]をクリックすると「<プロファイル名>.mobileprovision」という名前のファイルがダウンロードされます。ダウンロードされたファイルをダブルクリックするとプロビジョニングプロファイルがXCodeにインストールされます( ※2 )
- [Done]をクリックして閉じます
※1 プロビジョニングプロファイルに設定する証明書はPush通知用のものと別なので注意です
iOS – Cannot use APNS certificate to create new provisioning profile
※2 プロファイル名が「Hello Push」のようにスペースを含む場合、プロビジョニングプロファイルのファイル名はスペースはアンダーバーに置き換えられた名前「Hello_Push.mobileprovision」になります
インストールされたプロビジョニングプロファイルは、XCodeの[Preferences..]を開き[Accounts]タブでアカウントを選択して、[View Details]を開いて確認できます
Push通知をプロジェクトで有効化する
以下は、XCodeで開いたプロジェクトへ実施する手順になります
プロビジョニングプロファイルをプロジェクトをセット
[PROJECT] > [<プロジェクト名>] > [Build Settings]を開き、[Code Signing] > [Code Signing Identity]に、作成したプロビジョニングプロファイルを設定します
Code Sign error: No matching provisioning profiles found: No provisioning profiles matching the bundle identifier “XXXXXXXXXXXXXXXXXXXX” were found.
アカウントまわりをセットしたら解消
CapabilitiesでRemote notificationsを有効化
[TARGET] > [<プロジェクト名>] > [Capabilities]を開きます
[Background Modes]を[ON]にし、[Remote notifications]にチェックを入れます
以上で、アプリケーションに実装する準備が整いました。
アプリケーションの実装
アプリ起動時、AppDelegateのdidFinishLaunchingWithOptionsに、Push通知の許可をユーザーに要求するポップアップの表示とリモートPush通知を受診するためのdeviseTokenの取得を実装します
// AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// Push通知の許可画面を表示させる
UIUserNotificationType types = UIUserNotificationTypeBadge |
UIUserNotificationTypeSound |
UIUserNotificationTypeAlert;
UIUserNotificationSettings *mySettings =
[UIUserNotificationSettings settingsForTypes:types categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];
//リモートPush通知を受信するためのdeviceTokenを要求
[[UIApplication sharedApplication] registerForRemoteNotifications];
return YES;
}
DeviceTokenが発行されると、コールバック関数didRegisterForRemoteNotificationsWithDeviceTokenが呼ばれます
// AppDelegate.m
// DeviceToken受信成功
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSString *token = deviceToken.description;
// <aaaa bbbb cccc dddd>みたいな形式でくるので、"<"、">"、"(空白)"を除去しておく
token = [token stringByReplacingOccurrencesOfString:@"<" withString:@"];
token = [token stringByReplacingOccurrencesOfString:@">" withString:@"];
token = [token stringByReplacingOccurrencesOfString:@" " withString:@"];
NSLog(@"deviceToken: %@", token);
// ここでPushプロバイダーへのdeviceTokenを送信する
}
// DeviceToken受信失敗
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSLog(@"deviceToken error: %@", [error description]);
}
ビルドして実機に動かすと、APNsにデバイスが登録され返されたdeviceTokenがログに出力されます
このdeviceTokenは、次のPush通知プロバイダの実装と確認で使用するのでメモしておきます
実際には、サーバー側アプリが自作の場合は、取得したトークンを送信する処理を実装します。
また、Push通知プロバイダにmBaaSを利用する場合、多くはトークンを渡すと良きに計らってくれるクライアントライブラリが用意されています。
Push通知プロバイダー側のアプリ実装
(以下、2021/6/10に書き換えています)
PHPの簡単なスクリプトで通知の動作を確認してみます。
プロバイダー用証明書ファイルの準備
キーチェーンアクセスを開き、以下の手順で証明書をエクスポートします
- [証明書]を選択して追加したPush通知用の証明書でメニューを開き、[“<証明書名>“を書き出す]を選択します
- [名前]に適当なファイル名(例 aps_development)を入力して、[場所]はファイル書き出すディレクトリを選択、[フォーマット]は[個人情報交換鍵(.p12)]を選択して[保存]をクリックします
- [書き出した項目を保護するために使用されるパスワードを入力:]ではパスワードは空のまま[OK]をクリックします
- キーチェーンアクセスのパスワード(通常はMacにログインしているユーザーのパスワード)を要求されるのでパスワードを入力して[許可]をクリックするとファイルが書きだされます
ファイルを書き出したディレクトリに移動して、以下のコマンドを実行してpem形式のファイルに変換します
$ openssl pkcs12 -in aps_development.p12 -out aps_development.pem -nodes
Enter Import Password:
MAC verified OK
Push通知の実行
PHPのスクリプトは以下のリポジトリで公開しています。
Github: https://github.com/hrendoh/php-apple-apn-push
APNsへの通知の送信はComposerのパッケージ「apple/apn-push」を利用してみました。
$ composer require apple/apn-push
以下のようにプログラムを実装します
<?php
require_once "vendor/autoload.php";
use Apple\ApnPush\Certificate\Certificate;
use Apple\ApnPush\Protocol\Http\Authenticator\CertificateAuthenticator;
use Apple\ApnPush\Sender\Builder\Http20Builder;
use Apple\ApnPush\Model\Alert;
use Apple\ApnPush\Model\Aps;
use Apple\ApnPush\Model\Payload;
use Apple\ApnPush\Model\Notification;
use Apple\ApnPush\Model\DeviceToken;
use Apple\ApnPush\Model\Receiver;
use Apple\ApnPush\Exception\SendNotification\SendNotificationException;
// p12を変換したpem形式のファイルパス
$cert_pem_filepath = 'aps_development.pem';
// Bundle Id
$bundle_id = 'com.example.com';
// Device Token
$device_token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
// Create certificate and authenticator
$certificate = new Certificate($cert_pem_filepath, '');
$authenticator = new CertificateAuthenticator($certificate);
// HTTP/2プロトコルを使用するsenderを生成
$builder = new Http20Builder($authenticator);
$sender = $builder->build();
// デバイストークンを指定し、Receiverを生成
$receiver = new Receiver(new DeviceToken($device_token), $bundle_id);
// 通知を生成
$notification = Notification::createWithBody('Hello ;)');
$alert = (new Alert())
->withBody('Hello ;)')
->withTitle('Hi ;)');
$aps = (new Aps($alert))
->withBadge(2)
->withSound('pong.acc')
->withThreadId('my.app.thread')
->withContentAvailable(true);
$payload = (new Payload($aps));
$notification = (new Notification($payload));
try {
// 通知を送信、Sandboxの場合は第3引数にtrueを渡す
$sender->send($receiver, $notification, true);
} catch (SendNotificationException $e) {
var_dump($e);
}
プログラムを実行
$ php main.php
通知が正常に受信できると、以下のように通知が表示されます