Kotlin / kotlinx.serialization

Kotlin multiplatform / multi-format serialization
Apache License 2.0
5.38k stars 620 forks source link

Multiplatform iOS application does not compile due to malformed header file #1053

Closed DmyMi closed 4 years ago

DmyMi commented 4 years ago

The packForXcode task completes successfully, but when i try to compile iOS app i get a lot of errors that look like this:

CompileSwift normal x86_64 /Users/user/Development/AndroidStudioProjects/coolapp/ios/iosApp/Views/Account/AccountEditView.swift (in target 'iosApp' from project 'iosApp')
    cd /Users/user/Development/AndroidStudioProjects/coolapp/ios
    // long list of swift files to compile
<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "Headers/RNInject.h"
        ^
/Users/user/Development/AndroidStudioProjects/coolapp/inject/build/xcode-frameworks/RNInject.framework/Headers/RNInject.h:11265:792: warning: missing terminating '"' character
- (instancetype)initWithEncodeDefaults:(BOOL)encodeDefaults ignoreUnknownKeys:(BOOL)ignoreUnknownKeys isLenient:(BOOL)isLenient serializeSpecialFloatingPointValues:(BOOL)serializeSpecialFloatingPointValues allowStructuredMapKeys:(BOOL)allowStructuredMapKeys prettyPrint:(BOOL)prettyPrint unquotedPrint:(BOOL)unquotedPrint indent:(NSString *)indent coerceInputValues:(BOOL)coerceInputValues useArrayPolymorphism:(BOOL)useArrayPolymorphism classDiscriminator:(NSString *)classDiscriminator __attribute__((swift_name("init(encodeDefaults:ignoreUnknownKeys:isLenient:serializeSpecialFloatingPointValues:allowStructuredMapKeys:prettyPrint:unquotedPrint:indent:coerceInputValues:useArrayPolymorphism:classDiscriminator:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable("This class is deprecated for removal during serialization 1.0 API stabilization.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       ^
<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "Headers/RNInject.h"
        ^
/Users/user/Development/AndroidStudioProjects/coolapp/inject/build/xcode-frameworks/RNInject.framework/Headers/RNInject.h:11265:792: error: expected expression
- (instancetype)initWithEncodeDefaults:(BOOL)encodeDefaults ignoreUnknownKeys:(BOOL)ignoreUnknownKeys isLenient:(BOOL)isLenient serializeSpecialFloatingPointValues:(BOOL)serializeSpecialFloatingPointValues allowStructuredMapKeys:(BOOL)allowStructuredMapKeys prettyPrint:(BOOL)prettyPrint unquotedPrint:(BOOL)unquotedPrint indent:(NSString *)indent coerceInputValues:(BOOL)coerceInputValues useArrayPolymorphism:(BOOL)useArrayPolymorphism classDiscriminator:(NSString *)classDiscriminator __attribute__((swift_name("init(encodeDefaults:ignoreUnknownKeys:isLenient:serializeSpecialFloatingPointValues:allowStructuredMapKeys:prettyPrint:unquotedPrint:indent:coerceInputValues:useArrayPolymorphism:classDiscriminator:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable("This class is deprecated for removal during serialization 1.0 API stabilization.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       ^
<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "Headers/RNInject.h"
        ^
/Users/user/Development/AndroidStudioProjects/coolapp/inject/build/xcode-frameworks/RNInject.framework/Headers/RNInject.h:11267:226: warning: missing terminating '"' character
Instead of storing JsonConfiguration instances of the code, Json instances can be used directly:'Json(MyJsonConfiguration.copy(prettyPrint = true))' can be replaced with 'Json(from = MyApplicationJson) { prettyPrint = true }'")));
                                                                                                                                                                                                                                 ^
<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "Headers/RNInject.h"
        ^
/Users/user/Development/AndroidStudioProjects/coolapp/inject/build/xcode-frameworks/RNInject.framework/Headers/RNInject.h:11268:729: error: expected ')'
- (RNIJsonConfiguration *)doCopyEncodeDefaults:(BOOL)encodeDefaults ignoreUnknownKeys:(BOOL)ignoreUnknownKeys isLenient:(BOOL)isLenient serializeSpecialFloatingPointValues:(BOOL)serializeSpecialFloatingPointValues allowStructuredMapKeys:(BOOL)allowStructuredMapKeys prettyPrint:(BOOL)prettyPrint unquotedPrint:(BOOL)unquotedPrint indent:(NSString *)indent coerceInputValues:(BOOL)coerceInputValues useArrayPolymorphism:(BOOL)useArrayPolymorphism classDiscriminator:(NSString *)classDiscriminator __attribute__((swift_name("doCopy(encodeDefaults:ignoreUnknownKeys:isLenient:serializeSpecialFloatingPointValues:allowStructuredMapKeys:prettyPrint:unquotedPrint:indent:coerceInputValues:useArrayPolymorphism:classDiscriminator:)")));
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        ^
<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "Headers/RNInject.h"
        ^
/Users/user/Development/AndroidStudioProjects/coolapp/inject/build/xcode-frameworks/RNInject.framework/Headers/RNInject.h:11268:729: error: expected ')'
- (RNIJsonConfiguration *)doCopyEncodeDefaults:(BOOL)encodeDefaults ignoreUnknownKeys:(BOOL)ignoreUnknownKeys isLenient:(BOOL)isLenient serializeSpecialFloatingPointValues:(BOOL)serializeSpecialFloatingPointValues allowStructuredMapKeys:(BOOL)allowStructuredMapKeys prettyPrint:(BOOL)prettyPrint unquotedPrint:(BOOL)unquotedPrint indent:(NSString *)indent coerceInputValues:(BOOL)coerceInputValues useArrayPolymorphism:(BOOL)useArrayPolymorphism classDiscriminator:(NSString *)classDiscriminator __attribute__((swift_name("doCopy(encodeDefaults:ignoreUnknownKeys:isLenient:serializeSpecialFloatingPointValues:allowStructuredMapKeys:prettyPrint:unquotedPrint:indent:coerceInputValues:useArrayPolymorphism:classDiscriminator:)")));
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        ^
<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "Headers/RNInject.h"
        ^
/Users/user/Development/AndroidStudioProjects/coolapp/inject/build/xcode-frameworks/RNInject.framework/Headers/RNInject.h:16880:197: warning: missing terminating '"' character
+ (RNIJson *)JsonConfiguration:(RNIJsonConfiguration *)configuration context:(RNISerializersModule *)context __attribute__((swift_name("Json(configuration:context:)"))) __attribute__((unavailable("Deprecated in the favour of Json {} builder function during serialization 1.0 API stabilization.
                                                                                                                                                                                                    ^
<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "Headers/RNInject.h"
        ^
/Users/user/Development/AndroidStudioProjects/coolapp/inject/build/xcode-frameworks/RNInject.framework/Headers/RNInject.h:16880:197: error: expected expression
+ (RNIJson *)JsonConfiguration:(RNIJsonConfiguration *)configuration context:(RNISerializersModule *)context __attribute__((swift_name("Json(configuration:context:)"))) __attribute__((unavailable("Deprecated in the favour of Json {} builder function during serialization 1.0 API stabilization.
                                                                                                                                                                                                    ^
<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "Headers/RNInject.h"
        ^
/Users/user/Development/AndroidStudioProjects/coolapp/inject/build/xcode-frameworks/RNInject.framework/Headers/RNInject.h:16882:77: warning: missing terminating '"' character
Json(JsonConfiguration.Default) can be replaced with Json companion instead.")));
                                                                            ^
<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "Headers/RNInject.h"
        ^
/Users/user/Development/AndroidStudioProjects/coolapp/inject/build/xcode-frameworks/RNInject.framework/Headers/RNInject.h:16883:154: warning: missing terminating '"' character
+ (RNIJson *)JsonConfiguration:(RNISubtypeToDetectDefault *)configuration __attribute__((swift_name("Json(configuration:)"))) __attribute__((unavailable("Deprecated in the favour of Json.Default companion during serialization 1.0 API stabilization.
                                                                                                                                                         ^
<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "Headers/RNInject.h"
        ^
/Users/user/Development/AndroidStudioProjects/coolapp/inject/build/xcode-frameworks/RNInject.framework/Headers/RNInject.h:16884:1: warning: missing terminating '"' character
")));
^
<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "Headers/RNInject.h"
        ^
/Users/user/Development/AndroidStudioProjects/coolapp/inject/build/xcode-frameworks/RNInject.framework/Headers/RNInject.h:16885:204: warning: missing terminating '"' character
+ (RNIJson *)JsonConfiguration:(RNISubtypeToDetectDefault *)configuration context_:(RNISerializersModule *)context __attribute__((swift_name("Json(configuration:context_:)"))) __attribute__((unavailable("Deprecated in the favour of Json {} builder function during serialization 1.0 API stabilization.
                                                                                                                                                                                                           ^
<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "Headers/RNInject.h"
        ^
/Users/user/Development/AndroidStudioProjects/coolapp/inject/build/xcode-frameworks/RNInject.framework/Headers/RNInject.h:16886:1: warning: missing terminating '"' character
")));
^
<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "Headers/RNInject.h"
        ^
/Users/user/Development/AndroidStudioProjects/coolapp/inject/build/xcode-frameworks/RNInject.framework/Headers/RNInject.h:16887:155: warning: missing terminating '"' character
+ (RNIJson *)JsonConfiguration_:(RNISubtypeToDetectStable *)configuration __attribute__((swift_name("Json(configuration_:)"))) __attribute__((unavailable("Deprecated in the favour of Json {} builder function during serialization 1.0 API stabilization.
                                                                                                                                                          ^
<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "Headers/RNInject.h"
        ^
/Users/user/Development/AndroidStudioProjects/coolapp/inject/build/xcode-frameworks/RNInject.framework/Headers/RNInject.h:16888:1: warning: missing terminating '"' character
")));
^
<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "Headers/RNInject.h"
        ^
/Users/user/Development/AndroidStudioProjects/coolapp/inject/build/xcode-frameworks/RNInject.framework/Headers/RNInject.h:17641:6: error: expected ')'
@end;
     ^
<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "Headers/RNInject.h"
        ^
/Users/user/Development/AndroidStudioProjects/coolapp/inject/build/xcode-frameworks/RNInject.framework/Headers/RNInject.h:17641:6: error: expected ')'
@end;
     ^
<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "Headers/RNInject.h"
        ^
/Users/user/Development/AndroidStudioProjects/coolapp/inject/build/xcode-frameworks/RNInject.framework/Headers/RNInject.h:17641:6: error: expected ';' after method prototype
@end;
     ^
<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "Headers/RNInject.h"
        ^
/Users/user/Development/AndroidStudioProjects/coolapp/inject/build/xcode-frameworks/RNInject.framework/Headers/RNInject.h:17644:22: error: missing '@end'
NS_ASSUME_NONNULL_END
                     ^
/Users/user/Development/AndroidStudioProjects/coolapp/inject/build/xcode-frameworks/RNInject.framework/Headers/RNInject.h:16877:1: note: class started here
@interface RNIJsonKt : RNIBase
^
/Users/user/Development/AndroidStudioProjects/coolapp/ios/iosApp/Views/Account/AccountViewModel+iOS.swift:11:8: error: could not build Objective-C module 'RNInject'
import RNInject
       ^

To Reproduce my module's build.gradle.kts:

import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget

plugins {
    id("com.android.library")
    kotlin("multiplatform")
    id("dev.icerock.mobile.multiplatform-resources")
}

android {
    compileSdkVersion(Deps.Versions.compileSdk)
    buildToolsVersion(Deps.Versions.buildTools)

    defaultConfig {
        minSdkVersion(Deps.Versions.minSdk)
        targetSdkVersion(Deps.Versions.compileSdk)
        versionCode = 1
        versionName = "1.0"
        testInstrumentationRunner = "android.support.test.runner.AndroidJUnitRunner"
    }

    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }

    sourceSets {
        getByName("main").java.srcDirs("src/androidMain/kotlin")
        getByName("main").res.srcDirs("src/androidMain/res")
        getByName("main").manifest.srcFile("src/androidMain/AndroidManifest.xml")
    }
}

version = "1.0"

kotlin {
    android()
    ios() {
        binaries {
            framework {
                export(project(":presentation"))
                export(project(":domain"))
                export(project(":core"))
                transitiveExport = true
                baseName = "RNInject"
//                freeCompilerArgs += "-Xobjc-generics"
                linkerOpts.add("-lsqlite3")
            }
        }
    }

    sourceSets {
        val commonMain by getting {
            dependencies {
                api(project(":domain"))
                api(project(":core"))
                api(project(":presentation"))
                implementation(Deps.Kotlin.Multiplatform.coroutines)
                implementation(Deps.Kotlin.Multiplatform.serialization)
                implementation(Deps.Kotlin.Multiplatform.serialization_protobuf)
                implementation(Deps.Kotlin.Multiplatform.ktor_core)
                implementation(Deps.Kotlin.Multiplatform.kodein)
                implementation(Deps.Kotlin.Multiplatform.ktor_serialization)
                implementation(Deps.Kotlin.Multiplatform.ktor_logging)
                implementation(Deps.Kotlin.Multiplatform.settings)
            }
        }
        val androidMain by getting {
            dependencies {
                //
            }
        }

        val iosMain by getting {
            dependencies {
                implementation(Deps.Kotlin.Native.ktor_core)
            }
        }
    }
}

multiplatformResources {
    multiplatformResourcesPackage = "package.inject"
}

val packForXcode by tasks.creating(Sync::class) {
    val targetDir = File(buildDir, "xcode-frameworks")

    // / selecting the right configuration for the iOS
    // / framework depending on the environment
    // / variables set by Xcode build
    val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
    val sdkName = System.getenv("SDK_NAME") ?: "iphonesimulator"
    val targetName = "ios" + if (sdkName.startsWith("iphoneos")) "Arm64" else "X64"
    val framework = kotlin.targets
        .getByName<KotlinNativeTarget>(targetName)
        .binaries.getFramework(mode)
    inputs.property("mode", mode)
    dependsOn(framework.linkTask)

    from({ framework.outputDirectory })
    into(targetDir)
}

tasks.getByName("build").dependsOn(packForXcode)

i configure the Json builder during Ktor initialization:

import io.ktor.client.HttpClient
import io.ktor.client.engine.ios.Ios
import io.ktor.client.features.defaultRequest
import io.ktor.client.features.json.JsonFeature
import io.ktor.client.features.json.serializer.KotlinxSerializer
import io.ktor.client.features.logging.DEFAULT
import io.ktor.client.features.logging.LogLevel
import io.ktor.client.features.logging.Logger
import io.ktor.client.features.logging.Logging
import io.ktor.client.request.host
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.serialization.json.Json
import org.kodein.di.*

@ExperimentalMultiplatform
@ExperimentalCoroutinesApi
@ExperimentalUnsignedTypes
internal fun networkModule() = DI.Module(name = "networkModule") {
// other stuff
    bind<HttpClient>() with provider {
        val url = instance<String>(tag = "BASE_URL")
        HttpClient {
            engine {
                Ios.create {
                    configureRequest {
                        setAllowsCellularAccess(true)
                    }
                }
            }
            defaultRequest {
                host = url
            }
            install(JsonFeature) {
                serializer = KotlinxSerializer(
                    Json {
                        isLenient = true
                        ignoreUnknownKeys = true
                        allowSpecialFloatingPointValues = true
                        useArrayPolymorphism = true
                    }
                )
            }
        }
    }
}

Expected behavior app compiles

Environment

sandwwraith commented 4 years ago

I think it's #989