Skip to content

mercy-project/mercy-player-android

Repository files navigation

Mercy Player

앱 초기 설정 및 기본 설계에 초점

컨벤션

Code Style

일반적으로 회사 혹은 오픈소스들에는 사용하는 스타일 가이드가 존재

  • Preference > Editor > Code Style > Kotlin > set from > Kotlin style guide
  • Preference > Editor > Code Style > XML > Android

Square Android CodeStyles

Kotlin StyleGuide

Android Lint

Android Lint는 앱 소스 파일과 lint.xml를 통해서 앱의 문제점들을 해결해 줍니다.

린트 검사로 코드 개선

Ktlint / Detekt

  • Android Lint가 안드로이드의 관련된 디펜던시나 리소스 관련 부분들에 대해 정적분석을 해준다면 ktlint와 detekt는 kotlin 소스에 대한 정적분석을 실행합니다.
  • ktlint와 detekt는 Kotlin 상에서 실수할 수 있는 부분을 고쳐주며 다양한 rule들을 통해 코드를 분석하여 html이나 xml과 같은 형식으로 받아서 볼 수 있습니다.

ktlint

  1. app/build.gradle 설정 추가
configurations {
    ktlint
}

dependencies {
    ktlint "com.pinterest:ktlint:0.41.0"
    // additional 3rd party ruleset(s) can be specified here
    // just add them to the classpath (ktlint 'groupId:artifactId:version') and 
    // ktlint will pick them up
}

task ktlint(type: JavaExec, group: "verification") {
    description = "Check Kotlin code style."
    main = "com.pinterest.ktlint.Main"
    classpath = configurations.ktlint
    args "src/**/*.kt"
    // to generate report in checkstyle format prepend following args:
    // "--reporter=plain", "--reporter=checkstyle,output=${buildDir}/ktlint.xml"
    // see https://github.com/pinterest/ktlint#usage for more
}
check.dependsOn ktlint

task ktlintFormat(type: JavaExec, group: "formatting") {
    description = "Fix Kotlin code style deviations."
    main = "com.pinterest.ktlint.Main"
    classpath = configurations.ktlint
    args "-F", "src/**/*.kt"
}
KotlinDSL

val ktlint by configurations.creating

tasks.register<JavaExec>("verification") {
    group = "verification"
    description = "Check Kotlin code style."
    classpath = ktlint
    main = "com.pinterest.ktlint.Main"
    args("--android", "src/**/*.kt")
}

tasks.named("check") {
    dependsOn(ktlint)
}

/** 스타일 수정 후 자동으로 수정해 줌 */
tasks.register<JavaExec>("ktlintFormat"){
    description = "Fix Kotlin code style deviations."
    classpath = ktlint
    main = "com.pinterest.ktlint.Main"
    args("-F", "src/**/*.kt")
}
  • configurations 이 dependencies 보다 위에 선언 되어 있어야 ktlint 적용됨
  1. .editorconfig 로 Rule 세팅
  • rules 추가

Standard rules

detekt

  • Kotlin 프로젝트를위한 코드 분석
  • Gradle 빌드를 통한 코드 분석을위한 Gradle 플러그인
  1. detekt 플러그인 추가
plugins {
    ...
    id "io.gitlab.arturbosch.detekt" version "1.16.0"
}
KotlinDSL

plugins {
    ...
    id("io.gitlab.arturbosch.detekt") version "1.16.0"
}
  1. detekt.yml 생성
./gradlew detektGenerateConfig
  1. detekt 설정
  • app/build.gradle 에 detekt 추가 하고 detekt.yml 실제 경로로 수정
detekt {
    toolVersion = "1.16.0"
    config = files("$rootDir/config/detekt/detekt.yml")
    buildUponDefaultConfig = true
}

detekt 설정 참고

Git Hooks

  • 적용된 린트들을 깃에서 commit 혹은 push를 될 때마다 시켜주기 위해서 깃훅을 사용했습니다.
KotlinDSL

/** GitHooks 복사 */
tasks.register<Copy>("copyGitHooks"){
    from("${rootDir}/codeConfig/git/git-hooks/") {
        include("**/*")
        rename("(.*)", "$1")
    }

    into("${rootDir}/.git/hooks")
}

/** GitHooks 설치 */
tasks.register<Exec>("installGitHooks"){
    group = "git hooks"
    workingDir(rootDir)
    commandLine("chmod")
    args("-R", "+x", ".git/hooks/")
    dependsOn("copyGitHooks")
}

버저닝

  • GitHub 의 공동창업자인 톰 프레스턴 베르나가 만든 Semantic Versioning을 기반으로 버전 관리

Semantic Versioning 2.0.0

Given a version number MAJOR.MINOR.PATCH, increment the:

  1. MAJOR version when you make incompatible API changes,
  2. MINOR version when you add functionality in a backwards compatible manner, and
  3. PATCH version when you make backwards compatible bug fixes.
  • Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format.

🛠 Tech Sacks & Open Source Libraries

  • 비동기 처리 Coroutines
  • Jetpack
    • Lifecycle: 수명 주기 변경 사항을 관찰합니다.
    • ViewModel: UI 관련 데이터 홀더 및 수명 주기 인식.
    • Navigation: 다양한 화면 및 앱 간 탐색, 사용자가 앱내에서 이동할 때 동일한 탐색 휴리스틱과 패턴을 적용할 수 있습니다.
  • Hilt: 의존성 주입
  • Glide: 이미지 로딩 라이브러리
  • Retrofit2 & OkHttp3: REST API 네트워크 데이터를 구성합니다.
  • Timber: 유틸리티를 제공하는 가볍고 확장 가능한 API가 있는 로거.

🏛️ Architecture

아키텍처의 레이어 및 경계

  • User Interface Layer:

    • UI 레이어의 책임은 화면에 애플리케이션 데이터를 렌더링하는 것입니다.
    • 사용자 상호 작용 또는 네트워크 및 데이터베이스와의 외부 통신으로 인해 애플리케이션 데이터가 변경될 때마다 UI 요소를 업데이트해야 합니다.
  • Presentation Layer:

    • 프레젠테이션 계층의 책임은 UI 계층과 도메인 계층 간의 데이터 변경 사항을 상호 작용하고 알리는 것입니다.
    • 구성 변경 시 데이터를 보유하고 복원합니다.
  • Domain Layer:

    • 도메인 계층은 복잡한 비즈니스 로직을 추상화하고 재사용성을 향상시키는 역할을 합니다.
    • 이 계층은 복잡한 애플리케이션 데이터를 프레젠테이션 계층에 적합한 유형으로 변환하고 유사한 비즈니스 로직을 단일 기능으로 그룹화합니다.
  • Data Layer:

    • 데이터 계층의 책임은 CRUD 작업(생성, 검색, 업데이트, 삭제 – 모든 시스템 이벤트)과 같은 비즈니스 로직 실행 결과를 전달하는 것입니다.
    • 이 계층은 Repository나 DataSource와 같은 다양한 전략으로 실행 책임을 나누어 설계할 수 있습니다.

브랜치 전략

GitLab flow 사용

  • master 브랜치는 production 브랜치
  • production브랜치는 master 이상 권한만 push 가능
  • developer 권한 사용자는 master 브랜치에서 신규 브랜치를 추가
  • 신규 브랜치에서 소스를 commit 하고 push
  • merge request를 생성하여 master 브랜치로 merge 요청
  • merge_request를 생성하기 전에는 master 브랜치를 rebase 해서 병합 커밋을 방지
  • master 권한 사용자는 developer 사용자와 함께 리뷰 진행 후 master 브랜치로 merge
  • 테스트가 필요하다면 master에서 procution 브랜치로 merge하기 전에 pre-production 브랜치에서 테스트

Custom Template Plugin for Android Studio

  • MVVM 에서 기본적으로 사용하는 View, ViewModel, layout 을 기본으로 생성해주는 Custom Template 추가
  • Plugin Library Path: ./libs/android-mvvm-plugin-template-0.0.1.jar

플러그인 설치 방법 (Mac 기준)

  • Android Studio > Preferences.. > Plugins > 오른쪽 상단 톱니바퀴 모양 클릭 > Install Plugin from Disk > jar 파일 선택 > 스튜디오 재시작

사용법

  • 생성할 폴더에서 우클릭 > New > Other > Android Fragment MVVM Creator > 정보 입력

  • EntityName 규칙

    • Mvvm Activity creator
      • EntityName: FeatureHome 결과
        • view/FeatureHomeActivity
        • viewmodel/FeatureHomeViewModel
        • layout/activity_feature_home
    • Mvvm Fragment creator
      • EntityName: FeatureHome 결과
        • view/FeatureHomeFragment
        • viewmodel/FeatureHomeViewModel
        • layout/fragment_feature_home

구글 로그인 연동

  • 토큰만료시 작업

해결해야할 문제

  • 구글 계정 로그인 클릭 후 계정 선택시 서비스 약관 링크가 걸려있는데 어디서 작성해야하는지 검토 필요
    • 개인정보처리방침, 서비스 약관
  • 구글 idToken 만료 및 갱신 시점

참고


유저 정보 및 로그인 연결

UserInfoManager

유저 관련 정보를 관리

  • companion object 에 선언되어있는 메서드 활용
@JvmStatic
fun isLoggedIn() = getInstance().info != null

@JvmStatic
fun getUserInfo() = getInstance().info

@JvmStatic
fun getIdToken() = getInstance().info?.idToken

@JvmStatic
fun getUserName() = getInstance().info?.userName

@JvmStatic
fun getEmail() = getInstance().info?.userEmail
  • 로그인 여부, 상세 유저 정보를 가져올수 있습니다.

AuthenticationManager

로그인, 로그아웃, 인증 관련 정보를 관리

fun signIn()
fun signOut(updateAction: () -> Unit)
fun revokeAccess(updateAction: () -> Unit)
  • 위의 public fun 을 사용해서 로그인, 로그아웃 계정연결 해제

LoginChangeObserver

화면에서 로그인 상태를 옵저빙하고 로그인 여부에 따라서 처리해야 할 작업을 처리

observeChangedLogin { isSignedIn ->
    if (isSignedIn) {
        moveToNext()
    }
}
  • 사용 예시로 Activity, Fragment 에서 옵저버를 선언하고 로그인 상태가 변경되었을때 호출이 되며 이후 액션 추가

참고

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published