{"id":7946,"date":"2015-11-12T03:05:05","date_gmt":"2015-11-12T03:05:05","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2015\/11\/12\/parmanoir-jscocoa\/"},"modified":"2015-11-12T03:05:05","modified_gmt":"2015-11-12T03:05:05","slug":"parmanoir-jscocoa","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2015\/11\/12\/parmanoir-jscocoa\/","title":{"rendered":"parmanoir\/jscocoa"},"content":{"rendered":"<p>With JSCocoa, you can write Cocoa applications (almost) entirely in Javascript or use it as a Plugin engine (like Acorn and Spice). JSCocoa uses WebKit\u2019s Javascript framework, JavascriptCore.<\/p>\n<p><strong>JSCocoa is<\/strong> a way to use Cocoa from Javascript. It works on the Mac (i386, x86_64, PPC), the iPhone and the iPhone simulator. You can write new Cocoa classes in Javascript, replace existing methods of classes by Javascript functions (swizzling them) and call Javascript functions on Cocoa objects (call <code>filter<\/code> on an <code>NSArray<\/code>, or use Javascript regular expressions on <code>NSString<\/code> with <code>myNSString.match(\/pattern\/)<\/code>).<\/p>\n<p>JSCocoa can also be used as a replacement for the existing WebKit bridge, letting you use C functions, structs, and calling pretty much anything from your WebView. Access restriction can be setup by JSCocoa\u2019s delegate messages (<code>canGetProperty:ofObject:inContext:<\/code>, <code>canCallMethod:ofObject:argumentCount:arguments:<\/code>, etc.)<\/p>\n<p>Basically, JSCocoa works like these bridges :<\/p>\n<p><strong>JSCocoa isn\u2019t<\/strong> a Javascript framework to use on the Web. For that, check out :<\/p>\n<ul>\n<li>Cappuccino an open source framework that makes it easy to build desktop-caliber applications that run in a web browser<\/li>\n<li>SproutCore makes building javascript applications fun and easy<\/li>\n<\/ul>\n<h2>Syntax<\/h2>\n<pre><code>\/\/ Get current application name : dot syntax\nvar appName = NSWorkspace.sharedWorkspace.activeApplication.NSApplicationName\n\/\/ The same with Objective-J syntax\nvar appName = [[[NSWorkspace sharedWorkspace] activeApplication] NSApplicationName]\n\n\/\/ Alloc an object (need to release)\nvar button = NSButton.alloc.initWithFrame(NSMakeRect(0, 0, 100, 40))\n\/\/ Alloc an object (no need to release)\nvar button = [NSButton instanceWithFrame:NSMakeRect(0, 0, 100, 40)]\n\n\/\/ Setting : an ObjC method starting with 'set' can be set like a Javascript property\nvar window = NSWorkspace.sharedWorkspace.activeApplication.keyWindow\n\/\/ Instead of calling setTitle ...\nwindow.setTitle('new title')\n\/\/ ... set the 'title' property\nwindow.title = 'new title'\n\n\/\/ Call methods with Objective-J syntax\n[obj callWithParam1:'Hello' andParam2:'World']\n\/\/ Or with a jQuery-like syntax (need to be enabled with __jsc__.setUseSplitCall = true)\nobj.call({ withParam1:'Hello', andParam2:'World' }) \nobj['callWithParam1:andParam2:']('Hello', 'World') \nobj.callWithParam1_andParam2('Hello', 'World' )\n\n\/\/ Unicode identifiers !\nfunction    \u8ffd\u52a0\u3059\u308b(\u6700\u521d\u306e, \u6b21\u306e)   {   return \u6700\u521d\u306e+ \u6b21\u306e }\nvar \u7d50\u679c = \u8ffd\u52a0\u3059\u308b('\u3053\u3093\u306b\u3061\u306f', '\u4e16\u754c')\nNSApplication.sharedApplication.keyWindow.title = \u7d50\u679c\n\n\/\/ Write a new Cocoa class in Javascript (inspired by Cappucino)\nclass MyClass &lt; NSObject\n{\n    \/\/ Custom drawing, calling parent method\n    - (void)drawRect:(NSRect)rect\n    {\n        \/\/ do some drawing here\n        ...\n        \/\/ Call parent method\n        this.Super(arguments)           \n    }\n    \/\/ Class method\n    + (float)addFloatX:(float)x andFloatY:(float)y\n    {\n        return x + y\n    }\n}\n\n\/\/ Manipulate an existing class\nclass NSButton\n{\n    \/\/ Add a method to an existing class\n    - (void)someNewMethod:(NSString*)name\n    {\n        ...\n    }\n\n    \/\/ Swizzle an instance method of an existing class\n    Swizzle- (void)drawRect:(NSRect)rect\n    {\n        \/\/ Draw something behind the button\n        ...\n        \/\/ Call original swizzled method\n        this.Original(arguments)\n        \/\/ Draw something in front of the button\n        NSBezierPath.bezierPathWithOvalInRect(rect).stroke\n    }\n}\n<\/code><\/pre>\n<h2>Starting up<\/h2>\n<p>This will start a controller, eval a file, call a Javascript method and get an ObjC object out of it. You can start multiple interpreters, e.g. one for each document.<\/p>\n<pre><code>\/\/ Start\nJSCocoa* jsc = [JSCocoa new];\n\n\/\/ Eval a file\n[jsc evalJSFile:@\"path to a file\"];\n\/\/ Eval a string\n[jsc evalJSString:@\"log(NSWorkspace.sharedWorkspace.activeApplication.NSApplicationName)\"];\n\n\/\/ Add an object of ours to the Javascript context\n[jsc setObject:self withName:@\"controller\"];\n\n\/\/ Call a Javascript method - we can use any object we added with setObject\nJSValueRef returnValue = [jsc callJSFunctionNamed:@\"myJavascriptFunction\" withArguments:self, nil];\n\/\/ The return value might be a raw Javascript value (null, true, false, a number) or an ObjC object\n\/\/ To get an ObjC object\nid resultingObject = [jsc toObject:returnValue];\n\n\/\/ (Cleanup : only needed if you don't use ObjC's Garbage Collection)\n[jsc release];\n<\/code><\/pre>\n<h2>Add JSCocoa to your project<\/h2>\n<p>Use it as a framework :<\/p>\n<ul>\n<li>Build JSCocoa\/JSCocoa.xcodeproj<\/li>\n<li>Add built JSCocoa.framework to your project<\/li>\n<li>import<\/li>\n<\/ul>\n<p>Integrate its files directly into your project :<\/p>\n<ul>\n<li>Drag the JSCocoa folder in your project<\/li>\n<li>Delete irrelevant files (Info.plist, JSCocoa_Prefix.pch, English.lproj, project files)<\/li>\n<li>Add the JavascriptCore framework<\/li>\n<li>In \u2018Build\u2019 project settings, add -lffi to \u2018Other linker flags\u2019<\/li>\n<li>import \u201cJSCocoa.h\u201d<\/li>\n<\/ul>\n<h2>Contribute and discuss<\/h2>\n<ul>\n<li>Discussion group Questions ? Join the Google group and ask away !<\/li>\n<li>Twitter Tweet me questions and comments<\/li>\n<li>Github fork JSCocoa from Github, add changes, and notify me with a pull request<\/li>\n<li>Documentation on Google Code<\/li>\n<\/ul>\n<h2>Who uses it ?<\/h2>\n<ul>\n<li>KosmicTask Integrated Scripting Environment for OS X to run, create and share tasks<\/li>\n<li>Spice-sugar Spice.sugar allows the Espresso text editor to be extended using JSCocoa<\/li>\n<li>Narwhal-jsc A JavascriptCore + optional JSCocoa module for Narwhal (Server-side Javascript)<\/li>\n<li>JSTalk Gus Mueller, to let Cocoa applications be scripted in Javascript<\/li>\n<li>PluginManager Grayson Hansard wrote a manager that enables you to write Cocoa plugins in AppleScript, F-Script, Javascript, Lua, Nu, Python and Ruby.<\/li>\n<li>Elysium Matt Mower, to script Elysium, a MIDI sequencer<\/li>\n<li>Acorn Plugins Gus Mueller, to let Acorn users write Acorn plugins in Javascript<\/li>\n<li>Interactive console for iPhone Kumagai Kentaro wrote a console to interact with the iPhone simulator from a web page !<\/li>\n<li>JSCocoaCodaLoader write Javascript plugins that work in Coda<\/li>\n<li>REPL console Tom Robinson\u2019s command line interface<\/li>\n<\/ul>\n<p>Are you missing on that list ? Send me a mail !<\/p>\n<h2>Thanks !<\/h2>\n<ul>\n<li>280 North \u2014 Objective-J syntax idea<\/li>\n<li>Douglas Crockford \u2014 JSLint<\/li>\n<li>Gus Mueller \u2014 Distant Object code<\/li>\n<li>Jonathan \u2018Wolf\u2019 Rentzsch \u2014 JRSwizzle<\/li>\n<\/ul>\n<h2>Questions, comments, patches<\/h2>\n<p>Send me a mail !<\/p>\n<p>Patrick Geiller<br \/>\nparmanoir@gmail.com<\/p>\n","protected":false},"excerpt":{"rendered":"<p>With JSCocoa, you can write Cocoa applications (almost) entirely in Javascript or use it as a Plugin engine (like Acorn and Spice). JSCocoa uses WebKit\u2019s Javascript framework, JavascriptCore. JSCocoa is a way to use Cocoa from Javascript. It works on the Mac (i386, x86_64, PPC), the iPhone and the iPhone simulator. You can write new [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-7946","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/7946","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=7946"}],"version-history":[{"count":0,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/7946\/revisions"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=7946"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=7946"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=7946"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}