NativeScriptはちゃんとリモート通知、いわゆるPUSH通知のプラグインが存在する。
いや、PUSH通知がいわゆるリモート通知なのか? まあどうでもいいす。
プロジェクトトップで、
tns plugin add nativescript-push-notifications
とかやれば、よしなにプラグインをインストールしてくれます。
具体的な使い方は公式のドキュメントがあるので特にここで解説する必要は無いですよね。
https://github.com/NativeScript/push-plugin
ただし!
これだけで終わらないのが世の中のつらいところ。
PUSH通知はアプリが3つの状態の時にやってくる。
すなわち、
- アプリが起動していない状態
- アプリが起動している状態
- アプリが裏に回っている状態
AndroidとiOSでは上記の厳密な意味合いは異なってくるけど、ざっくりすればこんな感じです。
このプラグインを利用すると、2.の時は特に問題ないです。
iOSならregistするときの引数内に指定したコールバック、AndroidならonMessageReceivedで指定したコールバックが呼ばれます。
1.と3.も、Androidなら問題ないです。
iOSの場合は1.と3.のケースでは、プラグインバージョン0.0.17の現在、コールバックが呼ばれません…。
ネイティブコードレベルではdidReceiveRemoteNotificationやdidFinishLaunchingWithOptionsのdelegateはケアしてるみたいなのですが、少なくともうちのiOS9なiPhone5では何も起こりません。
通知バーから単純にアプリを起動するだけならこれでも問題ないのですが、payloadに何か情報を入れてそれを利用したい場合に困る、困りすぎて犬のおまわりさんになってしまう。
色々と模索しましたが、結局1.については自分でなんとかする、3.については理由はよく分からないけどapplicationDidBecomeActiveを自分で用意してやると機能するようになりました。
以下、私がapp.tsに加えた内容です。
global.notificationData = null;
if (application.ios) {
class CustomDelegate extends UIResponder implements UIApplicationDelegate {
public static ObjCProtocols = [UIApplicationDelegate];
applicationDidFinishLaunchingWithOptions(application, launchOptions): boolean {
if (launchOptions) {
var userInfo = launchOptions.objectForKey(UIApplicationLaunchOptionsRemoteNotificationKey);
if (userInfo) {
global.notificationData = userInfo;
}
}
return true;
}
applicationDidBecomeActive(application): void {
}
}
application.ios.delegate = CustomDelegate;
}
iOSの定数はそのままではTypeScriptではエラーになってしまうので、適宜declareでダミーを用意してください。
これでglobalにpayloadの情報がNSDictionaryで入ってきますので、あとは好きなタイミングで参照すれば良いです。
ちなみに、Android用のコールバックでは、JSON文字列が返ってきますので、parseする必要があります。
iOSはそのまま連想配列としてアクセスできます。実体はNSDictionaryだと思いますが。