Re: How can a plug-in bundle get access to its own resources?
Re: How can a plug-in bundle get access to its own resources?
- Subject: Re: How can a plug-in bundle get access to its own resources?
- From: Alastair Houghton <email@hidden>
- Date: Mon, 16 Nov 2009 17:09:02 +0000
On Nov 15, 2009, at 11:35 PM, Motti Shneor wrote:
> Thank you all, and thank you Steve - I think the point is clear now.
>
> However, I'm afraid this limit renders the whole Obj-C interface for plug-ins impractical for any medium-to-large company with legacy code.
Not really, no.
> There is nothing more natural than re-implementing an interface using the same class. Unfortunately, this is also the common practice in C++, Java and other OO languages. Most applications will naturally select plugins that fit a specific function by looking for "those implementing this specific interface" usually --- implementing the same class! (Yes, I know Java and Obj-C provide protocols/Interfaces for that).
You could conceivably cause yourself trouble in Java doing this as well, assuming you are really talking about implementing the exact same class. In practice you probably *aren't* talking about that, because the package name will be different, right?
So what's stopping you from building your ObjC class names up in the same way that a Java program might use a full class name (e.g. com_mycompany_MyPackage_ThisPlugin_Object)?
> In all other code-deployment mechanisms we encountered (Windows DLLs. Linux Dynamic libraries. Mac shared-libraries dylibs and even C/C++ code bundles, there is always a way for a piece of code when run (usually when initialized) to ask where it comes from (i.e. the path to the binary file it was loaded from) thus, allowing the code access its resources.
>
> If Obj-C intentionally lacks name-spaces, then some other replacement mechanism MUST exist to tell one loaded binary from another! This,to my opinion directly leads to the Bundle mechanism, responsible for loading and unloading of the actual code. It is only very natural to ask that code can access its own resources! what's simpler than that?
>
> Moreover, Cocoa provides such API (mainBundle) for applications, which makes perfect sense to everyone. How is it that ONLY application bundles support this API? After all, every code bundle is structured the same, and includes resources etc.
It *isn't* only application bundles that support it. It works just fine with *any* bundle. But the -bundleForClass: method assumes (as does the rest of the ObjC runtime) that each ObjC class has a unique name. The onus is on you to conform to that rule; how you do it is your business; one scheme that will work is the one I suggested above, copied from Java (though the usual approach is just to use a two letter prefix identifying the author/company/application/framework and work from there, but as you say, that might not work so well for the case you're dealing with).
If you don't like writing these long names out, you could use a #define to help, e.g.
#define P(x) com_mycompany_MyApp_Plugins_FooPlugin_##x
> The last solution from Steve seems the best way out currently, although it's a little hard to introduce into our build system. We currently control the product names and the binaries created using only the XCode projects facilities --- we use pre-build scripts that read the "product definition" from an external database, then modify the Project environment accordingly. The Product name is never hard-coded, and the high-level interface sources never change to produce a new product or a variation of it.
>
> Luckily, #define-s can be introduced at the project level. Maybe we'll just do that, If we can limit the number of exposed classes to just the plug-in names (over 200 i remind, not including versions and variations that must live together).
As I say, you must already have unique names for Java, right?
> Any Ideas for the Versioning problem? Does anyone have good experience with the Framework version mechanism?
I'm not 100% certain what you're asking about here, but...
> I saw these
>
> myFramework.framework packages with
>
> myFramework.framework
> myFramework.framework/Resources (alias)
> myFramework.framework/Versions/
> myFramework.framework/Versions/A/
> myFramework.framework/Versions/Current (alias)
>
> Structures everywhere --- Do they work right? I mean can a host application (or host library) load a plug-in by a specific version, and KNOW FOR SURE that the right library was loaded?
They do work, but I suspect they aren't what you're looking for. The framework version stuff is there so that an application or plug-in can link against what it considers to be the current version of the framework, and then someone can introduce a binary incompatible version without breaking the apps that are linking against its predecessor. It's really only a symlink structure, however, just like the similar one used on both Linux and OS X for "ordinary" shared objects/dylibs... there isn't anything clever going on per se.
I don't think there's an API for dynamically loading a particular version, though; you'll always load the version pointed at by the "Current" symlink if you use NSBundle or CFBundle.
Personally if I wanted a versioned API for plug-ins, I think I'd define protocols for the interfaces between plug-in and application, then have the app pass an object to the plug-in that implements the relevant protocol(s) and/or vice-versa. That way, you can easily query for support for particular protocols and use appropriate methods as a result. This is simple because there's only a single binary, and you shouldn't have binary compatibility problems doing this in general.
If you wanted to get more complex you could use a factory object on either side instead, and ask it for an object of a particular type (e.g. by defining your own interface IDs or something).
Or you could use a code-less bundle containing a set of bundles that hold the actual code, in which case the naming of the code bundles would be up to you and you'd just use the normal bundle resource finding functions to locate and load them from the outer bundle.
Kind regards,
Alastair.
--
http://alastairs-place.net
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden