NCMB Kotlin SDKを使って日報アプリを作る（その3 データの取得と一覧表示）

NCMBでは公式SDKとしてSwift/Objective-C/Kotlin/Java/Unity/JavaScript SDKを用意しています。また、それ以外にもコミュニティSDKとして、非公式ながらFlutter/React Native/Google Apps Script/C#/Ruby/Python/PHPなど幅広い言語向けにSDKが開発されています。

今回は公式SDKの一つ、Kotlin SDKを使って日報アプリを作ってみます。[前回はログインとデータの保存について解説しました](https://qiita.com/goofmint/items/ba8d8176b518af5273b1)ので、今回は保存したデータの取得と一覧表示について解説します。

## 完成版のコード

作成したデモアプリのコードは[NCMBMania/Kotlin_DailyReport](https://github.com/NCMBMania/Kotlin_DailyReport)にアップロードしてあります。

## 日報データの取得

日報データの表示は `ListScreen` にて行います。日報データは `ary` に入る形になります。入ったデータは `LazyColumn` を使って一覧表示します。

```kotlin
@Composable
fun ListScreen(navController: NavController) {
    var ary = remember { mutableStateOf<List<NCMBObject>>(emptyList()) }
		// データの取得（後述）
		// 画面構築
    Scaffold(
        topBar = {
                TopAppBar(
                    title = {
                        Text("日報一覧")
                    },
                    actions = {
                        IconButton(
                            onClick = {
                                navController.navigate("form")
                            }
                        ){
                            Icon(Icons.Filled.Add, contentDescription = "日報の作成")
                        }
                    }
                )
        },
        content = {
            Column {
                LazyColumn(
                ) {
                    items(ary.value) { obj ->
                        ListRow(obj, navController = navController)
                    }
                }
            }
        }
    )
}
```

![Screenshot_20220414_172126.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/57b582a7-de62-99d1-d2ba-bcc821374606.png)


### データの取得

データを取得する際には NCMBQuery を使います。今回は条件を指定していませんが、文字列の検索や以上以下などの条件が使えます。検索結果はAny型なので、 `List<NCMBObject>` にキャストします。

```kotlin
val query = NCMBQuery.forObject("DailyReport")
query.findInBackground(NCMBCallback { e, results ->
		if (e == null) {
				ary.value = results as List<NCMBObject>
		}
})
```

### 表示

データの表示を行っているのは `ListRow` になります。ここでは一覧画面から受け取ったNCMBObjectを表示しています。文字列の場合は `getString(key)` で取得できますが、Nullableなので注意してください。

```kotlin
@Composable
fun ListRow(obj: NCMBObject, navController: NavController) {
		// 詳細画面への遷移
    val moveDetail = {
				// 後述
    }
		// 画面構築
    Row(
        verticalAlignment = Alignment.CenterVertically,
        modifier = Modifier
            .fillMaxWidth()
            .padding(10.dp)
            .background(Color.White, RoundedCornerShape(5.dp))
            .clickable {
                moveDetail()
            }
    ) {
        Text(obj.getString("title")!!, fontSize = 25.sp)
    }
}
```

#### 詳細画面への遷移

詳細画面に遷移する際には、対象データを文字列として渡す必要があります。そこでJSONObjectを使ってデータを文字列に変換しています。

```kotlin
val moveDetail = {
		val json = JSONObject()
		obj.keys.forEach {key ->
				json.put(key, obj.get(key)!!)
		}
		navController.navigate("detail/obj=${json.toString()}")
}
```

このデータをNCMBObjectとして復元する処理については[KotlinのNavigation コンポーネントを使ってNCMBObjectを別画面に渡す - Qiita](https://qiita.com/goofmint/items/a0cd211fbcaafb375352)のstrToNCMBObjectを参照してください。

## 日報詳細表示について

日報の詳細表示は、ナビゲーションで復元したNCMBObjectを受け取ります。

```kotlin
composable(
		route = "detail/obj={obj}",
		arguments = listOf(navArgument("obj") { type = NavType.StringType })
) { backStackEntry ->
		val obj = strToNCMBObject(backStackEntry.arguments!!.getString("obj")!!, "DailyReport")
		DetailScreen(navController, obj)
}
```

DetailScreenは単純にデータを表示しているだけです。こちらでもまた、 `getString` でテキストを表示していますが、Nullableなので注意してください。編集画面に移動する際には、またデータを文字列に変換して渡しています。

```kotlin
@Composable
fun DetailScreen(navController: NavController, obj: NCMBObject) {
    Scaffold(
        topBar = {
            TopAppBar(
                title = {
                    Text("日報")
                },
                actions = {
                    IconButton(
                        onClick = {
                            val json = JSONObject()
                            obj.keys.forEach {key ->
                                json.put(key, obj.get(key)!!)
                            }
                            navController.navigate("edit/obj=${json.toString()}")
                        }
                    ){
                        Icon(Icons.Filled.Edit, contentDescription = "Edit")
                    }
                }
            )
        },
        content = {
            Column {
                Text(text = obj.getString("title")!!,
                    fontSize = 35.sp,
                    modifier = Modifier.padding(5.dp)
                )
                Text(text = obj.getString("body")!!,
                    fontSize = 30.sp,
                    modifier = Modifier.padding(5.dp)
                )
            }
        }
    )
}
```

![Screenshot_20220414_172234.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/f221b9f3-3917-9280-bb65-125d608fa296.png)


## まとめ

今回の日報アプリでは認証、データ保存、データ取得を実装しました。いずれもアプリ開発ではよく使う機能なので、ぜひ使い方を覚えてあなたのアプリ開発に役立ててください。

[mBaaSでサーバー開発不要！ | ニフクラ mobile backend](https://mbaas.nifcloud.com/)