Write debug messages to Xcode output window - objective-c

I have see this in sample objective c code before, but can't find it now and all the searches come back with irrelivent results.
I want to write debug messages to the Xcode output window. What's the command to do that? Basically like System.Diagnostics.Debug.WriteLine for C#.

NSLog(#"Your message here");
...should do it.
To include data from variables you can use string formatting, e.g:
NSLog(#"Value of string is %#", myNSString);
There are a bunch of different string format specifiers, you can look at them here: https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html

You are looking for NSLog. Calling
NSLog(#"Message");
will print Message on the console.
See here for more info about how to use string formatters to print the values of variables like in the examples below:
NSLog(#"This is a string: #", aString);
NSLog(#"This is an int: %d", anInt);

It's better to write the debug messages using debugger breakpoints instead of cluttering your code with NSLog messages. Breakpoints will also save you from having to remove all those log messages when you ship your app.
To do this, set a breakpoint in Xcode, double-click on it, and click the Add Action button in the pop-up window. Select "Log Message" and type your message. Check the "Automatically continue after evaluating" check box at the bottom to keep it from pausing execution on the breakpoint

Related

Xcode 6 variable inspector showing nil

I've got something like this:
NSArray* titleColors = #[defaultColorForTitles, defaultColorForTitles, defaultColorForTitles]];
If I NSLog it out, I get:
2015-02-09 15:26:21.984 project[27352:1574376] (
6c6c6c,
red,
blue
)
Yay!
But if I set a breakpoint at the next line and hover over the variable, instead of seeing the array values (like I'd expect), it shows nil. Is this expected? Is my Xcode broken? What's going on?
Are you running a debug build? When hit your break point, does NSLog print out the value? If it does print out, but your inspector shows nil. It can be you are running a released build and compiler made an optimization there (mostly because that line is the last use of titleColors). That's my guess based on current information.

How to print something to the console in Xcode?

How do you print something to the console of Xcode, and is it possible to view the Xcode console from the app itself?
Thanks!
How to print:
NSLog(#"Something To Print");
Or
NSString * someString = #"Something To Print";
NSLog(#"%#", someString);
For other types of variables, use:
NSLog(#"%#", someObject);
NSLog(#"%i", someInt);
NSLog(#"%f", someFloat);
/// etc...
Can you show it in phone?
Not by default, but you could set up a display to show you.
Update for Swift
print("Print this string")
print("Print this \(variable)")
print("Print this ", variable)
print(variable)
#Logan has put this perfectly. Potentially something worth pointing out also is that you can use
printf(whatever you want to print);
For example if you were printing a string:
printf("hello");
3 ways to do this:
In C Language (Command Line Tool) Works with Objective C, too:
printf("Hello World");
In Objective C:
NSLog(#"Hello, World!");
In Objective C with variables:
NSString * myString = #"Hello World";
NSLog(#"%#", myString);
In the code with variables, the variable created with class, NSString was outputted be NSLog. The %# represents text as a variable.
#Logan said it perfectly. but i would like to add an alternative here,
if you want to view logs from just your application then you can make
a custom method that keeps saving the log to a file in documents
directory & then you can view that log file from your application.
There is one good advantage for developers of the app after the app has been released & users are downloading it. Because your app will be able to send logs & crash reports to the developers (of course with the permissions of the device user !!!) & it'll be the way to improve your application.
Let me know (To other SO users), if there is another way of doing the same thing. (Like default Apple feature or something)
Let me know if it helps or you want some more idea.
You can also use breakpoints. Assuming the value you want is defined within the scope of your breakpoint you have 3 options:
print it in console doing:
po some_paramter
Bare in mind in objective-c for properties you can't use self.
po _someProperty
po self.someProperty // would not work
po stands for print object.
Or can just use Xcode 'Variable Views' . See the image
I highly recommend seeing Debugging with Xcode from Apple
Or just hover over within your code. Like the image below.
In some environments, NSLog() will be unresponsive. But there are other ways to get output...
NSString* url = #"someurlstring";
printf("%s", [url UTF8String]);
By using printf with the appropriate parameters, we can display things this way. This is the only way I have found to work on online Objective-C sandbox environments.
In Swift with Xcode you can use either print() or NSLog().
print() just outputs your text. Nothing more.
NSLog() additionally to your text outputs time and other useful info to debug console.

view the return value of method invocation

How could I view the value of [fetchedResultsController sectionIndexTitles] in the debugger without change the code?
return [fetchedResultsController sectionIndexTitles];
Currently, I use to trick of add an tempory variable s and then use "print the descriptions of 's'" command. But this method requires me change the code so it is not convenient.
NSArray *s= [fetchedResultsController sectionIndexTitles];
return s;
Similar, it would be very helpful to be able to see the value of [a method1] in following statement:
[b [a method1]]
Do use breakpoints ... Add breakpoint to your return line, right click on breakpoint, edit breakpoint and now you have two options ...
Add Action Debugger Command ...
expr (void)NSLog( #"%#", [fetchedResultsController sectionIndexTitles] );
... or Log Message Action in a similar way and turn on Automatically continue after evaluating.
What it does?
Every time you hit your line with breakpoint, your application is paused, breakpoint actions are processed and as you did turn on Automatically continue after evaluating, your program continues when these breakpoint actions are processed. This is the way how to log, inspect, ..., without modifying your code.
I found the trick:
After the breakpoint is hit, Simply type following command in the LLDB would do the job:
po [self.fetchedResultsController sectionIndexTitles]
Where po is an abbreviation for expression -o -- used to print the object description of the value resulting from the expression.
The return value is visible in Xcode debugger, immediately after returning from a function call (i.e. immediately after hitting the the "step out" button). See below screenshot for example:

Viewing NSData contents in Xcode

I am running Xcode and I would like to dump out a NSData*. The variable in question is buffer. Is there a way to do this through the UI or the GDB debugger?
Edit
I've moved my notes into an answer.
No one has ever correctly answered the question. After 2 years I think it's time for one :)
Assuming you have in your code
NSData* myData;
Then in lldb you type
me read `[myData bytes]` -c`[myData length]`
If the format of the dump is not to your liking you can add '-t ' for example
me read `[myData bytes]` -c`[myData length]` -t int
For more help type
help me read
in lldb
From Xcode 5 (lldb), you can use the following:
po (NSString *)[[NSString alloc] initWithData:buffer encoding:4]
Note that this assumes your NSData instance is encoded with NSUTF8StringEncoding, but you can look up the other values in the headers or the documentation.
So if you're debugging something like a JSON request that's wrapped up in an NSURLSessionDataTask, the request data is in task.originalRequest.httpBody, and you can view that in the debugger with
po (NSString *)[[NSString alloc] initWithData:task.originalRequest.HTTPBody encoding:4]
In lldb, the following works to let you examine the contents of NSData objects:
You can get the address of the bytes for use with various debugger commands like this:
p (void *)[buffer bytes]
You see something like this:
(void *) $32 = 0x0b5e11f0
If you know the underlying data is a string, you can do this:
p (char *)[buffer bytes]
and the debugger will output:
(char *) $33 = 0x0b5e11f0 "This is the string in your NSData, for example."
In Swift this should do the trick:
po String(data:buffer!, encoding: NSUTF8StringEncoding)
Right click buffer and click on Print description of "buffer".
The console should say
Printing description of buffer:
<your data here ...>
Unfortunately, none of the suggestions so far solved the problem of actually being able to quickly display the data inside NSData.
I wrote a simple method that works the way I need it to. From the GDB window, I can type in print [Util dumpData:theData] and I will get nice, formatted output.
+(void) dumpData:(NSData *)data
{
unsigned char* bytes = (unsigned char*) [data bytes];
for(int i=0;i< [data length];i++)
{
NSString* op = [NSString stringWithFormat:#"%d:%X",i,bytes[i],nil];
NSLog(#"%#", op);
}
}
NsLog Output
0:24
1:0
2:4
3:0
4:0
5:0
Your data instance is empty.
It wouldn't only display the address otherwise. -[NSData description] includes a printout of the contents of the data. The bytes are grouped in fours and printed in hex with a leading 0 placeholder:
char arr[] = {0x1, 0x2, 0xA, 0x4, 0xF};
NSData * dat = [NSData dataWithBytes:arr length:5];
NSLog(#"%#", dat);
2012-07-17 22:24:48.973 PrintDat[61264:403] <01020a04 0f>
Using po dat at the debugger's command line will give you the same results, including the address:
(NSData *) $1 = 0x00007f98da500180 <01020a04 0f>
The contextual menu route that Anshu suggested also uses the description method.
I think I have it now.
Right click on NSData in the list displayed there, and click 'Show Memory Of "x"'.
I posted this as an answer to this relevant question:
Once you place a breakpoint, run, and the program stops at the breakpoint, hover your cursor over the variable/value you want to see like this:
You could also place an NSLog(#"%#", yourLabel.text); to view the contents of that label/other object type.
One other option is to run GDB in the console like this:
gdb
attach <your process name>
And then use the po (print-object) command to view the value of a variable like this:
po variableName
To view the value of primitive types (int, float, long, double, char, etc.), you can just use the print command while running GDB in the console like this:
print yourPrimitiveVariable
Hope this helps!
EDIT:
With the po command, you can print out the value of an object using both the property name (self.myProperty) or the ivar name (possibly _myProperty). I demonstrate this here:
Xcode 11.4 (and probably earlier) supports examining the raw bytes of (NS)Data in the visual debugger. Set a breakpoint after the Data has been assigned, hover over the symbol until the popup appears, and click on the eye or info icon. Roll for dexterity to prevent the popup from closing on you by moving outside of the tiny target.
Tested with Swift but presumably works with C family languages, too.
(Note: the eye icon produces the output below which is nicely formatted but, uh... seems to be missing the final column of bytes?)
The easiest way for me (during local development only!) is to convert to unused NSString instances. Then the values show right up in the debugger. Once I'm finished, I nuke those lines of code.
From this old thread
NSString* newStr = [[NSString alloc] initWithData:theData encoding:NSUTF8StringEncoding];
For Swift code I'm doing the following:
When my program is stopped in a breakpoint I use the "Add expression" option and enter [UInt8](data) where data is my Data instance:
After that I can see the data contents:

Is it possible to stop on a breakpoint in an instance of an object?

I've tried creating a breakpoint within a class definition, stopping on the message sent to an object instance, hoping it would then jump to the class code and allow me to walk through line by line and see the values of the local variables.
However, I'm going to venture out and say "no, this should not be possible", as there could be multiple instances of the class in memory. If someone could give a better explanation, that would be grand.
(As a side note, my alternative is excessive NSLogging of the runtime data.)
Yes, it is possible! You can add a condition to a breakpoint:
http://d.pr/yZVB+
http://d.pr/pWOB+
The program will only pause at this breakpoint when the condition is satisfied. You could choose a condition such as self == _myGlobalInstanceOfInterest.
If you don't want to store the instance in a variable, you might, for example, start the breakpoint without a condition — and then when you figure out which instance you want as the program is running, use p myObject to get the address, and then just set the condition to use the that address (such as self == 0x8badf00d).
I take it you want to break upon a message being sent to a particular instance?
Read the Xcode documentation on breakpoints and watchpoints. Basically, you can set a condition on a breakpoint so that it will automatically continue if self isn't the instance you're interested in.
Assuming you're talking about something like this:
- (void)eatAPieceOfFruit: (NSFruit *)fruit {
NSString * fruitType = [fruit species];
BOOL hasSeeds = [fruit hasSeeds];
NSInteger deliciousnessRating = [self enjoymentOfFruitType: fruitType];
NSString * reactionToEating = [self phraseForFruitType: fruitType];
// Breakpoint set here
}
The debugger has access to and knows the name of any variable that's in scope -- any variable that you would be able to use in the actual code at the line where you broke, you can also get to via the debugger. So, at the debugger prompt, type:
po reactionToEating
(that's "po" for "print object"), or the name of any other local variable to see what it is. If you want to call a method on an object that's in scope you can do so:
print (int)[reactionToEating length]
po [reactionToEating capitalizedString]