Coding under the Hammer
Mac
Show hidden files in the Finder
Jan 10th
Sometimes when you are digging around in the under pinnings of Mac OS X, you need to access folders and files that are normally hidden by the OS. Thankfully there is preference in the Finder for this, which you can turn on and off in the Terminal.
The command is:
defaults write com.apple.Finder AppleShowAllFiles YES
The Finder needs to be restarted for this change to take effect. Luckily there is a Terminal command for this too:
killall Finder
Once you are done playing around with hidden files, you can stop showing them by replacing YES with NO in the original terminal command.
defaults write com.apple.Finder AppleShowAllFiles NO
It is as simple as that, but make sure your don’t break anything.
URL Encoding
Oct 25th
If you have tried to send any information using a GET web request, you would have come across an annoying problem. That annoying problem is making sure that the URL is correctly encoded.
At first glance it would seem that the Cocoa Frameworks do this for you, and you would be right …. well kind of.
The issue is that by default most of these methods leave characters such as & = ? within a URL, as they are strictly speaking valid. The problem is that these characters have special meanings in a GET request, and will more than likely make your request in valid.
Luckily there is a function in Core Foundation that helps:
CFStringRef CFURLCreateStringByAddingPercentEscapes (
CFAllocatorRef allocator,
CFStringRef originalString,
CFStringRef charactersToLeaveUnescaped,
CFStringRef legalURLCharactersToBeEscaped,
CFStringEncoding encoding
);
What makes this function useful, is the legalURLCharactersToBeEscaped parameter. This will escape legal characters such as & ? = if they are supplied. This allows you to escape parameters using the following code.
CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)parameter, NULL, CFSTR(":/?#[]@!$&’()*+,;="), kCFStringEncodingUTF8)
An example of when to use this, is Twitters Update status API. You can find that here http://apiwiki.twitter.com/Twitter-REST-API-Method%3A-statuses%C2%A0update
To update your status to the following:
This is my status
You would need to post up the following URL:
http://twitter.com/statuses/update.xml?status=This%20is%20my%20status
As this is such a common problem of mine, I have created a category on NSURL. This allows you to pass in a base URL and a parameters dictionary.
+ (NSURL *)URLWithBaseString:(NSString *)baseString parameters:(NSDictionary *)parameters{
NSMutableString *urlString =[NSMutableString string];
//The URL starts with the base string
[urlString appendString:baseString];
NSInteger keyIndex = 0;
for (id key in parameters) {
//First Parameter needs to be prefixed with a ? and any other parameter needs to be prefixed with an &
if(keyIndex ==0)
{
[urlString appendFormat:@"?%@=%@",key,CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)[parameters valueForKey:key], NULL, CFSTR(":/?#[]@!$&’()*+,;="), kCFStringEncodingUTF8)];
}else{
[urlString appendFormat:@"&%@=%@",key,CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)[parameters valueForKey:key], NULL, CFSTR(":/?#[]@!$&’()*+,;="), kCFStringEncodingUTF8)];
}
keyIndex++;
}
return [NSURL URLWithString:urlString];
}
Using a parameters dictionary keeps the code nice and clean, but beware, to use the category method above you still have to make sure that your keys, and the base URL are correctly encoded (no spaces or invalid characters !!!!!).
As we now have a category method to do all the hard work for us, to create the Twitter URL you just need to do the following:
NSString *baseString=@"http://twitter.com/statuses/update.xml";
NSDictionary *dictionary=[NSDictionary dictionaryWithObjectsAndKeys:@"This is my status",@"status",nil];
NSURL *url=[NSURL URLWithBaseString:baseString parameters:dictionary];
And thats it. Obviously this category can be used for things other than twitter ….. if you really want to.
Reopening an application’s main window by clicking on the Dock Icon
Aug 9th
When building Mac applications, Apple usually takes care of most of the default behaviours for you. One thing that Mac applications don’t do by default is, reopening the applications main window (if it has been closed), when the dock icon is pressed.
Although this information is very hard to find in the documentation, but is actually very easy to. The method you need to find is:
- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag;
This is an optional delegate method that your AppDelegate can choose to implement, and is called when the user presses your application’s dock icon. The bool flags indicates whether the application has any visible windows. To reopen your application’s main window, you need to have a pointer to it (In the example below assume that it is defined as NSWindow *window; in the header file). If you do have a pointer to then you simple need to implement the code below.
- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag{
if(flag==NO){
[window makeKeyAndOrderFront:self];
}
return YES;
}
It is as simple as that.