現在表示中:

注意:

アドビは、シングルページアプリケーションフレームワークをベースにしたクライアント側のレンダリング(React など)を必要とするプロジェクトには SPA エディターを使用することをお勧めします。詳細情報

注意:

このドキュメントは、AEM Mobile 使用の手引きの一部で、AEM Mobile のリファレンスの出発点として最適です。

コンテンツをパッケージ化してネイティブモバイルアプリケーションで使用できるようにするには、コンテンツ同期を使用します。AEM で作成されるページは、デバイスがオフラインの場合でもアプリコンテンツとして使用できます。さらに、AEM ページは Web 標準に基づいているので、ネイティブラッパーに AEM ページを埋め込むことを可能にするクロスプラットフォームを使用します。この戦略によって、開発の作業を削減し、アプリコンテンツを簡単に更新できます。

注意:

AEM ツールを使用して作成する PhoneGap アプリは、コンテンツ同期を経由して AEM ページをコンテンツとして使用するように既に設定されています。 

コンテンツ同期フレームワークは、Web コンテンツを格納するアーカイブファイルを作成します。このコンテンツには、シンプルなページのデータ、画像、PDF ファイルまたは Web アプリ全体を含めることができます。コンテンツ同期 API は、モバイルアプリまたはビルドプロセスからアーカイブファイルへのアクセスを提供することで、コンテンツを取得してアプリに追加できるようにします。 

次の一連の手順は、コンテンツ同期の一般的な使用例を示しています。

  1. AEM 開発者が、追加するコンテンツを指定するコンテンツ同期設定を作成します。
  2. コンテンツ同期フレームワークが、コンテンツを収集してキャッシュします。 
  3. モバイルデバイスで、モバイルアプリケーションが起動され、サーバーからコンテンツを要求します。コンテンツは ZIP ファイルで提供されます。
  4. クライアントが、ZIP のコンテンツをローカルファイルシステムに解凍します。ZIP ファイル内のフォルダー構造は、クライアント(ブラウザーなど)が、通常、サーバーから要求するパスをシミュレートします。
  5. クライアントが、組み込みのブラウザーでコンテンツを開くか、その他の方法でコンテンツを使用します。
  6. クライアントが、更新されたコンテンツを後でサーバーから要求します。コンテンツ同期フレームワークが、ダウンロードのサイズと時間を削減するための増分更新を提供します。これは、帯域幅とデータボリュームが限られているモバイルデバイスで重要になる場合があります。

注意:

コンテンツ同期ハンドラーの開発のガイドラインおよびすぐに使えるアプリハンドラーについて詳しくは、コンテンツ同期ハンドラーの開発を参照してください。

コンテンツ同期のコンテンツの設定

クライアントに提供される ZIP ファイルのコンテンツを指定するためのコンテンツ同期設定を作成します。任意の数のコンテンツ同期設定を作成できます。各設定には識別用の名前が付けられています。 

コンテンツ同期設定を作成するには、sling:resourceType プロパティを contentsync/config に設定して、cq:ContentSyncConfig ノードをリポジトリに追加します。cq:ContentSyncConfig ノードはリポジトリ内の任意の場所に配置できます。ただし、AEM パブリッシュインスタンスでユーザーがこのノードにアクセスできるようにしてください。そのため、/content の下にノードを追加する必要があります。

コンテンツ同期の ZIP ファイルのコンテンツを指定するには、cq:ContentSyncConfig ノードに子ノードを追加します。それぞれの子ノードの次のプロパティによって、追加するコンテンツ項目と追加の際の処理方法が特定されます。

  • path:コンテンツの場所。
  • type:コンテンツの処理に使用する設定タイプの名前。複数のタイプを使用できます。設定タイプを参照してください。
コンテンツ同期設定の例を参照してください。
 
作成したコンテンツ同期設定はコンテンツ同期コンソールに表示されます。

注意:

コンテンツ同期フレームワークは、アセットとデザインに関連するファイルの依存関係がコンテンツ同期パッケージに含まれているかどうかを確認しません。必要なファイルをすべて ZIP ファイルに含めてください。

コンテンツ同期のダウンロードへのアクセスの設定

コンテンツ同期からダウンロードを行うことのできるユーザーまたはグループを指定します。コンテンツ同期のすべてのキャッシュからダウンロードを行うことのできるデフォルトのユーザーまたはグループを設定できます。このデフォルト設定を上書きして、特定のコンテンツ同期設定のためのアクセスを設定できます。 

AEM をインストールすると、administrators グループのメンバーはデフォルトでコンテンツ同期からダウンロードできます。

コンテンツ同期のダウンロードのデフォルトアクセスの設定

Day CQ コンテンツ同期マネージャーサービスは、コンテンツ同期へのアクセスを制御します。このサービスを設定して、コンテンツ同期からのダウンロードをデフォルトで実行できるユーザーまたはグループを指定します。

Web コンソールを使用してサービスを設定する場合は、ユーザーまたはグループの名前を「許可可能なフォールバックキャッシュ」プロパティの値として入力します。

リポジトリで設定する場合は、サービスに関する以下の情報を使用します。

  • PID:com.day.cq.contentsync.impl.ContentSyncManagerImpl
  • プロパティ名:contentsync.fallback.authorizable

コンテンツ同期キャッシュのダウンロードアクセスの上書き

特定のコンテンツ同期設定のダウンロードアクセスを設定するには、次のプロパティを cq:ContentSyncConfig ノードに追加します。

  • 名前:authorizable
  • タイプ:String   
  • 値:ダウンロードを行うことのできるユーザーまたはグループの名前

例えば、ユーザーがアプリを使用してコンテンツ同期から直接アップデートをインストールできます。すべてのユーザーがアップデートをダウンロードできるようにするには、authorizable プロパティの値を everyone に設定します。

cq:ContentSyncConfig ノードに authorizable プロパティがない場合は、Day CQ コンテンツ同期マネージャーサービスの「許可可能なフォールバックキャッシュ」プロパティに設定されているデフォルトのユーザーまたはグループによって、ダウンロードできるユーザーが決定されます。

コンテンツ同期キャッシュの更新のためのユーザーの設定

ユーザーがコンテンツ同期キャッシュに対する更新を実行する場合は、特定のユーザーアカウントがそのユーザーの代わりにアクションを実行します。anonymous ユーザーは、デフォルトですべてのコンテンツ同期キャッシュを更新します。

デフォルトのユーザーを上書きして、特定のコンテンツ同期キャッシュを更新するユーザーまたはグループを指定できます。 

デフォルトのユーザーを上書きするには、次のプロパティを cq:ContentSyncConfig ノードに追加して、特定のコンテンツ同期設定に対する更新を実行するユーザーまたはグループを指定します。

  • 名前:updateuser
  • タイプ:String   
  • 値:更新を実行できるユーザーまたはグループの名前

cq:ContentSyncConfig ノードに updateuser プロパティがない場合は、デフォルトの anonymous ユーザーがキャッシュを更新します。 

設定タイプ

シンプルな JSON のレンダリングからページ(参照先のアセットを含む)の本格的なレンダリングまで、さまざまな処理が可能です。ここでは、使用可能な設定タイプとそのパラメーターについて説明します。

copy

ファイルとフォルダーをコピーします。

  • path - パスが 1 つのファイルを指す場合は、そのファイルだけがコピーされます。パスがフォルダー(ページノードを含む)を指す場合は、そのフォルダーに格納されているファイルとフォルダーがすべてコピーされます。

content

標準の Sling の要求処理を使用してコンテンツをレンダリングします。

  • path - 出力する必要のあるリソースのパス。
  • extension - 要求で使用する必要のある拡張子。一般的な例として、htmljson が挙げられますが、その他の拡張子を使用することもできます。
  • selector - オプションのセレクター(ドット区切りで指定します)。一般的な例として、touch(モバイルバージョンのページのレンダリング用)や infinity(JSON の出力用)が挙げられます。

clientlib

JavaScript または CSS クライアントライブラリをパッケージ化します。

  • path - クライアントライブラリのルートのパス。
  • extension - クライアントライブラリのタイプ。現時点では、js または css に設定してください。

assets

アセットの元のレンディションを収集します。

  • path - /content/dam の下にあるアセットフォルダーのパス。

画像

画像を収集します。

  • path - 画像リソースのパス。

image タイプは、zip ファイルに We.Retail ロゴを追加するために使用します。

pages

AEM ページをレンダリングして、参照先のアセットを収集します。

  • path - ページのパス。
  • extension - 要求で使用する必要のある拡張子。ページの場合は、ほぼ html ですが、その他の拡張子を使用することもできます。
  • selector - オプションのセレクター(ドット区切りで指定します)。一般的な例として、touch(モバイルバージョンのページのレンダリング用)が挙げられます。
  • deep - 子ページも含める必要があるかどうかを指定する、オプションのブール値プロパティ。デフォルト値は true です。
  • includeImages - 画像を含める必要があるかどうかを指定する、オプションのブール値プロパティ。デフォルト値は true です。
    デフォルトでは、リソースタイプが foundation/components/image の画像コンポーネントだけが追加の対象になります。Web コンソールで Day CQ WCM Pages Update Handler を設定することで、その他のリソースタイプを追加できます。

rewrite

rewrite ノードでは、書き出したページでリンクを書き換える方法を定義します。書き換え後のリンクは、zip ファイルに含まれるファイルまたはサーバー上のリソースを指すことができます。

rewrite ノードは、page ノードの下に配置する必要があります。

rewrite ノードには、次に示す 1 つ以上のプロパティを指定できます。

  • clientlibs:clientlib のパスを書き換えます。
  • images:image のパスを書き換えます。
  • links:link のパスを書き換えます。

各プロパティには、次のどちらかの値を指定できます。

  • REWRITE_RELATIVE:ファイルシステム上のページの .html ファイルを基準とした相対位置を使用してパスを書き換えます。
  • REWRITE_EXTERNAL:AEM Externalizer サービスを使用してサーバー上のリソースを指すことによって、パスを書き換えます。

PathRewriterTransformerFactory という名前の AEM サービスを使用すると、書き換える特定の html 属性を設定できます。このサービスは Web コンソールで設定できます。このサービスには、rewrite ノードの各プロパティ(clientlibsimages および links)の設定が含まれています。

この機能は AEM 5.5 で追加されました。

コンテンツ同期設定の例

コンテンツ同期の設定例を次に示します。 

 

+ weretail_go [cq:ContentSyncConfig]
  - sling:resourceType = "contentsync/config"

  + etc.designs.default [nt:unstructured]
    - path = "/etc/designs/default"
    - type = "copy"

  + etc.designs.mobile [nt:unstructured]
    - path = "/etc/designs/mobile"
    - type = "copy"

  + events.plist [nt:unstructured]
    - path = "/content/weretail_mobile/en/events/jcr:content/par/events"
    - type = "content"
    - extension = "plist"

  + events.touch.html [nt:unstructured]
    - path = "/content/weretail_mobile/en/events"
    - type = "pages"
    - extension = "html"
    - selector = "touch"

  + logo [nt:unstructured]
    - path = "/etc/designs/mobile/jcr:content/mobilecontentpage/logo"
    - type = "logo"

  + manifest [nt:unstructured]
    - indexPage = "/content/weretail_mobile/en/events.touch.html"
    - metadataPlist = "/content/weretail_mobile/en/events/_jcr_content/par/events.plist"

  + ...

etc.designs.default および etc.designs.mobile

設定の最初の 2 つのエントリは明白です。追加するモバイルページが複数あるので、関連するデザインファイルを /etc/designs に配置する必要があります。追加の処理は不要なので、copy で十分です。

events.plist

これは少し特殊なエントリです。概要で示したとおり、アプリケーションはイベントの位置のマーカーをマップビューに提供する必要があります。必要な位置情報を PLIST 形式の個別のファイルとして提供します。そのために、インデックスページで使用するイベントリストコンポーネントには plist.jsp というスクリプトがあります。このスクリプトは、コンポーネントのリソースが拡張子 .plist 付きで要求された場合に実行されます。Sling の要求処理を活用するので、通常どおり、コンポーネントのパスは path プロパティで指定され、typecontent に設定されます。

 

events.touch.html

次に、アプリに表示される実際のページを指定します。path プロパティはイベントのルートページに設定されます。deep プロパティのデフォルト値が true なので、そのページの下にあるすべてのイベントページも含まれます。設定タイプとして pages を使用して、ページ上の画像またはダウンロードコンポーネントから参照される可能性のある画像またはその他のファイルが含まれるようにします。また、touch セレクターを設定して、モバイルバージョンのページを指定します。機能パックの設定には、この種のエントリが他にも含まれていますが、説明を簡単にするためにここでは除外しています。

logo

設定タイプ logo についてはこれまで説明していませんが、これは組み込みのタイプではありません。ただし、コンテンツ同期フレームワークはある程度まで拡張可能であり、このタイプはその一例です。フレームワークの拡張については、以降の節で説明します。

manifest

多くの場合、何らかのメタデータ(コンテンツの開始ページなど)を zip ファイルに含めることをお勧めします。ただし、このような情報をハードコードすると、後から容易に変更できなくなります。コンテンツ同期フレームワークでは、manifest ノードを設定で検索することで、このような使用例をサポートします。このノードは名前で識別され、設定タイプは不要です。この特定のノードで定義される各プロパティは、マニフェストと呼ばれるファイルに追加されます。このファイルは zip ファイルのルートにあります。

前述の例では、イベントリストページが初期ページになります。この情報は indexPage プロパティで指定され、いつでも簡単に変更できます。2 つ目のプロパティでは、events.plist ファイルのパスを定義しています。後述のとおり、これでクライアントアプリケーションはマニフェストを読み取り、それに従って動作できるようになります。

 

設定が完了したらすぐに、ブラウザーまたはその他の任意の HTTP クライアントでコンテンツをダウンロードできます。iOS 用の開発をおこなう場合は、専用の WAppKitSync クライアントライブラリを使用できます。ダウンロード場所は、設定のパスと .zip 拡張子で構成されます。例えば、ローカル AEM インスタンスを操作する場合は、http://localhost:4502/content/weretail_go.zip です。

コンテンツ同期コンソール

コンテンツ同期コンソールには、リポジトリ内のコンテンツ同期設定(cq:ContentSyncConfig タイプのすべてのノード)がすべて表示されます。各設定を使用すると、次の操作を行うことができます。

  • キャッシュの更新
  • キャッシュのクリア
  • zip 全体のダウンロード
  • 現在および特定の日時の差分の zip のダウンロード

このコンソールは開発およびトラブルシューティングの際に役立ちます。

次の URL からコンソールにアクセスできます。

http://localhost:4502/libs/cq/contentsync/content/console.html

次のようなコンソールが表示されます。

chlimage_1

コンテンツ同期フレームワークの拡張

多数の設定オプションが用意されているとしても、特定の使用例のすべての要件に対応することはできない可能性があります。ここでは、コンテンツ同期フレームワークの拡張ポイントとカスタム設定タイプを作成する方法について説明します。

各設定タイプには、コンテンツ更新ハンドラーが用意されています。これは、特定のタイプに登録される OSGi コンポーネントファクトリです。これらのハンドラーは、コンテンツを収集して処理し、コンテンツ同期フレームワークが管理するキャッシュに追加します。次のインターフェイスまたは抽象基本クラスを実装します。

  • com.day.cq.contentsync.handler.ContentUpdateHandler - すべての更新ハンドラーが実装する必要のあるインターフェイス
  • com.day.cq.contentsync.handler.AbstractSlingResourceUpdateHandler - Sling を使用してリソースのレンダリングを簡略化する抽象クラス

実装したクラスを OSGi コンポーネントファクトリとして登録し、バンドル内の OSGi コンテナにデプロイします。そのためには、JavaDoc タグまたはアノテーションを使用して Maven SCR Plugin を使用します。次の例は、JavaDoc バージョンを示しています。

/*
 * @scr.component metatype="no"
 *                factory="com.day.cq.contentsync.handler.ContentUpdateHandler/customtype"
 */
public class CustomTypeUpdateHandler implements ContentUpdateHandler {
    // add your code here
}

/*
 * @scr.component metatype="no" inherit="true"
 *                factory="com.day.cq.contentsync.handler.ContentUpdateHandler/othertype"
 */
public class OtherTypeUpdateHandler extends AbstractSlingResourceUpdateHandler {
    // add your code here
}

ファクトリ定義には、共通のインターフェイスとカスタムタイプがスラッシュ区切りで含まれています。この方法により、設定エントリのカスタムタイプがコンテンツ同期フレームワークで認識されるので、フレームワークではカスタムクラスのインスタンスを検索および作成できます。次の節では、カスタム更新ハンドラーの具体例を示します。

 

警告:

AbstractSlingResourceUpdateHandler 基本クラスに基づいてビルドを行う場合は、inherit 定義を追加する必要があります。この定義を追加しないと、基本クラスで宣言される必要な参照が OSGi コンテナで設定されません。

カスタム更新ハンドラーの実装

すべての We.Retail Mobile ページには、左上隅にロゴが表示されます。当然ながら、このロゴも zip ファイルに含めます。ただし、キャッシュを最適化するために、AEM ではリポジトリ内の画像ファイルの実際の場所は参照されないので、単に copy 設定タイプを使用することはできません。代わりに、AEM から要求された場所で画像を取得できるようにする独自の logo 設定タイプを指定する必要があります。次のコードに、ロゴ更新ハンドラーの完全な実装を示します。

LogoUpdateHandler.java

package com.day.cq.wcm.apps.weretail.impl;

import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;

import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.jcr.resource.JcrResourceResolverFactory;

import com.day.cq.commons.jcr.JcrUtil;
import com.day.cq.contentsync.config.ConfigEntry;
import com.day.cq.contentsync.handler.ContentUpdateHandler;
import com.day.cq.wcm.foundation.Image;
import com.day.text.Text;

/**
 * The <code>LogoUpdateHandler</code> is used to update the content sync cache
 * with a page logo added using a logo component.
 *
 * @scr.component metatype="no"
 *                factory="com.day.cq.contentsync.handler.ContentUpdateHandler/logo"
 */
public class LogoUpdateHandler implements ContentUpdateHandler {

    private static final Logger log = LoggerFactory.getLogger(LogoUpdateHandler.class);

    /** @scr.reference policy="static" */
    protected JcrResourceResolverFactory resolverFactory;

    public boolean updateCacheEntry(ConfigEntry configEntry, Long lastUpdated, String configCacheRoot, Session admin, Session session) {
        ResourceResolver resolver = resolverFactory.getResourceResolver(admin);
        Resource resource = resolver.getResource(configEntry.getContentPath());

        Image img = new Image(resource);
        img.setItemName(Image.NN_FILE, "image");
        img.setItemName(Image.PN_REFERENCE, "imageReference");
        img.setSelector("img");

        try {
            if(img.getLastModified() == null || lastUpdated < img.getLastModified().getTime().getTime()) { 
                String src = img.getSrc();
                String parentPath = configCacheRoot + Text.getRelativeParent(src, 1);
	
                Node parent = JcrUtil.createPath(parentPath, "sling:Folder", admin);
                Node image = resolver.getResource(resource.getPath() + "/image").adaptTo(Node.class);
                JcrUtil.copy(image, parent, Text.getName(src));
				
                admin.save();

                return true;
            }
        } catch (RepositoryException e) {
            log.error("Unexpected error while updating logo: ", e);
        }
		
        return false;
    }
}

LogoUpdateHandler クラスは、ContentUpdateHandler インターフェイスの updateCacheEntry(ConfigEntry, Long, String, Session, Session) メソッドを実装します。このメソッドは、以下に示す複数の引数を使用します。

  • このハンドラーを呼び出す対象となる、設定エントリへのアクセスを提供する ConfigEntry インスタンスとそのプロパティ。
  • 前回のコンテンツ同期によってキャッシュが更新された日時を示す lastUpdated タイムスタンプ。このタイムスタンプ以降に変更されていないコンテンツをハンドラーで更新しないでください。
  • キャッシュのルートパスを指定する configCacheRoot 引数。更新されたすべてのファイルを zip ファイルに追加するには、このパスにファイルを格納する必要があります。
  • キャッシュに関連するすべてのリポジトリ操作に使用する必要のある管理セッション。
  • 特定のユーザーのコンテキストでコンテンツを更新し、ある種のパーソナライズされたコンテンツを提供するために使用できるユーザーセッション。

カスタムハンドラーを実装するには、設定エントリに指定されたリソースに基づいて、Image クラスのインスタンスを最初に作成します。基本的に、これはページ上の実際のロゴコンポーネントによって行われる手順と同じです。画像のターゲットパスは、ページから参照されるパスと同じです。

次に、前回の更新後にリソースが変更されたかどうかを確認します。カスタム実装では、キャッシュの不要な更新を避ける必要があります。変更が行われていない場合は、false が返されます。リソースが変更されている場合は、キャッシュのルートを基準とした相対的な位置に画像をコピーします。最後に、キャッシュが更新されたことをフレームワークに示すために true が返されます。

クライアントでのコンテンツの使用

コンテンツ同期が提供するコンテンツをモバイルアプリで使用するには、HTTP または HTTPS 接続を経由してコンテンツを要求する必要があります。その結果、取得したコンテンツ(ZIP ファイルにパッケージ化されます)がモバイルデバイスのローカルに解凍および格納されます。コンテンツは、データだけでなくロジック(つまり、完全な Web アプリケーション)も参照します。これにより、ネットワークに接続されていない場合でも、取得した Web アプリケーションと対応するデータをモバイルユーザーが実行できるようになります。

コンテンツ同期は、インテリジェントな方法でコンテンツを提供します。前回成功したデータ同期以降のデータの変更のみが提供されるので、データ転送に必要な時間が短縮されます。アプリケーションの最初の実行時には、1970 年 1 月 1 日以降のデータの変更が要求され、以降は前回成功した同期の後に変更されたデータだけが要求されます。AEM では、iOS 用のクライアント通信フレームワークを利用して、データの通信と転送を簡略化します。これにより、最小限のネイティブコードで iOS ベースの Web アプリケーションを使用できるようになります。

転送されたデータはすべて同じディレクトリ構造に解凍できます。データの解凍時に追加の手順(依存関係の確認など)を行う必要はありません。iOS では、すべてのデータが iOS アプリの Documents フォルダー内のサブフォルダーに格納されます。

iOS ベースの AEM モバイルアプリの一般的な実行パスは次のとおりです。

  • ユーザーが iOS デバイスでアプリを起動します。
  • アプリが AEM バックエンドへの接続を試行して、前回の実行時以降のデータの変更を要求します。
  • サーバーが対応するデータを取得して、zip ファイルに圧縮します。
  • データがクライアントデバイスに返されて、Documents フォルダーに解凍されます。
  • UIWebView コンポーネントが起動/更新されます。

接続を確立できなかった場合は、以前にダウンロードしたデータが表示されます。

さらに先のステップ

管理者および開発者の役割と責任について詳しくは、以下のリソースを参照してください。

本作品は Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License によってライセンス許可を受けています。  Twitter™ および Facebook の投稿には、Creative Commons の規約内容は適用されません。

法律上の注意   |   プライバシーポリシー