sandeepmistry / node-objective-c-runtime

Use the Objective-C Runtime from Node.js
MIT License
5 stars 1 forks source link

Example usage #2

Open shirakaba opened 1 year ago

shirakaba commented 1 year ago

Really interested in this project (I'm on the NativeScript TSC, and it feels like it has the potential to deliver a NativeScript-like experience for desktop), but just wish it would have some example usages. Here's what I've figured out so far:

Initialising an NSString instance (without a value)

// demo.js
const { objc, sel } = require('.');

const { getClass, msgSend } = objc;
const { registerName } = sel;

const NSString = getClass('NSString');
const allocated = msgSend(NSString, registerName('alloc'));
const inited = msgSend(allocated, registerName('init'));

console.log(inited);
// <Buffer 98 6c 89 01 02 00 00 00>

Initialising an NSString instance (with a value)

I'm not quite sure how to pass an NSString as a method argument though.

const { objc, sel } = require('.');

const { getClass, msgSend } = objc;
const { registerName } = sel;

const NSString = getClass('NSString');

const stringA = msgSend(
    msgSend(NSString, registerName('alloc')),
    registerName('initWithString:'),
    'Hello',
);

This gives the error:

/Users/jamie/Documents/git/node-objective-c-runtime/demo.js:8

const stringA = msgSend(
                ^

TypeError: Expected argument 3 to be a buffer! at Object. (/Users/jamie/Documents/git/node-objective-c-runtime/demo.js:8:17) at Module._compile (node:internal/modules/cjs/loader:1126:14) at Object.Module._extensions..js (node:internal/modules/cjs/loader:1180:10) at Module.load (node:internal/modules/cjs/loader:1004:32) at Function.Module._load (node:internal/modules/cjs/loader:839:12) at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12) at node:internal/main/run_main_module:17:47

So clearly JS strings aren't automatically marshalled into NSString when the method's expected param type is @. Which makes sense, though leads to the next question. How can we call some of these NSString methods for making basic types?

shirakaba commented 1 year ago

I made a proof-of-concept of auto-marshalling for method params with type @. If passed a primitive type like a napi_string, it could be automatically marshalled into an NSString like so: https://github.com/sandeepmistry/node-objective-c-runtime/commit/03928b2bf17f25e6af81916200919083aab2bbc4

Of course other primitive types like numbers could be handled the same way (marshalling to NSNumber).