Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ivar("name") not working for imported frameworks #58

Open
bernhard-42 opened this issue Feb 3, 2015 · 4 comments
Open

ivar("name") not working for imported frameworks #58

bernhard-42 opened this issue Feb 3, 2015 · 4 comments

Comments

@bernhard-42
Copy link
Contributor

I imported a framework (CocoaHTTPServer) and needed to access an instance variable.
To get it working I had to add

else if (basetype[0] == '@') return createObject(val, '@');

to

function wrapValue (val, type) 

in core.js line 183

Reason: The instance variable came back with type '@"HTTPMessage"' and not only with '@'
By checking only character 0 for '@', I could force to call 'createObject' with basetype "@"
Not sure this is correct, but it worked for me ...

@TooTallNate
Copy link
Owner

Do you have some code that I can reproduce the issue with?

@bernhard-42
Copy link
Contributor Author

See https://github.com/bernhard-42/node-cocoa-http

Without patch, calling via curl localhost:8080 -d '{"a":42}'

$ coffee app.coffee
[Class: PostConnection1]
server listening to port 8080
listening ...
expectsRequestBodyFromMethod
supportsMethod
processBodyData

/Users/bernhard/Development/node-cocoa-http/cocoa-http.coffee:124
        self.ivar("request")("appendData", postDataChunk);
                            ^
TypeError: object is not a function
  at /Users/bernhard/Development/node-cocoa-http/cocoa-http.coffee:91:7
  at /Users/bernhard/Development/node-cocoa-http/node_modules/NodObjC/lib/core.js:253:31
  at /Users/bernhard/Development/node-cocoa-http/node_modules/NodObjC/node_modules/ffi/lib/callback.js:52:23

With patch:

$ coffee app.coffee
[Class: PostConnection1]
server listening to port 8080
listening ...
expectsRequestBodyFromMethod
supportsMethod
processBodyData
httpResponseForMethod
{ method: POST,
  url: /,
  headers:
   { 'User-Agent': 'curl/7.37.1',
     Accept: '*/*',
     Host: 'localhost:8080',
     'Content-Length': '8',
     'Content-Type': 'application/x-www-form-urlencoded' },
  body: '{"a":42}',
  httpVersion: '1.1' }

@bernhard-42
Copy link
Contributor Author

Any idea whether this fix is correct or whether the issue sits deepr in import.js? - thanks

@nw
Copy link

nw commented Aug 13, 2015

@bernhard-42 I think the issue is deeper.

@TooTallNate code that reproduces a similar issue, generating the wrapped value. In this case type is undefined completely.

var $ = require('nodobjc');
$.framework('Foundation');
$.framework('Cocoa');
var pool = $.NSAutoreleasePool('alloc')('init');

var result = $.CGWindowListCopyWindowInfo($.kCGWindowListOptionAll, $.kCGNullWindowID);
var windowList = $.CFBridgingRelease(result);

var aWindow = windowList('objectAtIndex', 0);

console.log(aWindow.ancestors()); 
// ['__NSCFDictionary','NSMutableDictionary','NSDictionary','NSObject' ]

console.log(aWindow.toString())
/* example:
{
    kCGWindowAlpha = 1;
    kCGWindowBounds =     {
        Height = 1440;
        Width = 2560;
        X = 1440;
        Y = "-540";
    };
    kCGWindowIsOnscreen = 1;
    kCGWindowLayer = 20;
    kCGWindowMemoryUsage = 1008;
    kCGWindowNumber = 14764;
    kCGWindowOwnerName = Dock;
    kCGWindowOwnerPID = 354;
    kCGWindowSharingState = 1;
    kCGWindowStoreType = 1;
}
*/

pool('drain');

Trying to access a property

aWindow('kCGWindowOwnerName');

produces the following error:

2015-08-13 17:59:23.262 node[85901:3004028] -[__NSCFDictionary kCGWindowOwnerName]: unrecognized selector sent to instance 0x101351770

/node_modules/nodobjc/lib/class.js:193
      else throw e;
                 ^
-[__NSCFDictionary kCGWindowOwnerName]: unrecognized selector sent to instance 0x101351770
    at ID.module.exports.Class.msgSend (/node_modules/nodobjc/lib/class.js:192:45)
    at rtn (/node_modules/nodobjc/lib/core.js:375:47)
    at app.js:27:15
    at /node_modules/nodobjc/lib/core.js:256:31
    at /node_modules/nodobjc/node_modules/ffi/lib/callback.js:66:25
    at ForeignFunction.proxy (/node_modules/nodobjc/node_modules/ffi/lib/_foreign_function.js:59:14)
    at unwrapper (/node_modules/nodobjc/lib/core.js:301:31)
    at ID.module.exports.Class.msgSend (/node_modules/nodobjc/lib/class.js:189:34)
    at rtn (/node_modules/nodobjc/lib/core.js:3

using ivar produces:

aWindow.ivar('kCGWindowOwnerName');
/node_modules/nodobjc/lib/class.js:193
      else throw e;
                 ^
TypeError: Cannot read property 'type' of null
    at Object.wrapValue (/node_modules/nodobjc/lib/core.js:181:24)
    at ID.module.exports.ID.ivar (/node_modules/nodobjc/lib/id.js:74:19)
    at app.js:27:19
    at /node_modules/nodobjc/lib/core.js:256:31
    at /node_modules/nodobjc/node_modules/ffi/lib/callback.js:66:25
    at ForeignFunction.proxy (/node_modules/nodobjc/node_modules/ffi/lib/_foreign_function.js:59:14)
    at unwrapper (/node_modules/nodobjc/lib/core.js:301:31)
    at ID.module.exports.Class.msgSend (/node_modules/nodobjc/lib/class.js:189:34)
    at rtn (/node_modules/nodobjc/lib/core.js:375:47)
    at tock [as _onTimeout] (app.js:60:14)

For sanity I enumerated over the NSObject to verify the keys, and everything looked good.

var keys = aWindow('keyEnumerator');
var key;

while(key = keys('nextObject')){
  console.log(key);
}
/*
kCGWindowLayer
kCGWindowName
kCGWindowMemoryUsage
kCGWindowIsOnscreen
kCGWindowSharingState
kCGWindowOwnerPID
kCGWindowNumber
kCGWindowOwnerName
kCGWindowStoreType
kCGWindowBounds
kCGWindowAlpha
*/

Worth noting: numIvars does not exist in this code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants