初めに
ガーミンのウォッチフェイス等では、アプリケーション単位で、永続的な情報を保持することができる機能を持っている。この情報は、デバイス内にファイルとして保存されている。
これに関して本家の情報は、CONNECT IQ SDK-programmer’s guide-Resource Compiler中のData Storageにある。
アプリケーションから永続的情報を取り扱うには、以下の3種類の方法が提供されており、それぞれ利用可能な最低バージョンが定義されている。
- オブジェクトストア
1.0.0以降 - プロパティ
2.4.0以降 - ストレージ
2.4.0以降
永続データの種類
プロパティ
プロジェクト内リソースファイルのpropertiesとして設定されている情報を取り扱うための物。Properties
経由でデータの設定・取得を行うか、AppBase.setProperty/getProperty
でデータの設定・取得を行うことができる。
例えば、以下のようなリソースファイルの場合。
<resources>
<properties>
<property id="prop" type="number">0</property>
</properties>
</resources>
以下のような、アクセスが可能になる。
var val = Properties.getValue("prop");
ファイルへのデータの保存は、AppBase.onStop
の後になる。
ストレージ
Storage経由でデータの設定・取得を行うことができるもの。
ストレージに関しては、初期値というものはなく、プログラム内で生成、設定、取得、削除の操作を行うことができる。
プロパティは、生成、削除の操作ができないので、その点に違いがある。
ストレージは、AppBase.setProperty/getProperty
でアクセスはすることはできない。
アクセス方法は次のようになる。
var val = Storage.getValue("storage");
if (val == null) {
val = 1;
}
ストレージの場合、初期状態では値が存在しないため、事前に設定をしておくか、null判定をして値を別途代入しておく必要がある。
setValueなど情報の更新を行った場合、すぐファイルに反映される。
2.4以降のデバイスのみしか利用しない場合、Storageの利用を推奨されている。これは、データ更新時にすぐファイルに保存されるため、アプリケーションが異常終了をしても、データは保持される。
オブジェクトストア
プロパティの機能とストレージの一部の機能が混ざったような機能を保持している。
まずプロパティに類似する機能だが、リソースファイル中のpropertiesで設定された情報のアクセス機能を保持している。
例えば、以下のようなリソースファイルの場合。
<resources>
<properties>
<property id="prop" type="number">0</property>
</properties>
</resources>
以下のような、アクセスが可能になる。
var val = Properties.getValue("prop");
次にストレージに類する機能だが、こちらはプロパティにないキーに関して、生成、設定、取得できるようになっている。
アクセス方法は次のようになる。
var val = Application.getApp().getProperty("storage");
if (val == null) {
val = 1;
}
こちらのアクセスの考え方も、Storage
と同様で、初期状態は値が存在しないため、事前に設定をしておくか、null判定をして値を別途代入しておく必要がある。
ストレージと同じようなのだが、削除に関する機能は存在していない。AppBase.deleteProperty
はメソッドとしてあるのだが、試してみたが動作していなかった。APIリファレンスにも、Deprecated. This method will be removed in Connect IQ 4.0.0との記述もあった。
生成されたプロパティに関しては、ストレージと異なるファイルに保存される。
ストレージとオブジェクトストアのデータ互換性について
リソースファイルに記述がないキーに対してのアクセスは、ストレージとオブジェクトストアの間に互換性はない。
機能の違いについては、以下の様になる。
オブジェクトストア | ストレージ | |
キーの削除 | × | 〇 |
ファイル更新時期 | メソッド呼び出し時随時 | AppBase.onStopの後 |
永続データの取り扱い(想像)
CONNECT IQ SDKの資料とシミューレーターの動作から類推した、各永続データとファイル、インスタンスの動作シーケンスは次のような感じだと思う。
- AppBaseのインスタンス生成
以下の動作は、インスタンスが実施。 - SETTINGSフォルダにSETファイルがない場合、新規生成する。
生成時の初期値は、プロジェクトのリソースファイルに設定されているpropertiesの設定内容が反映される。 - AppBase インスタンス内に、SETTINGSフォルダにSETファイル、DATAフォルダ内のSTR, IDX/DATの情報が読み込まれる。
- getProperty/setProperty、Properties経由での情報の取得・設定は、AppBase インスタンス内の情報をもとに行われる。
Storageに関しては、直接ファイルとのやり取りが行われる。 - onStopの後、インスタンスが削除される前までに、AppBase インスタンス内のプロパティ、オブジェクトストアの情報がファイルとして保存される。
上記流れのため、ファイルとして保存される前までにインスタンスが削除された場合、インスタンス内で変更した各種情報は破棄されてしまう。
データ保存場所
実機
実機をUSB経由でPCに接続すると、USBのストレージデバイスとして認識される。
そのストレージのGARMIN/APPSの下のDATA、SETTINGSフォルダに格納される。
具体的には、以下のような感じに。
シミューレーター
%TEMP%GARMIN
にあり、フォルダ構成については実機と同等となっている。
ストレージデータについては、シミューレーターからのアクセスも可能になっており、オブジェクトストア・ストレージに設定された情報は、File – Edit Persistent Storageのメニューから参照が可能になる。
実際の参照結果は以下の通り。
こちらがオブジェクトストア。
こちらがストレージ。
メニューは別々になっているのだが、ウィンドウタイトルは同じ名称となっている。
保存ファイル
プロパティ
SETTINGSフォルダに、拡張子SETで保存される。
サンプルテストをバイナリエディタで見た結果は以下の様になった。
prop1がAppBase.getProperty/setProperty
でアクセスしたもの。
prop2がApplication::Properties.getValue/setValue
でアクセスしたもの。
オブジェクトストア
DATAフォルダに、拡張子STRで保存される。
サンプルテストをバイナリエディタで見た結果は以下の様になった。
strage1がAppBase.getProperty/setProperty
でアクセスしたもの。
ストレージ
DATAフォルダに、拡張子IDX,DATで保存される。実データはDATの方に格納されるようだ。
サンプルテストをバイナリエディタで見た結果は以下の様になった。
strage2がApplication::Storage.getValue/setValue
でアクセスしたもの。
問題点
今回、オブジェクトストアについてまとめたきっかけとなったのが、ForeAthlete 45の実機で、オブジェクトストアのsetProperty
が動作しなかったため。
本来の動作がどうなのか、確認するため、サンプルプログラムを作成し、試したのだが、結局setProperty
で保存した情報が、次のgetProperty
で取得できなかった。
ただ、AppBase
インスタンスが生きている間のsetProperty
で保存したものはgetProperty
で取り出されているので、AppBase.onStop
ののち、データをファイルとして保存していないものと思われる。
実際、実機をUSB接続してストレージの中を見ても、DATAフォルダにSTRファイルを見つけることができないので。
この問題、シミューレーター側では問題なく動作していたので、実機ファームの問題だとは思うのだが。
Vivoactive HRでは実機でも問題なく想定通りの動作をしていた。
コメント