How do I debug with NSLog(@"Inside of the iPhone Simulator")?

IphoneObjective CCocoaXcodeNslog

Iphone Problem Overview


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 applications. What is the best way to "trace" messages when coding in an iPhone Xcode development environment?

Iphone Solutions


Solution 1 - Iphone

There's a far more convenient way to trace with log messages in Xcode, and that's using Breakpoint Actions.

On the line of code where you'd be tempted to add a printf or NSLog, set a breakpoint, then control-click it and choose "Edit Breakpoint". In the blue bubble that appears, click the + button on the right to open the Breakpoint Actions: alt text

Enter your log text there. Any expression that can be printed in the Debugger can be used when delimited by @ signs.

For debugging Objective-C it's generally more useful to choose "Debugger Command" from the popup and enter 'po [[object method] method]' to print the description string of an Objective-C object or the result of a method call.

Make sure to click the "Continue" checkbox at the top right so execution continues after the log.

Advantages of this over NSLog and printf:

  • It's on the fly. You don't have to recompile and restart to add or edit log messages. This saves you a lot of time.
  • You can selectively enable and disable them. If you learn enough from one, but its spew is interfering, just uncheck its Enabled box.
  • All the output is generated on your Mac, never on the iPhone, so you don't have to download and parse through logs after the fact.
  • The chance of shipping console spew in your application is significantly decreased.

Also check out the Speak button; it's great for debugging full-screen apps where you can't see the debug log.

Solution 2 - Iphone

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__);

Solution 3 - Iphone

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]);

Solution 4 - Iphone

Paste this in your prefix header. ALL logs from project will dissappear for sure .

#ifndef __OPTIMIZE__

#    define NSLog(...) NSLog(__VA_ARGS__)

#else

#    define NSLog(...) {}

#endif

Solution 5 - Iphone

You could use NSLogger which brings a lot more to the table than just logging your messages. I use macros to disable logs in release builds, while leaving every single one of them active in debug builds. The log volume is not an issue, as NSLogger offers powerful log filtering options.

Solution 6 - Iphone

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 :)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRob SawyerView Question on Stackoverflow
Solution 1 - IphonecdespinosaView Answer on Stackoverflow
Solution 2 - IphoneElliotView Answer on Stackoverflow
Solution 3 - IphoneJane SalesView Answer on Stackoverflow
Solution 4 - IphoneAbhishek BediView Answer on Stackoverflow
Solution 5 - IphonefpilletView Answer on Stackoverflow
Solution 6 - IphoneEeKayView Answer on Stackoverflow