Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Seminar/7 #10

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open

Seminar/7 #10

wants to merge 5 commits into from

Conversation

hansh0101
Copy link
Contributor

📌 Related Issue

📝 What's-New

  • 필수과제 1. SharedPreferences를 사용한 자동로그인 / 자동로그인 해제 구현
  • 성장과제 1. Navigation Component를 사용한 온보딩 화면 만들기
  • 도전과제 1. Room을 사용한 자동로그인 로직 만들기

➕ Additional

1차 세미나

  • Hilt를 사용해 의존성 주입
  • Room을 사용해 내부 DB를 활용한 회원가입, 로그인, 회원정보 수정
  • EncryptedSharedPreference를 사용해 아이디 기억하기

2차 세미나

  • Room을 이용해 RecyclerView Item 이동, 삭제 시 내부 DB에서도 업데이트
  • (Encrypted)SharedPreference를 사용해 자동 로그인 구현
  • FrameLayout을 활용, RecyclerView Item 삭제 시도 시 DELETE 버튼 눌러야 삭제할 수 있도록 MyItemTouchHelper 구현

3차 세미나

  • Navigation Component를 이용해 BottomNavigationView 구현

4차 세미나

  • Github API 호출 횟수 제한 완화를 위해 Header를 추가한 Interceptor 구현
  • 회원가입 시 Github ID를 ID로 입력하도록 유도, 로그인 시 해당 Github ID에 대한 정보를 표시하도록 구현

7차 세미나

  • StateFlow를 활용한 Presentation Layer에서의 UI 조작 구현

- SharedPreferences를 활용한 자동 로그인 구현
- SharedPreferences를 활용한 자동 로그인 구현
- Navigation Componenet를 활용한 온보딩 구현
- Room을 사용한 자동 로그인 구현
- StateFlow 사용한 상태 갱신
@hansh0101 hansh0101 self-assigned this Jun 10, 2022
@hansh0101 hansh0101 linked an issue Jun 10, 2022 that may be closed by this pull request
3 tasks
Copy link
Member

@yeoncheong yeoncheong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

최고의 스승님 (_ _)

@@ -33,4 +33,8 @@ class SopthubDataStore @Inject constructor(
var autoLogin: Boolean
set(value) = dataStore.edit { putBoolean("AUTO_LOGIN", value) }
get() = dataStore.getBoolean("AUTO_LOGIN", false)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sharedPreference보다 dataStore를 사용하였을 때의 이점이 무엇이 있나요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DataStore를 공부해보려고 하긴 했는데, 결과적으로 보면 저 dataStore라는 애는 SharedPreferences입니다. 왜냐면 context.getSharedPreferences() 메서드로 가져오기 때문이죠.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

제가 공부해보려고 한 이유는 이런 3가지 특징이 있어서라고 합니다.

  • DataStore는 코루틴과 Flow를 통해 읽고 쓰기에 대한 비동기 API를 제공한다.
  • DataStore는 UI 스레드를 호출해도 안전하다.
  • runtime exception으로부터 안전하다.

@AndroidEntryPoint
class OnBoardingFirstFragment : BaseFragment<FragmentOnBoardingFirstBinding>() {
override val TAG: String
get() = OnBoardingFirstFragment::class.java.simpleName
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TAG의 역할은 무엇인가요?

Copy link
Contributor Author

@hansh0101 hansh0101 Jun 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이건 1차 세미나 과제를 할 때 생명주기를 Log로 남기고 싶어서 사용한 TAG입니다. OnBoardingFirstFragment::class.java의 simpleName은 말 그대로 이 Fragment의 name, 즉 OnBoardingFirstFragment가 됩니다. 따라서 이 TAG는 BaseFragment에서 생명주기 콜백 메서드(onCreateView, onViewCreated 등)에서 Log를 남길 때 TAG로서 작용하게 됩니다. 저같은 경우는 lifecycle에 observer를 붙여 생명주기마다 Log를 남기도록 했습니다.

https://github.com/KINGSAMJO/iOS_Seunghyeon/blob/seminar%2F7/app/src/main/java/co/kr/sopt_seminar_30th/util/MyDefaultLifecycleObserver.kt

위 링크는 제가 DefaultLifecycleObserver를 상속받아 구현한 Observer입니다.

private var _isEmpty = SingleLiveEvent<Boolean>()
val isEmpty: LiveData<Boolean> get() = _isEmpty

private var _isEmailIncorrect = SingleLiveEvent<Boolean>()
val isEmailIncorrect: LiveData<Boolean> get() = _isEmailIncorrect
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LiveData를 사용할 때 get()이 필요한 이유가 무엇인가요? 값이 계속 변경될거라면 MutableLiveData를 사용해도 되지 않나요?

Copy link
Contributor Author

@hansh0101 hansh0101 Jun 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get()을 사용해 가져오는 것은 값을 계속 변경시키기의 목적보다는 클래스 외부에서 값을 마음대로 변경하지 못하도록 하는 것에 더 큰 목적이 있습니다. 저의 경우 일반적으로 _ prefix가 붙은 MutableLiveData 변수는 ViewModel 클래스 안에서만 접근 가능한 private으로 지정하고 ViewModel 클래스 외부에서 LiveData의 값을 참조하고 싶을 경우에는 val로 선언해 set(value)를 불가능하게 한 뒤 get()으로 원본 데이터(_ prefix가 붙은)의 값을 가져오는 형태입니다. 이렇게 하면 무분별하게 ViewModel 클래스의 외부에서 MutableLiveData 값을 변경하는 행위를 막을 수 있습니다. 이렇게 하면 LiveData 값의 조작은 ViewModel 클래스 안에서만 일어나게 됩니다. 따라서 추후에 유지보수를 하게 되거나 코드에 수정을 하거나 에러가 발생했을 때 LiveData의 값을 조작하는 부분은 ViewModel 클래스 안에만 있으니 ViewModel 클래스 코드만 보면 된다는 장점이 있다고 생각합니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Assignment] 7차 세미나 과제
2 participants