Printing a dictionary nicely in Xcode - xcode

Is there a way to nicely print dictionaries in XCode during debugging? Selecting print description to console is ugly.

You should use a Category on NSDictionary and override - (NSString *)description.
(This way it automagically applies to all your existing NSDictionaries)
Below is a sample formatting, but you could change it to look like anything you want.
// NSDictionary+NicePrint.h
#import <Foundation/Foundation.h>
#interface NSDictionary (NicePrint)
#end
// NSDictionary+NicePrint.m
#import "NSDictionary+NicePrint.h"
#implementation NSDictionary (NicePrint)
- (NSString *)description
{
NSMutableString *output = [[NSMutableString alloc] init];
[self enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
[output appendFormat:#"%# => %#\n", key, obj];
}];
return [NSString stringWithString:output];
}
#end

You could subclass NSDictionary and override the -(NSString*)description function of NSObject.
Take you 5 minutes.

Related

NSString category failing on NSTaggedPointerString

I have a NSString category with a simple trim method in it. And it looks like my string is a NSTaggedPointerString and it won't evaluate properly.
Error:
[NSTaggedPointerString trim]: unrecognized selector sent to instance
What should I do to address this?
#import <Foundation/Foundation.h>
#interface NSString (StringHelper)
- (NSString *)trim;
#end
#import "NSString+Helper.h"
#implementation NSString (StringHelper)
-(NSString *)trim
{
return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
#end

Programmatically tagging in Mavericks from an Sandboxed App

I am writing to a file in an sandboxed app and later trying to set the tags for it using -[NSURL setResourceValue:theTags forKey:NSURLTagNamesKey error:&theTaggingError];. I am not getting any errors (i.e, tags are successfully applied once) but eventually file is kind of replaced and tags are lost. This is only in sandboxed app; if I turn off sandboxing things work fine. In sandboxed mode, if I set tags without writing to the file - again things work fine.
In essence, I am unable to set tags of a file after writing to it. How can I fix it? Any insights?
Sample Code:
#import <Cocoa/Cocoa.h>
#interface AppDelegate : NSObject <NSApplicationDelegate>
{
NSWindow *_window;
NSURL *_saveURL;
NSSavePanel *_savePanel;
}
#property (assign) IBOutlet NSWindow *window;
#property (retain) NSURL *saveURL;
#property (retain) NSSavePanel *savePanel;
- (IBAction)writeAndTag:(id)sender;
- (IBAction)justTag:(id)sender;
#end
#implementation AppDelegate
#synthesize window = _window;
#synthesize saveURL = _saveURL;
#synthesize savePanel = _savePanel;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
self.savePanel = [NSSavePanel savePanel];
}
- (IBAction)writeAndTag:(id)sender
{
[self.savePanel beginSheetModalForWindow:self.window completionHandler:^(NSInteger result) {
self.saveURL = [self.savePanel URL];
NSString *testString = #"Hello!";
NSError *error = nil;
[testString writeToFile:[self.saveURL path] atomically:NO encoding:NSUTF8StringEncoding error:&error];
if(error)
{
NSLog(#"Err in saving: %#" ,error);
error = nil;
}
// Tag is lost here
BOOL success = [self.saveURL setResourceValue:[NSArray arrayWithObjects:#"Test", nil] forKey:NSURLTagNamesKey error:&error];
NSLog(#"Tagging success: %#", (success)?#"YES":#"NO");
if(error)
{
NSLog(#"Err in tagging: %#" ,error);
}
}];
}
- (IBAction)justTag:(id)sender
{
// Works fine
[self.saveURL setResourceValue:[NSArray arrayWithObjects:#"Test", nil] forKey:NSURLTagNamesKey error:NULL];
}
#end

Using a UIPickerview

I have this code that i did on Xcode 4.2 in a tabbed application and it works perfectly but what i would like it to be is a drop down menu in to a picker view but I'm not to sure what code i will need to add can you guys help heres my code
.h
#import <UIKit/UIKit.h>
#interface FirstViewController : UIViewController {
IBOutlet UIPickerView *pickerView;
NSMutableArray *list;
IBOutlet UILabel *picklabel;
}
#end
.m
#import "FirstViewController.h"
#implementation FirstViewController
-(NSInteger)numberOfComponentsInPickerview:(UIPickerView *)thePickerView {
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)thePickerView numberOfRowsInComponent:(NSInteger)component {
return [list count];
}
-(NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component { return [list objectAtIndex:row];
}
-(void)pickerView:(UIPickerView *)thePickerView titleForRow:(NSInteger)row inComponent:(NSInteger)component {
NSString *string = [NSString stringWithFormat:#"you selected: %#" , [list objectAtIndex:row]];
picklabel.text = string;
}
- (void)viewDidUnload
{
[super viewDidUnload];
list = [[NSMutableArray alloc] init];
[list addObject:#"Giraffe"];
[list addObject:#"Water Bottle"];
[list addObject:#"spinning Fan"];
[list addObject:#"Hariy Monkey"];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
Follow this steps:
On selection of each pickerview, add that data to one mutable array
Each time reload your table view with that data (mutable array)
Selected data will get added to your tabular list.
Enjoy Coding :)

NSString out of scope

I used the codes below to set a NSString
#import <Foundation/Foundation.h>
#interface AppController : NSObject
{
NSString *myString;
}
#property (nonatomic, retain) NSString *myString;
#end
#import "AppController.h"
#implementation AppController
#synthesize myString;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
NSString *zs0= [[NSString alloc] initWithFormat: #"abc"];
myString =[zs0 retain];
[zs0 release];//breakpoint
}
- (void)dealloc {
[myString release];
[super dealloc];
}
#end
when I check the value of myString at the breakpoint
it always said 'out of scope'
Welcome any comment
You don't need the temp variable zs0 - just assign it to the property
You don't need initWithFormat since you're not formatting.
You don't need to alloc the string - if you call [NSString stringWithString] it will autorelease it and then when you assign it to a (retain) property, it will retain it.
You're over retaining. You alloc the string which gives it a retain count of 1, then you retain it which gives it 2, then you assign it to a retained property which retains it again.
One simple way is:
self.myString = [NSString stringWithString:#"abc"];
That will create a string that's autoreleased (not created with alloc, copy by convention) and then the property will retain it.
Why are you using initWithFormat if you aren't using a format?Next, why even allocate zs0 if you aren't going to use it? Just set myString to what you want it to be.
Thus, your code should look like this:
myString = [[NSString alloc] initWithString: #"abc"];
Try that and everything should work.

Cocoa - Calling a variadic method from another variadic one (NSString stringWithFormat call)

I have a problem with [NSString strigWithFormat:format] because it returns an id, and I have a lot of code where I changed a NSString var to an other personal type. But the compiler does not prevent me that there are places where a NSString is going to be set into another type of object.
So I'm writing a category of NSString and I'm goind to replace all my calls to stringWithFormat to myStringWithFormat.
The code is :
#interface NSString (NSStringPerso)
+ (NSString*) myStringWithFormat:(NSString *)format;
#end
#implementation NSString (NSStringPerso)
+ (NSString*) myStringWithFormat:(NSString *)format {
return (NSString*)[NSString stringWithFormat:format];
}
#end
The compiler tells me that "Format not a string literal and no format arguments".
Do you see any way to make this work ?
NSString includes a method that takes in an argument list from a variadic function. Look at this sample function:
void print (NSString *format, ...) {
va_list arguments;
va_start(arguments, format);
NSString *outout = [[NSString alloc] initWithFormat:format arguments:arguments];
fputs([output UTF8String], stdout);
[output release];
va_end(arguments);
}
Some of that code is irrelevant, but the key line is NSString *output = [[NSString alloc] initWithformat:format arguments:arguments];. That's how you can construct an NSString in a variadic function/method.
In your case, your code should look something like this:
+ (NSString *)myStringWithFormat:(NSString *)format, ... {
va_list arguments;
va_start(arguments, format);
NSString *formattedString = [[NSString alloc] initWithFormat:format arguments:arguments];
va_end(arguments);
// perform some modifications to formattedString
return [formattedString autorelease];
}
No Objective-C expert here, but the original method signature for stringWithFormat includes ellipses, which allows you to pass in the arguments that are going to be substituted to the placeholders in the format argument.
EDIT: stringWithFormat is a so-called variadic method. Here's a link to an example.
Thank you for your help.
Reading your reference documentations, I found the solution !
This works :
In the .h
#interface NSString (NSStringPerso)
+ (NSString*) strWithFormatPerso:(id)firstObject, ...;
#end
In the .m
#implementation NSString (NSStringPerso)
+ (NSString*) strWithFormatPerso:(id)firstObject, ... {
NSString* a;
va_list vl;
va_start(vl, firstObject);
a = [[[NSString alloc] initWithFormat:firstObject, vl] autorelease];
va_end(vl);
return a;
}
#end

Resources