구조는 요즘 핫한 구글의 클린아키텍처를 따르기로했다.(+MVVM)
대략적인 그림은 이러하다.
앞으로 여러 기능을 확장할테지만 아직은 네이버 맵에서 사용자가 저장한 곳을 마킹하고, 클릭 시 해당 장소에 대한 별칭을 띄우기만 할 것이다.
로그인 시 해당 사용자가 저장한 정보(위치 정보)를 RealtimeDatabase에서 빼와서 네이버 맵에 뿌려줄 것이다.
구조 설계에 있어서 초기 기능이 아직 많지 않기에 그다지 어렵지는 않지만, 추후에 있을 기능 확장에 대해 유연하게 대처할 수 있는 구조인지는 잘 모르겠다...
카카오 로그인은 공식문서를 참고하여 RxKotlin으로 진행했다.
대략적인 Flow는 이렇다. Login화면에서 로그인 후 성공시 Main화면으로 넘기는 것이다.
private fun kakaoLogin() {
if (UserApiClient.instance.isKakaoTalkLoginAvailable(this)) {
UserApiClient.rx.loginWithKakaoTalk(this)
.observeOn(AndroidSchedulers.mainThread())
.onErrorResumeNext { error ->
Log.e("TAG", "kakaoLogin:${error.message} ")
if (error is ClientError && error.reason == ClientErrorCause.Cancelled) {
Single.error(error)
} else {
UserApiClient.rx.loginWithKakaoAccount(this)
}
}.observeOn(AndroidSchedulers.mainThread())
.subscribe({ token ->
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
}, { error ->
Log.e("TAG", "로그인 실패", error)
}).addTo(disposable)
} else {
UserApiClient.rx.loginWithKakaoAccount(this)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ token ->
Log.i("TAG", "로그인 성공 ${token.accessToken} ")
}, { error ->
Log.e("TAG", "로그인 실패: ", error)
}).addTo(disposable)
}
}
로그인 성공 시 받아올 수 있는 값은 token에 관련한 값들밖에 없으므로, intent로 화면전환만 한 뒤
필요한 유저의 정보는 UserApiClient.rx.me() 를 통해 받아오면 된다.
이번 프로젝트는 만들어보고 싶은 앱이기도 했지만, Rx를 좀 더 익숙해지기 위한 프로젝트 이기 때문에 파이어베이스도 Rx를 적용하려고 했다.
검색을 하다 우연히 파이어베이스를 Rx로 래핑시켜놓은 오픈소스를 찾았다.
(물론 오픈소스를 뜯어서 어떻게 구현했는지도 봤다..너무 궁금)
우선 구조는 양방향 바인딩으로 가져온 이메일과 패스워드 정보로 유효성 검사를 한 후 boolean값이 모두 true라면 로그인이 가능케 짰다.
RxFirebaseAuth.signInWithEmailAndPassword(
auth,
inputEmail.value!!,
inputPassword.value!!
)
.observeOn(AndroidSchedulers.mainThread())
.map { it.user != null }
.subscribe({ isSuccess ->
if (isSuccess) {
_isLoginSuccess.value = true
} else {
_isLoginSuccess.value = false
}
}, { error ->
Log.e("TAG", "firebaseLogin: ", error)
}).addTo(disposable)
여기서 오픈소스는 RxFirebaseAuth.signInWithEmailAndPassword 이 부분인데 뜯어보니 Maybe 연산자로 돼 있었다.