Cordova NativeStorageプラグインでデータを保存

NativeStorageプラグインを使用するとアプリのデータを永続的に保存できます。Androidの場合はSharedPreferences、iOSの場合はNSUserDefaultsを利用します。データはローカルストレージ(LocalStorage)と同様にKey-Value形式で扱います。

NativeStorageプラグイン: cordova-plugin-nativestorage

API

const key = "message";
const value = "hello";
const successCallback => console.log("success");
const errorCallback => console.log("error");

// 保存
NativeStorage.setItem(key, value, successCallback, errorCallback);

// 読み出し
NativeStorage.getItem(key, successCallback, errorCallback);

// 読み出し(全キー)
NativeStorage.keys(successCallback, errorCallback);

// 削除
NativeStorage.remove(key, successCallback, errorCallback);

// 全削除
NativeStorage.clear(successCallback, errorCallback);

動作確認サンプル

<body>
  <div id="container">
    <ons-button onclick="onLoad()">Load</ons-button>
    <ons-button onclick="onSave()">Save</ons-button>
  </div>
</body>
// key
const KEY_NUMBERS = "nsNums";
const KEY_RECORDS = "nsRecords";

// value
const numbers = [100, 200, 300, 400, 500];  // 配列
const records = {     // オブジェクト
  "date": {
    "year": 2019,
    "month": 11,
    "day": 16,
    "week": 1
  },
  "time": [
    {"hour": 7, "min": 10},
    {"hour": 9, "min": 20},
    {"hour": 11, "min": 30},
    {"hour": 15, "min": 40},
    {"hour": 20, "min": 50}
  ]
};

ons.ready(function () {   // devicereadyイベント
  console.log("*** ons.ready ***");
  console.log(window.NativeStorage);
})

function onLoad () {
  console.log("*** onLoad ***");

  NativeStorage.getItem(KEY_NUMBERS, 
    obj => console.log("success", obj),
    err => console.log("error", err.code));

  console.log("check1");

  NativeStorage.getItem(KEY_RECORDS, 
    obj => console.log("success", obj),
    err => console.log("error", err.code));

  console.log("check2");
}

function onSave () {
  console.log("*** onSave ***");
  
  NativeStorage.setItem(KEY_NUMBERS, numbers,
    obj => console.log("success", obj),
    err => console.log("error", err.code));

  console.log("check1");

  NativeStorage.setItem(KEY_RECORDS, records, 
    obj => console.log("success", obj),
    err => console.log("error", err.code));

  console.log("check2");
}

console 出力

ローカルストレージとの相違点

アプリ起動時の読み込み

  • Cordovaの初期化が終わってから(devicereadyイベントリスナ―やons.ready()メソッドで)実行する
  • ローカルストレージの場合はどこで読み込んでもよい

非同期処理

  • データを読み出した後の処理はコールバックで行う
  • 複数のキーを順に呼び出したりFile APIのような非同期処理を続けて行うときはPromiseなどを使用するとソースコードが見やすくなる
  • ローカルストレージの場合は同期処理なので記述した順番に実行される

データ形式

  • オブジェクトや配列のデータを保存したり読み出したりする場合、そのままの形式で扱うことができる
  • ローカルストレージの場合はJSON形式の文字列で扱う必要がある(保存する前にJSON.stringify()で文字列に、読み出した後はJSON.parse()でオブジェクトに変換)

Note

SharedPreferencesへのアクセスモードはMODE_PRIVATE固定

NativeStorageプラグインでは他のアプリとのデータ共有は不可。そもそもSharedPreferences APIではAPI level23からMODE_MULTI_PROCESSがサポートされなくなったため、データ共有したい場合はSharedPreferencesの替わりにContentProviderなどを使用する必要がある。

アプリを再インストールしてもデータが消えない

アプリをアンインストールした後に再インストールした場合、SharedPreferencesに保存したデータは自動的に復元される。保存したデータが設定値であれば再設定する手間が省けるなど便利な面もあるが、スコアや過去の日付のような初期化したいデータの場合はクリーンな状態から始めることができなくなる。

これは、Androidの自動バックアップ機能が原因。

この機能により、SharedPreferencesがGoogle Driveへ自動的に保存され、再インストールしたときに自動的に復元される。この機能を無効化するには、アプリのマニフェストファイルにandroid:allowBackup=”false”を記述する。Monacaを使用している場合はAndroidManifest.xmlの替わりにconfig.xmlとCustom Configプラグインを使用する。

Smoking Note v1.3.3 アップデート

喫煙管理アプリ Smoking Note のアップデートを行いました。

v1.3.3 アップデート内容

  • 無効な記録の自動削除機能追加(スマホ端末の時刻設定で無効な記録が作成されたときのフェイルセーフ)
  • 月のグラフについて、記録を開始した月および現在集計中の月の表示を適正化

アップデート内容の詳細について、以下に記します。

無効な記録の自動削除機能

無効な記録とは、現在の日付より先の日付重複する過去の日付で登録された記録のことです。この日付は、日にちが変ってから一本目の喫煙をチェックするときに決定しますが、変更不可のため通常は無効な記録が作られることはありません。

しかし、スマホ本体の日付・時刻設定を手動で行った場合、日付を自由に設定できるため無効な記録が作られる可能性がでてきます。本アップデート前のv1.3.2では、無効な記録があっても記録自体は毎日登録されますが、集計処理が途中で終了してしまいグラフの表示がその前日で止まります。

そこで今回、記録の保存時に全記録の日付でソート・マージ、範囲外の記録の削除を行うことで無効な記録を削除するようにしました。

この問題に気づいたきっかけは、海外の方からグラフが更新されなくなったというメールを頂いたことです。スクリーンショットを送ってくれたり状況を詳しく教えて頂きとても感謝しています。ちなみに、最初メールを読んだときなぜスマホ本体の時間をいじったのか気になっていました。聞くに聞けないままメールのやり取りをしているうちに、おそらくサマータイムのせいだと気づきました(グラフが更新されなくなった日が11/3以降で、2019年のアメリカのサマータイム終了日は11/3)。おそらくですが、時刻を戻すことで日付が戻り、そこで記録を作成したため同じ日付の記録が作られたのだと推察しています。今回の対策で直ることを願っています。

月グラフの表示適正化

これまで月のグラフでは、単純に(一か月間の合計本数 / 一か月の日数)で一日の平均本数を算出し、月ごとに表示していました。

このため、記録を開始した月と現在の月では、分母となる(一か月の日数)が実際に経過した日数より多くなるせいで意味のある値になっていませんでした(現在の月の値は、現在の月が終わったときに正しい値となります)。

今回、月を以下の3パターンに場合分けすることで、月グラフの表示適正化を行いました。

  • 記録を開始した月 … (一か月間の合計本数 / 開始日から月末までの日数)
  • 集計を完了した月 … (一か月間の合計本数 / 一か月の日数)
  • 現在集計中の月  … (一か月間の合計本数 / 現在の日付)

※ 記録を開始した月で現在も集計中の場合は「現在集計中の月」。

適正化前(11月:6.7本。11月の日数30で割っているので謎値。)

適正化後 (11月:14.3本。11月の経過日数15で割っているので正確。)

その他

内部的なことをメモ代わりに書いておきます。

  • グラフ画面の表を角丸化
  • グラフ画面からメイン画面に戻る時に一回だけポップオーバーを表示(広告が表示されることを告知)
  • Cordova 7.1.0 —> 9.0.0
  • Onsen UI v2.10.1 —> v2.10.10
  • jQuery v2.0.3 —> v3.4.1(Google Play Consoleでアラートがでたため)
  • Cordova Admob Pro —> Admob Freeプラグインへ変更

Smoking Note は Google Play ストアから無料ダウンロードできます。

Google Play で手に入れよう

ながめておぼえる日本地図 リリース

都道府県を自然におぼえる学習アプリながめておぼえる日本地図をリリースしました。

特徴

  • 基本的にながめるだけです。
  • 指定したルートに沿って都道府県を自動表示します。
  • 記憶を確認するためのテスト機能を実装しています。
  • 都道府県や県庁所在地を調べたいときにも便利です。

解説

  • 本アプリは日本地図をおぼえるためのインプットを提供します。
  • ものごとをおぼえるためにはインプットを繰り返すことが大切です。1、2回でおぼえることができたとしても、すぐに忘れてしまうでしょう。
  • 本アプリで日本地図を繰り返しながめることにより、記憶を定着させ、気づいたらいつの間にかおぼえていたという状態になることを目指しています。
  • 日本地図をおぼえたい方の一助となれば幸いです。

ながめる

  • 指定したルートに沿って都道府県を自動表示します。
  • 移動スピードやズーム倍率の設定が可能です。

かくにん

  • 各県をおぼえているか確認することができます。
  • 間違えた県名を記録します。集中的におぼえるのに役立ちます。

しらべる

  • 調べながらおぼえる、タッチ&表示。
  • 都道府県の一覧表示、県名からの位置検索ができます。

その他

日本地図のテーマ(カラー、グラデーション)設定ができます。

県名と県庁所在地の切り替えが可能です。

Google Playストアで公開中ですので、よろしければご利用ください。

Google Play で手に入れよう