mBaaSお役立ちブログ

Monacaアプリにニフティクラウド mobile backendを接続してみよう

HTML5でiOS/Android、Google Chrome Appsを開発できるMonaca。スマートフォンのWebViewやJavaScriptエンジンが高速化されることで大抵のアプリは十分なパフォーマンスで開発できるようになっています。ニフティクラウド mobile backendはMonacaと連携しており、素早くMonacaとニフティクラウド mobile backendを組み合わせたアプリ開発がはじめられます。

そこで今回は既存のMonacaアプリに対してどのようにニフティクラウド mobile backendを組み込めば良いか、サンプルアプリをベースに紹介します。

必要なもの

Monacaで新規アプリ作成

Monacaにログインしてプロジェクトの作成をクリックします。

出てきたプロジェクトテンプレートの中で、メモ帳アプリを選択します。今回はこちらをベースにします。

メモ帳アプリはlocalStrageにメモ帳データを保存するようになっています。このデータをニフティクラウド mobile backendに保存するように変更します。

プロジェクトを作成したら開くボタンを押してMonaca IDEを開きます。

JavaScript SDKの追加

ニフティクラウド mobile backendよりJavaScript SDKをダウンロードします。

Monaca IDEにてjsフォルダを右クリックし、アップロードを選択します。

出てきたウィンドウの ファイルをドロップしてください と書かれているところに先ほどダウンロードしたJavaScript SDKをドロップします。

続いて index.html を開いて次のように修正します。

  :
<script src="components/loader.js"></script>
<script src="js/ncmb-latest.min.js"></script> <!-- ここに JavaScript SDKを追加読み込み -->
<script src="js/memo.js"></script>
<script src="js/app.js"></script>
<script src="js/cssua.min.js"></script>
  :

これで準備は完了です。

ニフティクラウド mobile backendでアプリを作成

続いてニフティクラウド mobile backend側での作業になります。管理画面にて新規アプリ作成を選択します。

作成するとアプリケーションキーとクライアントキーが表示されます。これを使いますのでコピーしておきます。

JavaScript SDKの初期化

まずJavaScript SDKの初期化処理を行います。 js/memo.js を開きます。そして一番上に次のように記述します。

NCMB.initialize("application_key",
  "client_key");
var Memo = NCMB.Object.extend("Memo");

この中にあるapplication_keyは前述のニフティクラウド mobile backendのアプリケーションキー、client_keyも同様にクライアントキーを入力してください。

その下にある var Memo = NCMB.Object.extend("Memo"); はデータストアで扱うクラス名とそのオブジェクトを生成しています。データストアは開発者が自由に構造を設定できるデータベースです。

初期表示設定

まずアプリを開いた時の表示処理を変更します。 js/memo.jsgetMemoList が該当部分です。

///// Return list of memo
function getMemoList() {
  var list = localStorage.getItem("memo_list");
  if (list == null) {
    return new Array();
  } else {
    return JSON.parse(list);
  }
}

localStrageを使う場合、データは同期処理でそのまま取得できます。対してニフティクラウド mobile backendを使った場合はネットワークを介しますので基本的に非同期処理です。そこでPromiseを使って処理するようにします。

///// Return list of memo
function getMemoList() {
  var promise = new NCMB.Promise();
  var query = new NCMB.Query(Memo);
  query.find({
    success: function(memos) {
      promise.resolve(memos);
    },
    error: function(err) {
      promise.reject(err);
    }
  });
  return promise._thenRunCallbacks();
}

Promiseを使う際にはNCMB.Promiseを使うと便利です。Memoクラスを検索し、その結果をそのまま Promiseのresolveに渡しています。失敗した場合はエラーメッセージをrejectに渡します。getMemoListを受け取る処理側も変更します。 js/app.js を開きます。

///// Initialize top page
function initTopPage() {
  $("#TopListView").empty();
  
  var list = getMemoList();
  for (var i in list) {
    var memo = list[i];
    var d = new Date(memo.time);
    var date = d.getFullYear() + "/" + (d.getMonth() + 1) + "/" + d.getDate();
    
    $li = $("<li><a href='#' class='show'><h3></h3><p></p></a><a href='#' class='delete'>Delete</a></li>");
    $li.data("id", memo.id);
    $li.find("h3").text(date);
    $li.find("p").text(memo.text);
    $("#TopListView").prepend($li);
  }
  if (list.length == 0) {
    $li = $("<li>No memo found</li>");
    $("#TopListView").prepend($li);
  }
  $("#TopListView").listview("refresh");  // Call refresh after manipulating list
}

こちらのgetMemoListの受け取った後の処理を変更します。

///// Initialize top page
function initTopPage() {
  $("#TopListView").empty();
  
  getMemoList().then(function(list) {
    for (var i in list) {
      var memo = list[i];
      var d = new Date(memo.get("time"));
      
      var date = d.getFullYear() + "/" + (d.getMonth() + 1) + "/" + d.getDate();
    
      $li = $("<li><a href='#' class='show'><h3></h3><p></p></a><a href='#' class='delete'>Delete</a></li>");
      $li.data("id", memo.id);
      $li.find("h3").text(date);
      $li.find("p").text(memo.get("text"));
      $("#TopListView").prepend($li);
    }
    if (list.length == 0) {
      $li = $("<li>No memo found</li>");
      $("#TopListView").prepend($li);
    }
    $("#TopListView").listview("refresh");  // Call refresh after manipulating list    
  });
}

Promiseを使ったので、thenで結果を受け取れるようになっています。後はNCMB.Objectが返ってきますのでgetでデータにアクセスするようになっています(timeおよびtext)。これだけでデータの表示処理について、localStrageからニフティクラウド mobile backendに移行できました。

メモの追加処理

続いてメモの追加処理です。こちらもまずは js/memo.js から修正します。元々の処理は次のようになっています。

///// Add memo
function addMemo(text) {
  var list = getMemoList();
  var time = new Date().getTime();
  list.push({ id: time, time: time, text: text });
  saveMemoList(list);
}

元々の処理ではlocalStrageに保存されているメモのJSONを取得し、新しいメモを追加して保存し直すと言った仕組みになっています。ニフティクラウド mobile backendを使った場合、既存データを取得する必要はありませんので新しいオブジェクトを作成して新規保存します。

///// Add memo
function addMemo(text) {
  var promise = new NCMB.Promise();
  var memo = new Memo();
  var time = new Date().getTime();
  memo.set("text", text);
  memo.set("time", time);
  memo.save({
    success: function(memos) {
      promise.resolve(memos);
    },
    error: function(err) {
      promise.reject(err);
    }
  });
  return promise._thenRunCallbacks();
}

こちらも取得時と同じくPromiseベースにしてあります。saveメソッドで保存処理が実行され、問題なければsuccessコールバックが呼ばれます。

そして続いて js/app.js も修正します。元々のコードは次のようになっています。

///// Save memo and return to top page
function onSaveBtn() {
  var text = $("#Memo").val();
  if (text != '') {
    // Save to local storage
    addMemo(text);
    // Clear form
    $("#Memo").val("");
    // Initialize top page
    initTopPage();
  }
  $.mobile.changePage("#TopPage", { reverse: true });
}

こちらはaddMemoのコールバックを使っていませんので、変更しなくとも動きますが、initToPage処理のタイミングがずれてしまう可能性がありますので次のように修正します。

///// Save memo and return to top page
function onSaveBtn() {
  var text = $("#Memo").val();
  if (text != '') {
    // Save to local storage
    addMemo(text).then(function(){
      // Clear form
      $("#Memo").val("");
      // Initialize top page
      initTopPage();
      $.mobile.changePage("#TopPage", { reverse: true });
    });
  }
}

addMemoがうまくいったらinitToPageなどの処理を実行するように変更しました。

メモの削除

最後にメモの削除処理です。元々の処理は次のようになっています。

///// Delete specified memo
function deleteMemo(id) {
  var list = getMemoList();
  for (var i in list) {
    if (list[i].id == id) {
      list.splice(i, 1);
      break;  // Quit for loop when found
    }
  }
  saveMemoList(list);
}

新規追加の時と同じく既存のメモリストを取得して、そこから該当idのメモを削除して保存し直しています。ニフティクラウド mobile backendを使った場合は既存データは不要になりますので、次のようなコードになります。

///// Delete specified memo
function deleteMemo(id) {
  var promise = new NCMB.Promise();
  var query = new NCMB.Query(Memo);
  query.get(id, {
    success: function(memo){
      memo.destroy({
        success: function() {
          promise.resolve();
        },
        error: function(err) {
          promise.reject(err);
        }
      })
    },
    error: function(err) {
      promise.reject(err);
    }
  });
  return promise._thenRunCallbacks();
}

まず既存データをid指定で取り出して、データが無事取得できたら memo.destroy を使って削除しています。取得と削除の両方がうまくいったら promise.resolve を実行して成功としています。では最後に js/app.js も修正します。元々のコードは次の通りです。

///// Delete memo
function onDeleteLink() {
  if (!confirm("Are you sure to delete this memo?")) {
    return;
  }
  var $li = $(this).parent();
  var id = $li.data("id");
  deleteMemo(id);
  
  initTopPage();
  
  // Return to top
  $.mobile.changePage("#TopPage", { reverse: true });
}

こちらが次のようになります。

///// Delete memo
function onDeleteLink() {
  if (!confirm("Are you sure to delete this memo?")) {
    return;
  }
  var $li = $(this).parent();
  var id = $li.data("id");
  deleteMemo(id).then(function () {
    initTopPage();
    // Return to top
    $.mobile.changePage("#TopPage", { reverse: true });
  });
}

こちらも追加の時と同じく、削除がうまくいった場合に表示を更新しています。

デモ

これらの変更を行った結果のデータが次の動画です。


見た目の動きは変わっていませんが、データはニフティクラウド mobile backendに保存されていますので、他のデバイスからでも同じデータが見られるようになります。ニフティクラウド mobile backendには認証機能もありますので、自分のデータだけをiOS/Android/Webなど多方面からチェック、変更できるメモ帳を作ることができるでしょう。

アプリはネットワークが使えないと広がりを失ってしまいます。逆にネットワークがあれば既存のアプリであっても新しい可能性を見いだせるかも知れません。その際にはぜひニフティクラウド mobile backendを使ってみてください。





ニフティクラウドmobile backend mbaas ご紹介 概要資料



バックナンバー