Как я могу сохранить токен входа в Kotlin? - PullRequest
1 голос
/ 02 ноября 2019

Я чувствую, что, должно быть, мне здесь не хватает чего-то простого. Я пытаюсь вернуть маркер входа, чтобы его можно было использовать в приложении. Токен входа в систему очень хорошо печатается на консоли в методе onResponse, но когда я пытаюсь вернуть этот токен, я не могу.

lateinit var authToken: String

    fun getAuthToken(user: User): String {
        sendPostRequest(user.username, user.password)
        return authToken
    }


    fun sendPostRequest(userName: String, password: String): String {


        var rb = MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            .addFormDataPart("username", userName)
            .addFormDataPart("password", password)
            .build()

        val request = Request.Builder().url(URL_AUTH_ADDRESS).post(rb).build()
        Log.d("request", request.toString())
        val client = OkHttpClient()

        var responseAuth = ""
        client.newCall(request).enqueue(object : Callback {

            override fun onResponse(call: Call?, response: Response?){
                val body = response?.body()?.string()
                authToken = response?.body()?.string()!!
                Log.d("usersAuthToken", body)
            }

            override fun onFailure(call: Call?, e: IOException?) {
                authToken = "fail"
            }

        })
        Log.d("outside method", "resp: " + authToken)
        return authToken


    }

Как показано выше, произойдет сбой, сообщив, что authToken никогда не инициализируется,Но когда я удаляю операторы return, оператор Log.d("usersAuthToken", body) печатает токен так, как должен.

Конечная цель - сохранить этот authToken в приложении после входа в систему. Я очень зеленый в этой областиKotlin, так что если есть лучший способ, который я пропускаю, ПОЖАЛУЙСТА, дайте мне знать!

1 Ответ

0 голосов
/ 03 ноября 2019

Вы пытаетесь вернуть токен до завершения асинхронной функции в sendPostRequest. Вам следует изменить ваши функции getAuthToken и sendPostRequest на следующие:

import kotlinx.coroutines.*

lateinit var authToken: String

    fun getAuthToken(user: User): String {
        runBlocking {
            sendPostRequest(user.username, user.password)
        }
        return authToken
    }


    suspend fun sendPostRequest(userName: String, password: String): String {


        var rb = MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            .addFormDataPart("username", userName)
            .addFormDataPart("password", password)
            .build()

        val request = Request.Builder().url(URL_AUTH_ADDRESS).post(rb).build()
        Log.d("request", request.toString())
        val client = OkHttpClient()

        var responseAuth = ""
        client.newCall(request).enqueue(object : Callback {

            override fun onResponse(call: Call?, response: Response?){
                val body = response?.body()?.string()
                authToken = response?.body()?.string()!!
                Log.d("usersAuthToken", body)
            }

            override fun onFailure(call: Call?, e: IOException?) {
                authToken = "fail"
            }

        })
        Log.d("outside method", "resp: " + authToken)
        return authToken


    }

suspend используется, чтобы указать, является ли это асинхронной функцией, а runBlocking используется, чтобы заставить поток ждать, покафункция завершилась.

Вы также должны добавить в файл build.gradle следующее, чтобы добавить зависимость coroutines:

dependencies {
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.2'
}

И убедитесь, что вы используете последнюю версию Kotlinверсия:

buildscript {
    ext.kotlin_version = '1.3.50'
}

Убедитесь, что в списке хранилищ есть jcenter () или mavenCentral ():

repository {
    jcenter()
}
...