3

EDIT

Since I posted the question I have found another working Objc example(http://mattgemmell.com/2008/02/24/skinnable-cocoa-ui-with-webkit-and-css + source: http://mattgemmell.com/files/source/skinnableapp.zip)

This is what I have now:

webview_obj_from_jsAppDelegate.py

from Foundation import *
from AppKit import *
import objc

class webview_obj_from_jsAppDelegate(NSObject):
  interface = objc.IBOutlet()
  def applicationDidFinishLaunching_(self, sender):
  NSLog("Application did finish launching.")

  def awakeFromNib(self):
    self.interface.setFrameLoadDelegate_(self)
    path = NSBundle.mainBundle().resourcePath() + '/interface/index.html'
    self.interface.setMainFrameURL_(path)
    self.interface.windowScriptObject().setValue_forKey_(self, 'AppController')

  #this is what I suspect to be the problem
  def isSelectorExcludedFromWebScript_(self, aSel):
    return NO

  def showMessage(self, message):
    NSLog(message)

index.html

  <!DOCTYPE html>
  <html lang="en">
    <head>
      <title>title</title>
      <meta http-equiv="Content-type" content="text/html; charset=utf-8">
      <meta name="description" content="description">
      <meta name="keywords" content="">
    </head>
    <body>
      <input id="message_button" type="button" value="Show Message" onClick="window.AppController.showMessage_('I clicked a button and I liked it');" />
    </body>
  </html>

Now, if I add a selector to isSelectorExcludedFromWebScript_ like this:

def isSelectorExcludedFromWebScript_(self, aSel):
  if aSel is objc.selector(self.showMessage, signature = 'v@:'):
    return NO

clicking the HTML button gives me this error:

WebKit discarding exception: <OC_PythonException> <type 'exceptions.ValueError'>: isSelectorExcludedFromWebScript:: returned None, expecting a value

END EDIT

I am trying to call a PyObjc function from javascript, but I can't get it to work. I found a working example(https://github.com/ryanb/cocoa-web-app-example) written in Objc, but no luck translating it.

A couple of days ago I've stumbled upon this(http://stackoverflow.com/questions/2288582/embedded-webkit-script-callbacks-how) which is more complicated. Needless to say, I couldn't get it to work.

So if anybody has a simple example(pyobjc & js) I'd really appreciate it if you'd show me.

Stelian
  • 181
  • 1
  • 5

3 Answers3

1

Can I make a suggestion? Javascript and Python both do a pretty bang up job of speaking HTTP. Perhaps setup a Python HTTP server on the machine, and when Javascript gets the trigger, it could just do an XHttpRequest to the local server?

Alternatively.. It is possible to get Javascript and Python chatting (very roughly) if you use QtWebKit with PySide / PyQt. PyObjC is very poorly supported these days and in many cases only manages to 'barely work' while in most cases not. No offense to the PyObjC folks, but lets be fair - the project just isn't kept up to date as frequently as it used to be.

synthesizerpatel
  • 27,321
  • 5
  • 74
  • 91
0

The second implementation for isSelectorExcludedFromWebScript_ is wrong:

def isSelectorExcludedFromWebScript_(self, aSel):
   if aSel is objc.selector(self.showMessage, signature = 'v@:'):
      return NO

The 'aSel' argument is a SEL in Objective-C, which is a selector name. Something like this should work better:

def isSelectorExludedFromWebScript_(self, aSel):
    if aSel == b'showMessage':
       return False

    return True

As a generic hint: when some Cocoa class logs that it ignored in Python exception, or when you expect that there might be a Python exception somewhere that got swallowed (which does happen), you can ask PyObjC to print information about exceptions that it converts to Objective-C:

import objc
objc.setVerbose(True)

And finally: the "showMessage" method should be named "showMessage_", the underscore ensures that the Cocoa method will be named "showMessage:" and has a single argument (as intended by the method signature)

Ronald Oussoren
  • 2,715
  • 20
  • 29
0

If you can call into Objective-C from JavaScript, then calling into a PyObjC authored Objective-C class or instance should "just work".

You can't, though, call straight into Python from JavaScript through PyObjC.

You'll need to show a bit more of what you've tried.

bbum
  • 162,346
  • 23
  • 271
  • 359