How to print something to the console in Xcode? - objective-c

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.

Related

Objective-C, Buzztouch coding alerts - Data argument not used by format string and Semantic issue. Can someone explain what is going on?

I'm currently running Mountain Lion OS X 10.8 with Xcode 4.4 installed. I'm running the iOS 5.1 simulator. I'm using Buzztouch as a learning tool while I'm studying Objective-C and Xcode. I get the following alerts when I compile, but the build succeeds. However, I would like to know exactly what is going on and how I can remedy the situation. Thank you for any assistance you can provide. Here's the code and the alerts I'm getting:
BT_fileManager.m
Data argument not used by format string
[BT_debugger showIt:self:[NSString stringWithFormat:#"readTextFileFromBundleWithEncoding ERROR using encoding NSUTF8StringEncoding, trying NSISOLatin1StringEncoding", #""]];
Data argument not used by format string
[BT_debugger showIt:self:[NSString stringWithFormat:#"readTextFileFromCacheWithEncoding ERROR using encoding NSUTF8StringEncoding, trying NSISOLatin1StringEncoding", #""]];
BT_camera_email.m
Semantic Issue
Sending 'BT_camera_email *' to parameter of incompatible type 'id'
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
NSLog(#"is camera ok");
UIActionSheet *photoSourceSheet = [[UIActionSheet alloc] initWithTitle:#"Select Image Source"
delegate:self
Again, thanks.
Greg
I have no idea what Buzztouch might be, however.... :-)
The first warning is fairly simple. In a format string there are placeholders beginning with a '%' sign to indicate where data values should be substituted. For example, to substitute a string, one would use '%#'. In the examples you show, there are no placeholders but there are data values -- empty strings. The compiler is warning that something you indicate you want to have put into the new string created by stringWithFormat: won't be.
To be sure about the second one, I'd want to see the .h file that declares BT_camera_email but my best guess is that it doesn't adopt the UIActionSheetDelegate protocol. The description of initWithTitle:... says the second parameter should be id<UIActionSheetDelegate> and that's probably what is being complained about.

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:

Write debug messages to Xcode output window

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

Is NSLog meant as a general purpose write?

In objective-c when I create a new project I get this in the main:
NSLog(#"Hello, World!");
I cannot find any other easy writing methods in the Foundation library.
Is NSLog the printf of objective-c? is it recommended to use it in production for printing on screen (of command line tools)?
If not, how can I print to screen using the Foundation library?
Edit:
It looks like NSLog also adds timestamp and things, I thought thats only the Xcode console.
How can I print objective c objects using a format like NSLog without timestamps?
Objective C is a superset of C, so you can still use your printf, scanf, etc. NSLog prints timestamp and some process information, and shows up in the system Console. NSLog also knows how to print Obj-C objects (use the %# format specifier).
If you like, you can do what I usually do: define my own printing function that works just as well, minus the timestamp:
void IFPrint (NSString *format, ...) {
if (!format) return;
va_list arguments;
va_start(arguments, format);
fputs([[[[NSString alloc] initWithFormat:format arguments:arguments] autorelease] UTF8String], stdout); // Omit autorelease call if using ARC.
va_end(arguments);
}
The way this works is that it uses NSString's text parsing (exactly how you use %# to print objects via NSLog), and prints it out very simply to the screen. It's faster than NSLog, and doesn't go through the system log service.
You can use printf. NSLog is convenient if you are printing NSStrings and other Objective-C objects.
NSLog is intended for writing debug trace to the console. Objective-c is not really geared towards developing a console based application, so if that was what you were intending, I would either look at the underlying C libraries and use printf and scanf, or a framework like this:
Objective-C Command Line Framework
In terms of how you can print out the object's description without the NSLog's timestamp information, I would use printf to print the output of [[myObject description] UTF8String], as I presume that's what NSLog uses when you print out the object using the %# format specifier.

Cocoa QTKit and recording movies

I'm new with the whole QTKit and I was looking for some feedback on the following code that I am attempting to use to display the camera's image and record movies.
- (void)initializeMovie {
NSLog(#"Hi!");
QTCaptureSession* mainSession = [[QTCaptureSession alloc] init];
QTCaptureDevice* deviceVideo = [QTCaptureDevice defaultInputDeviceWithMediaType:#"QTMediaTypeVideo"];
QTCaptureDevice* deviceAudio = [QTCaptureDevice defaultInputDeviceWithMediaType:#"QTMediaTypeSound"];
NSError* error;
[deviceVideo open:&error];
[deviceAudio open:&error];
QTCaptureDeviceInput* video = [QTCaptureDeviceInput deviceInputWithDevice:deviceVideo];
QTCaptureDeviceInput* audio = [QTCaptureDeviceInput deviceInputWithDevice:deviceAudio];
[mainSession addInput:video error:&error];
[mainSession addInput:audio error:&error];
QTCaptureMovieFileOutput* output = [[QTCaptureMovieFileOutput alloc] init];
[output recordToOutputFileURL:[NSURL URLWithString:#"Users/chasemeadors/Desktop/capture1.mov"]];
[mainSession addOutput:output error:&error];
[movieView setCaptureSession:mainSession];
[mainSession startRunning];
}
Also, I'm not sure about the whole error parameter that the methods keep calling for, I saw the "&error" symbol in an example but I don't know what it means.
I'm also getting an error "cannot initialize a device that is not open" when I explicitly open the devices.
If anyone could help me sort this out, it'd be a great help, thanks.
QTCaptureDevice* deviceVideo = [QTCaptureDevice defaultInputDeviceWithMediaType:#"QTMediaTypeVideo"];
QTCaptureDevice* deviceAudio = [QTCaptureDevice defaultInputDeviceWithMediaType:#"QTMediaTypeSound"];
Pass the actual constants here, not string literals containing their names. There's no guarantee that QTMediaTypeVideo is defined to #"QTMediaTypeVideo"; it could be #"Ollie ollie oxen free", and even if it is what you expect now, it could change at any time.
[output recordToOutputFileURL:[NSURL URLWithString:#"Users/chasemeadors/Desktop/capture1.mov"]];
Don't assume that the current working directory is /. Always use absolute paths. (I know this is test code; in real code, of course, you would have run an NSSavePanel and gotten the path from there.)
Also, I'm not sure about the whole error parameter that the methods keep calling for, I saw the "&error" symbol in an example but I don't know what it means.
The & means you're taking the address of a variable, which in this case is error. You're passing this address (a.k.a. pointer) to the error: argument of one of QTKit's methods. The method will, if it encounters an error, create an NSError object and store it at that address—i.e., in your variable. This is called “return-by-reference” (the “reference” being the pointer you provided).
I'm also getting an error "cannot initialize a device that is not open" when I explicitly open the devices.
Which method returns the error? Are you talking about an NSError, or just a Console message? If the latter, check your NSError variable and see what the problem method left behind.
This, incidentally, is why you should bail out if any of the QTKit methods returns an error: one of the subsequent messages may clobber it with a new error if you don't.
Also, you may want to look at the MyRecorder sample code. It's a fully functional video recorder based on the QTKit Capture API. The code is reasonably simple and should be easy to understand.