Task

This class should be used by the sdk manger to expose a functionally and handle multithreading as well,

Usually we expose the repository methods.


Why?

As of now due to some limitations in some platform like JS and Java we can not use suspend, therefor exposing suspended functions directly form the sdk’s client manger will not work

Using a wrapper class such as Task will provide a unified approach for multithreading by providing interfaces like await() and get() and other callbacks

Create a Task

To create a task we just need to invoke Task.execute , provide a return type and our logic goes inside the body block

```kotlin
Task.execute<String> {
    val response = repo.makeApiCall<String>()
    repo.saveDB(response)
    return response
}
```
```swift
Tasks.shared.create {
   makeApiCall()
} as! Task<JwtPayload> // make sure to cast the retured type
```
```java
Tasks.create((Callable<String>) () -> "")
```

Use a Task

There is two ways to get the result from a task

Callbacks

In all platforms (except java) you can use the following callbacks

```kotlin
ClientManager.getInstance().makeApiCall()
    .onSuccess { res ->
        // this runs in the background
        println(res)
    }.onSuccessUI { res ->
        // this runs in the UI thread
        println(res)
    }.onFailure { err ->
        // this runs in the background
        println(err)
    }.onFailureUI { err ->
        // this runs in the UI thread
        println(err)
    }.onCanceled {
        // the job is canceled 
    }
```
```swift
ClientManager.getInstance().makeApiCall()
    .onSuccess  { result in
        guard let list = result else { return }
        print(list)
    }.onSuccessUI  { result in
        guard let list = result else { return }
        print(list)
    }.onFailure { err in
        print("Failed: \(err)")
    }.onFailureUI { error in
        print("Failed: \(err)")
    }.onCanceled{
    }
```
```javascript
ClientManager.getInstance().makeApiCall()
    .onSuccess((result) => {
        console.log(result)
    })
    .onSuccessUI((result) => {
        console.log(result)
    }).onFailure((e) => {
        console.log(e)
    }).onFailureUI((e) => {
        console.log(e)
    }).onCanceled((e) => {
        console.log(e)
    })
```

Suspended (blocking)

You can still use the task as suspended to use inside your coroutines,
Or in a blocking approach in languages like java and javascript

```kotlin
ClientManager.getInstance().makeApiCall().await()
```
```java
@Controller
public class Controller {
    @RequestMapping("")
    @ResponseBody
    public String getResult() {
        try {
            // get() is blocking interface that returns the result of excpetoin if failed
            return ClientManager.getInstance().makeApiCall.get();
        } catch (CleintException e) {
            return "Failed! : " + e.message;
        }
    }
}
```
```java
@Controller
public class Controller {
    @RequestMapping("")
    @ResponseBody
    public String getResult() {
        try {
            // Tasks.future will return a CompletableFuture than you case it's get() interface 
            return Tasks.future(ClientManager.getInstance().makeApiCall).get();
        } catch (Exception e) {
            return "Failed! : " + e.message;
        }
    }
}
```
```swift
ClientManager.getInstance().makeApiCall().await(){result, err in
  // this is complation handler that will return both resulte and error
}
```
```javascript
// your sdk will always has a refrence to core classes
const Tasks = require('@example/my-lib').io.telereso.kmp.core.Tasks; 

async function getResult(){
    // Tasks.async will return you a promise from a task
    await Tasks.async(ClientManager.getInstance().makeApiCall())
}
```

onSuccess

Called when a task is done and successful, you can use the result in background thread


onSuccessUI

Called when a task is done and successful, you can use the result in main thread so you can make UI operations (hide loaders), Both onSuccess onSuccessUI will be invoked


onFailure

if the task failed , the result will be a ClientExcecptoin , if it was an api call you will get the http status and url that failed in case multiple api calls were made


onFailureUI

if task failed , the result will be a ClientExcecptoin , use this callback to update the UI in main thread (show error UI) the exception might hold the backend error message


onCancel

If the task is canceled , Task can be canceled using cancel()


onComplete

Will be called after success, failure of cancel and return a nullable result or ClientExcecptoin depending on the outcome , To check if task was completed due to cancellation you can use isCancellationException

onCompleteUI

Will be called after success, failure of cancel and return a nullable result or ClientExcecptoin depending on the outcome , To check if task was completed due to cancellation you can use isCancellationException Use this callback to update the UI in main thread (stop showing loaders) —

get

It’s a blocking call to executing the task, best used in java

You can use get or check getOrNull


future

Convert a Task into a CompletableFuture, only available in Java


async

Convert a Task into Promise, only available in JS