An Open Source Retrofit Adapter for Promises

 

Megha Gulati

I enjoy problem solving and seeing ideas come to life. I have a passion for architecting and implementing iOS/Android applications, and am an advocate for good engineering practices and great user experiences.

Updated Dec 20, 2019

Businesses often start with just one platform first, either iOS or Android. But if the product is successful, they realize they need to create an application for the other platform. As both platforms have their own unique interface, they provide different challenges.

One thing which makes it easier for the same development team to switch between these two platforms is to keep application architecture and implementation details similar to each other. Using similar third party libraries when possible is also important while trying to keep parity between the apps, as it allows teams to spend less time ramping up on different third party frameworks.

We recently worked on an Android application for which we had just built the iOS version and we wanted to keep the application architecture consistent. We were using the BrightFutures library for asynchronous calls in iOS and wanted to use something similar in Android. Unfortunately, there is no native Future class available on Android or Kotlin.

Our interface for services in Swift was:

protocol UserService {
    func getUser() -> Future<User, UserServiceError>
}

enum UserServiceError: Error {
    case TimeServiceError
}

After doing some research we found a Promise library in Kotlin which has a similar interface to Future’s in Swift. This would enable our Kotlin service interface to be almost the same as on iOS:

interface UserService {
    fun getUser(): Promise<User, Exception>
}

Great! Just one problem: there’s no retrofit adapter for Promises. (Retrofit is the essential HTTP client for Android.) So we created our own retrofit adapter for Promises. You can checkout the library here.

To use the adapter, add PromiseCallAdapterFactory as a Call adapter when building your Retrofit instance:

val retrofit = Retrofit.Builder()
                .baseUrl("https://example.com/")
                .addCallAdapterFactory(PromiseCallAdapterFactory())
                .build()

Your service methods can now use Promise as their return type.

interface UserService {
    @GET("/user")
    fun getUser(): Promise<User, Exception>
}

 

You can setup the library in your project via Gradle:

  1. Add the JitPack repository to your build by adding following in your root build.gradle at the end of repositories:
    allprojects {
        repositories {
        ...
        maven { url 'https://jitpack.io' }
        }
    }
    
  2. Add the dependency:
    implementation 'com.github.generalui:retrofit2-promise-adapter:1.0'

 

Or setup Via Maven following these steps:


<dependency>
    <groupId>com.github.generalui</groupId>
    <artifactId>retrofit2-promise-adapter</artifactId>
    <version>1.0</version>
</dependency>

How can we help?

Can we help you apply these ideas on your project? Send us a message! You'll get to talk with our awesome delivery team on your very first call.