手動同期は、スマートデバイス用オフラインアプリケーションの [ Data Receive Criteria ] プロパティで、同期の条件として設定できます。
注: ここでは、GeneXus によって自動的に生成される同期プログラムを使用せずに、デバイスとサーバーのテーブル間で完全に手動で同期を行う方法について説明します (GeneXus Tilo の初期のバージョンにはこのオプションは含まれません)。先に進む前に、オフラインデータの 自動同期を使用するか、 独自のデータ同期プログラムのコード記述を行うかを検討します。同期の方法については、 手動同期を使用した Sales の例のコード例を参照しています。
同期を完了するための主な手順を次に示します。
- マスターテーブルのサービスレイヤー
- マスターサービスの呼び出し
- 同期処理のトリガー
- イベントテーブルのサービスレイヤー
- サーバーへのイベントの送信
Web サーバーで公開される REST サービスです。デバイスで処理を開始するために必要なマスターデータを取得するために使用します。
たとえば、顧客のマスターテーブルを公開するには、次のものが必要です:
- Customer トランザクションに基づく SDT
- このトランザクションのすべてまたは一部のレジスタを返すデータプロバイダー
SDTCustomer
{
CustomerId
CustomerName
CustomerAddress
CustomerPhone
CustomerLocation
CustomerDistanceToMe
}
このデータプロバイダーは SDTCustomer のコレクションを返します。この例では、Customer のすべてのレジスタを返します。
このデータプロバイダーを REST サービスとして公開するには、こちらで説明しているプロパティを設定する必要があります。最後に Web サービスプロトコルを REST プロトコルに設定します。
マスター データ サービス レイヤーのサービスを実行し、デバイスにデータを挿入するために必要なオブジェクトです。このコードは、すべてデバイス上で実行されます。
次のコードのプロシージャーを作成できます。
For each Customer
delete
Endfor
ローカルデータベースの顧客をすべて削除します。段階的に同期する方法もあります。この場合、マスターの同期の前にテーブルを削除します。
GetParameters.Call(&serverprotocol, &serverHost, &serverBaseURL, &serverRestBaseURL, &serverPort)
GetParameters プロシージャーは HttpClient データタイプのパラメーターを取得します。値は次のようになります:
&serverprotocol = "http"
&serverHost = "apps3.genexusx.com"
&serverBaseURL= "/Idfe4nFfdfFwf4jf442nvanaf4r3rn904Faf/"
&serverRestBaseURL = "/Idfe4nFfdfFwf4jf442nvanaf4r3rn904Faf/rest/"
&serverPort = 80
サービスレイヤーから REST サービスを利用するための HTTPClient オブジェクトの初期設定です。
&httpclient.Host = &serverHost.Trim()
&httpclient.Port = &serverPort
&httpclient.BaseUrl = &serverRestBaseURL.Trim()
&httpclient.AddHeader(!'Content-type',!'application/json')
&httpclient.Execute(!'GET', !'GetAllCustomers?fmt=json')
REST サービスを呼び出し、GET メソッドを使用して、手順 1 で作成したすべての顧客に関するリソースを取得します。json 形式で返される文字列を &httpclient 変数に格納します。
&customerslist.FromJson(&httpclient.ToString())
&customerlist は、1 の a で作成した SDT に基づく変数です。FromJson メソッドで、サーバーから取得したすべてのレジスタを変数にロードします。これが可能なのは、REST サービスが同じ SDT を json 形式で返すからです。
For &Customer in &CustomersList
&CustomerBC = new()
&CustomerBC.CustomerId = &Customer.CustomerId
&CustomerBC.CustomerName = &Customer.CustomerName
&CustomerBC.CustomerAddress = &Customer.CustomerAddress
&CustomerBCCustomerPhone = &Customer.CustomerPhone
&CustomerBC.CustomerLocation = &Customer.CustomerLocation
&CustomerBC.CustomerDistanceToMe = &customer.CustomerDistanceToMe
&CustomerBCCustomerVisited = False
&CustomerBC.Save()
endfor
&CustomersList に対して反復処理を実行し、ビジネスコンポーネントを使用して、すべての顧客をローカルデータベースに挿入します。
ビジネスコンポーネントを使用する理由については、「手動同期のベストプラクティス」を参照してください。
commit
最後に、挿入による変更をローカルデータベースにコミットします。
前述のように、データ同期は常にデバイスから開始します。開発者は、ユーザーが意識的にこの処理をトリガーできるようにするか (例: [ Load Data ] ボタンや [ Synchronize ] ボタンをタップしたとき)、意識しないでトリガーできるようにするか (例: 同期をトリガーする画面を開いたとき) を選択する必要があります。いずれの場合も、このコードがスマートデバイス上 (クライアント側) でトリガーされます。
データをロードするユーザーイベントは、次のようになります:
Event 'Load Master Data'
Composite
ProgressIndicator.Title = "Data synchronization..."
ProgressIndicator.Description = "Checking connectivity..."
ProgressIndicator.Type = 0
ProgressIndicator.Show()
&server = getServerFromParameters() // 同期を行うサーバーホストの URL を返します。
&IsConnected = NetWorkAPI.IsServerAvailable(&server)
if &isConnected
ProgressIndicator.Description = "Retrieving data from server..."
&result = SyncReceive()
/******************************************************************************************************
注: デバイスがサーバーに接続している場合、同期を実行できます。場合によっては、
使用している接続を確認し、同期に Wi-Fi や 3G などが必要かどうかを
確認できます。そのためには、 [ [ Network 外部オブジェクト ] ] を使用します。
*******************************************************************************************************/
else
&result = "No connection detected"
endif
ProgressIndicator.Hide()
msg(&result)
Endcomposite
Endevent
イベントテーブルを生成するトランザクションも Web サーバーのアプリケーションに含まれます。オンラインでレジスタを挿入または更新するサービスを生成する最も簡単な方法は、トランザクション自体です。そのためには、トランザクションの [ Expose as Web Service ] プロパティを使用して、REST プロトコル用のトランザクションの CRUD サービスを公開します。
PurchaseOrder の挿入サービスは次のようになります:
<ホスト>/<ベース URL>/rest/PurchaseOrder/0
例:
http://apps3.genexusx.com/Idfe4nFfdfFwf4ja42nvanaf4r3rn904Faf/rest/PurchaseOrder/0
この手順では、ローカルでイベントテーブルに保存されているデータを Web サーバーに送信し、挿入します。そのためには、例に沿ってトランザクションのレコードごとに、PurchaseOrder REST サービスへの POST を実行する必要があります。
手順 2 のように &httpclient 変数を初期化したら、次のコードを記述します:
&ServerPOrder = LoadPurchaseOrder()
オフラインデータベースで追加されたすべての発注書をロードします。&ServerPOrder は、トランザクション ServerPOrder に基づく SDT に基づいています。
For &ServerPOrderItem in &ServerPOrder // ローカルデータベースからロードされた発注書に対して反復処理を実行します。
&body = &ServerPOrderItem.ToJson() // 発注書を JSON 形式で取得します。
&httpclient.AddString(&body) // 本文を HTTP POST に追加します。
&httpclient.Execute(!'POST', !'PurchaseOrderSrv/0') // 発注書のデータをサーバーに挿入するために実行します。
If &httpclient.StatusCode = 201 or &httpclient.StatusCode = 200
//Post 成功
else
//Post エラー
Endif
Endfor
残りのコードは、手動同期を使用した Sales の例で確認できます。
注: 手動同期を使用した Sales の例では、マルチメディア、具体的には Image データタイプのフィールドを同期する方法も説明しています。
|