简体   繁体   English

如何使用Cocoapods调整Kotlin Multiplatform项目的Swift类名?

[英]How to adjust Swift classnames for Kotlin Multiplatform project with Cocoapods?

In my Kotlin multiplatform project i heavily use namespaces. 在我的Kotlin多平台项目中,我大量使用名称空间。 Also since i'm using MVP i have similar classnames. 另外,由于我使用的是MVP,因此我具有类似的类名。 eg: 例如:

com.company.project.usecase1.Model
com.company.project.usecase1.View
com.company.project.usecase1.Presenter
com.company.project.usecase2.Model
com.company.project.usecase2.View
com.company.project.usecase2.Presenter

Now i want to use it in iOS app (written in Swift). 现在我想在iOS应用程序(用Swift编写)中使用它。 So i've added iOS target to build.gradle - everything like in example . 因此,我已将iOS目标添加到build.gradle示例中一样 I was able to generate Cocoapod ( gradlew podspec ) and use it Swift app. 我能够生成Cocoapod( gradlew podspec )并使用它Swift应用程序。

Related part of build.gradle : build.gradle相关部分:

version = "$rootProject.module_version"

kotlin {
    cocoapods {
        summary = "App MVP of NotesClientApp"
        homepage = "some url"
    }
}

However since Swift does not have namespaces and classnames look similar generated obj-c wrapper looks ugly: it uses artificial mutations (underline) in classnames just to distinguish the names, eg. 但是,由于Swift没有名称空间,而且类名看起来很相似,生成的obj-c包装器看起来很丑陋:它在类名中使用了人工突变(下划线)来区分名称,例如。

__attribute__((swift_name("Presenter__")))
@protocol App_mvpPresenter__ <App_mvpBasePresenter>
@required
@end;

__attribute__((swift_name("View__")))
@protocol App_mvpView__ <App_mvpBaseView>
@required
- (void)showValidationErrorError:(App_mvpKotlinException *)error __attribute__((swift_name("showValidationError(error:)")));
- (void)showNotesList __attribute__((swift_name("showNotesList()")));
@property NSString *host __attribute__((swift_name("host")));
@property NSString *port __attribute__((swift_name("port")));
@end;

__attribute__((swift_name("Model__")))
@interface App_mvpModel__ : KotlinBase
- (instancetype)initWith_host:(NSString * _Nullable)_host _port:(App_mvpUInt * _Nullable)_port __attribute__((swift_name("init(_host:_port:)"))) __attribute__((objc_designated_initializer));
- (void)updateHost:(NSString *)host port:(uint32_t)port __attribute__((swift_name("update(host:port:)")));
@property (readonly) NSString * _Nullable host __attribute__((swift_name("host")));
@property (readonly) App_mvpUInt * _Nullable port __attribute__((swift_name("port")));
@property id<App_mvpPresenter__> _Nullable presenter __attribute__((swift_name("presenter")));
@end;

__attribute__((objc_subclassing_restricted))
__attribute__((swift_name("PresenterImpl__")))
@interface App_mvpPresenterImpl__ : KotlinBase <App_mvpPresenter__>
- (instancetype)initWithModel:(App_mvpModel__ *)model __attribute__((swift_name("init(model:)"))) __attribute__((objc_designated_initializer));
- (void)attachViewView:(id<App_mvpView__>)view __attribute__((swift_name("attachView(view:)")));
- (void)onModelChanged __attribute__((swift_name("onModelChanged()")));
- (void)onViewChanged __attribute__((swift_name("onViewChanged()")));
- (void)onViewDetached __attribute__((swift_name("onViewDetached()")));
@property (readonly) App_mvpModel__ *model __attribute__((swift_name("model")));
@end;

I guess there should be some possibility to adjust the behaviour: add some config file or annotations for naming adjustments. 我想应该有一些调整行为的可能性:添加一些配置文件或注释以进行命名调整。

Any other possibility to rename classes in Obj-c/Swift not related to Kotlin? 在Obj-c / Swift中重命名与Kotlin不相关的类还有其他可能性吗? i've tried to use Swift typealiases, but got "typealias invalid redeclaration" error only. 我曾尝试使用Swift typealiases,但仅收到“ typealias无效的重新声明”错误。

Any thoughts? 有什么想法吗?

PS. PS。 Also i can see module name ( app-mvp ) works as prefix, eg. 我也可以看到模块名称( app-mvp )作为前缀,例如。 classname App_mvpView__ - any possibility to adjust generated Framework name without changing of Gradle module name (since i still want to use proper JVM build artifact names: app-mvp-jvm.jar )? classname App_mvpView__可以在不更改Gradle模块名称的情况下调整生成的框架名称的可能性(因为我仍然想使用适当的JVM构建工件名称: app-mvp-jvm.jar )?

PPS. PPS。 I do understand it could be easier just rename classes to make them unique in all namespaces, but anyway. 我确实知道,只要重命名类以使其在所有名称空间中都是唯一的,可能会更容易,但是无论如何。

At this time it isn't possible to override the class names for native. 目前,无法覆盖本机的类名。 JavaScript MPP has an annotation called JSName so I wouldn't rule it out in the future. JavaScript MPP有一个名为JSName的注释,因此将来我不会排除它。 To change your framework name you can simply set the baseName value in your framework configuration under targets. 要更改框架名称,您只需在framework配置中的目标下设置baseName值即可。

    fromPreset(iOSTarget, 'ios') {
        binaries {
            framework {
                baseName = "MyFrameworkName"
            }
        }
    }

If you're using the packForXcode task you will likely need to update it to find your new framework. 如果您使用packForXcode任务,则可能需要对其进行更新以找到您的新框架。 Mine looks like this: 我的看起来像这样:

task packForXCode(type: Sync) {
    final File frameworkDir = new File(buildDir, "xcode-frameworks")
    final String mode = (project.findProperty("XCODE_CONFIGURATION")?.toUpperCase() ?: 'DEBUG').split("_").first()


    inputs.property "mode", mode
    def bin = kotlin.targets.ios.compilations.main.target.binaries.findFramework("", mode)
    dependsOn bin.linkTask

    from bin.outputDirectory
    into frameworkDir

    doLast {
        new File(frameworkDir, 'gradlew').with {
            text = "#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '${rootProject.rootDir}'\n./gradlew \$@\n"
            setExecutable(true)
        }
    }
}

Mine also has a customization to support multiple project schemes in Xcode. 我的也有自定义以支持Xcode中的多个项目方案。 I have one for each environment (dev, test, prod) the app can point to. 对于应用程序可以指向的每个环境(开发,测试,生产),我都有一个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM