Version Number vs. Build Number in Your App's Info.plist File
A really useful discussion of the difference between the version number (bundle versions string, short) and build number (bundle version) and how to manage both in Xcode 4.
This is the web log of High Order Bit, makers of great software for iPhone and iPad. Learn more about us on our website, or follow us on Twitter.
Follow @highorderbit
|
Chirpy |
|
Twitbit |
|
GPS Tracks |
|
Notekeeper |
A really useful discussion of the difference between the version number (bundle versions string, short) and build number (bundle version) and how to manage both in Xcode 4.
I’ve written several times about my various attempts to get Vim to work well with Xcode. In my most recent post on the subject, I discussed my decision to finally stop trying to hammer a round peg into a square whole and just commit to Xcode full-time.
And use Xcode full-time I did. Text editing is a complete joke, of course, and while at one time I was able to customize the key bindings pretty heavily by editing the plist files directly, those tricks no longer work in Xcode 4. (These were a huge productivity boost. For example, in Xcode 3 and the first 5 betas of Xcode 4, I had a mapping to highlight the word under the cursor, use the selection for find, and find next. This is very similar to hitting * in Vim, and is so much faster than doing those 3 steps manually. Finding the next occurrence of the word under the cursor is something I do many, many times a day, and should be directly supported in the text editor. But alas, support for binding multiple commands to a single binding was removed in Xcode 4 beta 6 and hasn’t returned.) Binding multiple keystrokes to a single binding was also removed in Xcode 4 (e.g. mapping control-s control-l to select the line). Multiple keystrokes helped me “namespace” commands, making them easier for me to remember. For example, I had mapped control-s control-w to select the word, control-s control-l to select the line, control-s control-a to select all, and so on. I knew everything related to selection was mapped under control-s.
Despite Xcode slowly tightening the noose on those who were seeking out efficient text editing, I stuck with it. The advantages of being able to live inside the first party development tool still outweighed the downsides of a text editor that made me feel like I was wearing mittens while typing.
Enter Xvim. It’s a plugin for Xcode that provides Vim key bindings in the text editor. My friend Brad Umbaugh pointed it me to it, and my life hasn’t been the same since. It seems to support almost all of the Vim editing commands I use day-to-day. It even supports macros, which I have to admit I tried on a lark and had zero expectation would actually work, so I was extremely impressed. There are a few bugs and problems with it, but in the scheme of things they’re extremely minor and in no way detract significantly from the workflow gains made.
Clumsy native editing aside, I think Xcode 4 has turned into quite a nice IDE. It has stability problems to be sure (stability problems which got so bad during 4.3 that I started to really wonder about the overall quality of the codebase), but aside from the text editor, there is a lot to like: nib editing directly integrated into the environment is nice; project navigation is fast and easy (command-shift-o ftw); navigating splits, tabs, and windows is efficient; the built-in certificate/provisioning/submission management is a huge step forward; and lldb is a really nice debugger.
Vim for me was always a spectacular editor, but never a great IDE. I’ve experimented with various plugins to help with that, but I never really liked anything other than the NERD Tree file explorer to navigate my file system. But among obvious deficiencies like debugging, nib editing, and browsing documentation were seemingly simple problems like the fact that I was never really able find a good Vim plugin to let it understand the concept of a “project” the same way that Xcode or even other plain text editors like TextMate understand projects.
Overall for me then, Xcode plus Xvim is near perfection. I can use what’s evolved into quite a nice development environment in Xcode while still having an extremely efficient native text editor. If you’re a Vim user that’s doing iOS or Mac development, I highly recomment giving it a try.
I’ve been writing software for iOS full time for almost 3 years. During that time, I’ve noticed an increasing number of developers using C macros for operations where they’re not necessary, and could be more effectively replaced with either C functions or Objective-C methods.
C macros come with a host of problems that are well known to C and C++ programmers. There are situations where they provide unique functionality, but those situations are rare. My rough sense is that many members of the exploding iOS community are coming from a Java, Python, or Ruby background, and don’t have deep experience with a C-based language. Many of these developers don’t have a thorough understanding of how easy it is for macros to cause subtle and unexpected problems. There’s nothing wrong with this; learning the nooks and crannies of an archaic language like Objective-C takes time. It takes making lots of mistakes. Hopefully I can help a few people avoid some that I’ve tripped over in the past.
Macros are preprocessor definitions. What this means is that before your code is compiled, the preprocessor scans your code and, amongst other things, substitutes the definition of your macro wherever it sees the name of your macro. It doesn’t do anything more clever than that. Almost literal code substitution. There are plenty of great explanations online of the kinds of subtle and not-so-subtle problems they can cause. I’ll give one extremely simple example here.
Suppose you want a method to return the maximum of two numbers. You write a macro to do this simple task:
#define MAX(x, y) x > y ? x : y
Simple, right? You then use the macro in your code like this:
int a = 1, b = 2;
int result = 3 + MAX(a, b);
Looks innocent. The problem is that the preprocessor substitutes the macro definition into the code before compilation, so this is the code the compiler sees:
int a = 1, b = 2;
int result = 3 + a > b ? a : b;
C order of operations requires the sum 3 + a be calculated before the ternary operator is applied. You intended to save the value of 3 + 2 in result, but instead you add 3 + 1 first, and test if the sum is greater than 2, which it is. Thus result equals 2, rather than the 5 you expected.
Already alarm bells should be going off. But you’ve come this far, so you fix the problem by adding some parentheses and try again:
#define MAX(x, y) ((x) > (y) ? (x) : (y))
Seems to work now. You breath an uneasy sigh of relief. You continue along on your project until you have this code:
int a = 1, b = 2;
int result = MAX(++a, ++b);
When the preprocessor runs, this expands to:
int result = ((++a) > (++b) ? (++a) : (++b));
Parentheses can’t save you now. Whichever value is greater is going to be incremented twice, not once. This is almost certainly not what you intended. Now you know you’re doing something wrong, and you start to look around for alternatives.
So what’s a better way? It’s simple. Just write a function. Functions are easy to write, easy to read, state your intent clearly, and the compiler has all kinds of optimization tricks it can apply if appropriate. A max function is trivially written as:
int max(int x, int y)
{
return x > y ? x : y;
}
Done. No subtle errors, no seemingly random bugs causing you to rip your hair out, bashing your head against the keyboard, ruing the day you decided to become a programmer. And for Objective-C developers, rest assured that there’s no reason you can’t mix in C functions into your code. If you’ve ever written any CFNetworking or Quartz 2D code, you’re calling C methods.
Probably the most common macro use is to define a constant:
#define NUM_THREADS 4
Here it’s better to use a static const integer:
static const NSInteger NUM_THREADS = 4;
The advantages over the macro are that the value of the variable can be viewed in the debugger, it respects scope according to the rules of the language, and it’s type-safe.
Some people tote around header files full of frequently used macros, most of which should probably be functions or class categories. Consider detecting whether your app is running on an iPad. You can write this as a macro like so:
#define IS_PAD [[UIDevice currentDevice] interfaceIdiom] == UIUserInterfaceIdiomPad)
Make no mistake, though, that this brings along all the subtle problems of macros generally as demonstrated above.
One way to rewrite this is simply as a category on UIDevice (I’m only showing the implementation portion):
@implementation
- (BOOL)isPad
{
return [self interfaceIdiom] == UIUserInterfaceIdiomPad;
}
@end
Then it can be used easily:
if ([[UIDevice currentDevice] isPad])
// my iPad specific code
Or the macro can easily be rewritten as a C function:
(BOOL)isPad()
{
return [[UIDevice currentDevice] interfaceIdiom] == UIUserInterfaceIdiomPad;
}
Both are simple and clear, respect scope, are type-safe, etc. Unless you have some extremely special case, this should be the preferred way to write helper methods.
There are occasions where macros provide necessary functionality not available through other means. One example is when you do need to actually have the context of the current code location at hand when the code executes.
For example, I have a simple macro I sometimes use when debugging Objective-C to log when certain methods are called. This can be done like so:
NSLog(@"%@: %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
This can’t be moved into an Objective-C method because it will always log the name of that method. (Obviously it can’t be moved into a C method, as there is no self and no _cmd variables available.) Creating a macro for this is straightforward, however:
#define LOG_SELECTOR() NSLog(@"%@: %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
In a case like this, the only option is to use macros. That’s fine. Macros are a tool in one’s tool belt, so to speak. It’s great to use them when appropriate. But it’s important to understand their limitations, and to know what alternatives are available and why they should be preferred.
From my personal blog:
Twitter integration is a common requirement of iPhone apps. Indeed, two of the apps my company sells are built around Twitter. Many other apps I’ve worked on for clients have also required Twitter integration.
I’m hoping to make that job a little easier for other iOS (and Mac) developers in the future by releasing TwitterKit, a simple and lightweight library for communicating with the Twitter REST API. TwitterKit should work with iOS 4.0 and up, and Mac OS X 10.6 and up.
Source: debay
From my personal blog:
It’s one thing for Apple to nail data sync for their operating systems and their core applications like iWork. They have the expertise and the resources to devote to getting it just right. It’s another thing entirely to develop a general framework in which your average developer can nail data sync for their own applications.
Making things easy for developers is a crucial component of success in moving adoption of any technology. iCloud is no different. Apple is trying to make it as simple and transparent as possible for app developers. We just need to see how leaky the abstraction will be in practice.
Source: debay
Next week is WWDC 2011, the biggest event of the year for Mac and iOS developers. To celebrate the occasion, we’re putting all of our apps on sale for $0.99 each all week. As a bonus, even though WWDC doesn’t start until Monday, our sale is going to start today and run until Friday, June 10th.
That means you can get the all new hotness that is Chirpy 2.0, GPS Tracks, Twitbit, and Notekeeper for a combined price of $3.96. That’s less than the price of a latte at Starbucks. Ridiculous I know, but that’s just how much we love you.
As they say on TV, don’t wait! Act now!
|
|
|
|
| Chirpy 2.0 | Twitbit | GPS Tracks | Notekeeper |
About a year ago we released a wonderful iPhone app called Chirpy. Chirpy does one thing really well: it provides a way to quickly send and receive Twitter direct messages, without the other 2,000+ features of a full-fledged Twitter client getting in your way. It’s also great if you’re looking for a way to cut down on your monthly SMS usage, or need a simple and fast messaging app to keep in touch with friends and family overseas. And because it has incredibly fast push notifications, it’ll let you know when you get a new message right away, even when the app isn’t running.
Since we released the first version of Chirpy, we’ve gotten a lot of feature requests from people requesting things like updated graphics for the iPhone 4’s high-resolution Retina Display, the ability to delete messages, and a way to share photos privately, among others.
Today I’m extremely excited to announce Chirpy 2.0 that includes all of these features and so much more! Here’s a screenshot of the new chat screen:

First, you’ll notice the app has an entirely new look and feel. We didn’t just update the existing artwork for the iPhone 4. We have a completely new look to the chat bubbles in conversations (colors that you can configure yourself), and we’ve added contact pictures to both the “inbox” (your list of conversations) and the conversations themselves. If you’re using an iPhone 4, we’re using Twitter’s high-resolution pictures, so they look stunning on a Retina Display. Chirpy also automatically recognizes phone numbers, URLs, addresses, and events within message text. Tapping on them takes the appropriate action (for example, tapping on a phone number calls that number, tapping on an address opens it in Google Maps, and so on). And you can copy-and-paste text from a message.

Photo sharing has gotten a major upgrade with the ability to share photos privately using Dropbox. (If you’ve never used Dropbox before, I strongly suggest you check it out. Accounts are free and it’s an amazingly useful service that’s dead simple to use.) In Chirpy, when you attach a photo to a message, the image is uploaded to a Chirpy folder within your public Dropbox folder. Photos within this directory are accessible through a public URL. No one knows this URL except you and the recipient of the message, so only the sender and recipient of the message can see it. Chirpy embeds a thumbnail of the image directly into the message just as it always has. You don’t even see the ugly URLs in your conversation if you don’t want, though there’s an option to always show them if you prefer that.

We’ve also added another extremely common feature request: the ability to delete messages. In Chirpy, this works just like it does in the built-in Messages app, so there should be no learning curve. When you select a bunch of messages, you also have the option of sending them in an email message.
Here’s a full bulleted list of the major features in Chirpy 2.0:
With all of this good there is a tiny smidgeon of bad. Twitter recently announced that all third-party apps that want to access direct messages have to make two changes to their software. First, they have to use Twitter’s web-based log in workflow rather than the old workflow that allowed app developers to collect users’ usernames and passwords directly. Second, apps that access direct messages have to request all users to log in and explicitly grant the app access to their direct messages again, even if they already logged in to the app using the old system in the past.
This web-based log in is cumbersome within an iPhone app, but not terrible. And the pain is one-time only. Once you add your accounts, you’re done and never have to think about this process again.
Chirpy 2.0 is a huge leap forward over the current version. It’s a free upgrade for current users, and everyone else can buy it on the App Store today!
Moving Away from Vim
I’m a big believer in the Pragmatic Programmer maxim “Use a Single Editor Well”. My editor of choice is Vim. Modal editing lets you do just about everything without leaving the home row. No carpel-tunnel-inducing key combinations required.
I’ve spent more effort than I’d like to admit getting Vim to work in just about every possible text editing environment. I’m using MacVim and Markdown Mode to write this post. I’ve used Vi emulators to write Java code and C++ code in various IDEs. I use Vim as my line editor in my shell.
And of course I’ve taken the time to configure Vim to support as much of the iOS development cycle as possible. That is until a few months ago, when I ditched Vim cold turkey for iOS development and jumped with both feet into using Xcode full time.
Why abandon Vim in favor of the (in my opinion) clumsy editing environment of Xcode? I got tired of paying the tax of lugging around an extra tool. Vim is an absolutely phenomenal text editing tool. It’s a decent build tool, enabling one to walk through build errors fairly easily, as long as they’re compiler errors and not linker or other problems. Among major development tasks, debugging is the most important that can only be done in Xcode. That reality makes trying to fix a bug while debugging a pain because it’s hard to start navigating the project and typing code in an environment as different from Vim as Xcode. Interacting with iOS documentation in Vim is a pain, despite the best efforts of some useful plugins. Switching to Xcode to manage these and other extraneous tasks, like editing Core Data models, adding files to a project, or editing build settings, over time became increasingly grating.
Then I got a piece of advice I found convincing enough to push me over the edge: it’s better to invest time mastering the standard tool than waste an even greater amount of time trying to work around it. Considering this in the light of the forthcoming Xcode 4, with its even tighter overall integration of the iOS development cycle (integrated Interface Builder, for example), put me over the edge. I switched to Xcode full time and invested effort in making it work better for my workflow.
The primary focus for my efforts to improve development in Xcode has been in making text editing more efficient.
Customizing the Cocoa Text System
Most programmers who write code on Mac OS X are familiar with the Cocoa text system’s set of key bindings derived from Emacs. If not, here’s a quick primer. In any native Cocoa text field — the address bar in Safari or Chrome, a compose window in Mail, or, critically, Xcode’s text editor — a subset of Emacs editing commands are available. This includes ctrl-a to go to the beginning of a line (paragraph in OS X terms), ctrl-k to kill a line, ctrl-y to yank (paste) what was last killed, and ctrl-f to move forward one letter.
(Brief digression: one of the great advantages of Mac OS X is its reliance on the command and option keys to drive most of their key bindings. Windows and Linux rely on the control key. For example, on a Mac, command-a selects all, whereas on Widows control-a selects all. Using command-a allows Macs to support the Emacs binding of control-a to move to the beginning of the line. Most users will never know or care that this binding exists, but it’s wonderful for programmers.)
One more obscure aspect of the Cocoa text editing system that’s not known to most programmers is that new key mappings can be defined by editing a plist file called ~/Library/KeyBindings/DefaultKeyBinding.dict. By editing this file, you are able to create key bindings inaccessible through the UI. Once defined, these bindings are available in any native Cocoa text field in any application. It’s extremely simple to set up once you know the syntax, and the payoff is huge. It’s the next best thing to having a universal vi emulator.
Say you want to map ctrl-w to delete one word backwards. Here’s a snippet of the contents of the DefaultKeyBinding.dict file:
Simple, right?
While you can find plenty of good documentation on setting up your DefaultKeyBinding.dict file, there are a couple things I’d like to point out.
First, you can map single key bindings to multiple command selectors. For example, I’ve configured control-shift-k to delete the current line regardless of cursor position. This requires multiple commands to perform, which is accomplished like so:
This affords amazing flexibility to define your own custom bindings.
The second feature I’d like to call attention to is the ability to map commands to multi-stroke key bindings. For example, to map the command ctrl-m ctrl-m to set mark (I strongly suggest you read more about marking and yanking in OS X), add this to your file:
Rather than devise continually contorted key bindings to support the growing set of commands you’d like to create, you can use multi-key bindings to effectively provide a namespace for sets of related actions. Here’s an example set of commands related to marking and yanking. Note that multi-key bindings can be configured to use multiple selectors as well. Thus ctrl-m ctrl-x is configured to cut the text between the cursor and the mark.
Another advantage to this is that it’s easy to make bindings mnemonic and therefore easy for me to remember. Even better, they don’t require contorted gestures requiring the simultaneous typing of three modifier keys to work.
Investing some time in setting up custom binding has paid off in allowing me to do all of my text editing supported by fairly simple key combinations, none of which require reaching for the arrow keys. I keep my bindings on GitHub, so feel free to borrow from them and suggest improvements.
Custom Key Bindings for Xcode
Xcode uses the standard Cocoa text view as its text editor (for better or for worse). That means any bindings you’ve added to your DefaultKeyBinding.dict file will work just fine in Xcode. But Xcode provdes its own set of text editing selectors that aren’t available in the stock Cocoa text fields. These include commands for moving a subword backward or forward, or to use the current selection for find. Most of these commands can be configured easily in Xcode’s user interface for editing key bindings. Xcode 3 even supports multi-key bindings in the user interface (sadly this seems to be missing in the Xcode 4 GM).
It’s still useful to add key bindings manually, though. The general idea behind doing so is the same, but the syntax of the plist file is slightly different. The file for Xcode 3 lives in ~/Library/Application Support/Xcode/Key Bindings/, and for Xcode 4 in ~/Library/Developer/Xcode/UserData/KeyBindings/. Its name is the name of the bindings set, and has an extension of .pbxkeys for Xcode 3 and idekeybindings for Xcode 4. One binding I use frequently is ctrl-x ctrl-i to find the next occurance of the word under the cursor. This is done by selecting the word under the cursor, using the selection for find, and finding next:
Once again, taking the time to invest in a few simple customizations can remove much of the pain out of editing text with Xcode. I won’t go so far as to say that editing is as efficient as it is in Vim. I will say, though, that editing in Xcode no longer feels like typing with mittens, and I can now reap the benefits of keeping all of my iOS development within the single first-party tool. Feel free to use my bindings for Xcode 3 or Xcode 4 to get you started.
As I said at the outset, I went cold turkey from doing all of my editing and building in Vim and everything else in Xcode to now living in Xcode 100% of the time. Overall my life is easier and my development is more efficient. Most important, I’m spendign less time fighting with my tools and more time writing code.
Welcome to the new home of the High Order Blog. All new content will be posted here, so make sure to update your bookmarks and to point your RSS reader to the new address. I’m going to leave the old blog up, so old links will continue to work.
Lots of exciting stuff to come. Stay tuned.