こんにちは。
AMBLのクラウドネイティブ第1事業部 Webアプリケーション開発部のスガです。
好きな色は青(藍色)です。
今回の記事では、Androidアプリケーション開発において、AWS Amplifyを活用することで、開発効率を大幅に向上させる方法について解説します。
Amplifyは、モバイル開発者向けに設計された一連のツールおよびライブラリであり、認証、データストア、ストレージ、そしてプッシュ通知などの機能を、AWSの豊富なサービスと連携しながら、シームレスに実装することができます。
これにより、開発者はバックエンドの複雑なインフラストラクチャ構築から解放され、アプリケーションのフロントエンド開発に集中できるようになります。
今回は、そんなAmplifyを用いてログイン機能を有するToDo管理アプリを作成する手順を解説します。
AWS Amplifyの公式ドキュメントに沿って作業を進めつつ、個人的に分かりにくかった部分やエラーが出た部分などを詳しく説明していきます。
実際にAmplifyに触れて、導入方法やAWSとの連携のしやすさを体感していただけたら幸いです。
この記事は、ネイティブ開発に興味がある方、AWSに興味がある方、AWSアカウントを所持している方におすすめです。
前提条件:前提条件:
- ●AWS CLIがインストール済みであること
- ●AWSアカウントを所有していること
- ●GitHubアカウントを所有していること
- ●Android Studioがインストールされていること
- ●npmがインストール済みであること
開発環境はこちらです:
- ●OS:Windows 11
- ●IDE:Android Studio Koala | 2024.1.1
- ●AWS Amplify:Gen2
- ●開発言語:Java
- ●FW:Kotlin
AWS Amplifyとは
AWS Amplifyは、フロントエンド開発者がクラウドを活用したフルスタックアプリケーションを簡単に開発・ デプロイできるようにするためのツールとサービスのセットになります。
Amplifyは、iOS、Android、 Web、 React Nativeなどの一般的なフレームワークと統合されており、自分の好きなフレームワークを利用して開発を行うことができます。
主な機能はこちら:
- ●Amplify CLI: バックエンドを構成し、クラウドリソースをプロビジョニングするためのコマンドラインツールです。
- ●Amplify Libraries: 認証、ストレージ、データなどの一般的なユースケースを扱うためのクライアントライブラリです。
- ●Amplify UI Components: すぐに使用できるUIコンポーネントで、一般的なタスク( サインアップ、 サインインなど) を処理します。
- ●Amplify Hosting: フロントエンドとバックエンドをデプロイするためのフルマネージドサービスです。
※今回は上記全てを紹介することはできないので、気になる機能がある方はAWS Amplifyのドキュメントをご確認ください。
Amplifyを利用するメリットとしては、開発の高速化・セキュアなリソースアクセスが可能・導入しやすいといった点が挙げられます。
リポジトリを作成し、スターターを展開
1. GitHubにリポジトリを作成する
公式で用意してくれているテンプレートを使用していきます。
中身は、認証機能とデータ機能を備えたTo-doアプリになります。まずは、こちらリンクからリポジトリを作成します。
設定内容はこのままで、「Create repository」をクリックします。
2. AWSにデプロイする
こちらのリンクからAWSのコンソールにアクセスします。
※ご自身のアカウントでログインしてください。
ログインするとAmplifyの画面が開きますので、「GitHub」を選択します。
GitHubを選択すると、連携確認モーダルが表示されます。
全てのリポジトリをAWSに連携するか、一部のリポジトリのみを連携するかを選択できますので、お好きな方を選択してください。
手順①で作成したリポジトリを選択し、「次へ」を押下します。
アプリケーションの設定画面が表示されますが、特に項目を変更することなくそのまま「次へ」を押下します。
最後に、確認画面が表示されるので内容を確認して、問題なければ「保存してデプロイ」を押下します。
Amplifyプロジェクトを作成する
ここからは実際にAndroid StudioでAmplifyを使った機能を動かしてみましょう。
1. 新規プロジェクトの作成
Amplify用のプロジェクトを作成します。
「File」> 「新規」> 「新規プロジェクト」を選択します。
「Empty Activity」を選択し、任意のプロジェクト名を設定します。
Minimum SDKは、API 24:android7.0 とします。
2. amplify_outputs.jsonのダウンロード
先ほどのビルド完了画面で、「main」ブランチを選択します。
「デプロイされたバックエンドリソース」タブを選択し、amplify_outputs.jsonをダウンロードします。
ダウンロードしたamplify_outputs.jsonをapp/src/main/res/rawに配置します。
※Amplify側のバグで、amplify_outputs.jsonの値が一部無効な形で指定されている可能性があります。”mfa_configuration”の値が、「OFF」となっていた場合、こちらを「NONE」に書き換えてください。
3. 依存関係のダウンロード
Amplifyで、最新のJava API を使用する必要があるので、
app/build.gradle.ktsを以下の形に修正します。
android {
compileOptions {
// 追加
isCoreLibraryDesugaringEnabled = true
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
}
dependencies {
// 追加
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.3")
}
修正が完了したら「Sync Now」を押下して、変更内容を適用します。
4. ログインUIを実装する
今回デプロイしたスターターテンプレートには、既に認証システムを構築してくれています。
app/build.gradle.ktsに再度依存関係を追加しましょう。
dependencies {
// 追加
implementation("com.amplifyframework.ui:authenticator:1.2.0")
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.3")
}
しつこいようですが、編集後は「Sync Now」をお忘れなく。
app/build.gradle.ktsの編集が終わったら、MyAmplifyAppクラスを作成します。
MainActivity.ktと同階層に、「New」> 「Kotlinファイル/クラス」で、ファイル名をMyAmplifyAppにします。
ファイルが作成できたら、以下の形に書き換えます。
package com.example.myamplifyapp;
import android.app.Application
import android.util.Log
import com.amplifyframework.AmplifyException
import com.amplifyframework.auth.cognito.AWSCognitoAuthPlugin
import com.amplifyframework.core.Amplify
import com.amplifyframework.core.configuration.AmplifyOutputs
class MyAmplifyApp: Application() {
override fun onCreate() {
super.onCreate()
try {
Amplify.addPlugin(AWSCognitoAuthPlugin())
Amplify.configure(AmplifyOutputs(R.raw.amplify_outputs), applicationContext)
Log.i("MyAmplifyApp", "Initialized Amplify")
} catch (error: AmplifyException) {
Log.e("MyAmplifyApp", "Could not initialize Amplify", error)
}
}
}
次に、AndroidManifest.xmlで先ほど作成した、MyAmplifyAppを呼び出します。
<application
android:name=".MyAmplifyApp"
...
</application>
MainActivity.ktで、スターターのコンポーネントを使用するように処理を修正します。
import android.os.Bundle
..
import com.amplifyframework.ui.authenticator.ui.Authenticator
import androidx.compose.foundation.layout.Column
import androidx.compose.material3.Button
import com.amplifyframework.core.Amplify
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyAmplifyAppTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
)
{
Authenticator { state ->
Column {
Text(
text = "Hello ${state.user.username}!",
)
Button(onClick = {
Amplify.Auth.signOut { }
}) {
Text(text = "Sign Out")
}
}
}
}
}
}
}
}
※赤文字で警告が出る場合、Alt + Enterでオブジェクトのインポートを行ってください。
5. 動作確認
ここまで完了したら、エミュレータを起動してみましょう。
ログイン画面が表示されるとおもいますので、「Create Account」から新規アカウントを登録します。
登録後、AWSマネジメントコンソールでCognitoを確認すると、ユーザーが追加されていることが確認できるはずです。
ToDoリスト作成
次に、ToDoリストの作成を進めていきましょう。
Amplify側でToDoリストの枠組みは用意してくれています。
Android Studioのターミナルを開き、以下のコマンドを実行してください。
npx @aws-amplify/backend-cli generate graphql-client-code –format modelgen –model-target java –out app/src/main/java –app-id <your-amplify-app-id> –branch main
※<your-amplify-app-id>はAWS コンソールのアプリIDに置き換えてください。
※ こちらのコマンド実行時に、AWSのクレデンシャルやリージョンについてのエラーが出た方は、以下のコマンドを実行してみてください。
set AWS_ACCESS_KEY_ID=your_access_key_id
set AWS_SECRET_ACCESS_KEY=your_secret_access_key
set AWS_SESSION_TOKEN=your_session_token
クレデンシャルやリージョンの情報が更新され、コマンドが通る可能性があります。
依存関係を追加するため、build.gradle.ktsを修正します。
dependencies {
// 追加
implementation("com.amplifyframework:aws-api:2.19.1")
}
続いてMyAmplifyAppクラスを開き、Amplify.configureを呼び出している部分の前に以下の行を追加します。
class MyAmplifyApp: Application() {
override fun onCreate() {
super.onCreate()
try {
// ↓追加
Amplify.addPlugin(AWSApiPlugin())
Amplify.addPlugin(AWSCognitoAuthPlugin())
Amplify.configure(AmplifyOutputs(R.raw.amplify_outputs), applicationContext)
Log.i(“MyAmplifyApp”, “Initialized Amplify”)
} catch (error: AmplifyException) {
Log.e(“MyAmplifyApp”, “Could not initialize Amplify”, error)
}
}
}
MainActivityにToDoリストを追加するボタンを追加します。
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyAmplifyAppTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
Authenticator { state ->
Column {
Text(
text = "Hello ${state.user.username}!",
)
// ↓ここを追加
TodoList()
Button(onClick = {
val todo = Todo.builder()
.content("My first todo")
.build()
Amplify.API.mutate(
ModelMutation.create(todo),
{ Log.i("MyAmplifyApp", "Added Todo with id: ${it.data.id}")},
{ Log.e("MyAmplifyApp", "Create failed", it)},
)
}) {
Text(text = "Create Todo")
}
// ここまで
Button(onClick = {
Amplify.Auth.signOut { }
}) {
Text(text = "Sign Out")
}
}
}
}
}
}
}
}
MainActivityに、ToDoリストを表示するコンポーザブルを追加します。
@Composable
fun TodoList() {
var todoList by remember { mutableStateOf(emptyList<Todo>()) }
LaunchedEffect(Unit) {
// 全てのToDoをリストアップするAPIをリクエスト
Amplify.API.query(
ModelQuery.list(Todo::class.java),
{ todoList = it.data.items.toList() },
{ Log.e("MyAmplifyApp", "Failed to query.", it) }
)
}
LazyColumn {
items(todoList) { todo ->
Row {
// ここでレンダリング
Text(text = todo.content)
}
}
}
}
ここまで完了したら、再度エミュレータを起動してログインしてみましょう。
すると、「Create Todo」ボタンと「Sign Out」ボタンが表示されます。
「Create Todo」ボタンを押して、アプリを再起動すると、ToDo項目が追加されます。
現状、ToDoを追加してもすぐに画面に反映されないため、
リアルタイム更新機能を追加しましょう。
リアルタイム更新には、Amplify Dataのサブスクリプション機能を使用します。MainActivityにサブスクリプション機能を追加しましょう。
@Composable
fun TodoList() {
var todoList by remember { mutableStateOf(emptyList<Todo>()) }
LaunchedEffect(Unit) {
// API request to list all Todos
Amplify.API.query(
ModelQuery.list(Todo::class.java),
{ todoList = it.data.items.toList() },
{ Log.e("MyAmplifyApp", "Failed to query.", it) }
)
// ↓ここを追加
Amplify.API.subscribe(
ModelSubscription.onCreate(Todo::class.java),
{ Log.i("ApiQuickStart", "Subscription established") },
{
Log.i("ApiQuickStart", "Todo create subscription received: ${it.data}")
todoList = todoList + it.data
},
{ Log.e("ApiQuickStart", "Subscription failed", it) },
{ Log.i("ApiQuickStart", "Subscription completed") }
)
// ここまで
}
LazyColumn {
items(todoList) { todo ->
Row {
// Render your activity item here
Text(text = todo.content)
}
}
}
}
実装後、エミュレータを起動して「Create Todo」ボタンを押すと、ToDoがリアルタイムで追加されることを確認できます。
こちらで、ToDoリストの作成が完了しました。
お疲れ様です。
まとめ
今回は、AWS Amplifyを使って、簡単なToDoリストアプリを作成してみました。
Amplifyは、認証やデータストアなど、モバイルアプリ開発に必要な機能を幅広くサポートしています。
今回は基礎的な部分に触れましたが、CI/CDやGraphQLなど、さらに深掘りできる機能もたくさんあります。
Amplifyの公式ドキュメントで、より詳細な情報を確認してみてください。