-
Notifications
You must be signed in to change notification settings - Fork 571
Integrating NSLogger in your application
The NSLogger API can be used for both iOS (iPhone, iPad) and Mac OS X desktop applications. The client code is the same, and compiles and run without modification on both platforms.
1. Add files to your project
First and foremost, add the following files to your project:
LoggerCommon.h
LoggerClient.h
LoggerClient.m
Also, if your project does not already include it, add the frameworks CFNetwork.framework
and SystemConfiguration.framework
to your iOS or Mac OS X project.
2. Initialize NSLogger at application start
You’ll need to initialize and start the logger once, preferably in your -application:didFinishLaunchingWithOptions:
method (if you are developing an iOS application). Here is an example:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)options
{
LoggerStart(LoggerInit());
LogMessageCompat(@"Logger initialized, application starting");
...
}
3. Use NSLogger API calls to log stuff
You can now use all the NSLogger API calls to log text, images and data. Take advantage of tags to categorize the output, this will allow you to better filter out unwanted traces when you want to explore specific aspects of your application traces. Use log levels to further categorize traces if you need (log levels start a 0, the bigger the number, the more specific / detailed the trace is meant to be). For example:
- (void)sendData:(NSData *)data toServer:(NSURL *)aURL
{
LogMessage(@"network", 0, @"Going to send data to %@", aURL);
LogMessage(@"network", 1, @"-> data=%@", data);
...
}
A good way to cleanly instrument your code, while keeping the option of disabling all calls to NSLogger in release builds, is to use macros in conjunction with a preprocessor macro. For debug builds, define the preprocessor macro DEBUG. Then prepare a header file that will contain your logging macros.
Here are some example macros. Note that we use variadic macros, which are a way to transfer the macro arguments from the macro usage to its replacement.
#ifdef DEBUG
#define LOG_NETWORK(...) LogMessage(@"network", __VA_ARGS__)
#define LOG_GENERAL(...) LogMessage(@"general", __VA_ARGS__)
#define LOG_GRAPHICS(...) LogMessage(@"graphics", __VA_ARGS__)
#else
#define LOG_NETWORK(...) while(0){}
#define LOG_GENERAL(...) while(0){}
#define LOG_GRAPHICS(...) while(0){}
#endif
Now it suddenly becomes very easy and straightforward to add debug-only traces to your application. The previous code example would become:
- (void)sendData:(NSData *)data toServer:(NSURL *)aURL
{
LOG_NETWORK(0, @"Going to send data to %@", aURL);
LOG_NETWORK(1, @"-> data=%@", data);
...
}
And no code at all will be emitted when building the Release build of your application.