On 19 Feb 2014, at 00:23, Ian McCullough <ipmcc@pobox.com> wrote:


I'm trying to determine the best way to expose custom, application-specific, non-system-framework (i.e. not in one of the framework wrappers provided with PyObjC) classes written in Objective-C to python across the PyObjC bridge. My eventual hope is to develop a "hybrid" application in which some portions of the app are in Objective-C and others are in python, with the two side integrating via the PyObjC bridge. Most of the documentation I've been able to find seems to focus on situations where the goal is to have all the app-specific code be in python, and to have the python call out to AppKit classes, etc via the bridge and the pre-packaged system framework wrappers.

I've not seen any indication that it's possible to expose classes from an app. But I did find this web page: https://pythonhosted.org/pyobjc/dev/wrapping.html which makes it sound like the best way would be for me to move any classes that need to be visible to python out of my application, and into a framework (which I can embed in my application), and then to adapt an existing framework wrapper to wrap this newly-created framework. So far, the wrapper-adapting part is proving to be easier said that done.

Looking at the existing wrappers, many of them have a compiled component (i.e. .m files). As far as I can tell, that seems to be responsible for bringing in protocols, constants and C functions. That said, it's not clear to me what all triggers the need for a compiled extension. I also saw that the _metadata.py files in existing wrappers have this at the top of them: "This file is generated by objective.metadata". I tracked that down to this repo: https://bitbucket.org/ronaldoussoren/objective.metadata which, with some coaxing I could get to build, install and run, but I've not gotten it to do anything useful yet -- i.e. how I get it to generate these _metadata.py files is not obvious. 

I'm content to keep fighting through the source on my own, but there's this part of my mind saying, "You've *got* to be missing something. It can't possibly be this involved to expose a framework to python." I can understand the overhead for exposing C functions and constants, but all the Objective-C stuff should be doable at runtime, right?

That’s correct. The metadata is only needed to expose C functions, constants, C type definitions (e.g. “NSRect”)  and the API for methods where the API cannot be fully extracted from the Objective-C runtime. The latter are methods that have pointer arguments (excluding “id”), as the bridge cannot know what’s supposed to be passed there (input or output, 1 value or an array of some size, …)

So, in sum: 

1) Is this the right way to expose Objective-C classes to Python?

The framework wrappers are an example of the most comprehensive way to expose Objective-C APIs to Python. If that is the best way for you depends on the amount and complexity of the code you want to expose to python.

Assuming yes...

2) Exhaustively speaking, what triggers the need for a compiled extension?

* Protocols
* Methods and functions that cannot be represented using metadata

3) What is the magic invocation to get objective.metadata to spit out the _metadata.py files for my framework?

4) Any other tips that might help in with this "hybrid" app goal?

Many thanks,

Managing the Performance of Cloud-Based Applications
Take advantage of what the Cloud has to offer - Avoid Common Pitfalls.
Read the Whitepaper.
Pyobjc-dev mailing list