最近のアクセス:
ネイティブモバイルのキャッシュ処理

ネイティブモバイル用に生成されたアプリケーションでオフライン保存 (以降、「キャッシュ処理」と呼びます) を必要とするシナリオがいくつかあります。
以下では、このようなシナリオについて詳しく説明します。

シナリオ 1: クエリのキャッシュ

目的は、サーバー上のデータがまだ変更されていない場合に、クライアントとサーバーの間のデータトラフィックを防ぐことです。これは、解決したい最も基本的なケースです: つまり、完全にオンラインのアプリケーションで、サーバーへのクエリの繰り返しを避ける必要があります。
不必要なネットワークトラフィックを避けることが望ましいのは、主に以下を節約することになるからです:
  • 帯域幅の使用 (特に、Wi-Fi の代わりに電話回線を使用する場合)
  • デバイスのエネルギー消費 (コードレス通信、データの逆シリアル化)
  • Web サーバーの負荷
これを解決するために、ネイティブ モバイル アプリケーションから実行されたクエリについて、関連するデータが最後に使用されて以降変更されたかどうか知る必要があります。

シナリオ 2: オフラインアプリケーション (読み取り専用)

これは、上記で説明したケースの延長で、接続が失われた場合を想定しています。基本的な考え方は、上記で説明したような (クエリしたデータが変更されていなければ、サーバーにアクセスする必要がない) キャッシュがあれば、接続が失われた場合に、デバイスに格納されたデータを使用して、既にアクセスしたアプリケーションのセクションを参照することもできるということです。

解決策の実装

上記で説明した 2 つのシナリオを解決するために、必要なことが 2 つあります:
  • ローカルデータベースのストレージ
サーバーによって返されたデータは、メモリーの過度な消費を防ぎ、アプリケーションを終了しても存続させるために、データベースに格納する必要があります。格納する必要があるのはサーバークエリの結果なので、このデータベース用のデータモデルは、GeneXus が正規化したデータモデルではなく、「各 Data Provider オブジェクトのテーブル」になります。
この目的で使用されるデータベースは SQLite です。これは、すべてのデバイスに含まれます。
  • データがサーバー上で変更されたかどうかを判定するメカニズム
クライアントはサーバーに対してクエリを実行する際、クエリと一緒に、前回の応答のタイムスタンプ (つまり、前回クエリが行われた時間) も送信します。
サーバーは、何を返す必要があるのか定義するために、それ以降クエリに関係するいずれかのテーブルが変更されたかどうかを制御する必要があります。クライアントが行った最後のクエリがデータの更新よりも前である場合 (つまり、クエリに関連付けられているテーブルが変更された場合) は新しい結果を返し、クライアントのデータがまだ有効である場合はその旨を示すメッセージを返し、クライアントはキャッシュされた結果を表示します。この最後のケースでは、特別な応答 (HTTP 304) を返します。
サーバー側では、クライアントのデータがまだ有効であるのか判断するために、2 つのエレメントが必要になります (サーバーのキャッシュに格納されているエレメントです):
  1. テーブルのリスト
  2. テーブルが最後に変更されたタイムスタンプ
このため、ネイティブ モバイル アプリケーションのキャッシュには、常に、キャッシュを使用できるのか、それともクエリをもう一度行う必要があるのか判断するために必要なデータが入れられます。
テーブルのいずれかのレコードに挿入または更新があると、サーバーのキャッシュが更新されます。
テーブルの更新は、任意の GeneXus オブジェクトを使用して行うことができます (REST プロシージャーである必要はありません)。実際、ナレッジベースに 2 つのジェネレーター (Web とネイティブモバイル) がある場合、Web で生成されたオブジェクトがテーブルを更新すると、ネイティブモバイルのキャッシュも更新されます。Web ジェネレーターはネイティブ モバイル ジェネレーターの [ Smart Devices Cache Management ] プロパティを確認します。
唯一の例外は、システムのデータベースのテーブルが、GeneXus で開発されたアプリケーションの外部で更新される場合です。

ネイティブモバイルのキャッシュ処理を有効にする方法

まず、[ Smart Devices Cache Management ] プロパティと、キャッシュを使用する各オブジェクトの [ Enable Data Caching ] プロパティを有効にする必要があります。
オブジェクトの [ Enable Data Caching ] プロパティが True の場合、[ Check For New Data ] プロパティ[ Check For New Data After Minutes Elapsed ] プロパティが有効になります。

キャッシュの無効化

いくつかのシナリオでは、明確にキャッシュを無効にする必要があります。たとえば、アプリケーションにデバイスのフォームを強制的に再表示させる必要がある場合や、GeneXus 以外のアプリケーションからデータが変更された場合などです。
次のような場合について考えます:
Panel オブジェクトで、フォームにデータベースの変数および項目属性を表示し、そのパネルのアクションで Procedure オブジェクトを呼び出し、実行後に再表示を行います。再表示の処理時に、フォームの変数と、プロシージャーで変更された Web セッションの内容がロードされます。
パネルのイベントは、次のようになります:
Event ‘CallProc’
   Composite
      ModifyWebSession.Call()
      refresh
   EndComposite
EndEvent

Event Refresh
   &FormVar =&websession.get(‘Sample’)
Endevent
プロシージャー ModifyWebSession が次のようであると仮定します:
&websession.set(‘Sample’, &time)
この場合、Panel オブジェクトに戻るときに、パネルの &FormVar 変数は、修正されたようには表示されません (フォームの項目属性が実際に修正された場合を除く)。これは、データベースに対してクエリを実行した後、データが変更されていないことを示す応答をパネルが受け取るためです。その結果、再表示は実行されず、&FormVar 変数に変更が表示されることがなくなります。
この問題を解決するために、プログラムでキャッシュを無効にする方法が実装されています。これにより、データが変更されたかどうかに関係なく、(データが変更対象であったものとして) データベースにクエリが行われます。
これは外部オブジェクトとして実装されていて、ネイティブ モバイル ジェネレーターの使用時にインポートされます (SmartDevicesApi フォルダ内に自動的に統合されるすべての外部オブジェクトの場合と同じです)。このクラスは ServerAPI と呼ばれ、InvalidateCache メソッドを含んでいます。
したがって、上記の例の ModifyWebSession プロシージャーは、キャッシュを無効にするためにこのメソッドを使用する必要があり、パネルに戻るときに、(更新を伴って) データが変更されたと見なされ、もう一度クエリが実行される必要があります。そこで、プロシージャーのコードは次のようになります:
&websession.set(‘Sample’, &time)
ServerAPI.InvalidateCache()
GeneXus 15 については、Cache API および Cache.SmartDevices.Clear() を参照してください。

参考情報

GeneXus アプリケーションでのキャッシュ処理
Cache API


サブページ
Created: 14/09/18 03:12 by Admin Last update: 24/03/25 23:57 by Admin
カテゴリ
Powered by GXwiki 3.0