'swift "completion: @escaping" in kotlin language. How to use callback in kotlin?

I am looking for a way of completion block for my kotlin code. In Swift i have my function:

func fetchRegister(with request: RegisterRequest, completion: @escaping (Result<RegisterResponse,DataResponseError>) -> Void) { 
//do some stuff
// if i got error i can use completion(Result.failure(DataResponseError.networking))
}

in kotlin my current code is:

fun fetchRegister(withRequest: RegisterRequest, callback: (Result<RegisterResponse,DataResponseError>) -> Unit) {
//do some stuff
//cant use callback.onFailure(DataResponseError.networking)
}

My result interface:

interface Result<T,U: DataResponseError>  {
 fun onSuccess(data: T)
 fun onFailure(Error: U)
}

and my DataResponseError:

enum class DataResponseError(val errorMessage: String) {
 httpBody("An error occured while creating httpBody"),
 token("An error occured while getting token"),
 networking("An error occured while fetching data"),
 decoding("An error occured while decoding data")
}

at this moment data cant get out from this function , i cant use callback.onfailure or onSuccess with passing data. How can i fix it?



Solution 1:[1]

There are two ways of implementing callbacks in kotlin.

  1. You can have some interface and pass the reference of interface from actvity to the viewModel or the adapter and then you can call specific function from there.
    Example:
    Interface:
interface CompletionHandler {
   fun onSuccess(data: SomeClass)
   fun onFailure(error: String)
}

Class:

class MainActivity : AppCompatActivity() {

    private val viewModel: MainViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        viewModel.fetchData(this)
    }

    fun onSuccess(data: SomeClass) {
        //onSuccess
    }

    fun onFailure(error: String) {
        //onFailure
    }
}

ViewModel / Adapter class:

class MainViewModel(): ViewModel() {

    fun fetchData(completion: CompletionHandler) {
        //Logic
        completion.onSuccess(responseData)
    }
}
  1. Just like in IOS(swift) we can also use anonymous functions for callback into activities.
    Example:
    Class:
class MainActivity : AppCompatActivity() {

    private val viewModel: MainViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        viewModel.fetchData(data) { data ->
            //Logic
        }
    }
}

ViewModel / Adapter class:

class MainViewModel(): ViewModel() {

    fun fetchData(data: String, completion: (SomeClass) -> Unit) {
        //Logic
        completion(responseData)
    }
}

Solution 2:[2]

Replace your fetchRegister function with:

fun fetchRegister(withRequest: RegisterRequest, callback: Result<RegisterResponse,DataResponseError>){
        //In case of success
        callback.onSuccess(data)
        // In case of failure
        callback.onFailure(DataResponseError.networking)
}



val callback = object : Result<RegisterResponse,DataResponseError> {
    override fun onSuccess(response: RegisterResponse) {
        // Do Something
    }

    override fun onFailure(error: DataResponseError) {
        // Do Something
    }
}


fetchRegister(request, callback)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Vraj Shah
Solution 2