Android 프로젝트를 Appwrite와 연동하기 위해 진행한 Quick Start 작업을 진행했지만 시행착오들을 겪었다. 첫 시도라 중간중간 기억해둬야 하겠다 싶은 개념이나 작업들이 있어, 이를 기록해두기 위해서 이 글을 작성한다.
---
### 1. Android 프로젝트 생성
1. Android Studio에서 **New Project** 클릭
2. **Empty Activity** 템플릿 선택 후 **Next**
3. 앱 이름(App name)과 패키지 이름(Package name) 입력. 패키지 이름이 Appwrite 프로젝트의 Android 플랫폼과 연동이 되기 때문에 중요하다.
* 예: `cohttp://m.example.myapp`
4. **Finish** 클릭하여 프로젝트 생성
---
### 2. Appwrite 프로젝트 및 Android 플랫폼 등록
1. 브라우저에서 Appwrite Console([https://cloud.appwrite.io](https://cloud.appwrite.io)) 접속 후 로그인
2. **Create Project** 또는 기존 프로젝트 선택
3. 프로젝트 대시보드에서 **Settings > Platforms** 이동
4. **Add Platform → Android** 클릭
5. App 이름과 **패키지 이름** 입력
* 패키지 이름은 Android Studio에서 설정한 `cohttp://m.example.myapp`과 동일하게 입력
6. **Save** 클릭
---
### 3. Appwrite SDK 추가
1. `app/build.gradle.kts` (또는 `app/build.gradle`) 파일 열기
2. `dependencies` 블록에 다음 한 줄 추가:
```kotlin
implementation("io.appwrite:sdk-for-android:7.0.1")
```
3. **Sync Now** 클릭하여 Gradle Sync 실행
---
### 4. Appwrite 클라이언트 싱글톤 구현 및 구성 요소 설명
이 단계에서는 Appwrite SDK를 앱 전역에서 편리하게 사용하기 위해 **싱글톤 패턴**을 적용한다. `Appwrite.kt` 객체 하나에 주요 구성 요소를 모아 두어, 어디서든 `Appwrite.init(context)` 한 번으로 초기화 후 바로 호출할 수 있다.
#### Appwrite SDK 주요 구성 요소
* **Client**: Appwrite 서버와 통신하는 HTTP 클라이언트이다.
* `setEndpoint()`, `setProject()` 메서드를 이용해 요청할 기본 URL과 프로젝트 ID를 설정한다.
* **ID**: 고유 식별자(ID)를 생성하는 유틸리티 클래스이다.
* `ID.unique()` 등을 통해 사용자(User), 문서(Document) 등 리소스에 사용할 ID를 자동 생성한다.
* **Account**: 사용자 인증 및 세션 관리를 담당하는 서비스 클래스이다.
* 회원가입, 로그인, 로그아웃, 사용자 정보 조회 등의 메서드를 제공한다.
#### Region 및 Project ID 확인 방법
* **Region**: Appwrite 인스턴스가 호스팅된 위치를 의미한다. 프로젝트를 생성할 때 선택할 수 있도록 메뉴가 나타나는데, 아직은 선택권이 없는 것 같다. Frankfurt만 사용할 수 있었다.
* Appwrite 콘솔에 로그인 후, 프로젝트 대시보드로 진입하면 프로젝트 이름의 우측 편에 Frankfurt 라는 Region을 확인할 수 있고, 클립보드에 복사도 가능하도록 되어 있다.
* **Project ID**: Appwrite 콘솔에서 프로젝트를 식별하는 고유 ID이다.
1. Region을 확인할 때와 마찬가지로 대시 보드에서 프로젝트 이름의 우측에 16진수 형태의 수로 이뤄진 값이 보인다. Region과 마찬가지로 클립보드에 복사도 가능하다.
#### 싱글톤 구현 및 주요 메서드
1. **파일 생성**: `Appwrite.kt`를 프로젝트 루트 패키지(예: `cohttp://m.example.myapp`)에 추가. 공식 문서의 quick start 예제에 간단한 설명을 추가해뒀다.
2. **코드 예시**:
```kotlin
package cohttp://m.example.myapp
import android.content.Context
import io.appwrite.Client
import io.appwrite.ID
import io.appwrite.services.Account
object Appwrite {
// Appwrite 서버와 통신할 클라이언트 객체
lateinit var client: Client
// 인증, 세션 관리 등을 처리하는 Account 서비스 객체
lateinit var account: Account
/**
* 앱 시작 시 호출하여 Client와 Account를 초기화한다.
* - context: 애플리케이션 Context
* - setEndpoint: Appwrite 엔드포인트 URL (지역 및 버전 포함)
* - setProject: 프로젝트 ID 설정
*/
fun init(context: Context) {
client = Client(context)
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1")
.setProject("[PROJECT_ID]")
account = Account(client)
}
/**
* 이메일/비밀번호로 사용자 회원가입을 수행한다.
* - userId: 고유 ID 생성 (ID 유틸 사용)
* - email: 사용자 이메일
* - password: 사용자 패스워드
* 반환: 생성된 User 객체
*/
suspend fun onRegister(email: String, password: String) =
account.create(
userId = ID.unique(),
email = email,
password = password
)
/**
* 이메일/비밀번호로 로그인 시 세션을 생성한다.
* - email: 사용자 이메일
* - password: 사용자 패스워드
* 반환: 생성된 Session 객체
*/
suspend fun onLogin(email: String, password: String) =
account.createEmailPasswordSession(email, password)
/**
* 현재 활성화된 세션을 삭제하여 로그아웃 처리한다.
*/
suspend fun onLogout() {
account.deleteSession("current")
}
}
```
3. **용도 요약**:
* `init`: 앱 시작 시 Appwrite 서버와의 연결을 설정
* `onRegister`: 신규 사용자 등록 (회원가입)
* `onLogin`: 기존 사용자 로그인 및 세션 생성
* `onLogout`: 로그인 세션 종료 및 로그아웃 처리
이제 이 싱글톤 객체를 통해 어느 액티비티나 컴포넌트에서든 손쉽게 Appwrite 기능을 호출할 수 있다.
### 5. 간단한 로그인/회원가입 화면 구현
1. `MainActivity.kt`에 Compose UI 추가
2. 아래 예제에서 **package** 선언은 각자가 만든 것으로 변경:
```kotlin
package cohttp://m.example.myapp
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.launch
class MainActivity : ComponentActivity() {
@OptIn(ExperimentalMaterial3Api::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Appwrite.init(applicationContext)
setContent {
var email by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") }
var user by remember { mutableStateOf<String?>(null) }
val scope = rememberCoroutineScope()
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
verticalArrangement = Arrangement.Center
) {
if (user != null) {
Text(text = "Logged in as $user")
Button(onClick = {
scope.launch { Appwrite.onLogout(); user = null }
}, modifier = Modifier.padding(top = 16.dp)) {
Text("Logout")
}
} else {
TextField(
value = email,
onValueChange = { email = it },
label = { Text("Email") },
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Email
),
modifier = Modifier.fillMaxWidth()
)
TextField(
value = password,
onValueChange = { password = it },
label = { Text("Password") },
visualTransformation = PasswordVisualTransformation(),
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp)
)
Row(
modifier = Modifier
.fillMaxWidth()
.padding(top = 16.dp),
horizontalArrangement = Arrangement.SpaceEvenly
) {
Button(onClick = {
scope.launch {
Appwrite.onLogin(email, password)
user = email
}
}) { Text("Login") }
Button(onClick = {
scope.launch { Appwrite.onRegister(email, password) }
}) { Text("Register") }
}
}
}
}
}
}
}
```
---
### 6. 실행 및 확인
1. 에뮬레이터 또는 실제 기기에서 앱 실행
2. **Register** → **Login** → **Logout** 순으로 기능 동작 확인
'잡(job)기술' 카테고리의 다른 글
gst-rtsp-server 시그널 이해하기: media-configure와 media-constructed (0) | 2025.05.16 |
---|---|
PM2에서 ecosystem.config.js를 사용하는 이유와 장점 (0) | 2025.05.15 |
Jetpack Compose에서 FocusRequester의 개념과 필요성, 사용 방법 (0) | 2025.05.15 |
Jetpack Compose: 사용자 입력 경험을 향상시키는 KeyboardOptions & Actions (0) | 2025.05.15 |
glew 빌드 확인 (0) | 2018.03.13 |