I have an iOS application that uses some shared co...
# kotlin-native
g
I have an iOS application that uses some shared code that itself depends on a Kotlin multiplatform library. iOS.app -> shared -> library I’m trying to develop a timer that uses
CADisplayLink
in the Kotlin code. This is the code of my “timer”:
Copy code
@ThreadLocal
object AppTimer {

   fun start(){
      val selector = NSSelectorFromString("execution")
      val displayLink = CADisplayLink.displayLinkWithTarget(this, selector)
      displayLink.addToRunLoop(NSRunLoop.currentRunLoop, NSRunLoop.currentRunLoop.currentMode)
   }

   @ObjCAction
   fun execution(){
      NSLog("AppTimer::Execution through CADisplayLink")
   }
}
It works without problem if the timer code is located in the shared module. But, when I move it into the library, it throws this error:
Copy code
2021-10-27 13:45:35.769237+0200 iOSApp1[21754:6605253] -[App1_kobjcc0 execution]: unrecognized selector sent to instance 0x6000026025e0
2021-10-27 13:45:35.793415+0200 iOSApp1[21754:6605253] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[App1_kobjcc0 execution]: unrecognized selector sent to instance 0x6000026025e0'
*** First throw call stack:
(
	0   CoreFoundation                      0x00007fff20422fba __exceptionPreprocess + 242
	1   libobjc.A.dylib                     0x00007fff20193ff5 objc_exception_throw + 48
	2   CoreFoundation                      0x00007fff20431d2f +[NSObject(NSObject) instanceMethodSignatureForSelector:] + 0
	3   CoreFoundation                      0x00007fff204274cf ___forwarding___ + 1455
	4   CoreFoundation                      0x00007fff204297a8 _CF_forwarding_prep_0 + 120
Does anyone have an idea of why this is happening?
Found my problem. I forgot to export the library in my cocoapod:
Copy code
framework {
   baseName = "shared"
   export(project(":library"))
}
l
There's a better solution to make Objective-C selectors work in your Kotlin projects without forcing extra config on consumers: 1. Make the target selector class extend
NSObject
(that'd be
AppTimer
class in your case). 2. Don't use
object
as they cannot extend
NSObject
(it currently fails the compilation of the consumers…), use
class
instead (you can put a shared instance in a top-level
val
). 3. Make sure the class is public (but its constructor doesn't have to be,
internal
is fine). See example commit here: https://github.com/data2viz/data2viz/commit/9aa369fefb6c1c17ee71f6ae30356ffd15c4615f Thanks @jw for helping me get there 🙂