Ionic StorageでSQLiteを使う(Angular, iOS/Android)

2023/12/20に公開

はじめに

記事の目的

Ionic、Capacitor、Angular(standalone構成)で開発しているiOS/Androidアプリに、Ionic Storageを導入してSQLiteをストレージとして使用する手順で躓いたところがありました。
この記事は、2023年12月現在の正しい手順を備忘録としてまとめたものです。
サンプルコードはGitHubで公開しています。
https://github.com/EngiBeerHub/ionicstorage-sqlite-sample

Ionic Storageとは

Ionicフレームワークでモバイルアプリを開発していて、端末のストレージにデータを保存したいケースがあります。
使用するライブラリにはいくつか選択肢がありますが、代表的なものがIonic Storageです。
同じAPIでも、動作環境によってストレージの実装を変えることができるのが大きな特徴です。(環境共通でIndexedDBやlocalStorageが使用可能で、モバイル環境ではSQLiteも使用可能)
ライブラリを導入しなくてもlocalStorageはすぐに使用することができますが、モバイル環境においてlocalStorageやIndexedDBはOSによってデータが消される可能性があることがこちらのCapacitorのガイドで指摘されています。
これを踏まえると、Ionic StorageでSQLiteを利用するのが安全にデータを永続化できる選択肢ということがわかります。
https://capacitorjs.com/docs/guides/storage#why-cant-i-just-use-localstorage-or-indexeddb
ちなみに、IonicアプリケーションにおいてCapacitor提供のものも含めてどのようなストレージライブラリの選択肢が取り得るのかについてはこちらの記事がとても参考になりました。
https://ionic.io/blog/choosing-a-data-storage-solution-ionic-storage-capacitor-storage-sqlite-or-ionic-secure-storage

検証環境

  • Angular CLI: 17.0.7
  • Node: 20.10.0
  • npm: 10.2.4
  • Ionic: 7.1.5
  • Capacitor: 5.6.0
  • @ionic/storage-angular: 4.0.0
  • cordova-sqlite-storage: 6.1.0
  • localforage-cordovasqlitedriver: 1.8.0

導入手順

基本的には、ライブラリのREADMEの通りです。
https://github.com/ionic-team/ionic-storage
しかし、途中にReactなど他のJSライブラリでの導入手順やUsageなどが混ざっているため、Angular、SQLiteの部分だけを必要な順番で抜粋していきます。

Ionic Storageのインストール

npm install @ionic/storage-angular

SQLite関連のインストール

npm install cordova-sqlite-storage
npm install localforage-cordovasqlitedriver

セットアップ

今回はstandalone構成のため、main.tsにてIonicStorageModuleのproviderを追加します。
driverOrder配列内で、CordovaSQLiteDriver._driverを先頭に定義することでモバイル環境でSQLiteが優先的に利用されるようになります。
ちなみに検証環境の構成では、READMEの記載とは異なりCordovaSQLiteDriverはimport * as~とする必要がありました。

main.ts
import {IonicStorageModule} from "@ionic/storage-angular";
import * as CordovaSQLiteDriver from 'localforage-cordovasqlitedriver';
import {Drivers} from "@ionic/storage";

if (environment.production) {
  enableProdMode();
}

bootstrapApplication(AppComponent, {
  providers: [
    {provide: RouteReuseStrategy, useClass: IonicRouteStrategy},
    provideIonicAngular(),
    provideRouter(routes),
    importProvidersFrom(IonicStorageModule.forRoot({
      name: '__mydb',
      driverOrder: [
        CordovaSQLiteDriver._driver,
        Drivers.IndexedDB,
        Drivers.LocalStorage]
    }))
  ],
});

実際にStorageを利用するComponentやServiceのconstructorでStorageを注入します。
今回はIonicのBlankプロジェクトで自動生成されるHomePageコンポーネントで利用します。
defineDriverでCordovaSQLiteDriverを登録し、その後create()を呼び出すことでようやくStorageが利用可能になります。

home.page.ts
import {Storage} from "@ionic/storage-angular";
import * as CordovaSQLiteDriver from 'localforage-cordovasqlitedriver';

~~~

export class HomePage implements OnInit {
  constructor(private storage: Storage) {
  }

  async ngOnInit() {
    await this.storage.defineDriver(CordovaSQLiteDriver);
    await this.storage.create();
  }
}

動作確認

ボタンを押したら、カウントアップした数値をストレージに保存・取得する簡単な画面を作成して動作確認を行います。

Storageに利用されたDriverもログに出力しておきます。

home.page.ts
export class HomePage implements OnInit {
  count = 0;

  constructor(private storage: Storage) {
  }

  async ngOnInit() {
    await this.storage.defineDriver(CordovaSQLiteDriver);
    await this.storage.create();
    console.log(`Storage driver: ${this.storage.driver}`);
  }

  async onClickCountUp() {
    await this.storage.set('count', ++this.count);
    const value = await this.storage.get('count');
    console.log(`Stored value: ${value}`);
  }
}

テンプレートはこちらです。

home.page.html
<ion-content [fullscreen]="true" style="text-align: center">
  <ion-button expand="block" (click)="onClickCountUp()">Count Up</ion-button>
  <ion-text>{{count}}</ion-text>
</ion-content>

ブラウザ

ブラウザにはSQLiteが無いため、asyncStorage(IndexedDB)にデータが保存されています。

Storage driver: asyncStorage
Stored value: 1
Stored value: 2
Stored value: 3

モバイル環境

iOS

ログが長いので一部省略していますが、しっかりSQLiteにデータが保存されています。

⚡️  [log] - Storage driver: cordovaSQLiteDriver
⚡️  [log] - OPEN database: __mydb
To Native Cordova ->  SQLitePlugin open SQLitePlugin98149014 ["options": [{
    dblocation = nosync;
    description = "";
    key = "_ionickey";
    location = default;
    name = "__mydb";
    size = 4980736;
    version = 1;
}]]
⚡️  [log] - OPEN database: __mydb - OK
⚡️  [log] - DB opened: __mydb
⚡️  [log] - Stored value: 1

Android

しっかりSQLiteにデータが保存されています。

File: https://localhost/ - Line 2699 - Msg: onscript loading complete
File: https://localhost/957.fea4d96c03ed2138.js - Line 1 - Msg: Storage driver: cordovaSQLiteDriver
File: https://localhost/ - Line 3131 - Msg: OPEN database: __mydb
File: https://localhost/ - Line 3062 - Msg: new transaction is queued, waiting for open operation to finish
File: https://localhost/ - Line 3135 - Msg: OPEN database: __mydb - OK
File: https://localhost/ - Line 3036 - Msg: DB opened: __mydb
File: https://localhost/957.fea4d96c03ed2138.js - Line 1 - Msg: Stored value: 1

まとめ

Ionic Storageを使って、共通のコードで簡単にiOS/Android環境にSQLiteを導入することができました!
SQLも使わず、簡単にkey-value形式(コード上は)でデータを保存できるので便利ですね。

Discussion