setDeviceTokenの記述場所(組み込み場所)について
現在、MonacaでNCMBと連携したアプリ(プッシュあり)を作っているのですが、
iOSへの初回インストール後の起動時(プッシュの許可アラートが出るとき)のみ、
objectIDが取得できずに困っています。
(2度目以降の起動時には正常に取得できます。)
objectIDが取得できない直接の原因は、iOSが表示させている「プッシュの許可アラート」でほぼ間違いなさそう(※)なのですが
皆さま、setDeviceTokenはどのように実装してらっしゃいますか??
※ほぼ間違いなさそうという根拠
http://kenmaz.hatenadiary.jp/entry/20110826/1314376887
初回起動時に「OK」することでAPNsに端末が登録されプッシュを受信できるようになる。
つまり「OK」する前で、デバイストークンがまだAPNsに登録(コミット?)されていないのに
「setDeviceToken」が実行されているので、NCMBのInstallationに登録されない。
→getInstallationIdでobjectIdが取得できない。
●補足●
init.jsの「デバッグ用①」という箇所のalertを生かすと、ここで処理が止まるので
初回インストール後の起動時でもgetInstallationIdが正常に取得できるようになります。
アプリ起動時にsetDeviceToken→getInstallationIdという流れで処理したいケースは多いと思いますし
その方法で世にリリースされているアプリも多いと思います。
コードではなく処理タイミングのみでも結構ですので
お知恵を拝借いたしたく、お願いいたします。
以下ソース(現象が再現できる最小限のソースにしています。)
index.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<meta http-equiv="Content-Security-Policy" content="default-src *; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'">
<script src="components/ncmb/ncmb.min.js"></script>
<script src="components/loader.js"></script>
<link rel="stylesheet" href="components/loader.css">
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="lib/onsen/css/onsenui.css">
<link rel="stylesheet" href="lib/onsen/css/onsen-css-components.css">
<script src="lib/onsen/js/angular/angular.js"></script>
<script src="lib/onsen/js/onsenui.js"></script>
<script src="js/init.js"></script>
</head>
<body>
省略(画像を表示させているだけ)
</body>
</html>
init.js
$(function() {
document.addEventListener("deviceready", function()
{
//alert('setDeviceToken前');//デバッグ用①
window.NCMB.monaca.setDeviceToken(
"aplication_key",
"client_key",
"sender_id"
);
cnt = 0;
var ncmbTimer = setInterval(function() {
window.NCMB.monaca.getInstallationId(function(id) {
cnt = cnt + 1;
alert(cnt + '回目 id:' + id);//デバッグ用
//試行回数が3回を超えたら
if(cnt > 3){//
clearInterval(ncmbTimer);
alert('端末情報を取得できませんでした。アプリを再起動してください。');
}
if (id) {
clearInterval(ncmbTimer);
alert('init.jsで値取得成功 ' + cnt + '回目 id:' + id);//デバッグ用
window.location.href = '次の画面';
} else {
alert('init.jsで値取得失敗 ' + cnt + '回目');//デバッグ用
}
});
}, 1000);
},false);
});
2016/04/04 追記
上記のコードをMonacaに依頼して調査してもらい、下記の回答をいただきました。
以下、転記します。
・アプリ起動後の処理の流れ
1. アプリ起動後、アプリからAPNs(Apple Push Notification Service)へ、
デバイストークンを要求し、取得します。
2. setDeviceToken()により、1で取得したデバイストークンを取得します。
3. getInstallationId()にて、objectIdを取得します。
今回のお客様の事象といたしましては、「アプリ起動後の処理の流れ」の1の段階で、
まだAPNs側からデバイストークンを取得することができていない段階で、
2の処理が起動しているため、objectIdを取得することができないということが分かりました。
2回目以降のアプリ起動では、上記のAPNsへ要求するデバイストークンが作成されているため、
setDeviceToken()で、正常にデバイストークンを取得することができるため、
objectIdを取得できているという流れになります。