Tweakr: Firebase와 Android를 함께 사용하여 오즈의 마법사 프로토타입 제작 및 원격 제어

1. 소개

최종 업데이트: 2022년 3월 30일

원격 디버그와 환경설정 UI 자동 생성 및 오즈의 마법사 프로토타입 제작을 위한 라이브러리

애니메이션 값을 아주 조금만 조정해도 변경사항이 컴파일되는 것을 확인하는 데 몇 분이나 기다려야 하는 상황이 지긋지긋하신가요? 다른 사람들이 프로토타입의 다양한 옵션을 사용해보도록 제공하여 옵션을 즉석에서 조정하고 싶으신가요? 누군가가 '한 줄로 된 솔루션'을 언급하면 가슴이 두근거리시나요? 그렇다면 Tweakr를 사용해보세요!

Tweakr는 코드에서 필드와 메서드에 주석을 추가한 후 자동으로 UI를 생성하여 로컬에서 또는 원격으로 그러한 요소를 변경할 수 있는 Android 라이브러리입니다. Tweakr는 Firebase와 웹 기반 UI를 사용하여 즉석에서 바로 앱의 값을 고치고 설정을 변경할 수 있습니다. 또한 스마트폰의 SharedPreferences를 사용하여 환경설정 UI 화면을 자동으로 생성할 수도 있습니다.

그야말로 한 줄 코드를 작성하면 됩니다. 변경하고자 하는 것을 @Tweak으로 주석 처리하기만 하면 나머지는 알아서 처리됩니다.

c407af6de21474.gif

빌드할 항목

이 Codelab에서는 간단한 Android 앱을 빌드합니다. 이 앱에서는 다음 작업을 진행합니다.

  • 화면에 텍스트와 이미지를 그립니다.
  • 앱의 필드와 메서드에 @Tweakr 주석을 추가합니다.
  • Firebase를 사용하여 Tweakr 웹 UI에 연결합니다(웹 UI가 이미 사용할 수 있도록 빌드되어 있음).
  • Tweakr를 사용하여 뷰를 조작하고 화면에서 뷰를 이동시킵니다.

학습할 내용

  • Android 앱에 Firebase를 설정하는 방법
  • Tweakr에서 필드와 메서드를 제어하는 UI를 생성하도록 앱에서 필드와 메서드에 주석을 다는 방법

이 Codelab에서는 Tweakr 라이브러리 사용에 중점을 둡니다. 따라서 이와 관련 없는 개념과 코드 블록은 그냥 넘어가겠습니다. 단, 필요할 때 복사해서 붙여넣을 수 있도록 다른 설명 없이 제공만 해드리겠습니다.

필요한 항목

  • Android 스튜디오가 설치된 컴퓨터
  • Kotlin 및 Android 뷰에 관한 기본 지식

2. Firebase 프로젝트 만들기 및 설정

Tweakr는 Firebase를 사용해 Android 앱을 웹 UI에 자동으로 연결하는 UI를 만듭니다. 먼저 Android용 Firebase 프로젝트를 설정해야 합니다.

Firebase 프로젝트 만들기

  1. Firebase에 로그인합니다.
  2. Firebase Console에서 프로젝트 추가(또는 프로젝트 만들기)를 클릭한 후 Firebase 프로젝트의 이름을 Tweakr-Codelab으로 지정합니다. cd5d93d8733c5730.png
  3. 프로젝트 만들기 옵션을 클릭하며 살펴봅니다. 메시지가 표시되면 Firebase 약관에 동의합니다. 이 앱에는 애널리틱스를 사용하지 않으므로 Google 애널리틱스 설정은 건너뛰세요.

Firebase 프로젝트에 관해 자세히 알아보려면 Firebase 프로젝트 이해를 참고하세요.

Firebase에서 Android 앱 설정

  1. Firebase Console에서 자체 패키지 이름(예: com.[your-domain].tweakr.sample))을 사용하여 새 Android 앱을 추가합니다. 패키지 이름 및 디버그 키와 같은 필드입니다. 앱 등록 버튼
  2. 안내에 따라 google-services.json 파일을 다운로드합니다.
  3. google-services.json 파일을 Android 앱의 app 모듈 디렉터리(예: tweakr-codelab/app/)에 복사합니다.
  4. Firebase 연결 확인 작업은 건너뜁니다. 이 작업은 나중에 Android 앱에서 애플리케이션 ID를 업데이트한 후에 진행하게 됩니다.
  5. 안내에 따라 Gradle Sync를 클릭합니다.

Console에서 Firebase 제품 사용 설정

빌드 중인 앱에는 웹 앱에 사용할 수 있는 다음과 같은 몇 가지 Firebase 제품이 사용됩니다.

  • Firebase 인증 및 Firebase UI - 사용자가 앱에 간편하게 로그인할 수 있음
  • 실시간 데이터베이스 - Tweakr가 앱과 웹 UI 간에 즉시 데이터를 동기화하는 데 사용함
  • Firebase 보안 규칙 - 데이터베이스를 보호함

이러한 제품 중에는 특수 구성이 필요하거나 Firebase Console을 사용하여 사용 설정해야 하는 제품이 있습니다.

Firebase 인증에 익명 로그인 사용 설정

사용자가 웹 앱에 로그인할 수 있도록 이 Codelab에서는 익명 로그인 방법을 사용합니다.

  1. Firebase Console의 왼쪽 패널에 있는 빌드에서 인증을 클릭합니다.
  2. 인증을 클릭한 후 시작하기 -> 로그인 방법 탭을 클릭합니다(또는 여기를 클릭하여 로그인 방법 탭으로 바로 이동).
  3. 로그인 제공업체 목록에서 익명을 클릭하고 사용 설정 스위치를 켬 위치로 설정한 다음 저장을 클릭합니다. d7a9ec05ba37f407.png

실시간 데이터베이스 사용 설정

Tweakr는 실시간 데이터베이스를 사용하여 앱과 웹 UI 간의 상태를 1초에 여러 번 동기화합니다.

실시간 데이터베이스 사용 설정:

  1. Firebase Console의 빌드 섹션에서 실시간 데이터베이스를 클릭합니다.
  2. 데이터베이스 만들기를 클릭합니다. 21491f6ad60c0f3.png
  3. 데이터베이스의 위치를 선택합니다. 그냥 기본값을 사용할 수도 있습니다. 이 위치는 나중에 변경할 수 없습니다. 32f815f4648c3174.png
  4. 테스트 모드에서 시작 옵션을 선택합니다. 그러면 개발 중에도 데이터베이스에 자유롭게 쓸 수 있습니다. 보안 규칙에 관한 면책조항을 읽고 다음을 클릭합니다. acfcf535bff30f47.png
  1. 사용 설정을 클릭합니다.

3. Android 샘플 앱 빌드

코드 가져오기

이 프로젝트에 필요한 모든 것을 Git 저장소에 넣었습니다. 시작하려면 코드를 가져와 Android 스튜디오에서 열어야 합니다.

적극 권장: Android 스튜디오를 사용하여 저장소 가져오기

  1. Android 스튜디오를 열고 Version Control에서 File->New->Project를 선택합니다.
  2. Version Control 옵션으로 Git을 선택합니다.
  3. URL https://github.com/google/tweakr-codelab.git을 입력합니다.
  4. Clone을 클릭합니다.

애플리케이션 ID 업데이트

Firebase에는 Android 앱의 고유한 애플리케이션 ID가 필요하므로 샘플 이름을 자체 애플리케이션 ID로 변경해야 합니다.

  1. Tweakr_codelab.app 모듈의 app/build.gradle 파일을 엽니다.
  2. applicationId "com.yourdomain.tweakr.sample" 줄을 Firebase 설정에서 지정한 패키지 이름으로 변경합니다.
  3. Sync를 클릭하여 변경사항을 gradle 파일에 동기화합니다.

앱 실행

  1. Run을 클릭하여 앱을 그대로 컴파일하고 실행합니다. Android Emulator를 사용하는 경우 Firebase에 필요한 Google Play 라이브러리에서 AVD 이미지를 만들어야 합니다.

6f6d2c9539143a5a.png

앱에 텍스트와 원이 있는 간단한 화면이 표시됩니다.

  1. 텍스트를 클릭하여 애니메이션을 트리거합니다.

4. 이제 조정해 보겠습니다.

이 섹션을 마치면 Tweakr 웹사이트에서 앱의 뷰를 원격으로 제어할 수 있습니다.

Tweakr 라이브러리 종속 항목 추가

  1. settings.gradle 파일을 열고 저장소에 Jitpack을 추가합니다.

settings.gradle

dependencyResolutionManagement {
   repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
   repositories {
       google()
       mavenCentral()
       maven { url 'https://jitpack.io' }
   }
}
  1. Tweakr_codelab.app 모듈의 app/build.gradle 파일을 열고 Tweakr 라이브러리 종속 항목을 추가합니다.

app/build.gradle

dependencies {

...

   // Required for local SharedPreferences or Firebase
   implementation 'com.github.google.tweakr:core:2.2.2'

   // Include this if you want Firebase support.
   implementation 'com.github.google.tweakr:firebase:2.2.2'
}
  1. Sync Now를 클릭하여 gradle 변경사항을 동기화합니다.

Tweakr 저장소 초기화

우선 SampleApplication의 onCreate() 메서드에서 Tweakr 저장소를 초기화하여 Firebase 사용을 인식할 수 있도록 합니다.

  1. SampleApplication.kt 파일을 엽니다.
  2. Tweakr.setRepo(TweakrFirebaseRepo())라는 줄의 주석 처리를 삭제합니다.

그렇게 하면 Tweakr에 TweakrFirebaseRepo를 사용하여 관련 값을 클라우드에 동기화하라는 지시가 전달됩니다. TweakrFirebaseRepo는 첫 번째 섹션에서 추가한 google-services.json 파일을 통해 정의된 기본 Firebase 인스턴스를 자동으로 사용합니다.

조정 추가

Tweakr가 앱 일부 요소의 웹 UI를 생성할 수 있도록 이제 그 요소에 주석을 달 준비가 되었습니다.

  1. MainActivity.kt 파일에서 fun animateText() 줄 위에 @Tweak 주석을 추가합니다. 그러면 Tweakr는 이 메서드를 원격으로 제어하려고 한다는 사실을 알게 됩니다.

MainActivity.kt

@Tweak
fun animateText() {
 introText.animate()
...
}
  1. onCreate() 함수 하단에 Tweakr.register(this) 줄을 추가합니다. 그렇게 하면 Tweakr에 클래스의 모든 주석을 파싱하고 관련 값을 웹 서버와 동기화하라는 지시가 전달됩니다.

MainActivity.kt

override fun onCreate(savedInstanceState: Bundle?) {
 super.onCreate(savedInstanceState)
 setContentView(R.layout.activity_main)

 introText = findViewById(R.id.text)
 introText.setOnClickListener { animateText() }

 Tweakr.register(this)
}
  1. 이제 앱을 다시 실행합니다.

모든 것이 잘 진행되었다면 Tweakr가 백그라운드에서 초기화되었고 우리가 사용 중인 Tweakr를 Firebase 서버와 동기화했습니다. 다음 섹션에서 그 작업의 놀라운 결과를 확인할 수 있습니다.

5. 웹 UI의 값 조정

이제 앱에서 조정 가능한 값을 설정했으므로 Tweakr 웹 UI를 열어 인터넷을 통해 그 웹 UI를 원격으로 제어할 수 있습니다. 앱에서 값을 조정하는 가장 쉬운 방법은 Tweakr의 사전 빌드된 웹사이트인 Easyserver를 사용하는 것입니다. 이 웹사이트는 GitHub에서 호스팅되고 Firebase 데이터베이스에 연결되어 Android 앱에서 값을 동기화하고 웹 UI를 생성합니다.

Firebase에서 웹 앱 설정

먼저 Firebase에서 웹 앱을 설정하고 Easyserver에 웹 앱 액세스 권한을 부여해야 합니다.

  1. Firebase Console에서 프로젝트 개요를 클릭합니다.
  2. 앱 추가를 클릭하고 을 선택합니다.82b936ff2bbbbbac.png
  3. 닉네임을 입력하고 등록을 클릭합니다.
  4. Firebase SDK 추가 단계에서 const firebaseConfig의 모든 항목을 계속 복사합니다. 그것을 다음 단계에서 Tweakr Easyserver에 붙여넣을 것입니다. c4f2e17447f8442c.png

Easyserver 시작

  1. https://google.github.io/tweakr/easyserver/로 이동하고 관련 안내에 따라 Easyserver가 Firebase에 액세스할 수 있도록 허용합니다.
  2. 이전 단계에서 복사한 firebaseConfig 코드를 붙여넣습니다.

e8a19d25f923a76f.png

올바르게 붙여넣으면 고유 로그인 링크와 조정 시작 버튼이 표시됩니다.

  1. 조정 시작을 클릭합니다.

이전에 주석을 추가한 함수 이름을 딴 animateText() 버튼이 표시됩니다.

7e916285f11317d4.png

버튼을 누르는 동작

Android 앱이 열린 상태에서 Tweakr 웹 UI에서 animateText() 버튼을 클릭하고 휴대전화의 화면을 확인합니다.

f238f06c1cf5583e.gif

마법 같지 않나요? 텍스트에서 작은 애니메이션이 실행되는 것을 볼 수 있습니다. 어떻게 된 걸까요?

매개변수가 없는 메서드용 버튼인데 메서드에 매개변수를 사용하면 어떻게 되는지 궁금할 수 있습니다. 자세히 알아보려면 다음 섹션을 참고하세요.

6. 매개변수가 있는 메서드

Tweakr는 매개변수가 하나인 메서드와도 호환됩니다(매개변수가 두 개 이상인 메서드는 아직 지원되지 않음). 한번 보시죠.

  1. MainActivity 클래스에서 TextView의 텍스트를 변경하는 새 메서드를 추가합니다.

MainActivity.kt

class MainActivity : Activity() {
...

 @Tweak
 fun setMessage(text: String) {
   introText.text = text
 }

...
  1. 새 메서드에 @Tweak 주석을 추가해야 합니다.
  2. 앱을 다시 실행한 다음, Tweakr Easyserver 웹사이트가 메서드를 호출하는 텍스트 필드로 자동으로 업데이트되는 모습을 봅니다.
  3. 텍스트 필드에 내용을 입력하고 앱이 실시간으로 업데이트되는 모습을 확인합니다.

322a56390bd5fe31.gif

메서드를 원격으로 제어하는 것도 훌륭하지만 Tweakr의 진정한 힘은 코드에서 필드 값을 변경하는 기능입니다. 더 재미 있는 것을 해 보려면 다음 섹션을 참고하세요.

7. (선택사항) 필드 값 조정

Android 스튜디오에서 CircleView.kt 파일을 엽니다. 상단에 원의 크기와 위치를 제어하는 필드가 있는 것 같습니다. 그것을 조정해 보겠습니다.

주석 추가

  1. centerX, centerYradius 필드 위에 @Tweak 주석을 추가합니다.
  2. init() 메서드도 추가하기 위해 객체가 초기화될 때 Tweakr.register()도 호출합니다. 최종 코드는 다음과 같습니다.

CircleView.kt

/** A View that draws a circle **/
class CircleView @JvmOverloads constructor(
 context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

 @Tweak
 var centerX = 180f

 @Tweak
 var centerY = 180f

 @Tweak
 var radius = 50f

 init {
  Tweakr.register(this)
 }

...

이렇게 하면 Tweakr가 필드를 변경할 수는 있지만, 아직 그렇게 하지는 않았습니다. 이 뷰는 캔버스에 직접 그리는 맞춤 뷰이므로, Tweakr가 필드 값을 변경해도 뷰는 새 값으로 자동 다시 그려지지 않습니다. Tweakr가 변경사항을 동기화할 때마다 뷰에 다시 그리도록 알려야 합니다.

  1. 필드 값이 원격으로 변경될 때마다 알림을 받도록 Tweakr에 리스너를 등록합니다.

메모리 누수를 방지하기 위해 뷰가 리스너를 사용하지 않는 경우 attachedToWindow 이벤트를 사용하여 리스너를 삭제해야 합니다.

Tweakr 값의 변경 수신 대기

Tweakr.addListener(this) 호출로 onAttachedToWindow() 메서드를 재정의한 다음 onDetachedFromWindow()에서 리스너를 삭제합니다.

CircleView.kt

/** A View that draws a circle **/
class CircleView @JvmOverloads constructor(
 context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr), TweakrRepo.OnChangeListener
 {

...

  override fun onAttachedToWindow() {
   super.onAttachedToWindow()

   // Register onFieldChanged() to redraw when any value changes.
   Tweakr.addListener(this)
  }

  override fun onDetachedFromWindow() {
   Tweakr.removeListener(this)

   super.onDetachedFromWindow()
  }

  override fun onFieldChanged(name: String?, value: Any?) {
   // This is called whenever a field's value is changed in Tweakr's UI.
   // We could be granular here and check the name to match only the fields
   // we care about, but for this demo it's simple enough to just redraw
   // whenever *any* value changes.
   invalidate()
  }

...

this를 리스너로 설정하므로 클래스에서 TweakrRepo.OnChangeListener 인터페이스를 확장/구현해야 합니다.

직접 해 보기

이제 직접 해 볼 준비가 되었습니다. 앱을 실행하고, Tweakr Easyserver 웹사이트가 새 필드로 Tweak에 자동 업데이트되는 모습을 확인합니다.

80e03628ec47917c.gif

8. 축하합니다

축하합니다. Tweakr로 첫 앱을 빌드했습니다.

필드가 포함된 객체에 관해 Tweakr.register()를 호출하여 메서드와 필드에 @Tweak 주석을 다는 법과 Tweakr 변경 이벤트를 수신 대기하여 뷰를 수동으로 다시 그리는 고급 사용법을 알아봤습니다.

이 기술을 사용하여 프로토타입 제작 흐름의 속도를 높일 수 있습니다. 예를 들어 애니메이션 값을 즉시 변경하고, UX 연구와 사용자 연구 중에 오즈의 마법사 프로토타입을 원격으로 제어할 수 있습니다. Google팀에서는 모션 프로토타입 APK를 모션 디자이너와 공유하고 모션 디자이너에 Tweakr 웹 UI 링크를 보낸 다음 모션 디자이너가 애니메이션의 값을 원하는 대로 조정하는 데 보통 사용합니다. 모션 디자이너는 애니메이션 값이 매우 정확한 것을 좋아합니다.

또한 Google팀은 세부적인 상호작용과 동작 및 햅틱을 위한 프로토타입을 만들었으며, 설계를 위한 전환 가능한 다양한 구성과 옵션과 함께 Tweakr 링크를 팀과 공유했습니다. 그런 다음 Google은 공유 문서를 만들어 즐겨 찾는 Tweakr 값을 채울 수 있도록 했습니다. 이를 통해 프로덕션에 구현하기 전에 설계에 관한 합의를 쉽게 이끌어낼 수 있게 되었습니다.

다음 단계

기타 제안사항

  • 오즈의 마법사 원격 제어: 열거형으로 된 앱 화면 이름을 취하는 메서드를 활동에서 만들어 보세요. Tweakr가 메서드를 호출할 때 화면 이름에 해당하는 새 프래그먼트를 로드합니다. 그렇게 하면 Tweakr 웹 UI에서 원하는 화면을 클릭만 해도 휴대전화에서 앱을 보는 모든 사람에게 새 프래그먼트가 표시됩니다. 사용자 연구에 적합합니다.
  • 여러 사용자: 기본적으로 Tweakr 웹 UI는 앱을 사용하는 모든 사람에게 동시에 변경사항을 동기화합니다. 하지만 여러 명의 동시 사용자가 있는 경우 어떤 사용자가 UI에 변경한 사항이 그 사용자의 휴대전화에만 영향을 미치고 다른 사용자에게는 영향을 주지 않도록 사용자마다 고유한 세션을 갖도록 할 수 있습니다. getUserKey().로 여러 세션을 만드는 방법은 ToughrFirebaseRepoMultiuser 문서를 참고하세요.
  • 로컬 PreferenceScreen: Tweakr에 Firebase를 사용할 필요가 없습니다. 또한 Android 환경설정 UI를 자동 생성하므로, 휴대전화에서 로컬로 설정을 변경할 수도 있습니다. 샘플 코드문서를 참고하세요.