Deployment and Logging, a different approach
One of the main debugging techniques in Mac OS X is logging using NSLog. It’s quite simple and easy to log some useful information with it, but it’s even more simple to print a real huge amount of data to the console that is not really interesting and helpful.
When it comes to deploying some application it’s not really a good idea to keep all those NSLogs inside the code. A simple
#ifndef debugging NSLog(...)
really helps a lot there. If you add the “debugging” to the compiler option: “Preprocessor Macros” in your debug build options, this should remove all the NSLogs from your code when you deploy. Not much new stuff so far, I think 😉
But what if you want to keep the logging ability inside your application? What if you want the user to be easily able to enable logging in his built without sending him a new version? When I first thought about this question I instantly thought about the plugin enable/disable feature of Finder: if you open the info panel on an app (cmd-i) you’ll see a plugins section there.
So I created a plugin that, when enabled, will activate logging in my app again. And while it is disabled, there wouldn’t be any logging at all. The plugin is very simple, it only contains one class and upon initialization it will set a boolean to true.
This boolean will be read by a function called BSLog(). The function is implemented like this:
BOOL bs_enableLogging; void BSLog(NSString *format, ...) { va_list ap; va_start(ap,format); if (bs_enableLogging) { // if logging is enabled, pass the args to NSLogv NSLogv(format,ap); } va_end(ap); }
You can see it’s really simple, it only passes the arguments to the function NSLogv if bs_enableLogging is set. Of course you can enable and disable this bool everywhere in your app if you want, even if it doesn’t make much sense.
After creating the plugin, it also has to be installed in the application. The default place should be “Foo.app/Contents/PlugIns Disabled/”. Unfortunately there’s no such folder in the info panel for the “copy files”-build phase. There is however a destination called “Wrapper”, that’s the “Foo.app/” folder, so you’ll have to write the path like: “Contents/PlugIns Disabled”.
In the application code you have to load the plugin of course. Using the BSPluginLoader bundle, this is just one line of code.
This should be all I think. If you want to use logging during development, but still want to use the plugin, you should set the following Preprocessor Macro in your debug build setting:”BSLog(ARGS…)=NSLog(ARGS)”. This will ensure that NSLog is used instead of BSLog and the plugin is ignored.
I think tomorrow I’ll upload the archive to CodeBeach, but first I’ll upload something different, so stay tuned 😉
Karsten
June 16th, 2007 at 23:07
Shouldn’t that be #ifdef debugging NSLog(…), not #ifndef?
Cool idea for the logging plug-in.
June 17th, 2007 at 7:09
No, if it’s #ifdef debuggin NSLog(…) then all NSLog() calls will be removed if “debugging” is set.