Apollo Multiplatform is IOS

I’am trying to use apollo 3.0 (beta02) in kotlin multiplatform. I’ve made two shared modules in kmm project one with queries (":queries") and schema and another with network configuration (":network") which uses queries module to make requests.
I’ve made a method in interface of Networklient
suspend fun execute(operation: Operation): Data?
to make requests which works perfectly in Android, but i’m stacked in problem with using such a client on IOS with Swift.
When calling this method i’m getting an error: “Argument type ‘LogInUserMutation’ (generated mutation) does not conform to expected type ‘Apollo_apiOperation’” (generated operation type for IOS from KN). An these two types are not related. Could i solve this problem? I need to handle client and it configurations in km in order to have a single configuration and error handling, token prolongation and logging. Thank you in advance

Hi ! Thanks for reaching out! Can you share your Swift and Kotlin code?

Mutation inherits from Operation so I would expect this to work but maybe there’s something happening with generics.

Yes, of course!


this is queries module gradle


network module gradle


network client interface
where Operation is com.apollographql.apollo3.api.Operation


network client implementation


and this is how it used from Swift


from android is OK

I’ve found that two modules generates two different Operation types from KMM.

/**
 @note This method converts instances of Exception to errors.
 Other uncaught Kotlin exceptions are fatal.
*/
- (void)executeOperation:(id<ChoozieNetworkApollo_apiOperation>)operation completionHandler:(void (^)(id<ChoozieNetworkApollo_apiOperationData> _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("execute(operation:completionHandler:)")));

NetworkClient.execute() (":network" module) method expects ChoozieNetworkApollo_apiOperation, but generated Mutation is ChoozieQueriesApollo_apiMutation is another type (from “:queries” module):

@interface ChoozieQueriesLogInUserMutation : ChoozieQueriesBase <ChoozieQueriesApollo_apiMutation>
- (instancetype)initWithUsername:(NSString *)username password:(NSString *)password __attribute__((swift_name("init(username:password:)"))) __attribute__((objc_designated_initializer));

@mbonnin , maybe i have configured something wrong?

Hi! :wave: We are looking at multi module setup - in the meantime do you think you could share your project (or if that’s not possible, a similar simple project)?

Yeah, I will prepare the same simplified repository soon. Hope it would be helpful. Do I understand correctly that it will not be possible to do this in a multi-module project yet and I need to put queries into my network module?

Thanks!

Do I understand correctly that it will not be possible to do this in a multi-module project yet and I need to put queries into my network module?

To be honest we’re not sure yet :slight_smile: We’re investigating but we actually never tried this before.

Thanks! Then I will try to help with the project and try everything the same so far from one module

1 Like

A question: are you exporting both modules as separate frameworks? I managed to create a small project with 2 modules network and query as in your case, exporting only network as an XCode framework (but including its dependencies following this), and it looks like I don’t have the issue.

In case of one module == one exported framework looks like shouldn’t cause any problems. Yeah, I did with exporting two separated frameworks cause the point of separation is to be able to add or change requests without re-publishing the network module, so there would be no reason to store queries in different module.
I will try to make with one framework, as you said

There’s a strong possibility that exporting to multiple frameworks is not really supported by KMP right now, looking at this issue (sorry there’s a lot of information) that’s what I understand. Doing a single “umbrella” framework seems to be the workaround but I recognize this doesn’t address your need to republish only the query module and not the network one.

1 Like

Okay, I understand. It would be great someday to make real multimodule export, but now for workaround it would be quiete a good option. I’l try another idea, may be it will give a compromise. I will return with a result. Thank you very much for your work

1 Like

Hello, I’ve made one framework export with api(":queries) but I can’t now see any mutations, they are not generated from my network module. Could you please share the configuration you did to achieve this?

Of course!

Maybe you made it api but you didn’t set it to export specifically inside the framework block?

Here’s the full build.gradle.kts for the network module of my sample app:

plugins {
    kotlin("multiplatform")
    id("com.apollographql.apollo3") version "3.0.0-beta04-SNAPSHOT"
}

kotlin {
    iosX64("ios") {
        binaries {
            framework {
                baseName = "MyMppLibraryNetwork"
                export(project(":queries"))
            }
        }
    }
    sourceSets {
        val commonMain by getting {
            dependencies {
                implementation("com.apollographql.apollo3:apollo-runtime:3.0.0-beta04-SNAPSHOT")
                api(project(":queries"))
            }
        }
        val commonTest by getting {
            dependencies {
                implementation(kotlin("test"))
            }
        }
    }
}

dependencies {
    apolloMetadata(project(":queries"))
}

apollo {
    packageName.set("me.bod.library")
}

ooh, thank you very much, i did a mistake with defining export in wrong place. Everything works!

1 Like