Hi! I have a sealed interface in my Shared code. I...
# multiplatform
c
Hi! I have a sealed interface in my Shared code. It has 2 inner data classes. Those are not being exposed to the iOS library.
Copy code
sealed interface SomeInterface {
    data class SomeInnerClass(
        val internalObj: SomeInternalObj,
    ) : SomeInterface

    data class AnotherInnerClass(
        val internalObj: AnotherInternalObj
    ) : SomeInterface
}
🔴
SomeInterface.SomeInnerClass
is not exposed to iOS If I try the same, but using a class, it works:
Copy code
sealed class SomeClass {
    data class SomeInnerClass(
        val internalObj: SomeInternalObj,
    ) : SomeClass

    data class AnotherInnerClass(
        val internalObj: AnotherInternalObj
    ) : SomeClass
}
🟢
SomeClass.SomeInnerClass
is exposed to iOS Is it possible to make the internal classes visible to iOS using an interface instead of a class?
a
You can access it if you call the sealed interface class directly:
Copy code
let clazz = SomeClass.SomeInnerClass(internalObj: "42")
        let interface = SomeInterfaceSomeInnerClass(internalObj: "42")
c
For me it’s not being generated 😞
I have tried to search for it in the headers file. It’s not even created there
a
what is you kotlin version?
c
1.6.21
a
hmm.. I have the same version and I can see this classes generated for me.
Copy code
__attribute__((objc_subclassing_restricted))
__attribute__((swift_name("SomeClass.AnotherInnerClass")))
@interface GCMSomeClassAnotherInnerClass : GCMSomeClass
- (instancetype)initWithInternalObj:(int32_t)internalObj __attribute__((swift_name("init(internalObj:)"))) __attribute__((objc_designated_initializer));
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable));
+ (instancetype)new __attribute__((unavailable));
- (int32_t)component1 __attribute__((swift_name("component1()")));
- (GCMSomeClassAnotherInnerClass *)doCopyInternalObj:(int32_t)internalObj __attribute__((swift_name("doCopy(internalObj:)")));
- (BOOL)isEqual:(id _Nullable)other __attribute__((swift_name("isEqual(_:)")));
- (NSUInteger)hash __attribute__((swift_name("hash()")));
- (NSString *)description __attribute__((swift_name("description()")));
@property (readonly) int32_t internalObj __attribute__((swift_name("internalObj")));
@end;

__attribute__((objc_subclassing_restricted))
__attribute__((swift_name("SomeClass.SomeInnerClass")))
@interface GCMSomeClassSomeInnerClass : GCMSomeClass
- (instancetype)initWithInternalObj:(NSString *)internalObj __attribute__((swift_name("init(internalObj:)"))) __attribute__((objc_designated_initializer));
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable));
+ (instancetype)new __attribute__((unavailable));
- (NSString *)component1 __attribute__((swift_name("component1()")));
- (GCMSomeClassSomeInnerClass *)doCopyInternalObj:(NSString *)internalObj __attribute__((swift_name("doCopy(internalObj:)")));
- (BOOL)isEqual:(id _Nullable)other __attribute__((swift_name("isEqual(_:)")));
- (NSUInteger)hash __attribute__((swift_name("hash()")));
- (NSString *)description __attribute__((swift_name("description()")));
@property (readonly) NSString *internalObj __attribute__((swift_name("internalObj")));
@end;

__attribute__((swift_name("SomeInterface")))
@protocol GCMSomeInterface
@required
@end;

__attribute__((objc_subclassing_restricted))
__attribute__((swift_name("SomeInterfaceAnotherInnerClass")))
@interface GCMSomeInterfaceAnotherInnerClass : GCMBase <GCMSomeInterface>
- (instancetype)initWithInternalObj:(int32_t)internalObj __attribute__((swift_name("init(internalObj:)"))) __attribute__((objc_designated_initializer));
- (int32_t)component1 __attribute__((swift_name("component1()")));
- (GCMSomeInterfaceAnotherInnerClass *)doCopyInternalObj:(int32_t)internalObj __attribute__((swift_name("doCopy(internalObj:)")));
- (BOOL)isEqual:(id _Nullable)other __attribute__((swift_name("isEqual(_:)")));
- (NSUInteger)hash __attribute__((swift_name("hash()")));
- (NSString *)description __attribute__((swift_name("description()")));
@property (readonly) int32_t internalObj __attribute__((swift_name("internalObj")));
@end;

__attribute__((objc_subclassing_restricted))
__attribute__((swift_name("SomeInterfaceSomeInnerClass")))
@interface GCMSomeInterfaceSomeInnerClass : GCMBase <GCMSomeInterface>
- (instancetype)initWithInternalObj:(NSString *)internalObj __attribute__((swift_name("init(internalObj:)"))) __attribute__((objc_designated_initializer));
- (NSString *)component1 __attribute__((swift_name("component1()")));
- (GCMSomeInterfaceSomeInnerClass *)doCopyInternalObj:(NSString *)internalObj __attribute__((swift_name("doCopy(internalObj:)")));
- (BOOL)isEqual:(id _Nullable)other __attribute__((swift_name("isEqual(_:)")));
- (NSUInteger)hash __attribute__((swift_name("hash()")));
- (NSString *)description __attribute__((swift_name("description()")));
@property (readonly) NSString *internalObj __attribute__((swift_name("internalObj")));
@end;
I have copypasted to my common your example. The only thing I changed is parameter types from "SomeInternalObj" to String/Int so that I can complile.
c
Hmm. Not sure if this can be related with the inner object
This is really weird behavior. Can you confirm if something changes if you name your inner classes with the same name as some object you already have in your system
?
a
Nope. I literally copy pasted your example. Only thing was changed is the type of
internalObj
to
String/Int
Copy code
sealed interface SomeInterface {
 data class SomeInnerClass(
  val internalObj: String,
 ) : SomeInterface

 data class AnotherInnerClass(
  val internalObj: Int
 ) : SomeInterface
}
and
Copy code
sealed class SomeClass {
    data class SomeInnerClass(
        val internalObj: String,
    ) : SomeClass()

    data class AnotherInnerClass(
        val internalObj: Int
    ) : SomeClass()
}
Oh, and they are extracted to separate files.
c
separated files?
a
If you nest this classes inside other files, the name of the class will start with the prefix of the name of the parent file
c
ah ok, this
I’m not sure if this has something to do with the fact that the inner classes have names equal of other objects I already have in the system
Copy code
data class ExploreTv(
    val feed: Feed,
    val promo: ExploreTvPromo?,
) {
    companion object {
        val PREVIEW = ExploreTv(
            feed = Feed.PREVIEW,
            promo = ExploreTvPromo.Account(
                typeToPromote = <http://UserType.CLUB|UserType.CLUB>,
            ),
        )
    }
}

sealed interface ExploreTvPromo {

    data class Account(
        val typeToPromote: UserType,
    ) : ExploreTvPromo

    data class Match(
        val modelToPromote: ExploreMatch,
    ) : ExploreTvPromo
}
the actual code looks like this ^
Account and Match are objects that I have in other places of my application
a
Try to change that to string/int and see what happens