ClientInformation 外部オブジェクトの Id プロパティは、Web とネイティブモバイルの両方のプラットフォームで許容されるクライアント ID を返します。
一部のネイティブ モバイル アプリケーションでは、使用されているデバイスを識別することが重要となります。この例をいくつか示します:
- セキュリティ強化
- 特定の銀行口座の取引は、特定のデバイスからだけ実行できるようにする。
- 特定のユーザーが、指定された時間帯に特定のデバイスだけを使用できるようにする。
- プロモーション
- 特定のデバイスに特定の会社のアプリケーションを 2 つ以上インストールすると、割引が受けられる。
- 利用統計の計算
デバイスを一意に識別するための特徴となる、デバイスのシリアル番号や MAC アドレスに相当する情報を把握できるのが一番ですが、たやすくは入手できません。
すべてのデバイスに、ソフトウェアでアクセスできる何らかの一意の識別情報はありますが、プライバシーを理由に使用できるようにはなっておらず、アクセスすること自体禁じられている場合もあります (Apple)。
ClientInformation 外部オブジェクトの [ ClientInformation.Id ] プロパティは、デバイス識別メカニズムを用いて、この状況を打破します。このメカニズムの実装には、ベースとなる共通部分と、プラットフォームごとのバリエーションがあります。
ClientInformation.Id の値は次のようになります:
GUID (UUID) で適用されるのと同じ条件です。
次の状況下では、2 台のデバイスが ClientInformation.Id として同じ値を返す場合があります:
- Apple で、デバイスに別のデバイスのデータを復元した場合
- Android で、root 化したデバイスで戻り値が変わる可能性があり、その場合は一意性が保証されなくなる
- アプリケーションの存続期間 (インストールされてからアンインストールされるまで) にわたって (すべてのプラットフォーム上で) 不変です。
- 各デバイスの ClientInformation.Id の値は一意です。
Android では、あるデバイスにインストールされた GeneXus アプリケーションはすべて同じ値を返します (後出の「付録」で例外についてご確認ください)。
Apple では、同じデバイスがアプリケーションによって異なる ClientInformation.Id 値を返す場合があります (後出の「付録」を参照してください)。
まとめ:
- デバイス (ハードウェア) を一意に識別するという作業にベストプラクティスはなく、ときとして不可能な場合もある。
- GeneXus では、許容可能なデバイス識別メカニズムを採用し、そのメカニズムにはプラットフォームごとにバリエーションがある。
Web アプリケーションの場合、 [ ClientInformation.Id ] プロパティはユーザーに ID を返します。エンドユーザーがブラウザーの Cookie を削除するまで、すべてのセッションでこの ID が使用されます。ClientInformation.Id は、最長の有効期限を含む Cookie に保存されているため、いくつかのアプリケーションとブラウザーで同じままです。ユーザーがアプリケーションにアクセスするブラウザーを識別します。
以下に使用例を紹介します。この例では、ユーザーは
Web Panel オブジェクトの Start イベントで呼び出された ClientInformation.Id を使って識別されます。取得された ClientInformation.Id はデータベースに格納されます:
Event Start
&clientId = ClientInformation.Id
SaveClient(&clientId) //SaveClient is a Procedure object defined in the KB.
Endevent
SaveClient
Procedure オブジェクトは次のように定義されます:
Rules
Parm(&clientId);
Source
For each Clients
delete
Endfor
New
ClientId = &clientId
Endnew
その後、別の Web Panel オブジェクトが格納された ClientId を使用して、その特定ユーザーに
Web 通知を送信します。
通知を送信する Web Panel オブジェクトで、データベースに保存されている ClientId を取得します。
Event 'Notify'
for each Clients
&ClientId = ClientId
endfor
&NotificationInfo.Id= &ClientId //&NotificationInfo is based on the Server.Socket external object
&NotificationInfo.Message= &MyMessage
&NotificationInfo.NotifyClient(&ClientId, &NotificationInfo) //The NotifyClient method is sending the message only to the involved client/user.
Endevent
ClientInformation.Id のサンプルをダウンロードできます。
ClientInformation.Id の値は、
デバイスの内部 ID から生成された GUID です。このため、少なくとも、デバイスの寿命期間中は同じデバイスにインストールされた 2 つのアプリケーション間で必ず同じ値になります。
ただし、以下の例外が確認されています:
- 工場出荷時状態へのリセットを行った場合、ID が変わることがある。
- root 化されたデバイスでは、ID の変更が可能である。
生成された GUID は格納されるため、root 化前にインストールされたアプリケーションが返す ID 値と、root 化後にインストールされたアプリケーションが返す値が異なる可能性があります。ただし、同じアプリケーションから返される値は変化しません。
- 所定のメーカーのデバイスは Android 2.2 でエラーが起きるため、すべてが同じ ANDROID_ID を返す。
この数値は既知の数値です。このような場合は、ランダムな GUID を (アプリケーションごとに) 生成します。
詳しい解説については、Stack Overflow のこの回答を参照してください。提案されているソリューションは、GeneXus 社で採用しているものと実質的に同じですが、GeneXus 社では GUID の生成にあたって IMEI は考慮していません (そのためには、特別な許可が必要になるためです)。
ClientInformation.Id の値は、デバイスに初めて GeneXus アプリケーションをインストールした時点で割り出した GUID となります。この値は、いわゆるキーチェーンに格納され、値を作成したアプリケーションがアンインストールされ、再インストールされた場合でも維持されます。
Apple では、各アプリケーションに独自のキーチェーンがありますが、複数のアプリケーションで同じキーチェーンを共有することも可能です。共有キーチェーンがある場合は、1 つのキーチェーンを共有するすべてのアプリケーションが、所定のデバイスについて同じ ClientInformation.Id 値を返します。共有キーチェーンがない場合、デバイスにインストールされている各アプリケーションが異なる ClientInformation.Id 値を返します。
ClientInformation.Id の値は、工場出荷時状態へのリセットが行われた場合、またはファームウェアが復元された場合 (オペレーティングシステムの再インストール) に変わる可能性があります。また、セキュリティコピーが復元されなかった場合も同様です。たとえば、デバイスが別のユーザーの手に渡った (販売されたなど) 場合が該当します。
複数のデバイスで同じセキュリティコピーが復元されたときは、複数のデバイスで ClientInformation.Id 値が同じになる場合があります。こういう状況は、デバイスを新しいモデルに交換し、交換前のデバイスのセキュリティコピーを交換後のデバイスで復元したときに起こることがあります。
これを実現するには、実装を変更する必要があります。また、GX ユーザーが、この動作を制御可能であることを理解する必要があります。値を共有するアプリケーションと共有しないアプリケーションは、ユーザーの決断により異なります。
Apple アプリケーションの一意の識別子 (アプリケーション ID) は、2 つの部分から構成されます: <Bundle Seed ID>.<Bundle Identifier>。Bundle Seed ID は、一意の 10 文字から成るチェーンで、App Store 内で一意であり、Apple により生成されます。Bundle Identifier は、同じプロバイダーのアプリケーションで一意となる文字のチェーンで、GX では、メイン (Main) の同名のプロパティで設定します。
同じプロバイダーの複数のアプリケーションで、同じデバイスについて同じ ClientInformation.Id 値を返すには、それらのアプリケーションで Bundle Seed ID の値が同じであることが必要です。
Bundle Seed Id はアプリケーションの公開後は変更できないため、この仕組みについて理解しておくことがとても重要です。幸い、Apple サイト (developer.apple.com) で新しい App ID が作成されるときの既定値は、Bundle Seed ID で、これがすべてのアプリケーションで共有されます (コンボボックスで [ Use Team ID ] を選択):