Plug-in architecture, access to code in application? - objective-c

For a project I am doing, I want the Mac application to accept plug-ins. I like the whole idea of just adding Bundles to the application to extend it's functionality.
Only I came across a small question, where I can't find the answer to:
I need to include a JSON parser in my application, for some functionality. Is it possible for a plug-in Bundle to also use that same parser? Or does every plug-in that uses a JSON parser, need to include the parser themselves?
What is the best way to do this for separate Bundles?

On OS X there are two types of loadable things, a dylib and a plugin. (These two terms have specialized technical meaning in the context of mach-o, the binary format OS X uses.)
A loaded dylib can't refer to the libraries in the executable, while a loaded plugin can. As a side effect, a dylib can be loaded to any executable, but a plugin can only be loaded into the executable you specify when you make the plugin.
So you want to make a plugin. There is a template in the XCode to do that. Don't forget to specify the target executable in the linker flag, which can be set somewhere in the inspector.
For more, read Code Loading Programming Topics.

Related

Xcode: how to build a static library project correctly?

This question will be easy for Xcode pros but for a MonoTouch developer it seems to be impossible to resolve. :-)
I'm using Xcode 4.5 and I want to target iOS 5.1 and above and iOS Simulator 5.1 and above.
I have a a library project here and it is coming with a prebuilt binary named "DemoLib" (no extension and it is 11MB in size). The library is a fat lib for Simulator and iOS 5.1+.
I can use that library without any problem.
However if I try to build the library myself, I end up with a "DemoLib.a" file (notice the extension and the size of 30MB). How can I get the same build result? What is a .a file compared to the file without extension?
I tried to build the project "for running", and "for archiving" in Xcode. Both results in the same 30MB .a file.
I was expecting some dropdown in Xcode where one could select "DEBUG" or "RELEASE" build and the latter one would create the smaller lib.
Of course I could never tell without seeing the framework's project file. Having said that, there is an excellent guide to creating and compiling iOS frameworks here: https://github.com/jverkoey/iOS-Framework
Using the above guide, you should be able to recreate your framework's project from scratch, add the files you have to it, and properly compile it.
Hope this helps! :)
Did it come with a Makefile? Create a new target, set the build settings of the target to what's in the Makefile, then set your project to depend on that new target.
A file with the .a is a static library, which means it depends on nothing external and all the code it needs is compiled inside it. I think no extension generally implies dynamic library, which means it'll depend on some dependencies being present on your system to link against. Maybe that's why the .a is so much bigger. I think Xcode will build static by default because iOS does not allow the use of dynamic libraries.
The dropdown for what to build is in your scheme. Command+shift+< to view your scheme. Within the scheme you can edit which environment each method of building will use.

Understanding bundles frameworks and libraries

I'm developing ios B2B app and I have several questions regarding app modularization.
Firstly i need to understand main difference between bundles and frameworks. When to use bundles and when frameworks.
Another question is. Is it possible for bundle to contain a .framework inside in it and vice versa.
Is it possible to create a plugins for ios app and load them dynamically, if yes then what it should be? bundle framework or library?
Is it possible for library to contain a resource files ?
Is it possible to create a resource bundle and dynamic library and then load them dynamically at runtime.
Is it possible to create a plugins for ios app and load them
dynamically, if yes then what it should be? bundle framework or
library?
No
Is it possible for library to contain a resource files ?
No
Is it possible to create a resource bundle and dynamic library and
then load them dynamically at runtime.
No
A Bundle is a type of Directory, a folder. A Framework is a bundle. So is an Application and so is a Plugin.
A Static Library is a single file code archive you can compile into your app at build time
A Dynamic Library is a single file code archive you can load at Runtime
A Framework is a Dynamic library in a Bundle with other things
A Plugin is a Dynamic library in a Bundle with other things
The Xcode build option 'Bundle' means 'Place the compiled Dynamic Library in a Bundle' - this is what you do when you want to create a Plugin.
Static libraries are the only option for modularising your code on iOS.
On the desktop..
Typically a Framework is for sharing code and resources between multiple apps. You want your app to behave as though the code was actually compiled into it. You want loading to happen transparently and you don't want to do anything special to use the methods, functions, etc. contained in it.
A Plugin (a Bundle containing compiled code and resources) is for optional, dynamically loaded code, e.g. a software extension that you can choose to load or not. You want to carefully architect your app so that it isn't dependent on the Plugin but acquires new behaviour if you manually locate and load it at Runtime.
A Framework and a Plugin are very similar, but a Framework has a strict file layout to facilitate locating and loading code and resources. With a plugin, these jobs are your responsibility so you can structure the Bundle contents however you want.
Because loading code is so easy in Cocoa on OSX (but not iOS) Frameworks can contain Plugins which contain Frameworks which contain more Frameworks, etc.
On iOS some people put Static Libraries in Bundles with resources and call them Frameworks. This has none of the benefits and all of the drawbacks of a real framework.

Static Library vs. Source Code?

I'm creating a modular open-source library. Let's say the project has 15 .m files in it.
Should I (1) release it like the Venmo iOS SDK (Cocoa Touch Static Library) or (2) release it like JSONKit (just the source code)?
Releasing as source code means you, and your developers, don't have problems when a new architecture comes out. A static library built as armv6 wouldn't work with the latest Xcode today.
One caveat with source code releases, since you don't know what build settings the project it's added to will have, you'll need to do extra work to make sure it builds without warnings as best you can, even for pedantic warnings.
I prefer frameworks over static libs. Its easier to ship resources in the framework bundle if you eventually need to and there no cost to dynamic linking. If its pure C and the libraries dependencies are guaranteed to be there then it might be ok. But in general I try to avoid static linking unless I know the target OS has the exact dependencies for that binary at deployment time.
Its much easier to load a dynamic library with the endpoints you need at runtime (which were compiled for that exact platform but have the same external interface) than it is to fail with a static lib that was compiled directly to external dependencies which dont exist on the target platform.
Maybe Im crazy but this is what Ive always done in C, C++ or obj C. Just my opinion.
http://en.wikipedia.org/wiki/Static_library

Cocos2d Targeting iPhone/iPad/Mac

I recently did some research on making a cocos2d app for iPhone/iPad AND Mac. I have done the iPhone/iPad route but have never done it with a Mac target. It appears that some people have added it as a target but mentioned that it is finicky and others have suggested making a separate Cocos2d Mac project that uses the same files. Any wisdom to impart here?
I believe it is absolutely crucial to have both iOS and Mac targets in the same project. Otherwise you'll spend too much time keeping one platform in synch with the other, until eventually you either manage to create a good (but still time-consuming) workflow - or end up neglecting one of the two platforms.
Ideally the code base should make as little use as possible of compiler macros. You'll want to compile both iOS and Mac code even if it's not being used for one platform. So having some classes or methods that are #ifdef'ed to Mac, others to iOS, will more often than not lead to compile errors when you switch targets. That means wrapper classes, so that you can write the same code regardless of the platform, are essential.
Right now, Cocos2D doesn't offer you to create iOS & Mac targets in the same Xcode project. The way to get there isn't immediately obvious either, because each target requires its own build settings for: Base SDK, SDK Root, Deployment Target, Architectures and possibly Compiler version. It gets worse if you also want to use 3rd party libraries (Box2D, Chipmunk, etc) because in some cases you'll be forced to create iOS and Mac specific targets for those libraries as well - if only to ensure that the library is built with the same compiler as the project's target, otherwise you can run into the strangest build or runtime issues.
I've had issues getting these platform specific targets to work within a single Xcode project without Xcode complaining or otherwise misbehaving. I haven't tried it with Xcode 4.1 and 4.2. By that time I had created .xcconfig files to host the build settings. The .xcconfig files may or may not be necessary with the more recent Xcode versions but they definitely make managing multiple platform-specific targets easier.
Long story short, the best and easiest way to do cross-platform development with cocos2d-iphone is by using Kobold2D.
Most of the 15 template projects have an iOS and Mac target in each project, you just need to select the corresponding scheme, then hit build & run. The most commonly needed platform-specific code (processing user input) is wrapped in a platform-agnostic, simple to use wrapper class KKInput.
Disclaimer: I'm the developer of Kobold2D. There's a slim chance that I may be biased. You should try Kobold2D anyway. :)

Creating one static library for iOS and simulator for distribution

If you create a static library for iOS do you have to distribute the header file(s) with it or is there another way to get it to work?
Currently I have a single my_lib.a file for both device and simulator but when I drag it into another test app to use it, it says it can't find the header and that all the places I'm using it in the code are undeclared. So I figure I'm either doing something wrong, or I have to also send the appropriate header files with it.
Background to my process:
I've seen two guides for creating a static library for both device and simulator. One on this site: Build fat static library (device + simulator) using Xcode and SDK 4+
and one here: http://mark.aufflick.com/blog/2010/11/19/making-a-fat-static-library-for-ios-device-and-simulator
I used the second site to just try it out. I'm also a bit curious if I did it correctly. I just went into the Release-iphone(os|simulator) folders and found the .a in the ios one and the .o in the simulator one.
The short answer is yes, you have to package header files with your static library. You have to package header files with any library in fact, dynamic or static. The library itself contains the compiled code, but you still have to tell the compiler about the identifiers in the library so when it's compiling your code it knows that they exist.
If you care, you can package your static library into a static framework with a little care. You simply create the same directory structure that a dynamic framework has, with your .a file in place of the .dylib (or .so) file. Frameworks contain a directory for headers, so you can distribute the binary and headers as a single package, and you can easily import headers from a framework without messing with the Additional Header Search Paths build setting.
Just in case it's useful - I followed Ray Wenderlich's instructions from here and was able to produce a framework for iOS that supported several architectures at once (including the simulator). The instructions are a bit too long to just copy-paste here.