# 設定値配信での未実施を含むA/Bテストの実現方法

効果測定が可能なかたちで、設定値配信で未実施を含むA/Bテストを実現する初期実装の方法について記載しています。

***

下記実装手順は未実施を含むA/Bテストの実現に関連する内容のみ記載しています。設定値配信の利用における初期実装については、下記Deveroper Portalを併せてご参照ください。

* [iOS](https://app.developers.karte.io/ios-sdk/variables-ios-sdk)
* [Android](https://app.developers.karte.io/android-sdk/variables-android-sdk)

なお、管理画面側の設定含む、実現方法の全体像についてはサポートサイトを併せてご参照ください。

### 実装手順

1. トップバナーを表示する画面の描画処理（iOSの場合：`viewDidLoad()`、Androidの場合：`onCreate()`）より前に、管理画面側で設定した設定値を取得します

{% tabs %}
{% tab title="Swift" %}
{% code overflow="wrap" %}

```swift
// KARTEから設定値を取得する処理
Variables.fetch()
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code overflow="wrap" %}

```kotlin
// KARTEから設定値を取得する処理
Variables.fetch()
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Swift" %}
{% code overflow="wrap" %}

```swift
// KARTEから設定値を取得する処理
// fetch()の完了をハンドリングしたい場合
Variables.fetch { isSuccessful in
		if isSuccessful {
		// KARTEから設定値を取得できた場合の処理
				...
		} else {
		// KARTEから接客を取得できなかった場合の処理
				...
		}
}
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code overflow="wrap" %}

```kotlin
// KARTEから設定値を取得する処理
// fetch()の完了をハンドリングしたい場合
Variables.fetch { isSuccessful ->
		if (isSuccessful) {
		// KARTEから設定値を取得できた場合の処理
				...
		} else {
		// KARTEから接客を取得できなかった場合の処理
				...
		}
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

2. トップバナーを表示する画面で、取得した設定値によって、バナーの表示制御やA/Bテストで使用する計測イベントの送信を行います。

   サポートサイトには、以下の変数を使用した管理画面の設定例を記載しています。

   * アクションが配信されたかをアプリ側で判定するステータス
     * 変数名： `top_banner_variables_status`
     * 値（データ型）：`VARIABLES_FOUND` （文字列） “top\_banner\_variables\_status” の変数名を使用
   * 配信されたアクションが「接客用」か「未実施用」かをアプリ側で判定するフラグ
     * 変数名： `top_banner_flag`
     * 値（データ型）
       * 「接客用」のアクション：`true`（true/false）
       * 「未実施用」のアクション： `false` （true/false）
   * 設定値配信の接客から渡す値
     * 変数名： `top_banner_image`（URL）
     * KARTEの設定値配信の接客から、画像のURLのみを渡す場合のユースケース

   **なお、A/Bテストを実施したい接客が複数ある場合は、接客ごとにユニークな変数名を指定してください。**

{% tabs %}
{% tab title="Swift" %}
{% code overflow="wrap" %}

```swift
...
// デフォルトで画面上にトップバナー表示用のViewが表示されている想定
@IBOutlet weak var topBannerView: UIView!
...

override func viewDidLoad() {
    super.viewDidLoad()
    ...
    setupTopBanner()
    ...
}

private func setupTopBanner() {
    // アクションが配信されたか判定する変数を取得する処理
    // 上記の設定例の場合は、「top_banner_variables_status」が参照する変数名
    let statusVariable = Variables.variable(forKey: "{{参照する変数名}}")
    let defaultStatus = "VARIABLES_NOT_FOUND"
    let status = statusVariable.string(default: defaultStatus)

    // 配信されたアクションが「接客用」か「未実施用」か判定する変数を取得する処理
    // 上記の設定例の場合は、「top_banner_flag」が参照する変数名
    let flagVariable = Variables.variable(forKey: "{{参照する変数名}}")
    let flag = flagVariable.bool(default: false)

    if status == defaultStatus {
        // 該当の接客サービスが配信されなかった場合
        topBannerView.isHidden = true
    } else {
        if flag {
            // 該当の接客サービスが配信され、配信されたアクションが「接客用」の場合

            // アプリで表示するトップバナー画像の変数を取得する処理
            // 上記の設定例の場合は、「top_banner_image」が参照する変数名
            let imageVariable = Variables.variable(forKey: "{{参照する変数名}}")
            let image = imageVariable.string(default: "{{任意のデフォルト値}}")

            ...
            // imageを使用してtopBannerViewに画像を表示する任意の処理
            ...

            // 「接客用」のアクションのインプレッションを計測するイベント送信を行う処理
            Tracker.trackOpen(variables: [flagVariable])

        } else {
            // 該当の接客サービスが配信され、配信されたアクションが「未実施用」の場合
            topBannerView.isHidden = true

            // 「未実施用」のアクションのインプレッションを計測するイベント送信を行う処理
            Tracker.trackOpen(variables: [flagVariable])
        }
    }
}
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code overflow="wrap" %}

```kotlin
...
// デフォルトで画面上にトップバナー表示用のViewが表示・バインディングされている想定
private lateinit var binding: ActivityMainBinding
...

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    ...
    binding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(binding.root)
    ...
    setupTopBanner()
    ...
}

private fun setupTopBanner() {
    // アクションが配信されたか判定する変数を取得する処理
    // 上記の設定例の場合は、「top_banner_variables_status」が参照する変数名
    val statusVariable = Variables.get("{{参照する変数名}}")
    val defaultStatus = "VARIABLES_NOT_FOUND"
    val status = statusVariable.string(defaultStatus)

    // 配信されたアクションが「接客用」か「未実施用」か判定する変数を取得する処理
    // 上記の設定例の場合は、「top_banner_flag」が参照する変数名
    val flagVariable = Variables.get("{{参照する変数名}}")
    val flag = flagVariable.boolean(false)

    if (status == defaultStatus) {
        // 該当の接客サービスが配信されなかった場合
        binding.topBannerView.visibility = View.GONE
    } else {
        if (flag) {
            // 該当の接客サービスが配信され、配信されたアクションが「接客用」の場合
            // アプリで表示するトップバナー画像の変数を取得する処理
            // 上記の設定例の場合は、「top_banner_image」が参照する変数名
            val imageVariable = Variables.get("{{参照する変数名}}")
            val image = imageVariable.string("{{任意のデフォルト値}}")

            ...
            // imageを使用してtopBannerViewに画像を表示する任意の処理
            ...

            // 「接客用」のアクションのインプレッションを計測するイベント送信を行う処
            Variables.trackOpen(listOf(flagVariable))

        } else {
            // 該当の接客サービスが配信され、配信されたアクションが「未実施用」の場合
            binding.topBannerView.visibility = View.GONE
            // 「未実施用」のアクションのインプレッションを計測するイベント送信を行う処理
            Variables.trackOpen(listOf(flagVariable))
        }
    }
}
```

{% endcode %}
{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://app.developers.karte.io/karte-for-app-best-practices/abtest-for-variables-module.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
