views:

14065

answers:

5

I'm used to programming and having log messages be viewable. I know you used to be able to use NSLog() to trace out messages when debugging Cocoa apps. What is the best way to "trace" messages when coding in a iPhone XCode development environment?

+19  A: 

NSLog :)

The output is piped to the console window in XCode and the log files on the iPhone (which are viewable through the XCode device manager).

Andrew Grant
Beautiful, thanks!
Rob Sawyer
Just for reference, you can access the console by Run > Console, or Shift+Command+R
Jeff Winkworth
upvote to give @cdespinosa the well earned populist badge.
Nikolai Ruhe
@Andrew Grant, can you add the @Jeff Winkworth comment to your answer to make it complete?
Yar
+3  A: 

In my project I have a customised solution based on DebugOutput.m This adds the file & line number to the debug output, making it easier to identify where that output text is coming from, while still keeping it brief.

I've augmented the standard solution with a debug mask, so that I can switch debugging on and off for particular areas of functionality in my app. In Debug.h, I have

typedef enum {
kDebugMaskAp- = 1,
kDebugMaskXMLParser = 1 << 1,
kDebugMaskNetwork = 1 << 2,
kDebugMaskAnalytics = 1 << 3,
kDebugMaskCache = 1 << 4,
} debugBitMask;

#define debugForComponent(mask,format,...) if( currentDebugMask() & mask) [[DebugOutput sharedDebug]  output:__FILE__ lineNumber:__LINE__ input:(format), ##__VA_ARGS__]

And in Debug.m

-(void)output:(char*)fileName lineNumber:(int)lineNumber input:(NSString*)input, ...
{
  va_list argList;
  NSString *filePath, *formatStr;

  // Build the path string
  filePath = [[NSString alloc] initWithBytes:fileName length:strlen(fileName) encoding:NSUTF8StringEncoding];

  // Process arguments, resulting in a format string
  va_start(argList, input);
  formatStr = [[NSString alloc] initWithFormat:input arguments:argList];
  va_end(argList);

  // Call NSLog, prepending the filename and line number
  NSLog(@"File:%s Line:%d %@",[((DEBUG_SHOW_FULLPATH) ? filePath : [filePath lastPathComponent]) UTF8String], lineNumber, formatStr);

  [filePath release];
  [formatStr release];
}

In the application, calls look something like this:

debugForComponent(kDebugMaskApp,@"Request failed - error %@", [error localizedDescription]);
Jane Sales
+109  A: 
cdespinosa
Give him a Populist for this one!
fbrereto
There's one more advantage which, in my opinion, is the best of all: When developing in a team (using SCM), I hate to have my console cluttered with debugging output of other developers. Using your method, debugging output is not committed to the source code or project and will only be seen on the local machine where it was created.
Nikolai Ruhe
Love it. @Nikolai, agreed, but there's also an appropriate place for normal logging. This method should not exclude properly placed logging at points of critical failure. You're right though, I think most devs over-log and create clutter.
DougW
I don't get how to use it.Please give an example equivalent to NSLog(@"x %f",myView.center.x);
Allisone
Is there a way to log without stopping at the breakpoint, as you would with NSLog?
Luke
Aha, missed it. Good stuff.
Luke
One thing... if you have a block of code with an "if" statement... An nslog placed inside the "if" statment will only be called if the "if" statement is true. For some reason, the breakpoint method gets called regardless of whether the "if" statement is called. This limits the usefulness for me because one of the best uses of an nslog is knowing if an "if" statement was called.
Jonah
A: 

I simply use the replace all functionality....

I disable all my NSLog statements by replacing NSLog(@" with //***NSLog(@"

That way I can simply find it (using find in all project files) with //***NSLog(@" and re-enable them

Nothing fancy but it works :)

One minor tip for users looking for a Replace All button: There is no Replace All button in Find in Project window, that is because when none of the matches is selected, Replace button does a Replace All.
ustun
This is a tad dangerous when using Version Control...!
JBRWilkinson
+2  A: 

Here's a great bit of code I picked up somewhere on the web. It defines new functions DLog() and ALog(). DLog messages only appear when the app is compiled with a -DDEBUG flag (define DEBUG). ALog messages ALWAYS appear (even in Release mode).

// DLog is almost a drop-in replacement for NSLog
// DLog();
// DLog(@"here");
// DLog(@"value: %d", x);
// Unfortunately this doesn't work DLog(aStringVariable); you have to do this instead DLog(@"%@", aStringVariable);
#ifdef DEBUG
#       define DLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
#       define DLog(...)
#endif

// ALog always displays output regardless of the DEBUG setting
#define ALog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
Elliot