Using the Xcode Structure menu

Xcode’s Editor > Structure menu has a few great actions:

Screenshot demonstrating where to find the menu item in Xcode

These actions all act on either your cursor position or selection.

Balance Delimiter

Normally you can double-click quotes, brackets, or parenthesis to select the matching character and all text in-between. The Balance Delimiter behaves similarly: it looks at your cursor position (or selection), finds the nearest pair and selects in-between.

This doesn’t have a default keyboard shortcut, but you can set one up in Xcode’s Key Bindings preferences. I set it to ⇧⌃I since I use it in similar ways to Re-Indent.

Re-Indent ⌃I

Objective-C is a fairly indentation-heavy language, and Xcode generally does a good job at indenting while you’re typing. However, if you’re pasting text or refactoring things can get pretty hairy, so let Xcode fix up your code for you with Re-Indent.

Shift Left ⌘[, Shift Right ⌘]

You can also indent manually using the Shift Left and Shift Right actions, which unindent or indent by one tab, respectively. They do exactly what they say on the tin.

Move Line Up ⌥⌘[, Move Line Down ⌥⌘]

These actions move your current line (or selection) up or down by one line. Simple, right? What’s really useful is that it is context-aware: they understand going in and out of control flow or blocks. Much faster than cutting, pasting and re-indenting each time.

Comment Selection ⌘/

Rather than wrapping your code in /* … */ and dealing with the conflicting multi-line comments you probably already have, simply select what you want to temporarily eliminate and hit the shortcut. Each line selected is then prefixed by //.

Error arguments in Objective-C

From the Programming with Objective-C (backup) overview from Apple:

When dealing with errors passed by reference, it’s important to test the return value of the method to see whether an error occurred, as shown above. Don’t just test to see whether the error pointer was set to point to an error.

and from the Error Handling Programming Guide (backup):

Success or failure is indicated by the return value of the method. Although Cocoa methods that indirectly return error objects in the Cocoa error domain are guaranteed to return such objects if the method indicates failure by directly returning nil or NO, you should always check that the return value is nil or NO before attempting to do anything with the NSError object.

For example, let’s say we’re executing a fetch request:

NSError *error = nil;
NSFetchRequest *request = /* … */;
NSArray *objects = [context executeFetchRequest:request

To test if the fetch was successful, we must do:

if (objects) {
    // hooray!
} else {
    NSLog(@"Got an error: %@", error);

A method taking an NSError ** does not guarantee how it is used when successful. In this case, even a successful method call may end up with error set to something other than nil.

Cleaning up old git branches

My local git repository is full of branches which have long-since been merged: code review, one-off features, and quick bug fixes add up really quickly. Deleting these branches is cumbersome.

Complaining on Twitter proved really fruitful:

There’s also `git branch –merged`, which you could pipe to xargs (assuming you can remember the syntax, which I never can.) — @bjhomer

Of course, he’s right, so finding and deleting them is easy. The end result is this wonderful snippet, which deletes all merged branches:

$ git branch --merged origin/master | grep -v master | xargs git branch -d

The text spam after it executes can only be described as cathartic.

Portable encrypted backups

To keep track of the ever-growing array of passwords and private data, I use 1Password, which I could not recommend more.

There’s a problem though: what if I lose access to my database? I’ve toyed with a few options in the past, including uploading it to Dropbox or Google Drive, but these are services for which I’ve enabled multi-factor authentication, and require internet access.

For a few years now, Macbook Pros have included an SD slot for photographers. Or, as it turns out, everybody!

I bought a Transcend SD card with a decently-useful 16GB capacity for about $10. As of OS X 10.8, you can format any disk to be encrypted. Match made in heaven.

Going from the stock card to an encrypted version is easy, but does involve making the disk Mac-only:

  1. Launch Disk Utility from /Applications/Utilities
  2. Select the SD card from the source list and choose “Partition.”
  3. When repartitioning the drive, choose “Options…” and format using GPT.
  4. Erase the newly-created partition with the “Mac OS Extended (Journaled, Encrypted)” option.

With a tiny, portable, encrypted disk, there’s a lot of cool things you can back up. I currently save:

  • My 1Password and system keychains.
  • The database for Authy, which is like Google Authenticator, backed up via iExplorer.
  • Copies of my source code repositories.
  • Public and private SSH keys.

I’ll find more uses as time goes on. Right now it’s a manual process to update, but this is more of an emergency backup: I use Arq for my normal backup needs.

Incrementing with a bitmask

Bitmasks are fun. There’s lots of little tricks you can do with them. A common situation is checking for the presence of a flag among elements in a linked list, or some similar data structure. I came across a trick a few years ago that makes it drop-dead simple.

Let’s say we needed to check for AUsefulFlag in the flags element of each node, and total how many elements in the linked list had the flag.

uint64_t count = 0;
for(Node *iter = head; iter != NULL; iter = iter->next)
    count += !!(iter->flags & AUsefulFlag);

After execution, count is the number of items which have AUsefulFlag set.

Double-not (!!) is one of those useful operations which are especially useful with bitmasks. It may require a double-take at first, but it behaves exactly how you’d think.

!! of 1 is 1. !! of 0 is 0. In fact, !! of any true value evaluates to 1, so we can use it to transform something like 0b00001000 to simply 1 and increment by that value.