Foso / Ktorfit

HTTP client generator / KSP plugin for Kotlin Multiplatform (Android, iOS, Js, Jvm, Native, WasmJs)) using KSP and Ktor clients inspired by Retrofit https://foso.github.io/Ktorfit
https://foso.github.io/Ktorfit
Apache License 2.0
1.58k stars 41 forks source link

[Bug]: Running Ktorfit on normal Android app (non multiplatform) fails at compile time #87

Closed WarBorg closed 1 year ago

WarBorg commented 2 years ago

Ktorfit version

1.0.0-beta15

What happened and how can we reproduce this issue?

I am trying to port a Android app to KMM, but before I started to actually create the KMM project I wanted to move all my Android specific libraries to ones that support KMP so I switched from Room to SQLDelight, and from LiveData to Flow, not it was up to the web service to be migrated from Retrofit. While searching the internet I came to this nice library that basically mimics Retrofit. I followed the guide on how to set it up but I only found documentation for multiplatform projects, which didn't exactly worked in my situation since this is still a standalone Android app so at first I tried to use the gradle dependencies like so:

def ktorfit_version = '1.0.0-beta15'
implementation "de.jensklingenberg.ktorfit:ktorfit-ksp:$ktorfit_version"
implementation "de.jensklingenberg.ktorfit:ktorfit-lib:$ktorfit_version"

This compiled fine but I was getting an error saying that no KPS files were generated so I checked the build/generated/source folder and indeed no files were generated. After some more reading I finally found some info on the KPS website and tried also adding in the dependencies under the lines shown above

ksp "de.jensklingenberg.ktorfit:ktorfit-ksp:$ktorfit_version"

Although it is stated clearly this is deprecated, at least it manage to generate the files in build/generated/kps but I am getting a compilation error saying that my interface cannot be found : Unresolved reference: BusApi and that my methods have nothing to override

Screenshot 2022-11-04 at 01 24 59

My configuration looks like this

    private val api: BusApi by lazy {
        val ktorClient = HttpClient() {
            install(ContentNegotiation) {
                json(Json { isLenient = true; ignoreUnknownKeys = true })
            }
        }

        Ktorfit.Builder()
            .baseUrl(BASE_URL)
            .httpClient(ktorClient)
            .build()
            .create<BusApi>()
...
    companion object {
        const val BASE_URL = "https://mywebsitehere/api/"
    }

and my interface like this:


    interface BusApi {

        @GET("buslines")
        suspend fun getBusLines(): List<BusLineDto>

        @GET("busstations/{lineNumberLink}")
        suspend fun getBusStations(
            @Path("lineNumberLink") lineNumberLink: String
        ): List<BusStationDto>

        @GET("bustimetables/{scheduleLink}")
        suspend fun getBusTimetables(
            @Path("scheduleLink") scheduleLink: String
        ): List<BusTimetableDto>
    }

Unfortunately I am not an expert on Gradle or KPS so I don't know if my configuration is good or actually what I am trying to do even supported on non multiplatform apps

Any help would be appreciated

What did you expect to happen?

To have no compilation errors

Is there anything else we need to know about?

No response

Foso commented 1 year ago

Hi @WarBorg , please check the Android only example here: https://github.com/Foso/Ktorfit/tree/master/example/AndroidOnlyExample

WarBorg commented 1 year ago

@Foso thx for the hint, actually my issue was that I was having the API interface declared inside the class that was implementing it (a leftover from the retrofit implementation) as soon as I exposed the interface outside of the class, everything worked as expected