https://kotlinlang.org logo
#multiplatform
Title
# multiplatform
p

Piasy

01/09/2020, 11:52 AM
Hello Guys, I want to build my KMPP iOS sources into an iOS static library, and my iOS kotlin code uses some ObjC classes from another iOS framework, which are accessed using cinterop. When my ObjC app code (
ViewController.m
) calls iOS kotlin function (
KmppBootstrap.test
, built to iOS static library), which accept an ObjC object (
IOSDummyObj
from
IOSDummyFramework.framework
), if
KmppBootstrap.test
use
IOSDummyObj
, my app will crash at
Kotlin_Interop_refToObjC
with
EXC_BAD_ACCESS (code=1, address=0x1a102ba0120)
, but if
KmppBootstrap.test
don't, my app runs fine. Could you guys please help me, thanks! I upload my repro project onto GitHub, in the
ios_static_lib_repro
branch of https://github.com/Piasy/KmppBootstrap , my iOS kotlin code is mainly
kmpp/src/iosMain/kotlin/com/piasy/kmpp/KmppBootstrap.kt
, and iOS app is under
iOSExample2/iOSExample2/ViewController.m
. Or maybe my app code is wrong?
Copy code
IOSDummyObj* obj = [[IOSDummyObj alloc] initWithInt:42];

    libkmpp_ExportedSymbols* lib = libkmpp_symbols();

    libkmpp_kref_com_piasy_kmpp_KmppBootstrap kmpp = lib-><http://kotlin.root.com|kotlin.root.com>.piasy.kmpp.KmppBootstrap.KmppBootstrap();

    libkmpp_kref_Dummy_IOSDummyObj dummy;
    dummy.pinned = (__bridge libkmpp_KNativePtr)(obj);
    lib-><http://kotlin.root.com|kotlin.root.com>.piasy.kmpp.KmppBootstrap.test(kmpp, dummy);
a

Artyom Degtyarev [JB]

01/10/2020, 1:41 PM
Hello! Can you please extend the repro project with some additional instructions? Unfortunately, I cannot make it work as you described here.
p

Piasy

01/10/2020, 1:49 PM
Hi Artyom, thanks for your reply! at first, you can download the repro branch with this url: https://github.com/Piasy/KmppBootstrap/archive/ios_static_lib_repro.zip then you can unzip it, and open the
iOSExample2.xcodeproj
under
iOSExample2
folder, sorry that it was ignored, I just commit it. Then after you run it in iPhone device, it would crash. If you change kotlin code, then you need run
./gradlew :kmpp:linkDebugStaticIos && cp kmpp/build/bin/ios/debugStatic/libkmpp.a libs/iOS/ && cp kmpp/build/bin/ios/debugStatic/libkmpp_api.h libs/iOS/
.
👀 1
a

Artyom Degtyarev [JB]

01/13/2020, 8:48 AM
FYI: This discussion seems relevant: https://github.com/JetBrains/kotlin-native/issues/1395
p

Piasy

01/13/2020, 8:48 AM
@Artyom Degtyarev [JB] Thanks, I'll check it out.
Hi @Artyom Degtyarev [JB], thanks for your update, but I'm not sure if I understand it right. In my case, do you mean I need provide a kotlin method, e.g.
createIOSDummyObj
, and call it from ObjC?
a

Artyom Degtyarev [JB]

01/13/2020, 11:39 AM
Yes, AFAIK thats the best option here. I’ll ping you if something else can be done, but for now I would recommend this approach.
p

Piasy

01/13/2020, 11:50 AM
okay, thank you very much!
Hi @Artyom Degtyarev [JB], I have another question when I try your suggestion: I have a ObjC class (let's call it
DummyObjWithMap
) which need a
NSDictionary*
to init, so I create a kotlin wrapper function (let's call it
createDummyObjWithMap
) to create it, which require a kotlin
Map
. I can write kotlin code without any question, but in the generated header,
createDummyObjWithMap
require a
libkmpp_kref_kotlin_collections_Map
, how could I convert my ObjC
NSDictionary*
to
libkmpp_kref_kotlin_collections_Map
?
a

Artyom Degtyarev [JB]

01/14/2020, 9:03 AM
II managed to do it like described here(https://kotlinlang.slack.com/archives/C3SGXARS6/p1565279186194700?thread_ts=1565203926.191700&amp;cid=C3SGXARS6). Assuming existance of
IOSDummyObj(dict: NSDictionary)
constructor, I’ve made a wrapper like:
Copy code
fun wrappedInit(dict: CPointer<*>){
	IOSDummyObj(interpretObjCPointer<NSDictionary>(dict.rawValue)))
}
and called it from Objective-C as
Copy code
NSDictionary* dict = [NSDictionary alloc];
  dict = @{ @“firstInt”  : @2,
            @“secondInt” : @2,
  };
 lib-><http://kotlin.root.com|kotlin.root.com>.piasy.kmpp.KmppBootstrap.wrappedInit(kmpp, (__bridge void *)(dict));
I think it can be done even prettier, but I am no expert in this particular case 😅.
p

Piasy

01/14/2020, 9:04 AM
Okay thanks! I'll try it later.
Hi @Artyom Degtyarev [JB], it works like a charm, and I don't even need to create the wrapper method you suggest earlier, thanks!
🎉 1
Hi @Artyom Degtyarev [JB], I have another question now, I have a kotlin function returns a
List<KtObj>
, in the generated header, it returns
libkmpp_kref_kotlin_collections_List
, how could I iterate over it?
a

Artyom Degtyarev [JB]

01/17/2020, 1:12 PM
Make a wrapper method
iterate
, I suppose. Nothing is exposed to the library API by default.
p

Piasy

01/17/2020, 1:13 PM
Okay, thanks! I'll try that.
9 Views