#始めに
なんというかMeteorアドベントカレンダー出張版みたいな感じです。
もともとBaaSであるfirebaseをサーバサイドでiOSアプリを作ろうとしたところで
push Notificationが無くて、がっかりしたことがあるんですが、
Meteorならfirebaseっぽくサーバサイドを使えて(勝手に該当コレクションが永続化されている)
かつ、サーバサイドがカスタマイズ可能なのでpush Notificationが実装できるかなと思い試してみます。
ここで作ってたやつにpushNotificationを実装してみます。
Meteorについて
MeteorとはリアルタイムWebアプリケーションフレームワークであり、サーバサイドとクライアントは
webSocket上に実装したDDPというプロトコルをベースに双方向通信を行っています。
なんかイマイチという話題も聞きますが、今Node.js界で一番騒がれているフレームワークなようです。
実装
ぶっちゃけここで終わっているんですが、
アプリが起動中にしか値の更新が行われないので、アプリが停止中でもpush Notificationで通知されるようにしてみようと思います。
まずはleaderboardを取得します。
meteor create --example leaderboard
cd leaderboard
nodeのモジュールを組み込めるようにパッケージを追加します。
meteor add meteorhacks:npm
プロジェクト直下にpackages.json
を作成します
{
"apn": "1.6.2"
}
ここでmeteor
と叩くとパッケージの取り込みが行われて、再度meteor
を実行するように要求されます
それとpush Notification用の証明書を作っておきます。
参考にしたサイトはこちら:
http://intink.blogspot.jp/2012/11/ios-nodejs.html
http://www.lancork.net/2013/08/how-to-ios-push-first/
上記情報を参考にcert.pemとkey.pemを作成しprivate/
配下におきます。
private/
以下はサーバからしかアクセスできなくなります。
server/
ディレクトリを作成しpush notification用のコードを追加します。
Meteor.startup(function(){
//playersコレクション変更時に実行
Players.find().observe(
{
'changed': function (oldDocument,newDocument) {
console.log("player changed!!");
Meteor.call("sendAppleNotifications");
}
}
);
});
(function(){
"use strict";
var apn = Meteor.npmRequire("apn"),
path = Npm.require('path'),
apnOptions = Meteor.settings.apnOptions || {},
alertSound = apnOptions.sound || "alert.aiff",
apnConnection;
// default apn connection options
apnOptions = _.extend({
cert: Assets.getText("cert.pem"), //Meteor独自 private/下のcert.pem
key: Assets.getText("key.pem"), //Meteor独自 private/下のkey.pem
production:false //*.meteor.comに置くとデフォルトではproduction扱いになるようです
}, apnOptions);
apnConnection = new apn.Connection(apnOptions);
var pushIds = ["0ccf880dfda2214560d1c3d3f0df67db11605fc27df1b1XXXXXXXXXX"]; //実機から取得。本来ならアクセス時に登録したものを取得すべきですよねー。
var url = "testURL";
var alertMessage = "alert";
Meteor.methods({
'sendAppleNotifications': function() {
console.log("run sendAppleNotifications");
var note = new apn.Notification();
// expires 1 hour from now
note.expiry = Math.floor(Date.now() / 1000) + 3600;
note.sound = alertSound;
note.alert = alertMessage;
note.payload = {'url': url};
note.badge=10;
_.each(pushIds, function (token) {
var device = new apn.Device(token);
apnConnection.pushNotification(note, device);
console.log("send notification!!!");
});
return {success: 'ok'}
}
});
})();
サーバサイドはautorunが動かないらしく、observeで監視して自動実行するようにしています。