mrousavy / nitro

🔥 Insanely fast native C++, Swift or Kotlin modules with a statically compiled binding layer to JSI
https://nitro.margelo.com
MIT License
598 stars 15 forks source link

Nitrogen: Callback functions cause a compiler error after codegen on iOS #96

Closed gtokman closed 2 months ago

gtokman commented 2 months ago

Description

When adding a callback function to the interface and running nitrogen, I get a compiler error on iOS.

// .nitro.ts
export interface Callback
  extends HybridObject<{ ios: 'swift'; android: 'kotlin' }> {
  onEvent: (data: AnyMap) => void;
}

Causes an error in the HybridCallbackSpecCxx codegen file:

Screenshot 2024-09-02 at 9 27 49 AM

Seems like we need something like this and maybe expose the AnyMap type:

// Generated 
  func callClosure(closureHolder: UnsafeMutableRawPointer?, data: AnyMapHolder) -> Void {
          let closure = Unmanaged<ClosureHolder>.fromOpaque(closureHolder!).takeUnretainedValue()
          closure.invoke(AnyMapHolder(withCppPart: data))
  }

// Need something like this:      
func callClosure(closureHolder: UnsafeMutableRawPointer?, data: std.__1.shared_ptr<AnyMap>) -> Void {
    let closure = Unmanaged<ClosureHolder>.fromOpaque(closureHolder!).takeUnretainedValue()
    let anyMapHolder = AnyMapHolder(withCppPart: data)
    closure.invoke(anyMapHolder)
}
gtokman commented 2 months ago

As a work around assigning a callback like this works:

final public class Callback: HybridCallbackSpec {
    public var notify: ((AnyMapHolder) -> Void)?

    public var hybridContext = margelo.nitro.HybridContext()

    public var memorySize: Int {
        return getSizeOf(self)
    }

    public func onEvent(notify: @escaping ((AnyMapHolder) -> Void)) {
        self.notify = notify
    }
}
mrousavy commented 2 months ago

fixed in https://github.com/mrousavy/nitro/pull/97!