Safe Argsのセットアップ&使い方(Kotlin)

## はじめに

Safe Argsのセットアップ方法と使い方を紹介します。

## 「Safe Args」とは？

Navigationで型安全に値を扱うGradleプラグインです。
型安全が保証されるため、ナビゲーションやデータの受け渡しでは __Safe Argsを使うことが推奨されています__ 。

## 環境

- OS：macOS Big Sur 11.5.2
- Android Studio：Arctic Fox | 2020.3.1
- Kotlin：1.5.21
- Gradle：7.0.2
- Gradle plugin：7.0.0
- Navigation：2.3.5

## セットアップ

### Navigationのセットアップ

Safe ArgsはNavigationのコンポーネントのため、Navigationのセットアップが必要です。
以下の記事を参考にセットアップしてください。
https://qiita.com/uhooi/items/ce3264fa2609c141c454

### Safe Argsのインストール

ルート直下の「build.gradle」にプラグインを追加します。

```diff_groovy:/build.gradle
buildscript {
    ext {
        nav_version = '2.3.5'
    }
    repositories {
        google()
    }
    dependencies {
+       classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
    }
}
```

appフォルダ配下の「build.gradle」にプラグインの適用を追加します。

```diff_groovy:/app/build.gradle
+ apply plugin: "androidx.navigation.safeargs.kotlin"
```

これでSafe Argsのセットアップは完了です。

## 使い方

### 引数なしのナビゲーション処理の実装

Safe Argsプラグインを使うと、アクションの元のデスティネーションごとに `○○Directions` クラスが自動生成されます。

実装方法は以下の記事をご参照ください。
https://qiita.com/uhooi/items/ce3264fa2609c141c454#ナビゲーション処理の実装

### 引数ありのナビゲーション処理の実装

デスティネーション間で値の受け渡しをする場合の実装です。

値を受け取りたいデスティネーションに `argument` で引数を定義します。

以下は `MainFragment` から `WebViewFragment` へ遷移するナビゲーショングラフで、 `WebViewFragment` に `urlString` という `String` の引数を追加する例です。

```diff_xml:nav_graph.xml
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/nav_graph"
    app:startDestination="@id/main_fragment">

    <fragment
        android:id="@+id/main_fragment"    
        android:name="com.theuhooi.uhooipicbook.ui.main.MainFragment"
        android:label=""
        tools:layout="@layout/main_fragment">
        <action
            android:id="@+id/action_main_to_web_view"
            app:destination="@id/web_view_fragment" />
    </fragment>

    <fragment
        android:id="@+id/web_view_fragment"
        android:name="com.theuhooi.uhooipicbook.ui.webview.WebViewFragment"
        android:label=""
        tools:layout="@layout/web_view_fragment">
+       <argument
+           android:name="urlString"
+           app:argType="string" />
    </fragment>

</navigation>
```

`argType` に指定できる、つまり引数に使える型は公式ドキュメントをご参照ください。
https://developer.android.com/guide/navigation/navigation-pass-data?hl=ja&authuser=1#supported_argument_types

`data class` を渡したい場合、 `Parcelable` を継承する必要があります。
以下の記事を参考に `Parcelable` を継承したクラスを実装してください。
https://qiita.com/uhooi/items/81244ca207080ff70335

ナビゲーション処理でアクションに引数を渡すことで、対象のデスティネーションに引数を渡せます。

```kotlin:MainFragment.kt
val action = MainFragmentDirections.actionMainToWebView("https://example.com")
findNavController().navigate(action)
```

渡された引数は、自動生成された `○○Args` クラスから取得できます。

```kotlin:WebViewFragment.kt
val args: WebViewFragmentArgs by navArgs()
binding.webview.loadUrl(args.urlString)
```

## おわりに

Safe Argsを使うことで、型安全にナビゲーション処理を実装できました！

## 参考リンク

- [デスティネーション間でデータを渡す  |  Android デベロッパー  |  Android Developers](https://developer.android.com/guide/navigation/navigation-pass-data?hl=ja&authuser=1)