Xcode 4.4 and Objective-C

Apple recently released Xcode 4.4. The list of new features is quite intriguing.

      • The compiler automatically calls @synthesize by default for unimplemented @properties.
      • For the NSArray and NSDictionary classes, support is provided for Objective-C literals.
      • Subscripting using '[ ]' syntax is supported for Objective-C container objects.
      • Compatibility with the C++11 standard is improved.
      • New static analyzer checks for common security mistakes in API and malloc usages.
      • The caller and callee for selected methods can be displayed in the Assistant Editor.
      • Code completion is enhanced with QuickHelp.
      • Scene Kit is supported with a viewer-editor for 3D document files.
      • Improved localization workflow uses base language .xib files.
      • Git supports staging of individual changes.

Leave it to Apple to introduce core language features in a point release of their IDE!

Anyway, it got me thinking about Objective-C, productivity, and John Siracusa’s comments from a few years back:

 A framework with methods like this:

NSInteger myCount = [[myDict objectForKey:@"count"] integerValue];
NSArray *myArray = [myString componentsSeparatedByString:@","];
myItem = [myArray objectAtIndex:i];

is just not going to fly in a language that (hypothetically) supports this:

myCount = myDict["count"];
myArray = myString.split(",");
myItem  = myArray[i];

Looks like John finally got his wish! And quite frankly, it’s about time. It doesn’t get much more basic than strings and arrays, and it boggles my mind that it took Apple this long to give us a non-eye-gouging syntax. Don’t get me wrong; I’m glad to have these improvements. It’s just that in my opinion, ObjC still lags far, far behind the rest of the civilized world when it comes to programmer productivity.

Over the next little while I will be taking a closer look at some of Objective-C’s productivity failures in comparison with languages like C#, Ruby, Python, and F#.

Creating NSManagedObject Subclasses – So Handy, Yet So Strange

If you are a Core Data user, you’ll likely become intimately familiar with NSManagedObject and the Core Data model editor.

One aspect of NSManagedObject is the the creation of NSManagedObject subclasses. The only way I have found to (automatically) do this is to select your entities, then go to Editor -> Create NSManagedObjectSubclass.

Why on earth is ‘Create NSManagedObject Subclass’ a global menu item? And why is it in the ‘Editor’ menu? Whose brilliant idea was it to have a global menu item for something so incredibly specific to a particular portion of a particular screen? Why is generating code from your Core Data model so completely non-discoverable? Why isn’t there a ‘Create NSManagedObject Subclass’ button right next to the ‘Add Entity’ button?

And those are just my issues with the placement of the functionality. So aside from that, how well does it actually work?

In my limited usage so far, I would say that it’s marginally useable.

First of all, having to perform a manual process in order to keep your data model and your object model in sync is pointless. By contrast, when you edit an Entity Framework EDMX file or a LINQ to SQL DBML file, your object model classes are automatically regenerated. And hey, if you’re using EF Code-First, there’s nothing else you need to do!

Second, the code generation itself seems… inflexible. As far as I can tell, there is absolutely nothing remotely similar to .TT files in Xcode/Core Data. For those unfamiliar with the Visual Studio world, a .TT file is essentially a template that can describe, among other things, how classes are generated from a data model. You can customize a .TT file so that the generated classes look exactly like you want them to – add in validation attributes, extra fields, property change notifications, and so on. This standard functionality in EF/VS, but doesn’t seem to exist in Xcode.

In order to something similar, it appears that you need a third-party tool such as mogenerator. Now it’s great that such a tool exists, but it’s sad that it needs to exist. Customization of generated code is a pretty basic IDE feature these days, and it’s yet another area where Xcode falls short of the competition.

On another code generation note, it’s quite amusing that Xcode can’t even remember what group I previously added the NSManagedObject subclasses to, forcing me to manually select it every time I change my data model.

iOS Quick Tips – ‘A signed resource has been added, modified, or deleted’

While trying to run my latest app on my device, I kept encountering a very strange error. Xcode would pop up with a message box saying

‘A signed resource has been added, modified, or deleted’

Huh? What? In typical Xcode fashion, the error message doesn’t actually tell you anything about what’s wrong or how to fix it. It turns out that the problem was caused by having special character in the product name – in my case, a ?. Removing the ? from the product name fixed the problem. But I really wanted that question mark; the app wouldn’t be the same without it! Not to worry, because you can set the bundle name (the name that gets shown on your device’s home screen) independently of the product name, and the bundle name can contain special characters.

So, let this be a warning: don’t put any special characters in your product name – only put them in your bundle name!

 

As an aside, the issues with broken links on the blog should now be fixed. Sorry for the inconvenience!

iOS Pain Points – the Xcode 4.3 / iOS 5.1 / Lion versioning debacle

Earlier today I wanted to test out March’s application on my iPod, which I had upgrade to iOS 5.1 a while ago. I was quite surprised to see that I was not able to, because “The version of iOS on my iPod does not match any of the versions of iOS supported for development with this installation of the iOS SDK.”

It turns out that in order to run your apps on an iOS 5.1 device, you need Xcode 4.3. Ok, fair enough; I’ll just go and downlo…. oh, wait. It requires OS X Lion.

Huh?

In order to develop for a minor revision of iOS, I need a minor revision of Xcode, which requires an entirely new operating system?

So, my options are now:

  1. Upgrade to Lion
  2. Downgrade to IOS 5
  3. Hack Xcode 4.3 to run on Snow Leapoard
Since there appears to be no officially supported way of doing #2 or #3, my only choice is to upgrade to Lion.

Thanks, Apple. Nice to see you still have no respect for your developers. At least I’m not the only one who feels this way.

iOS Pain Points: Xcode debugger failures

If you’ve ever done much iOS development, you’ve probably experienced the fun of Xcode debugger failures. One of the most popular ones is a hang at ‘Attaching to (name of your app)’, which seems to mysteriously appear once in a while. The StackOverflow post for it lists dozens of possible solutions, some or all of which may accomplish absolutely nothing. In my most recent case, none of the fixes mentioned solved the problem. I eventually rolled back my changes (thanks to ‘git reset –hard HEAD’), and things started to work again.

The sad part? My changes consisted entirely of adding icons to the project and setting up the Icons plist. I’m not sure what bizzaro world Xcode lives in where adding icons to a project is enough to completely and utterly destroy the debugger, but somehow that was apparently the case.

As if that wasn’t enough, I ran into another issue shortly thereafter. This time it was the ever-popular ‘Couldn’t register (name of your app) with the bootstrap server’. Fortunately, StackOverflow came to the rescue once again, and I was back in business after a reboot.

It’s really quite depressing that Visual Studio 6 – which is almost 15 years old at this point – offered a better overall debugging experience than even the newest version of Xcode.

iOS Pain Points: Autocomplete in Xcode is a usability disaster

Xcode, like many IDEs, gets autocomplete wrong. Compared to Visual Studio 2010, for example, autocomplete in Xcode is a frustrating experience. Here are some of the ways it is inadequate:

  • It commits the cardinal sin of autocompletion by requiring that you press enter or tab to accept an autocompletion. It should accept the current selection with any key press that makes contextual sense – such as ], ;, =, or (, instead of only accepting the current selection when you press enter or tab.

This is a pretty subtle point, but it makes a world of difference in terms of usability. Here’s an example. Suppose you want to type

self.foo = bar;

In Xcode, i have to do the following:

s[enter].f[enter][space]=[space]b[enter];

for a total of 11 keypresses.
To get the same thing in VS 2010, using C#, you have to type the following

t.f=b;

.. for a total of 6 keypresses – almost half as many as the Xcode version. And it even automatically inserts spaces around the = sign.

  • As previously discussed, it does a horrible job of offering context-sensitive help when for constants or enums, populating the list with everything in the current scope, regardless of how irrelevant it is or how many compile errors using it would cause.
  • It does not display the autocomplete list automatically when you press period. Or, for that matter, when sending a message with [foo . You have to either start typing (which isn’t very useful if you don’t know what you are looking for), or press Esc (which is a pain).
  • When you use autocomplete to insert a function call such as CGRectMake(,,,), Xcode inserts the last ), but there seems to be no way to have it automatically insert the ; or move the cursor outside of the ). This means that you have to take your hands off the keyboard and use the arrow keys to manually move the cursor over just so you can type a stupid semicolon.
  • Pressing PageUp or PageDown doesn’t scroll the autocomplete list, it hides the autocomplete list and scrolls the file you are editing.

It’s death by 1000 paper cuts, and it makes iOS development far more painful than it needs to be.

Anybody have any autocomplete frustrations that I missed?