ヘッドレスOracle Content ManagementによるAndroid用ブログ・アプリケーションの構築

イントロダクション

JavaまたはKotlinを使用するAndroid開発環境は、Oracle Content Managementからコンテンツを使用するアプリケーションを構築するための強力なツールです。適切なコンテンツ・モデルを採用することで、一般的なブログ・アプリケーションを構成するAndroidユーザー・インタフェースを迅速に構築できます。

このチュートリアルでは、Oracle Content ManagementをヘッドレスCMSとして活用して、Kotlinを使用してAndroid用の単純なブログ・アプリケーションを作成します。このAndroidのサンプルは GitHubで入手できます。

このチュートリアルは、次の3つのステップで構成されています。

  1. Oracle Content Managementの準備
  2. Androidでブログを構築
  3. デプロイメント用のアプリケーションの準備

前提条件

このチュートリアルを進める前に、まず次の情報をお読みください。

このチュートリアルに従うには、次が必要です:

構築対象

私たちのブログアプリは、訪問者がトピックに整理されたブログ記事を探索できる3つの画面で構成されています。最初の画面であるホーム画面は、ブログトピックのリストで構成されています。

作成している内容を確認するには、チュートリアルの最終状態を示します。これは、Oracle Content Managementのコンテンツを使用する基本的なAndroidブログ・アプリケーションです。

このチュートリアルの最後にあるホーム画面は次のようになります。

この図は、Cafe Supremoデモ・サイトのホーム画面と、使用可能なトピックのリストを示しています。

2ページ目のトピック画面には、トピックに属する各ブログ記事のプレビューが表示されます。個々のトピック画面は次のようになります。

このイメージは、そのトピックで使用可能な記事のリストを含む「コーヒーを作る方法」というトピック画面を示しています。

最後に、記事画面には、ブログの作成者に関する情報を含む最終ブログ記事が表示されます。個々の記事ページの外観は次のとおりです。

このイメージは、コンテンツと作成者参照を含む個別の記事ページを示しています。

続行するには、Oracle Content Managementのアクティブなサブスクリプションを持ち、コンテンツ管理者ロールでログインする必要があります。

タスク1: Oracle Content Managementの準備

Oracle Content Managementインスタンスがまだない場合は、クイック・スタートを参照して、Oracle Cloudへの登録、Oracle Content Managementインスタンスのプロビジョニング、およびOracle Content ManagementをヘッドレスCMSとして構成する方法を学習します。

このチュートリアルでは、2つの方法のいずれかでコンテンツ・モデルを作成する必要があります。使用可能なダウンロード可能なアセット・パックは、空のリポジトリにコンテンツ・タイプおよび関連付けられたコンテンツを埋めるか、独自のコンテンツ・モデルおよびコンテンツを作成できます。

Oracle Content Managementを準備するには:

  1. チャネルおよびアセット・リポジトリを作成します
  2. 次の2つの方法のいずれかを使用して、コンテンツ・モデルを作成します:

チャネルおよびアセット・リポジトリの作成

コンテンツを公開するには、まずOracle Content Managementでチャネルおよびアセット・リポジトリを作成する必要があります。

Oracle Content Managementでチャネルおよびアセット・リポジトリを作成するには:

  1. Oracle Content Management Webインタフェースに管理者としてログインします。

  2. 左側のナビゲーション・メニューで「コンテンツ」を選択し、ページ・ヘッダーの選択リストから「チャネルの公開」を選択します。

    この図は、「コンテンツ」ページ・ヘッダーのドロップダウン・メニューで選択された「公開チャネル」オプションを示しています。

  3. 右上隅にある「Create」をクリックして、新しいチャネルを作成します。このチュートリアルの目的でチャネルにOCEGettingStartedChannelという名前を付け、アクセスを公開したままにします。「保存」をクリックしてチャネルを作成します。

    この図は、「チャネル名」フィールドにOCEGettingStartedChannelがある公開チャネル定義パネルを示しています。

  4. 左側のナビゲーション・メニューで「コンテンツ」を選択し、ページ・ヘッダーの選択リストから「リポジトリ」を選択します。

    この図は、「コンテンツ」ページ・ヘッダーのドロップダウン・メニューで選択された「リポジトリ」オプションを示しています。

  5. 右上隅にある「作成」をクリックして、新しいアセット・リポジトリを作成します。このチュートリアルの目的で、アセット・リポジトリにOCEGettingStartedRepositoryという名前を付けます。

    この図は、リポジトリ名フィールドにOCEGettingStartedRepositoryがあるリポジトリ定義パネルを示しています。

  6. 「公開チャネル」フィールドで、OCEGettingStartedChannelチャネルを選択して、OCEGettingStartedRepositoryリポジトリ内のコンテンツをOCEGettingStartedChannelチャネルに公開できることをOracle Content Managementに示します。終了したら、「Save」をクリックします。

    この図は、「公開チャネル」フィールドにOCEGettingStartedChannelがあるリポジトリ定義パネルを示しています。

コンテンツ・モデルの作成

次のステップでは、コンテンツ・モデルを作成します。次の2つの方法のいずれかを使用できます。

Oracle Content Managementサンプル資産パックのインポート

このチュートリアルに必要なすべてのコンテンツ・タイプおよびアセットを含む事前構成済のOracle Content Managementサンプル・アセット・パックをダウンロードできます。必要に応じて、サンプル・アセット・パックをダウンロードするのではなく、独自のコンテンツ・モデルを作成することもできます。

このチュートリアルで使用しているコンテンツのコピーは、Oracle Content Managementサンプル資産パックからアップロードできます。これにより、コンテンツ・タイプを試し、コンテンツを変更できます。Oracle Content Managementサンプル・アセット・パックをインポートする場合は、アセット・パック・アーカイブOCESamplesAssetPack.zipをダウンロードし、選択したディレクトリに抽出します:

  1. Oracle Content Managementのダウンロード・ページからOracle Content ManagementのSamples Asset Pack (OCESamplesAssetPack.zip)をダウンロードします。ダウンロードしたzipファイルをコンピュータ上の場所に抽出します。抽出後、この場所にはOCEGettingStarted_data.zipというファイルが含まれます。

  2. Oracle Content Management Webインタフェースに管理者としてログインします。

  3. 左側のナビゲーション・メニューで「コンテンツ」を選択し、ページ・ヘッダーの選択リストから「リポジトリ」を選択します。次に、OCEGettingStartedRepositoryを選択し、上部アクション・バーの「コンテンツのインポート」ボタンをクリックします。

    この図は、OCEGettingStartedRepositoryアイテムが選択された「リポジトリ」ページを示しています。

  4. ローカル・コンピュータから「ドキュメント」フォルダにOCEGettingStarted_data.zipをアップロードします。

    この図は、OCEGettingStarted_data.zipファイルのアップロード確認画面を示しています。

  5. アップロードしたら、OCEGettingStarted_data.zipを選択し、「OK」をクリックしてコンテンツをアセット・リポジトリにインポートします。

    この図は、「OK」ボタンが有効になっている、選択したOCEGettingStarted_data.zipファイルを示しています。

  6. コンテンツが正常にインポートされたら、「アセット」ページに移動し、OCEGettingStartedRepositoryリポジトリを開きます。すべての関連イメージおよびコンテンツ項目がアセット・リポジトリに追加されたことがわかります。

    この図は、インポートされたすべてのアセットを含むOCEGettingStartedRepositoryリポジトリを示しています。

  7. 左上の「すべて選択」をクリックし、「公開」をクリックして、前に作成した公開チャネルOCEGettingStartedChannelにインポートされたすべてのアセットを追加します。

    この図は、すべてのアセットが選択され、アクション・バーに「公開」オプションが表示されているOCEGettingStartedRepositoryリポジトリを示しています。

  8. 公開する前に、すべてのアセットを検証する必要があります。最初にOCEGettingStartedChannelを選択したチャネルとして追加し、「検証」ボタンをクリックします。

    この図は、「チャネル」フィールドにOCEGettingStartedChannelチャネルが追加され、検証するすべてのアセットおよび「検証」ボタンが有効になっている「検証結果」ページを示しています。

  9. アセットの検証後、右上隅の「公開」ボタンをクリックして、選択したチャネルにすべてのアセットを公開できます。

    この図は、「チャネル」フィールドにOCEGettingStartedChannelチャネルが追加され、すべてのアセットが検証され、「公開」ボタンが有効になっている「検証結果」ページを示しています。

完了すると、「アセット」ページで、すべてのアセットが公開されていることがわかります。(アセット名の上のアイコンで確認できます。)

この図は、すべてのアセットが公開されている「アセット」ページを示しています。

Oracle Content Managementサンプル資産パックをインポートした後、Androidでのブログの構築を開始できます。

独自のコンテンツ・モデルの作成

Oracle Content Managementサンプル・アセット・パックのインポートのかわりに、独自のコンテンツ・モデルを作成することもできます。

このチュートリアルでは、'OCEGettingStartedHomePage'というコンテンツ・タイプを使用して、ブログのホーム画面を構築しています。このホーム・ページは、画面に含める必要があるブログ・トピックのリストで構成されています。

この図は、Cafe Supremoデモ・サイトのホーム画面を示しています。

コンテンツ・モデルのコンテンツ・タイプを作成するには:

  1. Oracle Content Management Webインタフェースに管理者としてログインします。
  2. 左側のナビゲーション・メニューで「コンテンツ」を選択し、ページ・ヘッダーの選択リストから「アセット・タイプ」を選択します。
  3. 右上隅の「作成」をクリックします。
  4. (デジタル・アセット・タイプではない)コンテンツ・タイプを作成することを選択します。必要なすべてのコンテンツ・タイプについて、これを繰り返します。

この図は、Oracle Content Management Webインタフェースの「アセット・タイプの作成」ダイアログを示しています。

それぞれ独自のフィールド・セットを持つ4つのコンテンツ・タイプを作成します。

最初のコンテンツ・タイプOCEGettingStartedHomePageには、次のフィールドが必要です。

表示名 フィールド・タイプ 必須 マシン名
会社名 単一値テキスト・フィールド X company_name
会社ロゴ 単一値テキスト・フィールド X company_logo
トピック 複数値参照フィールド X トピック
担当者URL 単一値テキスト・フィールド X contact_url
URLについて 単一値テキスト・フィールド X about_url

OCEGettingStartedHomePageコンテンツ・タイプ定義は次のようになります。

この図は、コンテンツ・タイプ'OCEGettingStartedHomePage'の定義を示しています。「会社名」、「会社ロゴ」、「トピック」、「連絡先URL」および「情報URL」のデータ・フィールドが含まれます。

2番目のコンテンツ・タイプOCEGettingStartedTopicには、次のフィールドが必要です。

表示名 フィールド・タイプ 必須 マシン名
サムネイル 単一値イメージ・フィールド X サムネイル

OCEGettingStartedTopicコンテンツ・タイプは次のようになります。

この図は、コンテンツ・タイプ'OCEGettingStartedTopic'の定義を示しています。これには、「サムネイル」データ・フィールドが含まれます。

3番目のコンテンツ・タイプOCEGettingStartedAuthorには、次のフィールドが必要です。

表示名 フィールド・タイプ 必須 マシン名
Avatar 単一値イメージ・フィールド X アバター

OCEGettingStartedAuthorコンテンツ・タイプは次のようになります。

この図は、コンテンツ・タイプ'OCEGettingStartedAuthor'の定義を示しています。このデータ・フィールドには、アバターが含まれます。

4番目と最後のコンテンツ・タイプOCEGettingStartedArticleには、次のフィールドが必要です。

表示名 フィールド・タイプ 必須 マシン名
公開日 単一値日付フィールド X published_name
作成者 単一値参照フィールド X 文書作成
イメージ 単一値イメージ・フィールド X イメージ
イメージ・キャプション 単一値テキスト・フィールド X image_caption
項目コンテンツ 単一値の大きいテキスト・フィールド X article_content
トピック 単一値参照フィールド X topic

OCEGettingStartedArticleコンテンツ・タイプは次のようになります。

この図は、コンテンツ・タイプ'OCEGettingStartedArticlePage'の定義を示しています。これには、「公開日」、「作成者」、「イメージ」、「イメージ・キャプション」、「記事コンテンツ」および「トピック」のデータ・フィールドが含まれます。

コンテンツ・タイプを作成したら、前に作成したリポジトリOCEGettingStartedRepositoryに次のコンテンツ・タイプを追加できます。

  1. Oracle Content Management Webインタフェースに管理者としてログインします。
  2. OCEGettingStartedRepositoryに移動します。
  3. リポジトリを編集し、「アセット・タイプ」で、新しく作成された4つのコンテンツ・タイプすべてを指定します。「保存」ボタンをクリックして変更を保存します。

この図は、OCEGettingStartedRepositoryリポジトリに関連付けられた、新しく作成された4つのコンテンツ・タイプを含むOracle Content Managementの「リポジトリの編集」ページを示しています。

コンテンツ・タイプをリポジトリに追加した後、「アセット」ページでOCEGettingStartedRepositoryリポジトリを開き、すべてのコンテンツ・タイプのコンテンツ項目の作成を開始できます。

このイメージは、Oracle Content Management Webインタフェースの「アセット」ページのコンテンツ・アイテムを示しています。コレクション、チャネル、言語、タイプ、コンテンツ・アイテム選択およびステータスのオプションは左側にあります。

タスク2: Androidでのブログ・アプリケーションの構築

AndroidアプリケーションでOracle Content Managementコンテンツを使用するには、GitHubのオープンソース・リポジトリとして入手可能なKotlinで記述されたAndroidブログ・サンプルを使用できます。

ノート: Androidサンプルの使用はオプションであり、このチュートリアルで使用するとすぐに開始できます。SDKと互換性があるため、JavaまたはKotlinで独自のAndroidアプリケーションを構築することもできます。

Androidでのブログの作成は、次のステップで構成されています。

  1. サンプル・リポジトリおよびAndroid SDKをクローニングし、SDKをローカルに公開します
  2. Androidアプリケーションの構成
  3. Oracle Content Management REST APIを使用したコンテンツのフェッチ

サンプル・リポジトリおよびAndroid SDKのクローニングおよびSDKのローカルでの公開

Androidブログのサンプルは、GitHubのオープンソース・リポジトリとして入手できます。

まだクローニングしていない場合は、まずGitHubからローカル・コンピュータとAndroid SDKにGitHubからサンプルをクローニングする必要があります。

サンプル・コードとSDKが完成したら、サンプル・プロジェクトでAndroid SDKを消費するために、SDKをローカルMavenリポジトリに構築および公開して、サンプル・プロジェクトで使用できるようにする必要があります。Android StudioでAndroid SDKプロジェクトを開き、publishToMavenLocalタスクを実行してSDKを構築し、ローカルMavenリポジトリに公開します。

Android StudioでAndroidサンプルを開きます

Androidアプリケーションと同様に、Androidエミュレータまたはデバイスで構築して実行できるように、Android Studioにインポートする必要があります。サンプル・コードは、ブログ・アプリケーションのデータを取得するために使用されるサーバーおよび公開チャネルですでに事前構成されています。

Oracle Content Management REST APIを使用したコンテンツのフェッチ

コンテンツ配信用のREST APIでは、Oracle Content Managementで公開済アセットにアクセスできます。公開されたアセットには、コンテンツ・アイテムやデジタル・アセットやそのレンディションが含まれます。コンテンツ管理のためのREST APIを利用してコンテンツをフェッチし、ブログ・アプリケーションでレンダリングできるようになりました。

src/.../samples/blog/MainActivity.ktファイルには、REST APIへのコールに使用されるContentDeliveryClientオブジェクトを作成するための関数があります。次の関数は、使用されている値を示すサンプル・アプリケーションの関数の簡易バージョンです。

   fun createDeliveryClient() {

        // preferences for cache
        val cacheEnabled = true

        // the server url and channel token for blog data
        val serverUrl = "https://ocemobile-oce0002.cec.ocp.oraclecloud.com"
        val channelToken = "b9ea60be0abf7255934cd2202fcf1314"


        val settings = ContentSettings()
        if (cacheEnabled) {
            // enable caches, using default settings
            settings.enableCache(appContext.cacheDir)
        }

        // SDK: create client API we'll use to make calls
        deliveryClient =
                ContentSDK.createDeliveryClient(
                        serverUrl,
                        channelToken,
                        settings)
    }

ブログ・サンプル・アプリケーションに移入するデータの取得に使用されるコア・クラスは、viewmodelパッケージの下にあり、Repositoryという接尾辞が付いています。たとえば、ファイルHomePageRepository.ktには、ホーム・ページに表示されるトピックのリストなど、ブログ・アプリケーションのホーム・ページのデータを取得するメソッドが含まれています。

ホーム・ページ・データ

ホーム・ページでは、すべてのデータを取得するために複数のデータ・コールが必要です。

  1. まず、ホーム・ページ・タイプに一致するチャネル内の項目を問い合せます。
  2. 次に、各トピック・アイテムの詳細をフェッチします。

SDKを使用してホーム・ページのデータを取得する関数を次に示します。この関数は使用される値を示し、サンプル・アプリケーション関数では定数を使用します。

  private fun getHomePage(): HomePage {

        // SDK: create search request to get home page
        val getHomePageRequest = SearchAssetsRequest(ContentApi.deliveryClient)
                .type("OCEGettingStartedHomePage")    // search by content type
                .name("HomePage")    // ...and by content name
                .linksNone()        // do not include links in the response
                .fieldsAll()        // do include all fields

        val searchResult = getHomePageRequest.fetchResult()

        // from the search result, only expect a single home page
        val contentItems = searchResult.contentItems

        // handle situation where no data is returned
        if (contentItems.isNullOrEmpty())
            throw ContentException(ContentException.REASON.itemNotFound, "No home page found for type")

        // get first itme in home page data
        val item = contentItems.first()

        // convert list of ids into topic list
        val topicList = item.getReferenceListIds("topics").map { Topic(it) }
        // grab the topic type from one of the references
        topicType = item.getReferenceListField("topics").first().value.type

        return HomePage(
                companyName = item.getTextField("company_name"),
                logoImageUrl = item.getDigitalAssetField("company_logo").getThumbnailUrl(),
                contactUrl = item.getTextField("contact_url"),
                aboutUrl = item.getTextField("about_url"),
                topics = topicList.associateBy { it.id }) // convert list to map

    }

前述のコード内のSearchAssetsRequestオブジェクトはリクエストを作成し、fetchResult()関数は、ホーム・ページ・データを取得するために、次のリクエストと同様の同期RESTコールを行います。

GET content/published/api/v1.1/items?q=(type eq "OCEGettingStartedHomePage" AND name eq "HomePage")?fields=all&links=none&channelToken={channelToken}

トピック・ページ

「記事」画面には、特定のトピックのすべての記事が表示されます。ホーム・ページと同じパターンを使用しますが、今回は、トピックIDが選択されているトピックを参照するOCEGettingStartedArticleタイプのコンテンツ・アイテムを検索します。また、SDKを使用して非同期メソッド・コールを行う方法も示します。詳細は、ファイルArticlesRepository.ktを参照してください。ただし、使用されるパターンと値を示すコア・メソッドを次に示します。

// SDK: create search request to get all the articles
// sort by published_date field in descending order
   
val searchRequest = SearchAssetsRequest(ContentApi.deliveryClient)
        .type("OCEGettingStartedArticle")                // get "article" type
        .fieldEquals("topic", topicId)  // match topic id (e.g. drinks, recipes)
        .sortByField("published_date")  // sort by published date (optional)
        .sortOrderDescending(true)
        .linksNone()            // no need for links (optional)

// SDK: make request to get articles using async callback method
   
searchRequest.fetchAsync {response ->
     // successful SDK call?
     if (response.isSuccess) {
         // process the list and display in ui
      } else {
         // handle error case
      }
  }   
  

記事ページ

個々の記事画面には単一の記事が表示されますが、画面には別のコンテンツ・タイプである作成者のコンテンツが含まれています。1つのコンテンツ・アイテムとそれによって参照されるコンテンツ・アイテムをフェッチするには、次に示すように、リクエスト・オブジェクトの作成時にexpand()メソッドを使用してfields.authorを取得します。詳細はAritcleDetailRepository.ktにありますが、コア・コード・パターンは次のとおりです:

// make a call to get the article, expanding the "author" field

val request  = GetContentItemRequest(ContentApi.deliveryClient, articleId)
       .expand("author")     // only expand the author field
       .linksNone()

// get the article detail as an asynchronous call

request.fetchAsync {response ->
     // successful SDK call?
     if (response.isSuccess) {
         // process the list and display in ui
      } else {
         // handle error case
      }
  }   

データ問合せができたので、AndroidアプリケーションUIでレスポンスをレンダリングできます。

Android ViewModelクラス

ブログ・アプリケーションは、標準のViewModel Androidアプリケーションとして構造化されています。ViewModelがAndroidで使用され、Kotlinで実装されている方法を説明するオンライン・リソースが多数あります。

コンポーネント構成

アプリケーションの画面ごとに3つのコア・クラスがあります。

たとえば、記事リスト画面のクラスは次のとおりです。

タスク3: アプリケーションのデプロイメントの準備

Androidブログ・アプリケーションを構築したので、Android Studioのモバイル・エミュレータまたはデバイスでテストする必要があります。これにより、問題をデバッグし、アプリケーションが稼働する前にプレビューできます。

まとめ

このチュートリアルでは、Android用のブログ・アプリケーションを作成しました。これは、GitHubにあります。このサイトでは、Oracle Content ManagementをヘッドレスCMSとして使用しています。ブログ・サイト・チュートリアル用に公開されたコンテンツのチャネルを使用してOracle Content Managementを設定および構成した後、Androidサイトをインストールして実行し、必要なコンテンツをフェッチしてサイトを構築しました。

Oracle Content Managementの重要な概念については、ドキュメンテーションを参照してください。

このようなサンプルは、Oracle Content Managementのサンプル・ページのOracle Help Centerにあります。