In my Kotlin multiplatform project i heavily use namespaces. Also since i'm using MVP i have similar classnames. 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).
So i've added iOS target to build.gradle
- everything like in example. I was able to generate Cocoapod (gradlew podspec
) and use it Swift app.
Related part of 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.
__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? i've tried to use Swift typealiases, but got "typealias invalid redeclaration" error only.
Any thoughts?
PS. Also i can see module name (app-mvp
) works as prefix, eg. 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
)?
PPS. I do understand it could be easier just rename classes to make them unique in all namespaces, but anyway.