在我的Kotlin跨平台项目中,我大量使用名称空间。另外,由于我使用的是MVP,因此我具有类似的类名。例如:
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
现在我想在iOS应用程序中使用它(用Swift编写)。
因此,我已将iOS目标添加到build.gradle
-像example中一样。我能够生成Cocoapod(gradlew podspec
)并使用它的Swift应用程序。
build.gradle
的相关部分:
version = "$rootProject.module_version"
kotlin {
cocoapods {
summary = "App MVP of NotesClientApp"
homepage = "some url"
}
}
但是,由于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;
我想应该有一些调整行为的可能性:添加一些配置文件或注释以进行命名调整。
还有其他重命名Obj-c / Swift中与Kotlin不相关的类的可能性吗?我尝试使用Swift typealiases,但仅收到“ typealias无效的重新声明”错误。
有什么想法吗?
PS。我也可以看到模块名称(app-mvp
)作为前缀,例如。 classname App_mvpView__
-是否有可能在不更改Gradle模块名称的情况下调整生成的框架名称(因为我仍然想使用正确的JVM构建工件名称:app-mvp-jvm.jar
)?
PPS。我确实知道,只要重命名类以使其在所有名称空间中都是唯一的,可能会更容易,但是无论如何。
答案 0 :(得分:2)
目前,无法覆盖本机的类名称。 JavaScript MPP有一个名为JSName
的注释,因此将来我不会排除它。要更改框架名称,您只需在目标的baseName
配置中设置framework
值即可。
fromPreset(iOSTarget, 'ios') {
binaries {
framework {
baseName = "MyFrameworkName"
}
}
}
如果您正在使用packForXcode
任务,则可能需要对其进行更新以找到新的框架。我的看起来像这样:
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)
}
}
}
我的矿井还进行了自定义,以支持Xcode中的多个项目方案。应用程序可以指向的每种环境(开发,测试,生产)都有一个。