谷歌/Facebook 登录 MVVM [英] Google/Facebook Sign In in MVVM

查看:23
本文介绍了谷歌/Facebook 登录 MVVM的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的项目中使用 MVVM 结构和数据绑定.当涉及到 GG/FB 登录时,事情变得很奇怪,因为他们需要 Context

I'm using MVVM structure with Data Binding in my project. Things get weird when it comes to GG/FB Sign In, because they need Context

googleApiClient = new GoogleApiClient.Builder(context)
            .enableAutoManage(this, this)
            .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
            .build();
Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(googleApiClient);
startActivityForResult(signInIntent, GOOGLE_AUTH);

GoogleApiClient 需要 Context 所以我不能把它传递给 ViewModel,它接收 DataBinding 事件.

GoogleApiClient needs Context so I can't pass it to ViewModel, which receives DataBinding events.

class LoginViewModel(
    dataManager: DataManager,
    schedulerProvider: SchedulerProvider
) : BaseViewModel<LoginNavigator>(dataManager, schedulerProvider) {

    fun loginGoogle(){
        setIsLoading(true)
        //No idea what to write in here
    }
}

有什么方法可以使用带有 MVVM 结构的 Gg/FB 登录?或者我只需要按照原来的方式(在 Activity 中做所有事情)?

Is there any way to use Gg/FB Sign In with MVVM structure ? Or I just have to do the original way (do everything in Activity) ?

推荐答案

非常简单,感谢 @Erik Browne 和 Kotlin 的带有接收器的函数字面量

It is very simple thanks to @Erik Browne and Kotlin’s Function literals with receiver

创建 单个直播事件

创建 LiveMessageEvent

Create LiveMessageEvent

class LiveMessageEvent<T> : SingleLiveEvent<(T.() -> Unit)?>() {

    fun setEventReceiver(owner: LifecycleOwner, receiver: T) {
        observe(owner, Observer { event ->
            if ( event != null ) {
                receiver.event()
            }
        })
    }

    fun sendEvent(event: (T.() -> Unit)?) {
        value = event
    }
}

创建界面

interface ActivityNavigation {
    fun startActivityForResult(intent: Intent?, requestCode: Int)
}

** 现在是实施的时候了!**

在您的 LoginViewModel

const val GOOGLE_SIGN_IN : Int = 9001

class LoginViewModel @Inject constructor(
    private val loginRepository: LoginRepository,
    private val googleSignInClient: GoogleSignInClient
): ViewModel() {

    val startActivityForResultEvent = LiveMessageEvent<ActivityNavigation>()
    ..

    //Called on google login button click
    fun googleSignUp() {
        val signInIntent = googleSignInClient.signInIntent
        startActivityForResultEvent.sendEvent { startActivityForResult(signInIntent, GOOGLE_SIGN_IN) }
    }

    //Called from Activity receving result
    fun onResultFromActivity(requestCode: Int, resultCode: Int, data: Intent?) {
        when(requestCode) {
            GOOGLE_SIGN_IN -> {
                val task = GoogleSignIn.getSignedInAccountFromIntent(data)
                googleSignInComplete(task)
            }
            ..
        }
    }

    private fun googleSignInComplete(completedTask: Task<GoogleSignInAccount>) {
        try {
            val account = completedTask.getResult(ApiException::class.java)
            account?.apply {
                // .. Store user details
                emitUiState(
                    showSuccess = Event(R.string.login_successful)
                )
            }
        }catch (e: ApiException) {
            emitUiState(
                showError = Event(R.string.login_failed)
            )
        }
    }

在您的 LoginActivity[实现 ActivityNavigation 界面]

//Called from onCreate once the ViewModel is initialized.
private fun subscribeUi() {
        //this sets the LifeCycler owner and receiver
        viewModel.startActivityForResultEvent.setEventReceiver(this, this)
        ..
}

public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        viewModel.onResultFromActivity(requestCode,resultCode,data)
        super.onActivityResult(requestCode, resultCode, data)
}

这篇关于谷歌/Facebook 登录 MVVM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆