nativescriptnativescript-angularnativescript-plugincocoaasyncsocket

CocoaAsyncSocket and NativeScript issue


I'm writing a Nativescript Plugin for UDP comms based on CocoaAsyncSocket but my app is crashing when I try to perform any async operation in the context of this pod. It seems to be something related to the queues/threads on iOS x {N}, but I haven't been able to solve it, any idea?

Here is how I'm creating my Plugin iOS class in Typescript:

export class UdpProtocol extends NSObject implements GCDAsyncUdpSocketDelegate

Here is how I'm initialising my GCDAsyncUdpSocket:

let dispatchQueue = dispatch_queue_create("sendUnicast_queue", null);
let sock = GCDAsyncUdpSocket.alloc()
           .initWithDelegateDelegateQueue(this, dispatchQueue);

Here is one example of async method I'm calling in my .ts:

sock.sendDataToHostPortWithTimeoutTag(sendData, address, port, -1, this.tag);

Here is the callback I was expecting to be correctly fired:

udpSocketDidSendDataWithTag(sock: GCDAsyncUdpSocket, tag: number): void {
        console.log('udpSocketDidSendDataWithTag callback');
}

But unfortunately what I got is the JS exception below:

CONSOLE LOG file:///node_modules/@nativescript/core/inspector_modules.js:1:0: Loading inspector modules...
CONSOLE LOG file:///node_modules/@nativescript/core/inspector_modules.js:6:0: Finished loading inspector modules.
NativeScript debugger attached.
***** Fatal JavaScript exception - application has been terminated. *****
Native stack trace:
1   0x11033960e NativeScript::reportFatalErrorBeforeShutdown(JSC::ExecState*, JSC::Exception*, bool)
2   0x110388f76 -[TNSRuntimeInspector reportFatalError:]
3   0x10fc2d23b TNSInspectorUncaughtExceptionHandler
4   0x7fff23e3a36d __handleUncaughtException
5   0x7fff50ad7c05 _objc_terminate()
6   0x7fff4f926c87 std::__terminate(void (*)())
7   0x7fff4f926c29 std::terminate()
8   0x7fff519128df _dispatch_client_callout
9   0x7fff5191860c _dispatch_lane_serial_drain
10  0x7fff51919044 _dispatch_lane_invoke
11  0x7fff519230c4 _dispatch_workloop_worker_thread
12  0x7fff51b37a3d _pthread_wqthread
13  0x7fff51b36b77 start_wqthread
JavaScript stack trace:
UIApplicationMain(file:///node_modules/@nativescript/core/application/application.js:312:0)
at run(file:///node_modules/@nativescript/core/application/application.js:312:0)
at file:///node_modules/@nativescript/angular/platform-common.js:210:0
at file:///node_modules/@nativescript/angular/platform-common.js:111:0
at file:///node_modules/@nativescript/angular/platform-common.js:91:0
at file:///app/bundle.js:198:144
at ./main.ts(file:///app/bundle.js:203:34)
at __webpack_require__(file:///src/webpack/bootstrap:750:0)
at checkDeferredModules(file:///src/webpack/bootstrap:43:0)
at webpackJsonpCallback(file:///src/webpack/bootstrap:30:0)
at anonymous(file:///app/bundle.js:2:61)
at evaluate([native code])
at moduleEvaluation([native code])
at [native code]
at asyncFunctionResume([native code])
at [native code]
at promiseReactionJob([native code])
JavaScript error:
file:///node_modules/@nativescript/core/application/application.js:312:0: JS ERROR Error: -[__NSCFString bytes]: unrecognized selector sent to instance 0x6000036496c0
NativeScript caught signal 6.
Native Stack:
1   0x11038a251 sig_handler(int)
2   0x7fff51b2f5fd _sigtramp
3   0x7fff51a23f39 itoa64
4   0x7fff51a1fb7c abort
5   0x7fff4f927858 abort_message
6   0x7fff4f926cad std::__terminate(void (*)())
7   0x7fff4f926c29 std::terminate()
8   0x7fff519128df _dispatch_client_callout
9   0x7fff5191860c _dispatch_lane_serial_drain
10  0x7fff51919044 _dispatch_lane_invoke
11  0x7fff519230c4 _dispatch_workloop_worker_thread
12  0x7fff51b37a3d _pthread_wqthread
13  0x7fff51b36b77 start_wqthread
JS Stack unavailable. Current thread hasn't initialized a {N} runtime.

I've already tried solutions like this one here, but no success.

The plugin with the angular demo causing the issue is available in this brach

Any tip or help is very welcomed :)


Solution

  • Actually I've found out that the error was associated to how I was creating sendData variable, I've changed it from:

    let sendData: any = NSString.alloc().initWithCString(msg);
    

    to

    const sendData: NSData = NSData.alloc().initWithBase64EncodedStringOptions(msg, 1);