Passing Date object from JS back to ObjC

82 views
Skip to first unread message

Thomas Elstner

unread,
Oct 8, 2011, 2:19:07 PM10/8/11
to JSCocoa
Hello, I'm trying to embed JSCocoa into my App as a Scripting Engine
and currently I'm trying to pass a Date object from JavaScript back to
Objective-C... without success (passing strings, integers and doubles
works fine).

My approach:

demo.js:
function test4()
{
return new Date();
}

someViewController.m:
JSCocoaController *jsc = [JSCocoaController sharedController];
[jsc evalJSFile:[NSString stringWithFormat:@"%@/demo.js", [[NSBundle
mainBundle] bundlePath]]];

JSValueRef result = [jsc callJSFunctionNamed:@"test4" withArguments:
nil];
JSObjectRef dateRef = JSValueToObject(jsc.ctx, result, NULL);
JSStringRef millisecondsString =
JSStringCreateWithUTF8CString("milliseconds");
JSValueRef milliseconds = JSObjectGetProperty(jsc.ctx,
dateRef,
millisecondsString,
NULL);
JSStringRelease(millisecondsString);

if (JSValueIsUndefined(jsc.ctx, milliseconds)) {
NSLog(@"nah!");
} else {
unsigned long long millis = JSValueToNumber(jsc.ctx,
milliseconds, NULL);
NSDate *dateResult = [NSDate dateWithTimeIntervalSince1970:
millis / 1000];
NSLog(@"dateResult=%@",dateResult);
}

Unfortunately the property 'milliseconds' seems to be undefined, so
dateRef does not seem to reference a Date object.

I was trying to inspect my dateRef with the following code:

JSPropertyNameArrayRef nameArray =
JSObjectCopyPropertyNames(jsc.ctx, dateRef);
size_t count = JSPropertyNameArrayGetCount(nameArray);
for (size_t i = 0; i < count; ++i) {
JSStringRef curStr =
JSPropertyNameArrayGetNameAtIndex(nameArray, i);
NSString* resultString =
(NSString*)JSStringCopyCFString(kCFAllocatorDefault, curStr);
NSLog(@"Javascript property=%@", resultString);
}
JSPropertyNameArrayRelease(nameArray);

But JSPropertyNameArrayGetCount returns 0, so something is miserably
wrong with my dateRef - but what?
I also tried to create a my dateRef via
JSStringRef scriptJS = JSStringCreateWithUTF8CString("return new
Date");
JSObjectRef dateRef = JSObjectMakeFunction(jsc.ctx, NULL, 0, NULL,
scriptJS, NULL, 1, NULL);
but this doesnt change the result.

Any ideas on what's going wrong here?

Cheers,
Thomas

Patrick Geiller

unread,
Oct 9, 2011, 5:41:57 AM10/9/11
to jsc...@googlegroups.com
JSValueRef result = [jsc callJSFunctionNamed:@"test4" withArguments:
nil];
JSObjectRef dateRef = JSValueToObject(jsc.ctx, result, NULL);
JSStringRef millisecondsString =
JSStringCreateWithUTF8CString("milliseconds");
JSValueRef milliseconds = JSObjectGetProperty(jsc.ctx,
                                                 dateRef,
                                                 millisecondsString,
                                                 NULL);
JSStringRelease(millisecondsString);

In WebKit you have to use the function getMilliseconds() http://www.w3schools.com/jsref/jsref_obj_date.asp

JSCocoa does not have eval methods taking JSValueRefs as parameters, I'll have to add those.






Patrick Geiller

unread,
Oct 10, 2011, 8:59:30 PM10/10/11
to jsc...@googlegroups.com
>
> JSValueRef result = [jsc callJSFunctionNamed:@"test4" withArguments:
> nil];
> JSObjectRef dateRef = JSValueToObject(jsc.ctx, result, NULL);

You can now use 'anonEval:withThis:' to easily get an object's properties. anonEval creates an anonymous function and calls it using its JSValueRef argument as 'this'.

// Get milliseconds
[jsc evalJSString:@"function test4() { return new Date() }"];
JSValueRef v = [jsc evalJSString:@"test4()"];
JSValueRef milliseconds = [jsc anonEval:@"return this.getMilliseconds()" withThis:v];
NSLog(@"milliseconds=%f", [jsc toDouble:milliseconds]);

-Patrick

Reply all
Reply to author
Forward
0 new messages