【実践FuelPHP】作成アプリからiPhoneへpush通知をする

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

ウェブアプリで更新した内容を、プッシュ通知でAndroidアプリやiOSアプリへプッシュ通知したくなることは多々あるはず。
弊社では、AWSを推奨している関係上、AmazonSNSを使うのが一般的になっています。
が、私が趣味で作成しているアプリはさくらのVPS上に設置されているので、できればこれ単独での通知を行いたい。
というわけで、今回はあえてAmazonSNSを使わずにプッシュ通知を行います。
まずはiOSからのプッシュを行えるようにしましょう。

なお、Androidへの通知とAmazonSNSを利用したプッシュ通知はまた別の機会にまとめます。

有志が作成したパッケージを使用

 今回は、有志が作成したパッケージ、その名も「FuelPHP-Pushnotifications」を使います。
そのまんまの名前ですね。このパッケージをインストールします。
インストールするとは言ったものの、パッケージなのでsubmodules管理しましょう。

git submodule add git://github.com/Benni-chan/FuelPHP-Pushnotifications fuel/packages/pushnotifications
git add .
git commit -m "submodules pushnotifications package add"

今パッケージで、Android側へのプッシュ通知も管理できます。
が、今回はあくまでiOSのみで考えます。が、Androidはここから枝分かれするだけです。

必要ファイル群をgithubから取得したら、次は設定ファイルをコピーします。
/fuel/packages/pushnotifications/config/pushnotification.php ファイルを、/fuel/app/config/pushnotification.php にコピーします。
次に、設定ファイル内のAPNS情報を書き換えます。
今回は試験としてsandboxでのDeveloper/sandboxでの動作を確認します。
なお、この時点で、通知を受け取るアプリ用のAPNS設定ファイルが必要となりますので、「Apple Push Notification Serviceを使ってiOSにプッシュ通知をするために必要な証明書の準備方法」や、弊社Blog記事を参考にpemファイルを取得してください。

私は、とりあえずconfigの直下にfileというフォルダを作成し、その中にblogtest.pemという名前で作成しました。
設定ファイルの該当箇所を書き換えます。

'sandbox' = array(
    'certificate' = APPPATH.'/config/file/blogtest.pem',
    'certificate_passphrase' = 'blogtest',
    'push_gateway' = 'ssl://gateway.sandbox.push.apple.com:2195',
    'feedback_gateway' = 'ssl://feedback.sandbox.push.apple.com:2196',
),

次に、このパッケージを常にロードするように設定します。
別に必要なときにロードする方法もあるのですが、今回は手っ取り早くです。

/fuel/app/config/config.php のファイルの下記箇所のコメントを外します。

// 'always_load'  = array(
'always_load'  = array(

    // 'packages'  = array(
    'packages'  = array(
    // //'orm',
        'pushnotifications',
    // ),
    ),

    'config'           = array(
        'pushnotification',
    ),
    
// ),
),

iOSでプッシュ通知のレシーブアプリを作成する

iOS側でプッシュ通知を受け取るアプリを作成します。
とはいっても、あくまでサンプルアプリのため、起動した時にプッシュ時に使用するtokenを取得して、そのアプリでプッシュ通知を待つという至極簡単なアプリです。

ただ、ここは本題ではないため、横着をさせてください。
弊社のブログで、AWSのSNSからプッシュ通知を受け取る記事にある、このアプリをまるぱ・・・流用します。

このTokenが取得できるところまでとりあえず参考にアプリを作ってください。
このTokenを使用します。

サーバサイドでプッシュするプログラムを作成する

今回は、あくまでプッシュされることが目的であり、見た目とかどうでもいいので、
アクセスした際のリクエストによって実行すればいいので、基本的にRestコントローラを使うことにします。
まずは、/fuel/app/classes/controller/blogtest.php ファイルを作って、下記のように修正します。

/**
 * Blogtest Controller.
 *
 * @package app
 * @extends Controller
 */

class Controller_Blogtest extends Controller_Rest
{
    /**
     *
     */
     public function get_index()
     {
         $apns = Pushnotification::forge('apns');
         
         $apns->payload_method = 'simple';
         $apns->connect_to_push();
         
         $apns->set_data(array(
             'event' = 'testevent',
         ));
         
         $device_token = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
         $send_result = $apns->send_message($device_token, 'FuelPHPからのテストだよ', 0, 'default');
         if ($send_result) {
             $test = "apns send successful";
             $res = 0;
         } else {
             $test = $apns->error;
             $res = 1;
         }
         $apns->disconnect_push();
         
         $result = array(
             'result' = $res,
             'message' = $test,
         );
         return $result;
     }
}

ほぼサンプルのソースそのままです。
が、気をつけなければならないのは、この方法で送信した場合、resultに0が入る(OKになる)ことはありません。
なぜなら、send_messageの返り値が、payload_methodをsimpleにすると指定されていない(returnされない)からです。

payload_method = 'enhance'

にすると、正常な値が返却されます。
正常にプッシュされると、アプリがアクティブになっていない状態であれば以下の様な画面でメッセージが表示されます。

 photo

また、先ほどのアプリコンソールにも、ステータスがしっかりと表示されます。

ReceiveRemoteNotification on foreground: {
    aps = {
        alert = "FuelPHP\U304b\U3089\U306e\U30c6\U30b9\U30c8\U3060\U3088";
        badge = 0;
        sound = default;
    };
    event = testevent;
}

おわりに

この方法を使えば、FuelPHPからでも至極簡単にpush通知できますね。
あとは、受信したメッセージをトリガに処理をする箇所を作ればいいだけです。
次回はAndroidアプリに対してpush通知を行いたいと思います。