Categories
Uncategorized

Updating RayWenderlich.com’s “AFNetworking Crash Course” for iOS 6

weather app

Whether you’re new to iOS programming or a long-timer, RayWenderlich.com is a valuable resource for the iOS developer. They regularly publish tutorials, tips, tricks and other goodies that you’d be crazy to do without if you’re serious about writing apps for iDevices. In addition to articles on the site, they go deeper with their books, which are excellent.

RayWenderlich.com recently published an article titled AFNetworking Crash Course, which covers how to write networking apps using AFNetworking, a library created by the folks at Gowalla that simplifies iOS network programming. In this tutorial, you build a weather app that uses AFNetworking to get its data from the World Weather Online service. Check it out; AFNetworking’s useful, and the tutorial’s pretty nice.

In order to reach the widest possible audience, the tutorial was written for iOS 5 and earlier versions of Xcode. If you’re developing with the current version of Xcode and for iOS 6 (which accounted for 83% of all iOS traffic in North America in February), you might want to make a few changes to the code in the tutorial. I’ve listed the changes below:

Use Modern Array Notation

Here’s the old way to get at the element of an array whose index is theIndex in Objective-C:

element = [theArray objectAtIndex:theIndex];

It’s a little clunky, and as I wrote in an earlier article, Objective-C’s New NSNumber, NSArray and NSDictionary Syntaxes Mean Less “Yak Shaving” for iOS and OS X Developers, there’s a much nicer way to do it:

element = theArray[theIndex];

In AFNetworking Crash Course, where you see code like this:

daysWeather = [upcomingWeather objectAtIndex:indexPath.row];

path = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"WeatherHTTPClientImages/"];

change it to this:

daysWeather = upcomingWeather[indexPath.row];

path = [paths[0] stringByAppendingPathComponent:@"WeatherHTTPClientImages/"];

Use Modern Dictionary Notation

Here’s the old way to get at the item in a dictionary whose key is theKey:

item = [theDictionary objectForKey:theKey];

Again: it’s clunky. Also again, in my earlier article, I showed the modern way to access dictionary items:

item = theDictionary[theKey];

Setting items for a dictionary used to be like this:

[theDictionary setObject:theObject forKey:theKey];

Now, it’s like this:

theDictionary[theKey] = theObject;

So, in the places where you see code like:

*array = [self.xmlWeather objectForKey:@"weather";];

change it to:

*array = xmlWeather[@"weather"];

…and where you see code like:

[self.xmlWeather setObject:array forKey:@"weather"];

change it to:

self.xmlWeather[@"weather"] = array;

Update the Deprecated Location Manager Delegate Method

If you use the code as-is with iOS 6, you’ll get an error message that looks like this:

Deprecated in iOS 6.0
locationManager:didUpdateToLocation:fromLocation:
Tells the delegate that a new location value is available. (Deprecated in iOS 6.0. Use locationManager:didUpdateLocations: instead.)

Instead of using the deprecated locationManager:didUpdateToLocation:fromLocation: method, use the current locationManager:didUpdateLocations: method instead:

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
    // locations is an array of locations where the device has recently been
    // starting with the least recent and ending with the most recent.
    CLLocation *lastLocation = (CLLocation *)[locations lastObject];

    // Fetch the weather only if the last location is less than 5 minutes old
    if ([lastLocation.timestamp timeIntervalSinceNow] < 300) {
        [self.locationManager stopUpdatingLocation];
        WeatherHTTPClient *client = [WeatherHTTPClient sharedWeatherHTTPClient];
        client.delegate = self;
        [client updateWeatherAtLocation:lastLocation forNumberOfDays:5];
    }
}
Categories
Uncategorized

The iPhone’s Virtual Keyboards: A Visual Catalogue

The computer desk in Joey deVilla's home office.

The Apple side of my desk at my home office.

Vaya con iOS: Exploring iPhone and iPad programmingWhile doing some serious iOS development self-training this long weekend (it’s Family Day weekend in many parts of Canada), I looked around for a visual catalogue of the standard iPhone virtual keyboards, but couldn’t find any.

Yes, Xcode’s Interface Builder gives you a list of keyboard types…

Drop-down menu of keyboard types in Xcode

…and the UITextInputTraits Protocol Reference in Apple’s online docs does an adequate job of telling you what the UIKeyboardType enums are:

typedef enum {
   UIKeyboardTypeDefault,
   UIKeyboardTypeASCIICapable,
   UIKeyboardTypeNumbersAndPunctuation,
   UIKeyboardTypeURL,
   UIKeyboardTypeNumberPad,
   UIKeyboardTypePhonePad,
   UIKeyboardTypeNamePhonePad,
   UIKeyboardTypeEmailAddress,
   UIKeyboardTypeDecimalPad,
   UIKeyboardTypeTwitter,
   UIKeyboardTypeAlphabet = UIKeyboardTypeASCIICapable
} UIKeyboardType;

…but I couldn’t find any resource that showed me both the human-friendly and UIKeyboardType enums, what the primary and alternate views for each keyboard look like, and a half-decent description of each. In the spirit of the “See a need, fill a need” hacker ethos, I put together this visual catalogue of the iPhone’s standard virtual keyboards to share with the iOS developer community. Enjoy!

iPhone Virtual Keyboards and UIKeyboardTypes Visual Catalogue

Keyboard Name Description
ASCII Capable

UIKeyboardTypeASCIICapable

iOS "ASCII capable" keyboard, default letter viewiOS "ASCII capable" keyboard, alternate number view

A general-purpose keyboard, containing standard ASCII characters. The primary view shows letters, and the alternate view shows numbers and punctuation.

Numbers and Punctuation

UIKeyboardTypeNumbersAndPunctuation

iOS "Numbers and punctuation" keyboard, default number view

iOS "Numbers and punctuation" keyboard, alter letter view

Like the ASCII Capable keyboard, but the views are reversed: the primary view shows numbers and punctuation, and the alternate view shows letters.

URL

UIKeyboardTypeURL

iOS "URL" keyboard, default letter view

iOS "URL" keyboard, alternate number view

A keyboard optimized for entering URLs. The keyboard features a “.com” key, makes the “.” and “/” keys prominent, and omits the space bar. The primary view shows letters, and the alternate view shows numbers and punctuation.

Number Pad

UIKeyboardTypeNumberPad

iOS "Number pad" keyboard

A numeric keypad designed for PIN entry. It’s labelled phone-style with letters, featuring the digits 0 through 9 prominently. This keyboard has a single view and doesn’t support auto-capitalization.

Phone Pad

UIKeyboardTypePhonePad

iOS "Phone pad" keyboard, default number view

iOS "Phone pad" keyboard, alternate "star/pound/plus" key view

A numeric keypad designed for phone number entry. It’s labelled phone-style with letters, featuring the digits 0 through 9 prominently in the primary view, and the pause, wait, “*“, “#” and “+” keys in the alternate view. This keyboard doesn’t support auto-capitalization.

Name Phone Pad

UIKeyboardTypeNamePhonePad

iOS "Name phone" keyboard, default "name" view

iOS "Name phone" keyboard, alternate "phone" view

A keyboard for entering names and phone numbers. The primary view shows letters. The alternate view shows a phone-style number pad with the digits 0 through 9; holding down the 0 key enters a “+” character.

E-mail Address

UIKeyboardTypeEmailAddress

iOS "E-mail address" keyboard, default letter view

iOS "Email address" keyboard, alternate number view

A keyboard for entering email addresses, with “@“, “.” and space characters featured prominently (even though email addresses shouldn’t have spaces in them). The primary view shows letters, and the alternate view shows numbers and punctuation.

Decimal Pad

UIKeyboardTypeDecimalPad

iOS "Decimal pad" keyboard

A numeric keypad suitable for entering general numbers including a decimal point.

Twitter

UIKeyboardTypeTwitter

iOS "Twitter" keyboard, default letter view

iOS "Twitter" keyboard, alternate number view

A keyboard optimized for tweets, providing easy access to the “@” and “#” characters. The primary view shows letters, and the alternate view shows numbers and punctuation. As the only keyboard type devoted to a specific third-party web application, it’s a testament to Twitter’s reach.

Categories
Uncategorized

My Favourite Xcode Improvement

Xcode 4.6 was released on January 28th, the same day that iOS 6.1 was released. It adds support for iOS 6.1 and Mac OS X 10.8, and two new devices, the iPad mini and the 4th-gen iPad with Retina display. There are also a number of improvements to the LLVM compiler and Objective-C language, including some new warnings to help find subtle bugs when using ARC and weak references.

The improvement that jumped out at me is a simple one, but one that is already saving me a lot of frustration. It used to happen when typing in the class name NSString. This problem is best explained by this classic pic from the Tumblr called Texts from Xcode:

text from xcode 1

I don’t know about you, but I use NSString waaaay more than NSStream.

With Xcode 4.6, as I started typing in NSString, here’s what happened:

NSString

Autocomplete, mirabile dictu, jumped straight for NSString!

Sometimes, it’s the little things that make the experience.

Categories
Uncategorized

Like a Book Club, But For Toronto Developers Who Want to Learn How to Make iOS Games

learning cocos2d

NSCoderTO, a Toronto-based Mac/iOS coder group, is dedicating a series of book club meetups to Learning Cocos2D, an iOS game programming book written by Rod Strougo and Ray Wenderlich (the guy behind the ever-so-useful RayWenderlich.com site). Between now and late April, they’re going to read and do the exercises in this book, meeting up 5 times during that period to discuss their progress and any issues encountered along the way. You can take a look at the full schedule to see when you should be reading and doing the exercises in each chapter and when the meetups will take place.

The first meetup takes place next Tuesday, February 12th at Ryerson University’s Hub Cafeteria and will cover chapters 1 through 4 of the book. I’ve got the book, and they’re relatively easy (chapter 1 is the obligatory intro and setup, chapter 2 is “Hello World”, chapters 3 and 4 cover animation and collision detection); you can get started on it today and be ready by the time the meetup comes around. I’ve signed up, and I might see you there!

Categories
Uncategorized

A Step Forward (or: Objective-C Doesn’t Need Forward Declarations Anymore)

The Old Way: Forward Declarations

The Commodore 64 is from about the same era as Objective-C. The 64 hit the market in 1982; Objective-C (and C++ as well) first appeared in 1983.

Older languages like C (and recently, Objective-C), won’t just let you call a function or method whose definition is later on in the same file. Consider these two C functions, which appear in my Inpulse Magic 8-Ball tutorial:

void set_time_mode()
{
    start_timer(TIME_UPDATE_INTERVAL_LENGTH_MS,
                &update_time_display);
}

void update_time_display()
{
    pulse_blank_canvas();
    pulse_get_time_date(&current_time);
    printf("The time is\n%d:%0.2d:%0.2d\n", 
           current_time.tm_hour,
           current_time.tm_min,
           current_time.tm_sec);
    set_time_mode();
}

The function set_time_mode refers to update_time_display, whose definition comes after set_time_mode‘s. As far as the C compiler is concered, set_time_mode doesn’t exist yet, and it will refuse to compile, giving you an error message that looks something like this:

src/pulse_app.c: In function ‘set_time_mode’:
src/pulse_app.c:76: error: ‘update_time_display’ undeclared (first use in this function)
src/pulse_app.c:76: error: (Each undeclared identifier is reported only once
src/pulse_app.c:76: error: for each function it appears in.)

You can’t simply switch the order of the two functions since update_time_display also calls set_time_mode.

Forward declarations solve this problem. By including the signature for update_time_display before the definition of set_time_mode, we give the compiler enough information so that it knows what to do with update_time_display when it’s compiling set_time_mode:

void update_time_display();

void set_time_mode()
{
    start_timer(TIME_UPDATE_INTERVAL_LENGTH_MS,
                &update_time_display);
}

void update_time_display()
{
    pulse_blank_canvas();
    pulse_get_time_date(&amp;amp;amp;current_time);
    printf("The time is\n%d:%0.2d:%0.2d\n", 
           current_time.tm_hour,
           current_time.tm_min,
           current_time.tm_sec);
    set_time_mode();
}

The code above compiles.

The New Way: No Forward Declarations

Newer languages like Python and Ruby don’t need forward declarations. You can have a method refer to another method that appears later in the file in Python:

# A quick and dirty example in Python

def first_method():
  # second_method appears later in this module
  second_method("Hello there")

def second_method(statement):
  print statement

first_method()

And here’s the Ruby equivalent:

# A quick and dirty example in Ruby

def first_method
  # second_method appears later in this module
  second_method "Hello there"
end

def second_method(statement)
  puts statement
end

first_method

Objective-C joins the club in Xcode 4.3 and later (as of this writing, the current version of Xcode is 4.5); you no longer need to make forward declarations. The compiler will “look ahead” if the function or method it’s compiling makes calls to functions or methods that appear later on in the file.

This means that the following code compiles in Xcode (at least in Objective-C):

void set_time_mode()
{
    start_timer(TIME_UPDATE_INTERVAL_LENGTH_MS,
                &update_time_display);
}

void update_time_display()
{
    pulse_blank_canvas();
    pulse_get_time_date(&amp;current_time);
    printf("The time is\n%d:%0.2d:%0.2d\n", 
           current_time.tm_hour,
           current_time.tm_min,
           current_time.tm_sec);
    set_time_mode();
}
Categories
Uncategorized

Autosynthesis / I’m Really Into This / Everybody Happy When We Write Less Code

In an earlier post, I talked about a couple of changes to Objective-C that should reduce the amount of “yak shaving” you need to do while coding: syntaxes for NSNumber, NSArray and NSDictionary literals, as well as the new, shorter syntaxes for NSArray/NSMutableArray and NSDictionary/NSMutableDictionary item access.

Here’s the tl;dr version of this post: you no longer have to @synthesize properties! (Most of the time, anyway.)

From Public Variables to Getters and Setters to Properties

In the early days of object-oriented programming, you were supposed to make a class’ public attributes accessible through public variables. Access was pretty simple:

previousSpeed = myCar.speed;
myCar.speed = 50;

Then, it became a better idea to lock away all the variables and use getters and setters:

previousSpeed = [myCar getSpeed];
[myCar setSpeed:50];

It does the job, but it’s a little clunky.

Nowadays, the preferred way to expose class attributes in a number of languages is through public properties. With them, we’re back to accessing object attributes through this simple syntax:

previousSpeed = myCar.speed;
myCar.speed = 50;

What @synthesize Was For

Creating properties in Objective-C classes used to require statements in a couple of places. For a public property, you had to declare it in the interface (.h) file:

// Car.h
@interface Car : NSObject
@property int speed;
@end

The @property statement tells the compiler that you want to expose a property; in the case of the code above, the name of the property is speed. Properties are by default both readable and writeable. If you like to spell everything out very explicitly, you can by declaring the property this way:

@property (readwrite) int speed;

If for some reason you wanted speed to be read-only, you can declare the property this way:

@property (readonly) int speed;

With every property declaration comes the need for the underlying instance variables — ivars in Objective-C parlance — and the requisite getter and setter methods, which go in the implementation (.m) file. All this setup for each property can get a little tedious, and the @synthesize statement saves you from that tedium. Instead of having to declare the corresponding ivar and write those methods, @synthesize lets you do all that in a single line of code:

// Car.m
@synthesize speed;

By default, the name of the ivar created by @synthesize was the name of the corresponding property preceded by an underscore character. For example, the default name of the ivar behind a property named speed would be _speed. If you preferred, you could specify a different ivar name this way:

// Car.m
@synthesize speed=someOtherIvar;

The general rule was that if you only needed a simple getter and/or setter for a @property, use @synthesize.

Introducing Autosynthesis

The version of CLang (the Objective-C compiler) that comes with XCode versions 4.3 and later (the latest version is 4.5), supports autosynthesis, which automatically does the synthesizing for any class properties you declare in the header. If your @property needs only a simple getter and/or setter, you don’t need to have a corresponding @synthesize anymore. The compiler takes care of that for you.

Properties with autosynthesis work like they did with manual synthesis. You access them using the self.propertyName syntax, and the name of the ivar that gets generated is still the name of the property preceded by an underscore character.

Cases Where @synthesize is Still Useful

There are some cases where you’ll still want to use the @synthesize keyword, and this article in the blog Use Your Loaf does a good job explaining these cases. Such cases are a little more rare; most of the time, you can simply skip added @synthesize to your code because the compiler’s taking care of that for you!

In Case You Were Wondering…

The title for this article comes from the chorus of Shriekback’s 1985 alt-dance number, Nemesis:

Priests and cannibals
Prehistoric animals
Everybody happy as the dead come home

Categories
Uncategorized

Objective-C’s New NSNumber, NSArray and NSDictionary Syntaxes Mean Less “Yak Shaving” for iOS and OS X Developers


Yak shaving is a term used to describe a seemingly pointless activity that you actually have to do in order to get a larger task done, or as Jeremy Brown put it:

You see, yak shaving is what you are doing when you’re doing some stupid, fiddly little task that bears no obvious relationship to what you’re supposed to be working on, but yet a chain of twelve causal relations links what you’re doing to the original meta-task.

The term “shaving a yak” was used in the 1950 film Sunset Boulevard, but it’s more likely that its use in programming comes from Ren and Stimpy:

Many programming languages, especially those that pre-date modern scripting languages, often call on the programmer to do some yak shaving, and Objective-C is no exception. With XCode 4.5 and its new Clang compiler, you get some nice bits of syntactic sugar that I’m certain will make you say “Finally!” and save you from a fair bit of yak shaving.

NSNumber Literals

If you’ve been coding in Objective-C even just a little bit, you’ve probably come across NSString, the non-mutable string type used when developing for OS X’s Foundation framework. If you have, it’s likely that you’ve seen assignments that look like this:

NSString *myString = @"Hello, world!";

The @ is a handy bit of shorthand that specifies to the compiler that Hello, world! is an NSString literal. Without this bit of syntactic sugar, we’d have to write the above line of code like so:

NSString *myString = [NSString stringWithCString:"Hello, world!"];

Until now, there’s been no such syntactic sugar for NSNumber, Foundation’s type for wrapping numerical values in an object. It’s handy for doing things like wrapping numbers so that you can store them in collection classes like NSArray and NSDictionary, which can only store objects.

Until the current version of Objective-C (which comes with XCode 4.5), here’s how you’d assign NSNumbers given some numeric literals:

NSNumber *meaningOfLife = [NSNumber numberWithInt:42];
NSNumber *ussReliantPrefixCode = [NSNumber numberWithUnsignedInt:16309];
NSNumber *floatPi = [NSNumber numberWithFloat:3.14159];
NSNumber *doublePi = [NSNumber numberWithFloat:3.14159265358979];
NSNumber *avogadrosNumber = [NSNumber numberWithDouble:6.02214129E+23];

That’s a lot of work just to simply box a simple number type into an object. Luckily for us, Objective-C now supports NSNumber literals. Just as with NSString literals, NSNumber literals are preceded with the @ sign.

The code below uses NSNumber literals and is equivalent of the code above, but requires less typing and is easier to read:

NSNumber *meaningOfLife = @42;
NSNumber *ussReliantPrefixCode = @16309U;
NSNumber *floatPi = @3.14159F;
NSNumber *doublePi = @3.14159265358979;
NSNumber *avogadrosNumber = @6.02214129E+23;

Array Literals, NSArray, and NSMutableArray

Initializing NSArray and Accessing Its Elements the Old Way

If you’re coming to Objective-C from languages like JavaScript, Python or Ruby, you’re used to doing array assignments using literals.

Suppose you wanted to create an array containing the first names of the members of the Stark family from Game of Thrones. Here’s how you’d do it in Python and Ruby (and in JavaScript, as well, although you’d probably want to place the var keyword before starkFamily):

starkFamily = [
    "Eddard",
    "Catelin",
    "Robb",
    "Sansa",
    "Arya",
    "Bran",
    "Rickon"
]

There used to be no such thing as an NSArray literal. Here’s how you’d create the array above using Objective-C and NSArray — using the arrayWithObjects: method, which expects a comma-delimited list of objects terminated with nil.

NSArray *starkFamily = [NSArray arrayWithObjects:
    @"Eddard",
    @"Catelin",
    @"Robb",
    @"Sansa",
    @"Arya",
    @"Bran",
    @"Rickon",
    nil
];

It’s not that much more typing, but you have to remember to mark the end of the list with nil.

What’s far more unwieldy is array access. In JavaScript, Python and Ruby, if you wanted to access the element of starkFamily whose index is 2, you’d do it this way:

starkFamily[2]

In earlier versions of Objective-C, here’s how you’d access that element:

[starkFamily objectAtIndex:2]

Wow, that’s clunky. Even with XCode’s autocomplete feature (the analogue of Visual Studio’s Intellisense), it’s still a lot of typing for something as simple as array element access.

Initializing NSArray and Accessing Its Elements the New Way

With the latest version of Objective-C, we have NSArray literals. Here’s how you’d initialize the starkFamily array using an NSArray literal:

NSArray *starkFamily = @[
    @"Eddard",
    @"Catelin",
    @"Robb",
    @"Sansa",
    @"Arya",
    @"Bran",
    @"Rickon"
];

NSArray literals look almost like JavaScript, Python and Ruby array literals. The big difference is NSArray literals begin with a @ character, just as NSString and NSNumber literals do.

As for accessing elements from NSArrays you can now do so using a more familiar notation:

starkFamily[2]

Finally! I much prefer myArray[index] over [myArray objectAtIndex:index].

Initializing NSMutableArrays Using Array Literals

NSArray is an immutable type; once initialized, you can’t reassign, add, or remove any of its elements. NSMutableArray, a subclass of NSArray, is mutable. Here’s how you initialize an NSMutableArray using an NSArray literal:

NSMutableArray *starkFamily = [@[
    @"Eddard",
    @"Catelin",
    @"Robb",
    @"Sansa",
    @"Arya",
    @"Bran",
    @"Rickon"
] mutableCopy];

In the code above, we create an NSArray using an array literal and invoke NSArray‘s mutableCopy: method on it. The result is an NSMutableArray containing the array literal’s values.

As with NSArray, you can now access elements of an NSMutableArray using standard array notation…

starkFamily[2]

…and, of course, since the array is mutable, you can do stuff like this:

starkFamily[2] = @"Tony";
[starkFamily removeObjectAtIndex:0];

Dictionary Literals, NSDictionary, and NSMutableDictionary

Initializing NSDictionary and Accessing Its Elements the Old Way

Different programming languages use different terms for what’s roughly the same thing: an object that stores values which you can look up using keys. JavaScript keeps it simple by using objects for this task, Ruby has hashes and Python has dictionaries.

Consider the following Python dictionary definition:

importantNumbers = { 
  "Meaning of life" : 42, 
  "USS Reliant prefix code" : 16309, 
  "Single-precision pi" : 3.14159, 
  "Double-precision pi" : 3.14159265358979, 
  "Avogadro's Number" : 6.0221415E+23
}

Ruby’s hash syntax is similar:

importantNumbers = { 
    "Meaning of life" => 42,
    "USS Reliant prefix code" => 16309,
    "Single-precision pi" => 3.14159,
    "Double-precision pi" => 3.14159265358979,
    "Avogadro's Number" => 6.0221415E+23
}

If you wanted to access the number associated with the key Meaning of life in either Ruby or Python, you’d do it this way:

importantNumbers["Meaning of life"]

In Objective-C, the equivalent structure is the NSDictionary class. Here’s the old-school Objective-C equivalent to the code above. Since NSDictionary stores only objects, we have to wrap the numbers in NSNumbers using the new literal syntax:

NSDictionary *importantNumbers = [NSDictionary dictionaryWithObjectsAndKeys:
    @42, @"Meaning of life",
    @16309U, @"USS Reliant prefix code",
    @3.14159F, @"Single-precision pi",
    @3.14159265358979, @"Double-precision pi",
    @6.0221415E+23, @"Avogadro's Number",
    nil];

Note that the list have to provide the dictionaryWithObjectsAndKeys: method lists the value first and the key second, which is the reverse of how most other programming languages do it. As with NSArray‘s arrayWithObjects: method, we have to mark the end of the list with nil.

If you thought the code above was a bit much, imagine what it would look like without NSNumber literals!

As for accessing values in the dictionary, here’s the old way of doing it:

[importantNumbers objectForKey:@"Meaning of life"]

That’s a lot of typing just to get to a value.

Initializing NSDictionary and Accessing Its Elements the New Way

Luckily, the Objective-C that you get with XCode 4.5 gives us dictionary literals. Here’s how you define importantNumbers now:

NSDictionary *importantNumbers = @{
    @"Meaning of life" : @42,
    @"USS Reliant prefix code" : @16309U,
    @"Single-precision pi" : @3.14159F,
    @"Double-precision pi" : @3.14159265358979,
    @"Avogadro's Number" : @6.0221415E+23
};

That’s much better. Languages like JavaScript, Python and Ruby have standardized curly braces ({ and }) for specifying dictionary-style collections, and it’s nice to see this syntax in Objective-C. The order is also what we expect: key first, value second. And finally, no need to use nil to terminate the list.

The syntax for accessing a value from an NSDictionary is also much simpler:

importantNumbers[@"Meaning of life"]

Much better.

Initializing NSMutableDictionary Using Dictionary Literals

Like NSArray, NSDictionary isn’t mutable, but it has a mutable subclass with a similar name. It’s NSMutableDictionary, and like NSArray, you can use a literal and the mutableCopy: method to create one:

NSMutableDictionary *importantNumbers = [@{
    @"Meaning of life" : @42,
    @"USS Reliant prefix code" : @16309U,
    @"Single-precision pi" : @3.14159F,
    @"Double-precision pi" : @3.14159265358979,
    @"Avogadro's Number" : @6.0221415E+23
} mutableCopy];

As with NSDictionary, you can access elements of an NSMutableDictionary using the new syntax:

importantNumbers[@"Meaning of life"]

And since it’s mutable, you can make changes:

importantNumbers[@"Meaning of life"] = @43;
[importantNumbers setObject:@2012 forKey:@"iOS 6 launch year"];

Available Now, and Not Just for iOS 6

The latest version of XCode, 4.5, includes the latest Clang compiler, which supports these new syntaxes. Since they’re syntactic sugar and not part of any additions or revisions to the Foundation framework, you can use them in any iOS project.

Better still, if you’ve got old projects that you’d like to update to use these new syntaxes but dread having to do so manually, XCode 4.5 has a feature you’ll like. Under the Edit menu, you can select Refactor, and inside that submenu is the Convert to Modern Objective-C… command.