Xcode code snippets and syncing

Earlier today I took some time to create a few more code snippets in Xcode for code I’ve been writing a lot of lately. I’ve never really seen or discussed these much with other developers, so I was wondering whether people actually use them – and to what extent? I know from my own experience that I don’t use them nearly enough, so I thought I’d write up a quick post on Xcode’s awesome Code Snippet Library.

The Code Snippet Library in Xcode is a great feature and a huge time saver – you’ll be doing yourself a favour by using it if you haven’t already! Ever noticed how when you start typing “init” Xcode will autosuggest the Objective-C init method? It does this because it’s a code snippet with a completion shortcut “init”. Same with “forin”, “dealloc” and many more built-in code snippets. Check each snippet’s completion shortcut in their edit mode.

Objective-C init method code snippet

Here’s a basic example of a “user” code snippet I have in my library:

UIAlertView boilerplate code snippet

I wrote up the code for a UIAlertView, highlighted the code and dragged it into the Code Snippet Library. The code snippet retains the parameter placeholders as well as your indentation (don’t worry about the indentation in the preview box such as in the example above, as long as it’s correct when used in your code). Now for the awesome part: Notice how I set the Completion Shortcut to “alertview” and the Completion Scope to “Code Expression”? Now, if I type alertview inside a method Xcode will auto-suggest this entire code snippet and I simple hit enter to use it and tab through the parameters to quickly setup a UIAlertView. Thanks Xcode <3

The Completion Scope is fairly important as it allows you to set the scope for when Xcode should auto-suggest your code snippet. If a code snippet is a method, set the scope as such and Xcode won’t auto-suggest that snippet if you’re inside a method. If you’re writing code for both OS X and iOS you can also set a specific platform for the code snippet so you’re not having your UIKit-specific code snippets suggested when you’re writing code for a Mac app.

Keeping your Code Snippet Library in sync

An hour ago, I tweeted about syncing Xcode Code Snippet Library with Xcode, which basically led me to writing up this blog post.

I’ve got my Macbook Pro at work and Mac Pro at home and often switch between the two. Unfortunately Xcode doesn’t have iCloud syncing – though what a nice feature this would be – so keeping your Code Snippet Library in sync could be a small pain. Enter symlinks.

Custom code snippets can be found in

~/Library/Developer/Xcode/UserData/CodeSnippets/

Each code snippet is a plist file, which means adding or deleting code snippets on any machines won’t give you any issues (I believe it would in Xcode 3 because all snippets were saved into one file, which may have created some conflicts depending on the method used to sync).

Assuming you’re a Dropbox user*, you can use it to sync user Code Snippets between two or more machines. In the following example, I’ve setup a folder in Dropbox for Xcode. I’ll move my /CodeSnippet folder to the Xcode folder in Dropbox and setup a symlink in the original path that points to the CodeSnippet folder in my Dropbox:

$ cd ~/Library/Developer/Xcode/UserData
$ mv CodeSnippets /Dropbox/Xcode/
$ ln -s ~/Dropbox/Xcode/CodeSnippets/ CodeSnippets

You may have to sudo the last line, but now you should be all set. Do the same thing on your other machine(s) and start creating lots of useful snippets to use on any machine you’re working on! Don’t forget Completion Shortcuts to make your life much easier.

Hope you found this post useful. If you have similar tips, feel free to share in the comments. @tewha replied to my tweet saying that he uses symlinks to sync Archived builds and other Xcode User Data across several machines.

*If you’re not a Dropbox user, feel free to use my referral link :)

Random tips

I was expecting this blog post to be about something completely different, but I’m still out of the country and have come down with a bad cold, so it’ll be a bit of a short and simple.

I’ve decided just to a few coding tips, I have come across and though might be useful for other devs, especially if you haven’t worked much with UIKit before in your development, or perhaps just these areas below. (At the bottom of this post is an Xcode project file which includes examples of the tips below).

Tip #1: Check for URL scheme and open correct app from your own
You’ll probably run into having to link to another app, for example your company’s Twitter account. Instead of just linking to the Twitter website, you can do a quick check in code and open the Twitter app instead. You can also do it with other Twitter client apps as well, however, not all have URL schemes setup (that I could find), and most users will probably be using the official one anyway. Regardless, the code is good to do the same check for other apps, or if Twitter.app doesn’t exists on the user’s device, you can try another Twitter client app, or use a UIAlertView to ask the user what else they’d like to use (depending on which ones are possible to open using the URL scheme).

Basically, all you have to do is ask whether UIApplication responds to the URL:

BOOL twitter = [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"twitter://user?screen_name=runmad"]];
if (!twitter) {
	[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://www.twitter.com/runmad"]];
} else {
	[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"twitter://user?screen_name=runmad"]];
}

List of URL Schemes: http://wiki.akosma.com/IPhone_URL_Schemes

Tip #2: Getting a free UINavigationController in your UIViewController
I have seen some apps that use a UIToolbar as a navigation bar, and this just doesn’t work. If you compare the two, they’re actually a bit different, and this really shows when put in the wrong place.

If you’ve got a UIViewController, turning it into a UINavigationController is really easy:

RootViewController *rootViewController = [[RootViewController alloc] init];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
[self.navigationController presentModalViewController:navigationController animated:YES];
[rootViewController release];
[navigationController release];

Tip #3: Getting a free UIToolbar in your UINavigationController
This one I only just recently found out (thanks to @auibrian)
. UINavigationController actually comes with a UIToolbar. It’s property is set to hidden:YES by default, so all you have to do is override this property when you load the view.

[self.navigationController setToolbarHidden:NO];

Note: I have seen some weird behaviour when pushing view controllers onto the screen (buttons not getting a pushing animation, just appearing in the toolbar in place). Also, you will need to hide the toolbar if you’re popping or pushing to a view controller that you do not want to show the toolbar (because with pushing you’re reusing the same navigation controller). In my opinion it’s not a very good way, I wish the view controllers were more separate for this.

Tip #4: Use shadowColor and shadowOffset appropriately when faking text indention
One thing that bugs me are improper use of a UILabel’s shadowColor and shadowOffset. When using these, one has to pay attention to the colour of the background as well as the text colour. In the below example (when we’re going for the look where text looks carved into the display, used by Apple across the entire UI), we’ll see that when using darker text, use a lighter colour for the shadow and a positive value for the offset.

When displaying lighter coloured text, use a darker shadow colour and a negative value for the offset, which in both cases create the proper indented or “carved” effect.

Using the wrong combination doesn’t create this effect and makes the text appear raised from the rest of your UI, which is most likely not what you should be going for in most cases ;)

I’ve made a small Xcode project you can download here, which has the code examples from tips 1, 2 and 3 and I suppose #4 as well, since navigationItem.title is using text indention.

Again, apologies for a bit of a short and simple post due to being under the weather and traveling.

Quick guide to updating your app’s UI for iPhone 4

iPhone 4 will make your UI look stunning. Everything in UIKit has been scaled up already so it will require only a bit of work on your end to make the rest of your app look amazing on iPhone 4. If you only code and don’t touch Photoshop, you’re in luck. However, if you’re a UI designer or have the skills to do your own UI, hopefully you did your original artwork in a nice high resolution – if not, you have a bit of work cut out for you with updating all the UI elements to 2x the resolution.

Updating your app’s UI to be compatible with iPhone 4’s Retina Display is amazingly simple. Since the scale works in points, not pixels, you will have to do very little work on the layout itself. Apple Engineers have made it really simple to use new graphics for all your UI on iPhone 4, at the same time as being compatible (and not using 2x memory) on older, lower resolution, lower memory devices.

All you have to do is add the same image file at 2x the pixels to your app’s resources and name it the same it’s lower resolutions sibling with the following suffix: “@2x”.

For example, in your Resources folder, you will now need to have two image files, one for older devices called myImage.png and one for iPhone 4 called myImage@2x.png, which is twice the resolution.

This way, when you call [UIImage imageNamed:@”myImage.png”]; (or contentsOfFile:) iPhone 4 will automatically grab the filename with a @2x suffix, and lower resolution images will grab the lower resolution copy. You don’t have to check for the device loading the image and write any additional code to grab the correct image. Genius!

If you have seen an iPhone app on the iPad in 2x scale, that’s pretty much how your app is going to look on the iPhone 4. Perhaps not so drastic, but there will be a noticeable difference from app not optimized for iPhone 4 and “Retina Apps” as Apple calls them.

Thoughts on @2x on iPad…
I didn’t hear anything at WWDC regarding this, but my thought is that they’ll integrate this into the iPad for the next major OS release. Basically, it will be able to do the same and grab the higher resolution image appropriately for iPhone apps running at 2x scale.

Happy Photoshopping to UI designers and happy relaxing programmers!

UPDATE JULY 7, 2010:

I have discovered a bug in Apple’s code that deals with grabbing the correct image on iPhone 4. If you are using imageWithContentsOfFile: the code will in fact not automatically grab the @2x if running on iPhone 4. I have submitted a bug report to Apple, and they’ve informed me they are now aware of the issue and the Engineers are currently working to fix the bug. So for now, stick with imageNamed: for all your images.

Debugging Executables for Push Notifications

I am implementing Push Notifications in one of my apps. Doing so may be a bit tricky in terms of debugging since you cannot actually debug incoming Push Notifications appropriately while the app is running, so I wanted to share this tip. Also, I am writing this post on my iPad on an airplane, so pretty excited about that :)

Xcode allows you to debug applications that are running locally on your device. You can even set breakpoints in your code and print out any information you may need from the console in order to debug your app and fix whatever issue you’re experiencing, should you not be able to fix it via “live” debugging.

This feature is especially useful if you’re doing Push Notifications (a great way to easily communicate information to your user with their permission, such as notifications, reminders, marketing (be careful with this one), etc.).

With Push Notifications, your app receives data from Apple Push Notification servers in a dictionary in the UIApplication delegate application:didFinishLaunchingWithOptions: that you’ll need to parse and do in your app whatever is appropriate for the implementation you’ve chosen (launching with specific views in front, etc.). Since your app cannot be running while receiving Push Notifications (it actually does receive notifications while running, but you’re required to deal with that through another delegate method), you’ll need to use the “debug executables” with “Wait for next launch/push notifications” ticked. Once you run the debugger and launch your app (for example directly via a Push Notifications UIAlertView) you can set breakpoints anywhere in your code and use the console to print out (po) any objects you may wish to inspect.

As your app launches immediately when you debug, it’s a problem if you’re debugging Push Notification (which, by the way, does not work in Simulator). So here’s the hidden treasure in Xcode: In the Groups & Folder pane, find Executables, expand and select your app executable. Hit command+option+i to “Get Info” and select the Debugging tab. From here, tick “Wait for next launch/push notification”.

Now, when you Run & Debug your app it will not launch, but instead wait until you tap the app icon to launch it or the app is launched via a Push Notification UIAlertView (this of course requires you have not set the “action-loc-key” to null in your Push Notification JSON dictionary).

Once your app launches via a Push Notification, it will stop at the breakpoint you set and you can now print out any information you need to debug your app, such as the NSDictionary your app receives, whether the appropriate view will be displayed and any other issue you may have.

Dedicated Static Analyzer Debug Configuration in Xcode

I went to iPhone Tech Talk in Toronto yesterday, and among the many sessions, I attended Michael Jurewitz’ (@jurewitz) session, “Testing and Debugging Your iPhone Application.” He covered a lot of the basics for using Instruments (very similar to last year’s session on that), how to setup provisioning, etc. for Ad-Hoc Beta testing, etc.

He also covered Xcode’s new built in Static Analyzer (Clang), which is incredibly useful and powerful now that it’s a part of Xcode. However, I haven’t been using it that much (he said to use it at least once a week), but he briefly showed that there’s actually a setting in the project’s build settings called “Run Static Analyzer,” which is a checkbox and checking this will run the Static Analyzer every time you build your project. Jurewitz mentioned you could make a duplicate Debug build configuration that is dedicated to running the Static Analyzer.

He went over this very fast, so I think a lot of people missed the benefit of this great tip!

So here’s how you do it:

Open your project settings and go to the Configurations pane. Pick your Debug configuration (or whichever build configuration you want to dedicate to running the Static Analyzer) and hit Duplicate in the bottom of the window. I called mine “Debug with Clang,” so I know it’s my Debug build configuration.

Next, hop into the Build pane and find “Build Options”. Within those options you’ll find the “Run Static Analyzer” option. Check the checkbox and you’re good to go!

Now, every time you build your project using your new “Debug with Clang” it’ll automatically analyze your project. Personally it’ll probably help me remember to run the Static Analyzer way more often on my project, instead of just once in a while.

Keep in mind that running the Static Analyzer increases the time it takes to build your project, so don’t choose that build setting if you’re just testing new code, etc. Also, I find it’s a good idea to “Clean All Targets” once in while, as it seems to ‘reset’ the Static Analyzer, because otherwise I am finding that it tends to miss certain errors on the second, third, fourth, etc. time you build with the “Run Static Analyzer” option on.