What’s New in Objective-C and Foundation in iOS 7

Matt Galloway Matt Galloway

Objective-C Tutorial

Note from Ray: This is an abbreviated version of a chapter from iOS 7 by Tutorials that we are releasing as part of the iOS 7 Feast. We hope you enjoy!

Objective-C is the most common language for developing iOS and OS X apps. Sure, you can use third party frameworks that allow you to develop apps using other languages such HTML & Javascript or C#, but if you want to write blazingly fast, super efficient native apps then you need to use Objective-C.

Foundation is one of the core frameworks that you’ll use when developing Objective-C applications.

As an iOS developer, it’s critical to keep up-to-date with the latest advances in Objective-C and Foundation – and in iOS 7, there are some important changes you need to know about.

In this article, you’ll take a quick tour of some of the new features in Objective-C and Foundation.

Note that this is an article instead of a tutorial – you’ll get a quick crash course of what’s new (with some code snippets along the way), so you can get up-to-speed as quickly as possible.

Let’s dive in!

Modules

Chances are good that you’ve written the #import statement a thousand times or more:

#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <iAd/iAd.h>

This syntax harkens back to the roots of Objective-C: vanilla C. The #import statement is a pre-processor directive that works in a similar fashion to #include. The only difference is that #import doesn’t re-import headers that have already been imported; it’s a one-shot deal.

When the pre-processor meets an #import directive, it literally replaces that single line with the entire contents of the header file being imported. It does this recursively, through a potentially large number of header files.

The UIKit umbrella header, UIKit.h, imports all of the other headers included in the UIKit framework. This means that you don’t have to manually import each header file in the framework, such as UIViewController.h, UIView.h or UIButton.h.

Curious about the size of the UIKit framework? Go through and count all the lines in the entirety of UIKit’s headers, you’ll find it amounts to over 11,000 lines of code!

In a standard iOS app, you’ll import UIKit in most of your files, meaning every single file ends up being 11,000 lines longer. That’s less than ideal; more lines of code means longer compile times.

Original solution: Pre-compiled Headers

Pre-compiled header files, or PCH files, attempt to address this problem by providing a mechanism for pre-computing and caching much of the work required during the pre-processing phase of compilation. You’ve probably seen the stock PCH file that’s generated by the templates bundled with Xcode; it looks like this:

#import <Availability.h>
 
#ifndef __IPHONE_5_0
#warning "This project uses features only available in iOS SDK 5.0 and later."
#endif
 
#ifdef __OBJC__
    #import <UIKit/UIKit.h>
    #import <Foundation/Foundation.h>
#endif

The #warning in there notifies the developer if the app they’re building targets an SDK prior to iOS 5. The UIKit and Foundation umbrella header files are part of this stock PCH, since every file in your app will use Foundation and most will use UIKit. Therefore these are generally good additions to the PCH file so that the pre-computation and caching will benefit the compilation of every file in your app.

“So what’s wrong with that?” you might ask. There’s nothing technically wrong with the PCH as-is — if it isn’t broke, don’t fix it. However, you may be missing out on a host of performance benefits that result from a well-maintained, highly tuned PCH file. For instance, if several areas of your app use the Map Kit framework, you may see an improvement in compilation time by simply adding either the Map Kit umbrella header file or the individual header files of the Map Kit classes you use to the PCH file.

We’re all guilty of being lazy developers though, and nobody has time to tune their PCH file for each project they work on. That’s why modules were developed as a feature of LLVM.

Note: LLVM is a collection of modular and reusable compiler and toolchain technologies bundled with Xcode. LLVM has several components; the most important ones for Objective-C developers are Clang, the native C, C++ and Objective-C compiler; and LLDB, the native debugger ¬¬— which is the developer’s best friend.

New solution: Modules

The first public appearance of modules in Objective-C was in a talk given by Apple’s Doug Gregor at the 2012 LLVM developers’ meeting. It’s a fascinating talk, and it’s highly recommended for anyone interested in the workings of their compilers. You can find the video of the session online at http://llvm.org/devmtg/2012-11/#talk6.

Modules encapsulate frameworks in much cleaner ways than ever before. No longer does the pre-processor need to replace an #import directive with the entire contents of the file verbatim. Instead, a module wraps a framework into a self-contained block, which is pre-compiled in the same manner as a PCH file and delivers the same improvements in compilation speed. However, you no longer have to state which frameworks you’re using in a PCH file; you get the speed boost simply by using modules.

But there’s more to modules than just that. I’m sure you recall the numerous steps you go though the first time you use a new framework in an app; it tends to go something like this:

  1. Add #import line to the file using the framework.
  2. Write code that uses the framework.
  3. Compile.
  4. Watch as errors are spat out during linking.
  5. Remember that you forgot to link the framework.
  6. Add the linking of the framework to the project build phase.
  7. Compile again.

It’s incredibly common to forget to link the framework, but modules solve this issue neatly as well. (Is there anything that modules can’t do?)

A module tells the compiler not only which header files make up the module, but also what needs to be linked. This saves you from having to manually link the framework yourself. It’s only a small thing, but anything that makes developing code easier is a good thing!

How to use modules

Modules are extremely easy to use in your projects. For existing projects, the first thing to do is enable them. You can find this option by searching for modules in the project’s Build Settings (making sure to select All, not Basic) and then changing the Enable Modules options to Yes, like so:

RW - Modules

All new projects created with Xcode 5 have this enabled by default, but you should definitely enable it on all your existing projects.

The Link Frameworks Automatically option can be used to enable or disable the automatic linking of frameworks as described earlier. There’s little reason why you’d want to disable this though.

Once modules are turned on, you can start using them in your code. To do that, it’s simply one small change to the syntax you’re used to. Instead of the usual #import syntax, you simply use @import:

@import UIKit;
@import MapKit;
@import iAd;

It’s still possible to import the parts of a framework that you need. As an example, if you wanted to import just UIView, you would write this:

@import UIKit.UIView;

Yup — it really is that simple! Well, sorry, that’s not exactly the truth. It’s even simpler than that. Technically, you don’t need to convert all your #import lines to @import lines, as the compiler will implicitly convert them for you under the hood. However, it’s always good practice to start using new syntax as often as you can.

Before you start getting too excited about modules, there is one little caveat, unfortunately. As of Xcode 5.0, it’s not possible to use modules with your own frameworks or third-party frameworks. This will probably come in time — but for now it’s an unfortunate downside. Nothing’s perfect – not even Objective-C!

New return type – instancetype

A new type has been added to Objective-C, aptly named instancetype. This can only be used as a return type from an Objective-C method and is used as a hint to the compiler that the return type of the method will be an instance of the class to which the method belongs.

Note: This feature is not strictly new in Xcode 5 and iOS 7, but has been stealthily dropped into recent Clang builds over time. However, Xcode 5 marks the first time that Apple has started using it throughout their frameworks. You can read more about this language feature on the official Clang website: http://clang.llvm.org/docs/LanguageExtensions.html#objective-c-features.

Why is instancetype useful? Consider the following code:

NSDictionary *d = [NSArray arrayWithObjects:@(1), @(2), nil];
NSLog(@"%i", d.count);

While this is clearly incorrect, the compiler would historically do absolutely nothing to inform you of the error. Try it for yourself if you still have a copy of Xcode 4.6 lying around on a floppy somewhere. You’ll notice that no warning is generated, even though the code is clearly wrong! The code will even run without complaint as both NSDictionary and NSArray instances respond to count.

The reason this works at runtime is thanks to the powerful, dynamic nature of Objective-C. The type is purely a guide to the compiler. The count method is looked up at runtime on whatever class the dictionary variable happens to be. In this case, the count method exists, so the compiler believes all is well. However, this may come back to bite you later if you added code that uses another method that NSArray doesn’t have in common with NSDictionary, such as objectAtIndex:. At first, it wouldn’t be clear exactly where the issue lies.

But why does the compiler not figure out that the instance returned by +[NSArray arrayWithObjects:] is not an instance of NSDictionary? Well, that’s because its method signature is as follows:

+ (id)arrayWithObjects:(id)firstObj, ...;

Notice the return type is id. The id type is an umbrella type meaning any Objective-C class; it doesn’t even have to be a subclass of NSObject. It literally has no type information other than the fact it’s an instance of an Objective-C class. For this to be useful, the compiler doesn’t bother warning you when you implicitly cast id to a concrete type, such as NSDictionary* in the example above. If it did generate a warning, the id type would be largely useless.

But why is the return type of that method id in the first place? That’s so you can successfully subclass the method and still use it without issue. To demonstrate why, consider the following subclass of NSArray:

@interface MyArray : NSArray
@end

Now consider the use of your new subclass in the code below:

MyArray *array = [MyArray arrayWithObjects:@(1), @(2), nil];

Ah — now you see why the return type of arrayWithObjects: must be id. If it were NSArray*, then subclasses would require to be cast to the necessary class. This is where the new instancetype return type comes in.
If you look at the header file for NSArray in the iOS 7.0 SDK, you’ll notice the method signature for this method has changed to the following:

+ (instancetype)arrayWithObjects:(id)firstObj, ...;

The only difference is the return type. This new return type provides a hint to the compiler that the return value will be an instance of the class the method is called on. So when arrayWithObjects: is called on NSArray, the return type is inferred to be NSArray*; if called on MyArray, the return type is inferred to be MyArray* and so on.

This works around around the problem with the umbrella id type, while maintaining the ability to subclass successfully. If you compile the original code in Xcode 5, you’ll now see the following warning:

warning: incompatible pointer types initializing 'NSDictionary *' with an expression of type 'NSArray *' [-Wincompatible-pointer-types]
  NSDictionary *d = [NSArray arrayWithObjects:@(1), @(2), nil];
                ^    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

w00t — now that’s helpful! You now have the opportunity to fix the problem before it turns into a crash later down the line.

Initializers are also candidates for using this new return type. The compiler has warned you for some time now if you set the return type of an initializer to that of an incompatible type. But presumably it’s just implicitly converting the id return type to instancetype under the hood. You should still use instancetype for initializers though, because it’s better to be explicit for habit’s sake.

Strive to use instancetype as much as possible going forward; it’s become a standard for Apple — and you never know when it will save you some painful debugging time later on.

New Foundations

The remaining part of this article is dedicated to various new bits of functionality in Foundation, the core framework of all Objective-C development. It’s hard to develop Objective-C applications without Foundation, as all iOS apps require its use. Finding new gems in Foundation is a big part of the fun of getting your hands on a new release of the iOS SDK!

One of the major improvements in this release of Foundation lies in networking; so much, in fact, that there’s an entire chapter dedicated to it in iOS 7 by Tutorials. This is pretty important stuff, so we’re going to release an abbreviated version of the chapter later on in the iOS 7 Feast to help everyone get up to speed with it.

The rest of this section outlines other interesting additions and changes to Foundation.

NSArray

Trying to retrieve an object from an instance of NSArray will throw an exception if the index you supply is beyond the length of the array. You’ll also often find a need to access the first and last objects of an array, such as when you’re using a mutable array to hold a queue. In a first-in-first-out (FIFO) queue you pop objects from the front of the array, and in a first-in-last-out (FILO) you pop objects from the end of the array.

However, when you retrieve the first or last objects from an array, you must always ensure that you’re not going to read past the end of the array, which could easily occur if the array were empty. This leads to a lot of tedious code to ensure a call to objectAtIndex: won’t throw an exception, like so:

NSMutableArray *queue = [NSMutableArray new];
 
// ...
 
if (queue.count > 0) {
    id firstObject = [queue objectAtIndex:0];
    // Use firstObject
}
 
// ...
 
if (queue.count > 0) {
    id lastObject = [queue objectAtIndex:(queue.count - 1)];
    // Use lastObject
}

In the case of retrieving the last object, you’ve always had the option of using the following method of NSArray:

- (id)lastObject;

Objective-C developers are the rejoicing the world over, as for the first time they have access to an equivalent method to retrieve the first object of the array:

- (id)firstObject;

This single, simple method turns out to be extremely useful. No longer do you have to account for an array being empty. If you’ve ever felt the sting of a crash because of an out of bounds exception then you’ll definitely see this as a welcome addition.

Note: If you look at the header for NSArray carefully, you’ll see that firstObject has actually been around since iOS 4.0 but it wasn’t made public until iOS 7. Therefore you could have accessed the method prior to iOS 7, but that would have required declaring the firstObject selector in one of your own header files to inform the compiler that it does in fact exist. That’s certainly not a recommended approach, so it’s good that Apple finally brought it out of hiding.

The previous code snippet can now be rewritten to use these two utility methods and forego the length checks, as illustrated below:

NSMutableArray *queue = [NSMutableArray new];
// ...
 
id firstObject = [queue firstObject];
// Use firstObject
 
id lastObject = [queue lastObject];
// Use lastObject

NSData

Data is one of those things you deal with a lot when you’re programming. NSData is the Foundation class that encapsulates raw bytes and provides methods for manipulating those bytes, as well reading and writing data to and from a file. But one very common task for which there’s been no native implementation is Base64 encoding and decoding. At least that was the case until the release of iOS 7.

Base64 is a group of binary-to-text encoding schemes that represent binary data in ASCII format. These schemes are commonly used where there’s a need to encode binary data to be stored on or transferred over media designed to deal solely with textual data. This ensures the data remains intact without modification during transport. The most common use of Base64 encoding is handling attachments in email, as well as encoding small images that form part of a JSON response returned by a web based API.

Prior to iOS 7.0, Base64 encoding and decoding tasks required you to implement your own method or include part of a third party framework.In typical Apple fashion, it’s now very easy to use this functionality. There are four core Base64 methods as follows:

- (id)initWithBase64EncodedString:(NSString *)base64String 
      options:(NSDataBase64DecodingOptions)options;
 
- (NSString *)base64EncodedStringWithOptions:
      (NSDataBase64EncodingOptions)options;
 
- (id)initWithBase64EncodedData:(NSData *)base64Data 
      options:(NSDataBase64DecodingOptions)options;
 
- (NSData *)base64EncodedDataWithOptions:
      (NSDataBase64EncodingOptions)options;

The first two methods deal with strings, while the latter two deal with UTF-8 encoded data. Both pairs of methods perform the same action, but sometimes using one over the other will prove more effective. If you were to Base64 encode a string and then write it to a file, you may decide to use the pair that handles UTF-8 encoded data. On the other hand, if you were to Base64 encode a string and then use that in some JSON, you may decide to use the pair that handles strings.

So if you’ve ever included a Base64 method or two in your project, now is the time to remove that unnecessary code and use Apple’s implementations instead!

NSTimer

Timers often find homes in apps that perform periodic tasks. As useful as they may be, the problem is that they may fire off constantly when several timers are in use. This means the CPU is constantly active; it would be much more efficient if the CPU woke up, performed a batch of tasks and then went back to sleep. To solve this issue, Apple has added a tolerance property to NSTimer to help accommodate this behavior.
The tolerance property provides the system with a guide as to how late a timer is permitted to fire after its schedule time. The underlying system will then group actions accordingly to reduce CPU overhead. The methods for accessing this new property are as follows:

- (NSTimeInterval)tolerance;
- (void)setTolerance:(NSTimeInterval)tolerance;

You may find you never need to use this property, but if you’re firing several timers in very close succession, you may find it useful to benchmark your app’s CPU usage using Instruments while tinkering with this setting.

NSProgress

It’s not often that entirely new classes get added to Foundation. It’s a pretty stable framework, mainly because new core classes aren’t required too often. However, iOS 7.0 presents an entirely new class named NSProgress.

In essence, NSProgress aims to deliver progress reporting throughout Objective-C code, neatly separating the progress of individual components. For example, if you perform a few different tasks on some data, then each task can monitor its own progress and report back to its parent task.

The structure of NSProgress

The simplest way of using NSProgress is to use it to report progress on a set of tasks. For example if you have 10 tasks to achieve, then you can report progress as each task finishes. As each task finishes the progress goes up by 10%. Then, using Key Value Observing (KVO) on the NSProgress instance, you will be notified about this increase in progress. You might use this notification as an opportunity to update a progress bar, or set the text on a label to give an indication of the progress.

But there is more to NSProgress than just this. Apple have made it incredibly powerful, mainly through the use of a child-parent relationship structure. The structure of NSProgress is much like a nested tree: each instance can have one parent and many children. Each instance has a total number of units of work to be performed, and as the task progresses the completed number of units is updated to reflect the current state. In doing so, the parent (if one exists) is notified of the progress as well.

To reduce the need to pass around NSProgress instances, each thread has its own NSProgress instance and child instances can be created directly from this instance. Without this functionality, every task that wanted to report progress in this way would have to be altered to take an NSProgress parameter.

Reporting progress

Using NSProgress is simple. It all starts with the following method:

+ (NSProgress *)progressWithTotalUnitCount:(int64_t)unitCount;

This creates a new instance of NSProgress as a child of the current instance and initializes it with the total number of units of work that will be performed overall. For example, if the task were to loop through an array, then you would probably initialize the NSProgress instance with the count of the array, like so:

NSArray *array = /* ... */;
 
NSProgress *progress = 
    [NSProgress progressWithTotalUnitCount:array.count];
 
[array enumerateObjectsUsingBlock:
    ^(id obj, NSUInteger idx, BOOL *stop) {
        // Perform an expensive operation on obj
        progress.completedUnitCount = idx;
    }];

As the iteration progresses, the above code updates the instance of NSProgress to reflect the current progress.

Receiving progress updates

You can determine the progress of the task at any point through the following property:

@property (readonly) double fractionCompleted;

This returns a value from 0 to 1, indicating the total progress of the task. When there are no child instances in play, fractionCompleted is simply the completed unit count divided by the total unit count.

Key Value Observing (KVO) is the best way to be notified when the fractionCompleted property changes its value. Doing so is simple. All you need to do is register as an observer of the fractionCompleted property of the relevant NSProgress object like so:

[_progress addObserver:self 
            forKeyPath:@"fractionCompleted" 
               options:NSKeyValueObservingOptionNew 
               context:NULL];

Then, override the method that KVO uses to notify you of changes, like so:

- (void)observeValueForKeyPath:(NSString *)keyPath 
                      ofObject:(id)object 
                        change:(NSDictionary *)change 
                       context:(void *)context
{
    if (object == _progress) {
        // Handle new fractionCompleted value
        return;
    }
 
    // Always call super, incase it uses KVO also
    [super observeValueForKeyPath:keyPath 
                         ofObject:object 
                           change:change 
                          context:context];
}

In this method you would handle the change in fractionCompleted value. For example, you might change the value of a progress bar or a label to indicate the current level of completion.

Of course, it’s important to remember to unregister from KVO once you’re done, like so:

[_progress removeObserver:self 
               forKeyPath:@"fractionCompleted" 
                  context:NULL];

You must always unregister and your app will crash if you don’t unregister by the time the registered object (self in this example) is deallocated. So ensure that you unregister as a last resort in dealloc if necessary.

Where To Go From Here

In this article you’ve learned about several new features of Objective-C and its associated frameworks. You should always aim to stay up-to-date with advances in both the language and core system frameworks such as Foundation. If you do so, then you’ll be able to make use of the latest and greatest offerings from Apple.

Go forth and make your apps compiler faster using modules. Make them more resilient to awkward bugs arising from umbrella id return types by using instancetype instead. And finally, start using all the fun new methods and classes found in Foundation!

If you’d like to learn more about What’s New with Objective-C and Foundation (or more about iOS 7 in general), check out our new book iOS 7 by Tutorials. The book contains more info and examples of NSProgress along with tons of other chapters on almost everything else in iOS 7.

In the meantime, if you have any questions or comments, please join the forum discussion below!

Matt Galloway
Matt Galloway

Matt is the founder of SwipeStack, a mobile development company based in London, UK which create apps for clients and also a few of their own. One client's app was featured by Apple in the best apps of 2011, the App Rewind in the newsstand category.

BeerMap is one of their own creations, helping beer drinkers find a great pub near them! You can find him on Twitter.

User Comments

11 Comments

  • open source beerMap, please ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    zzz6519003
  • nice!!!
    zzz6519003
  • Very good and to the point article!! :)
    etheras
  • Excellent...Start of with Objective-C to the new iOS 7.
    siennaamelia81
  • Very Nice and to the point informative Tutorial (y)
    ask4asif
  • Nice!!!
    Kanglu
  • This is very basic but good to known~_~
    pcliu
  • One question: can this @import thing be used for our own classes?
    lunarmoon
  • lunarmoon wrote:One question: can this @import thing be used for our own classes?

    No, it's for the system frameworks only. Maybe one day...
    Hollance
  • this article is so good for newer iOS dev as me :)
    tuyenbq
  • Hi! I suspect there are a chain of articles like this one going back in time, one for each iOS release. It would be nice if there was a link at the top/bottom of each article pointing to the last one, so one could get a quick overview of changes over time.
    Maury Markowitz

Other Items of Interest

Ray's Monthly Newsletter

Sign up to receive a monthly newsletter with my favorite dev links, and receive a free epic-length tutorial as a bonus!

Advertise with Us!

Vote for Our Next Tutorial!

Every week, we alternate between Gaming and Non-Gaming tutorial votes. This week: Non-Gaming!

    Loading ... Loading ...

Last week's winner: How To Make a Tower Defense Game with Swift.

Suggest a Tutorial - Past Results

Hang Out With Us!

Every month, we have a free live Tech Talk - come hang out with us!


Coming up in December: The Great CALayer Tour

Sign Up - December

Our Books

Our Team

Tutorial Team

  • Pietro Rea
  • Kyle Richter

... 59 total!

Update Team

... 13 total!

Editorial Team

  • John Clem
  • Matt Galloway

... 17 total!

Code Team

  • Orta Therox

... 3 total!

Subject Matter Experts

  • Richard Casey

... 4 total!