Mac Developer Library Developer
Document Generated: 2015-09-09 14:03:49 -0700
OS X Release Notes Copyright © 2015 Apple Inc. All Rights Reserved.

OS X 10.11 and iOS 9 Release Notes
Cocoa Foundation Framework

The Foundation Framework is a library of Objective-C classes that provide the infrastructure for object-based applications with or without graphical user interfaces. It is available on OS X and iOS.

You can find release notes for the Application Kit as well as some notes on general backward compatibility issues, version handling, etc, here.

Some of the major topics covered in this document:

Note that even though some APIs and descriptions refer to the APIs in Objective-C, and some others in Swift, in general all Foundation APIs are available in both Objective-C and Swift.


Framework APIs in both OS X 10.11 and iOS 9 have adopted new Objective-C features such as nullability, lightweight generics, and “kindof.” These features enable API intent to be expressed more precisely and APIs to come across better in Swift.

For instance we can now indicate that nil is a valid value for the destination view when converting an NSRect between coordinate systems:
- (NSRect)convertRect:(NSRect)rect toView:(nullable NSView *)view;
and that the array returned by splitting an NSString with componentsSeparatedByString: is an NSArray of NSStrings, and it will never be nil:
- (NSArray<NSString *> *)componentsSeparatedByString:(NSString *)separator;
You will notice many API changes in Foundation and other frameworks due the adoption of these new features. When building your projects against the new SDKs you may get build warnings or errors; these are important to react to since in some cases they may point out actual issues. In addition, adopting these new features in your own code should allow better compile time detection of bugs.

Please see WWDC 2015 Session 202, “What’s New in Cocoa,” for more info on this “Swiftification” effort, as well as other changes in Foundation as well as AppKit.

Variable Width Presentation Strings

Framework level support for variable width strings. To exemplify the problem, imagine an iOS app meant to run on different screen sizes and/or different orientations. Now, say there was some text, “Welcome to the Apple Store.” At times, that text may fit perfectly well in the available space. For others, it may be too long and it’d be desirable to shorten it to something like “Welcome."

Our solution is to allow developers/localizers to provide different width-variations for a string in a stringsdict file, the same file meant for different cardinalities (“1 file is selected” vs. “2 files are selected”). The -[NSBundle localizedStringForKey:value:table:] method reads the stringsdict file and creates an NSString that knows about the different variations.

We have a single method, variantFittingPresentationWidth: on NSString. It selects the appropriate variation for the given width. The width is just an integer identifying one of the variations. The strings are sorted such that if the width does not exist, the string at the next smaller width is returned or the smallest available if none are smaller. The application can decide on their own contexts, but iOS uses em’s; the number of ‘M' characters for the current system-font that will fit the width of the window.

After obtaining a string from variantFittingPresentationWidth:, the application can invoke the method again on the returned string object for a different width. It effectively “preserves the magic.”

NSString API exposed in NSBundle:
- (NSString *)variantFittingPresentationWidth:(NSInteger)width;
For strings with width variations, such as from a stringsdict file, this method returns the variant at the given width. If there is no variant at the given width, the one for the next smaller width is returned. And if there are none smaller, the smallest available is returned. For strings without variations, this method returns self. The unit that width is expressed in and what width is a measurement of is decided by the application or framework. But it is intended to be some measurement indicative of the context a string would fit best to avoid truncation and wasted space.

The format of the stringsdict file looks like this. We’re also introducing NSStringVariableWidthRuleType.

        <string>Welcome to the store!</string>


In OS X 10.11 and iOS 9.0 NSNotificationCenter and NSDistributedNotificationCenter will no longer send notifications to registered observers that may be deallocated. If the observer is able to be stored as a zeroing-weak reference the underlying storage will store the observer as a zeroing weak reference, alternatively if the object cannot be stored weakly (i.e. it has a custom retain/release mechanism that would prevent the runtime from being able to store the object weakly) it will store the object as a non-weak zeroing reference. This means that observers are not required to un-register in their deallocation method. The next notification that would be routed to that observer will detect the zeroed reference and automatically un-register the observer. If an object can be weakly referenced notifications will no longer be sent to the observer during deallocation; the previous behavior of receiving notifications during dealloc is still present in the case of non-weakly zeroing reference observers. Block based observers via the -[NSNotificationCenter addObserverForName:object:queue:usingBlock] method still need to be un-registered when no longer in use since the system still holds a strong reference to these observers. Removing observers (either weakly referenced or zeroing referenced) prematurely is still supported. CFNotificationCenterAddObserver does not conform to this behavior since the observer may not be an object.

NSNotificationCenter and NSDistributedNotificationCenter will now provide a debug description when printing from the debugger that will list all registered observers including references that have been zeroed out for aiding in debugging notification registrations. This data is only valid per the duration of the breakpoint since the underlying store must account for multithreaded environments. Wildcard registrations for notifications where the name or object that was passed to the addObserver method family was null will be printed in the debug description as *.


In OS X 10.11 and iOS 9 integral floating point and double numbers will now be created as tagged pointers when possible. This only applies to 64 bit architectures and integral values that can be stored in 56 bits of storage.
NSNumber *tagged = [NSNumber numberWithDouble:5.0];
NSNumber *notTagged = [NSNumber numberWithDouble:4.2];

Low Power Mode

iOS 9.0 introduced a new feature for reducing battery usage across applications and system settings called Low Power Mode. This setting can be read by accessing the newly introduced NSProcessInfo property lowPowerModeEnabled and can respond to changes of the state by registering for the notification NSProcessInfoPowerStateDidChangeNotification. When Low Power Mode is enabled applications should reduce power intense operations such as tasks that have heavy cpu load, network activity that may bring either WiFi or cellular radios online, or keeping the screen on.

The notification for NSProcessInfoPowerStateDidChangeNotification is posted on a global dispatch queue from the default NSNotificationCenter. The notification’s object is the NSProcessInfo instance.
- (void)setup {
[[NSNotificationCenter defaultCenter] addObserver:self
name:NSProcessInfoPowerStateDidChangeNotification object:nil];
- (void)lowPowerModeChanged:(NSNotification *)notification {
if ([[NSProcessInfo processInfo] isLowPowerModeEnabled]) {
// change behavior to consume less power
} else {
// restore behavior to normal


NSProgress now has a -resume method, which parallels the behavior of the existing -pause method.

NSProgress now supports composition of progress objects into trees both implicitly and explicitly. The implicit approach uses the existing API, such as -becomeCurrentWithPendingUnitCount: and -resignCurrent. The explicit approach uses these new methods:
/* Directly add a child progress to the receiver, assigning it a portion of the receiver's total unit count.
- (void)addChild:(NSProgress *)child withPendingUnitCount:(int64_t)inUnitCount;
/* Return an instance of NSProgress that has been attached to a parent progress with the given pending unit count.
+ (NSProgress *)progressWithTotalUnitCount:(int64_t)unitCount parent:(NSProgress *)parent
/* Return an instance of NSProgress that has been initialized with -initWithParent:userInfo:. The initializer is passed nil for the parent,
resulting in a progress object that is not part of an existing progress tree. The value of the totalUnitCount property is also set.
+ (NSProgress *)discreteProgressWithTotalUnitCount:(int64_t)unitCount;
This additional API makes it appropriate to expose a progress object as a property of a class, because the progress object can now be retrieved and directly added as a child of another progress object. A new protocol has also been added, NSProgressReporting, which can be adopted to mark a class which reports progress in this way. When creating a progress object that will be vended from your class, you most likely want to use the new +discreteProgressWithTotalUnitCount: method to ensure you are creating a progress object which does not get implicitly attached to the current progress.

The rules about unit counts remain the same: completed and total unit count are in the units of the receiver NSProgress object. When adding a child, the pending unit count given to that child is also in the units of the receiver NSProgress object. NSProgress objects should either have no children and update their completedUnitCount directly (“leafy”), or they should have children and hand out all of their totalUnitCount as pendingUnitCount to those children.

In general, use the explicit addChild methods to compose trees when it is possible to get a progress object as the result of a method or a property of a class. Use the implicit methods to compose trees when the progress object is not directly accessible, for example calling through a proxy object (as NSProgress support over NSXPCConnection works today), or through an existing method which cannot gain an NSProgress return value (eg -[NSData dataWithContentsOfFile:]).

Starting in 10.11 and iOS 9.0, implicitly composed progress objects will no longer split pending unit count amongst themselves. This change was made to ensure that progress did not unintentionally move backwards, due to unanticipated child NSProgress objects being attached to the parent. Instead, the first child will consume the entire pending unit count. This means it is important for a method which supports implicitly attaching NSProgress objects by using +[NSProgress progressWithTotalUnitCount:] should make this call at the very first opportunity inside the implementation of the method. If other methods are invoked first, and they also use implicit progress, then there is the possibility that they will instead consume the pending unit count of the current progress. For example:

/* This method supports implicitly-created progress, and -becomeCurrentWithPendingUnitCount: was called right before this method. */
- (void)myMethod {
[object doSomething];
[object doSomethingElse];
NSProgress *p = [NSProgress progressWithTotalUnitCount:10]; // WRONG - doSomething or doSomethingElse may have already created a progress object
// and attached it to the currentProgress. This progress object will now have no effect.
// work, where p.completedUnitCount is updated
- (void)myMethod {
NSProgress *p = [NSProgress progressWithTotalUnitCount:10]; // RIGHT - by creating this first, we ensure that ‘p’ is attached to the currentProgress,
// regardless of what the following two methods do.
[object doSomething];
[object doSomethingElse];
// work, where p.completedUnitCount is updated


Foundation has new API to support the Handoff features of OS X Yosemite and iOS 8.0.

The NSUserActivity class provides a means for your application to store a small amount of information about what a user may be doing and to send that information from your application to another application of your creation when the user indicates that they would like to "hand off" this user activity from one device to another. The intention is that the application running on the second device, upon being given the information you created and put into a user activity, is able to reproduce the same state, showing the same information to the user, as is on the first device.

User activities allow a user to exchange information between applications created by the same developer. Applications that wish to receive user activities must be signed with the same developer certificate (and must share the same developer team identifier) as the application which created those user activities.

User activity type strings should follow a reverse-DNS style format (for example, "com.companyname.activityType".)

An application may have at most one "current" user activity, which is the NSUserActivity that the system would choose to show on a second device when this application is the frontmost application and the system has determined that a user activity can be handed off. Many factors contribute to whether a system makes a user activity available for Handoff, including whether the user appears to be interacting with the system, whether Bluetooth or Wi-Fi networking is available, and other factors. If you want to support Handoff, do not attempt to determine whether a system is capable of supporting Handoff. Simply create a user activity for whatever the user is doing and respond to any delegate messages that you receive. On devices where Handoff is not supported, the overhead of creating a user activity is quite low.

If you have a current user activity and wish to make it no longer current, but don't have another user activity that you want to make current, you should invalidate the user activity. If you need to make that user activity current again, you should recreate it.

Applications should fill in the title and userInfo properties of user activity objects they create. Its is acceptable to leave the title property empty, but if there is a reasonable value for it (for example, the name of the document the user is editing) then set it. It is not useful to set the title to the name of the application that creates the user activity, or to some other static string. The user info dictionary can contain any value or values of use to the application of the following classes: NSArray, NSData, NSDate, NSDictionary, NSNumber, NSString, NSURL, and NSUUID. The dictionary is generally transmitted unchanged between the creating application and the receiving application with the exception of NSURL objects representing files in the Cloud Documents container on the sending device. These NSURLs will be changed, on the receiving device, so that they point to the same file in the Cloud Documents folder on the receiving device, and so may have different paths or names than they did on the originating device.

Because Handoff is suppose to be a quick operation between two devices, it is important that the data placed into the user info dictionary be as small as possible. Your goal should be that the dictionary represent less than 3 KB of information. The exact method of encoding is an implementation detail, but the following code can give you a rough estimate of your dictionary's size:
NSInteger roughGuessAtDataSize = [NSKeyedArchiver archiveDataWithRootObject:userActivity.userInfo];
NSLog(@"The user info dictionary is roughly %lu bytes in size", (unsigned long)roughGuessAtDataSize.length);
Mac OS X 10.11 and iOS 9.0 add additional properties to NSUserActivity, for use by the App Search and History features.

Several new properties are added. Three new properties control when a NSUserActivity object will be available for Handoff, Spotlight, and public App Search. These properties are eligibleForHandoff, eligibleForSearch, and eligibleForPublicIndexing. All activities will initialize .eligibleForHandoff to YES and .eligibleForSearch and .eligibleForPublicIndexing to NO.

For an NSUserActivity which should be added to the local spotlight index, set eligibleForSearch to YES, add any appropriate keywords that describe this object to the keywords set, and set the contentAttributeSet property (which is declared as a category in CoreSpotlight.h, so you must #import <CoreSpotlight/CoreSpotlight.h>. When a user chooses at item from the Spotlight UI, your application will be opened with the application:continueUserActivity:restorationHandler: delegate.

For an NSUserActivity which should be found by other users via Siri, you should also set the requiredUserInfoKeys set to include only those keys in the top level of the .userInfo dictionary which contain values that are appropriate for the public indexing. See the NSUserActivity and App Search documentation for more information on how to decide this for your application.

A new property, expirationDate, can be set and which indicates a point in time after which an activity, even if still the current activity, should no longer be considered eligible for handoff, search, or public indexing.

If an NSUserActivity has a delegate set and if .eligibleForSearch or .eligibleForPublicIndexing set to YES, then periodically the delegate will get a userActivityWillSave: callback, to update the information in the NSUserActivity. The userActivityWasContinue: callback will only be called when the activity is sent via Handoff to another device.


Several new file system resource property keys have been added for OSX and/or iOS.

Several new methods have been added:

NSURL Deprecations

In OSX 10.9 and iOS 7.0, we introduced replacement API for the NSURL methods and CFURL functions:
The old "PercentEscapes" API was deficient and needed to be replaced for four reasons:

1 - Text encoding in URLs should be UTF8 because that is the text encoding the internet standards organizations have standardized on (see ). When the "PercentEscapes" methods and functions were introduced over a decade ago, that wasn't always the case. Because the text encoding is not embedded in the URL strings, using a non-standard text encoding will likely cause interoperability problems unless you know all code using the URL is using the same non-standard text encoding.

2 - With the older APIs, text encodings that are not a superset of ASCII encoding don't always work correctly (a text encoding that is a superset of ASCII encoding is where all 7-bit ASCII characters can be stored in a single 8-bit byte -- those text encodings include MacRoman, WindowsLatin1, ISOLatin1, NextStepLatin, ASCII, and UTF8) -- if you use one of those text encodings to percent-encode a string and then percent-decode the encoded string with the same text encoding, you won't always get the original string. Even with text encodings which are a superset of ASCII encoding, you can run into problems when one text encoding is used to percent-encode and a different text encoding is used to percent-decode because of characters which are not available in both text encodings.

3 - The "AddingPercentEscapes" methods and functions were originally documented in a way which made it seem you could pass an unpercent-encoded URL string in and get a correctly percent-encoded URL string out. That is not the case because each URL component has it's own rules about what unencoded characters are legal, and which illegal characters must be percent-encoded. The old "AddingPercentEscapes" code has these problems:
    The characters '/', ':', '?' and '@' in the user, password, and host sub-components are not being percent-encoded.
    The characters '[' and ']' in an IPv6 host address in the host sub-component are being percent-encoded.
    The characters ':', ';' and '?' in the path components are not being percent-encoded.
    The characters '"' and '#' are being percent-encoded everywhere in the string.

4 - It's never been documented what characters the "AddingPercentEscapes" methods and functions by default consider legal. That makes it hard to determine what they actually do, and in the case of CFURLCreateStringByAddingPercentEscapes(), how to correctly use the charactersToLeaveUnescaped and legalURLCharactersToBeEscaped arguments.The only ways to find out are to either look at the source code in CFURL.c (which is available open source), or to test by feeding all 7-bit ASCII characters through the API to see what characters are not percent-encode. FWIW: Here are the characters considered legal by default:
Those characters are not the correct set for any URL component.

The replacement API for those two methods and two functions are:
With the predefined character sets:
So, we're deprecating the old API. Because the old API has existed since OSX 10.3 and has always existed in iOS, there is a lot of code using it. What follows is a short guide to replacing the old API with the new API.

• "I was using a text encoding other than kCFStringEncodingUTF8 or NSUTF8StringEncoding."

 If the input string only contained 7-bit ASCII characters and the text encoding was a superset of ASCII encoding, the deprecated API using one of those text encodings didn't do anything wrong and switching to kCFStringEncodingUTF8 or NSUTF8StringEncoding will work the same (only it'll be faster); otherwise, you should ask yourself why you thought that text encoding was the correct text encoding to use.

• "I was percent-encoding an entire URL string."

If you thought -stringByAddingPercentEscapesUsingEncoding: or CFURLCreateStringByAddingPercentEscapes() were working for you, they might have been working only by accident.  If you are creating an URL from separate component values, you should use NSURLComponents to construct the URL. NSURLComponents knows now to correctly percent-encode the individual URL component and sub-components. If you need to percent-encode a single URL component or sub-component string (i.e., you aren't going to create a URL or URL string), you should use -stringByAddingPercentEncodingWithAllowedCharacters:. If you need to percent-encode an entire URL string, you can use this code to encode a NSString intended to be a URL (in urlStringToEncode):
        NSString *percentEncodedURLString =
[[NSURL URLWithDataRepresentation:[urlStringToEncode dataUsingEncoding:NSUTF8StringEncoding] relativeToURL:nil] relativeString];
(The CoreFoundation equivalent to URLWithDataRepresentation: is CFURLCreateWithBytes() using the encoding kCFStringEncodingUTF8 with a fall back to kCFStringEncodingISOLatin1 if kCFStringEncodingUTF8 fails.)

• "I wasn't using the percent-escaping functions/methods for anything having to do with URLs -- they just looked like a good way to encode my data as ASCII so I used them."

-stringByAddingPercentEncodingWithAllowedCharacters: will also work for your purposes. You can easily create your own NSCharacterSet and then you'll know exactly what characters are being encoded and what characters are not being encoded. Or if one of the predefined URL character sets works for your purposes, you can use them.

• "My code cannot link with Foundation so it cannot use the new Foundation replacement API."

Unfortunately, you're going to have to keep using the old deprecated API. You will have to be careful to not trip over the problems which made a replacement API necessary. You should always use kCFStringEncodingUTF8. You should never use a text encoding that isn't a superset of ASCII encoding. You must not encode an entire URL string. You must make sure the characters you want percent-encoded are encoded and those you do not want percent-encoded are not (you may have to pass in strings in the charactersToLeaveUnescaped and legalURLCharactersToBeEscaped arguments to get the results you expect). You can disable deprecation warnings around your use of deprecated functions by using these #pragmas:
    #pragma GCC diagnostic push
    #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
        // use deprecated functions
    #pragma GCC diagnostic pop
Other deprecations:

NSURLComponents New API

The following properties were added to NSURLComponents to return the character range of a component in the URL string returned by -[NSURLComponents string].

NSFileManager New API

NSFileManager now provides a method for unmounting and optionally ejecting file system volumes.
The options for unmountVolumeAtURL:options:completionHandler are:
If unmountVolumeAtURL:options:completionHandler: fails, the process identifier of the dissenter can be found in the NSError's userInfo dictionary with the NSFileManagerUnmountDissentingProcessIdentifierErrorKey.

NSAffineTransform now conforms to NSSecureCoding

In OS X 10.11 and iOS 9, NSAffineTransform now conforms to NSSecureCoding. Invalid archives of NSAffineTransform will now raise an NSGenericException if they do not strictly match the expected layout.

Dictionaries created with dictionaryWithSharedKeySet now fully supports NSSecureCoding

Dictionaries created via NSSharedKey dictionary can now survive unarchive even if the the underlying hash implementation of the contained objects changes between archival/unarchival.

NSCache deadlock

On iOS 8 it was possible for NSCache to cause an application to deadlock if managed to retain itself during an UIApplicationDidEnterBackgroundNotification notification. This no longer occurs in iOS 9.

NSPropertyListSerialization now populates error on validation failures

On OS X 10.10 and iOS 8 and earlier, invalid property lists passed to -[NSPropertyListSerialization dataWithPropertyList:format:options:error] could return nil, but not populate the error (it would log instead). Beginning in OS X 10.11 and iOS 9, this API will now populate the error appropriately if provided.

NSCoder gains support for expressing decode failures via NSError

In OS X 10.10 and iOS 8 and earlier, instances of NSCoder communicated errors primarily through NSException, even if the underlying problem was not a programmer error (i.e.. corrupt archive). New to OS X 10.11 and iOS 9, all NSCoder implementations gain support for error notification through NSError out-parameters. These APIs should make it much easier to unarchive data in Swift.

You can opt-in to this behavior by calling any of these new top-level decode methods:

- (nullable id)decodeTopLevelObjectAndReturnError:(NSError **)error;
- (nullable id)decodeTopLevelObjectForKey:(NSString *)key error:(NSError **)error;
- (id)decodeTopLevelObjectOfClass:(Class)aClass forKey:(NSString *)key error:(NSError **)error;
- (nullable id)decodeTopLevelObjectOfClasses:(nullable NSSet<Class> *)classes forKey:(NSString *)key error:(NSError **)error;
+ (id)unarchiveTopLevelObjectWithData:(NSData *)data error:(NSError **)error NS_AVAILABLE(10_11, 9_0);
The top-level distinction is important, as NSCoder implementations still use exceptions internally to communicate failure. Any other decode-related API on NSCoder can still throw. The idea is that you would make use of one of the top-level methods, and then use the non-NSError variants as you would have previously.

In addition to the new top-level APIs, we additionally introduce a method that can be used to signal to your coder that the decode has failed.
 - (void)failWithError:(NSError *)error NS_AVAILABLE(10_11, 9_0);
Typically, you would want to call this method in your -initWithCoder: implementation when you detect situations like:
- lack of secure coding
- corruption of your data
- domain validation failures

Before calling -failWithError: within your -initWithCoder: implementation, you should clean up any resources that are not automatically recovered (malloc's, etc.).

Once an error has been signaled to a decoder, it remains set until it has handed off to the first TopLevel decode invocation above it. For example, consider the following call graph:
 A    -decodeTopLevelObjectForKey:error:
B -initWithCoder:
C -decodeObjectForKey:
D -initWithCoder:
E -decodeObjectForKey:
F -failWithError:
In this case the error provided in stack-frame F will be returned via the outError in stack-frame A. Furthermore the result object from -decodeTopLevelObjectForKey:error: will be nil, regardless of the result of stack-frame B.

The call-stack-unwinding from frame F to A utilizes NSException which matches the historical behavior of decode failures for NSCoder based unarchival.

To differentiate between missing values and invalid archives, the following NSError code can be examined for: NSCoderValueNotFoundError when the decode method returns nil. Note that this error will not be encountered in Swift, where the decode methods do return an optional.

It is still possible for the top-level APIs to raise NSExceptions in the presence of programmer error (e.g. calling -decodeObjectForKey: on an unarchiver that you have already called -finishDecoding).

NSUndoManager Block-based Undo

In the interest of providing an easier way to use implement undo operations in Swift, NSUndoManager gains the following API:
/*! @abstract records single undo operation for the specified target
@param target non-nil target of the undo operation
@param undoHandler non-nil block to be executed for the undo operation
As with other undo operations, this does not strongly retain target. Care should be taken to avoid introducing
retain cycles by other references captured by the block.
- (void)registerUndoWithTarget:(id)target handler:(void (^)(id target))undoHandler;
Additionally, like the other undo operations (target/selector and invocation), the target can be used with the -removeAllActionsWithTarget:.

Single Object NSSet Performance Improvements

Changes have were made to dramatically increase the performance of single-object immutable sets.

Various Performance Improvements in our collections

Improved immutable NSArray performance across the board, especially around access, creation and deletion.

NSDictionary -isEqual: is now faster, along with numerous other dictionary related operations.

Safer Buffer API for NSDictionary

In OS X 10.11 and iOS 9, NSDictionary gains the following method:
- (void)getObjects:(ObjectType __unsafe_unretained [])objects andKeys:(KeyType __unsafe_unretained [])keys count:(NSUInteger)count;
It is intended to replace the following method, which is soft-deprecated this release, and will be officially deprecated in the future.
- (void)getObjects:(ObjectType __unsafe_unretained [])objects andKeys:(KeyType __unsafe_unretained [])keys;

Safer Buffer API for NSIndexPath

Similarly, NSIndexPath gains the following method:
- (void)getIndexes:(NSUInteger *)indexes range:(NSRange)positionRange;
Replacing the older, less safe variant (which is now soft-deprecated):
- (void)getIndexes:(NSUInteger *)indexes;

NSFileVersion hasLocalContents Bug Fix

In OS X 10.10 and iOS 8, NSFileVersion exposed the "hasLocalContents" property to indicate whether a particular NSFileVersion originated locally, or from some non-local source, like iCloud. Unfortunately, the property returned the opposite value than intended. This is has been fixed in OS X 10.11 and iOS 9.

NSMutableDictionary subscript syntax change

In OS X 10.11 and iOS 9, NSMutableDictionary now allows you to use its subscript syntax to assign nil for a key. Like Swift's Dictionary type, doing so will remove an existing object for that key from the dictionary. In effect, the following lines of code are now equivalent:
[dictionary removeObjectForKey:@"Key"];
dictionary[@"Key"] = nil;
These new semantics exist only when building with the OS X 10.11 or iOS 9 SDKs. If your application's deployment target is earlier operating system, then runtime support will be implicitly linked into your binary by Xcode to ensure the behavior works on any targeted operation system.

NSFileCoordinator and NSFilePresenter usage on iOS (New since WWDC Seed)

Prior to iOS 9, NSFileCoordinator and NSFilePresenter were documented as unsafe to use for coordinating access to files in iCloud or group containers. If an application or extension left an NSFilePresenter registered for a file in such a container or had an active coordinated read or write at the time the application was backgrounded and suspended, future attempts to access these files would deadlock.

In iOS 9, NSFileCoordinator and NSFilePresenter were improved to avoid these problems. In general, applications and extensions should typically remove their NSFilePresenters via -[NSFileCoordinator removeFilePresenter:] when the application enters the background. For applications that fail to do so, the system will now automatically kill a suspended application or extension with an NSFilePresenter that File Coordination would need to message and get a response (i.e. relinquishPresentedItemToWriter:) to avoid deadlock. If such an application or extension got "lucky" and was not killed while suspended, a message will be logged in the application when it becomes active again to help you discover this problem.

One-way NSFilePresenter messages are not vulnerable to deadlock, so starting in iOS 9, it is now safe to leave an NSFilePresenter registered if it does not implement any NSFilePresenter methods that require a reply via a block (i.e. a completionHandler or relinquisher block).

Additionally, a coordinated read or write, when granted, will now automatically begin a background task similar to -[UIApplication beginBackgroundTaskWithExpirationHandler:]. This should ensure that your application has enough time to finish the operation and unblock other processes's attempts to do coordinated access of the file. If the background task expires, the process will be killed. If a process is suspended while waiting for a coordinated read or write to be granted, the request will be cancelled, returning an NSError with NSUserCancelledError.


NSURLConnection is deprecated as of OS X 10.11 and iOS 9. Please use NSURLSession.

Application Transport Security

Application Transport Security is a new security feature whose goal is to protect customer data. If your app is linked on or after OS X 10.11 or iOS 9, all NSURLSession and NSURLConnection based cleartext HTTP loads (http://) will be denied by default. Encrypted HTTPS (https://) connections will also require "best practice" TLS behaviors, such as TLS version and cipher suite requirements. Temporary exceptions can be configured via your app's Info.plist file. For more information, see the WWDC sessions covering Application Transport Security.


The symbols NSURLSessionTaskPriorityDefault, NSURLSessionTaskPriorityHigh and NSURLSessionTaskPriorityLow are missing from the WatchOS SDK.

NSLocaleMeasurementSystem Support for UK

In appropriate locales, NSLocale may now return @"U.K." for the NSLocaleMeasurementSystem key. This indicates "imperial" values for non-metric measurements, e.g. a pint is 568.3 mL (vs a US pint's 473.2 mL); can also serve to indicate the mix of metric and non-metric measurements used in UK, such as miles for road distances but litres for volume of gasoline and other liquids.


NSString now exposes API for transliteration. This was available in CFString previously.
- (nullable NSString *)stringByApplyingTransform:(NSString *)transform
The indicated transformation is applied to the receiver (see below for the predefined set of transforms provided in NSString). reverse indicates that the inverse transform should be used instead, if it exists. Attempting to use an invalid transform identifier or reverse an irreversible transform will return nil; otherwise the transformed string value is returned (even if no characters are actually transformed). In addition to the predefined transforms, you can pass in any valid ICU transform ID as defined in the ICU User Guide. Arbitrary ICU transform rules are not supported.

There’s also API on NSMutableString for the same thing:
- (BOOL)applyTransform:(NSString *)transform
updatedRange:(nullable NSRangePointer)resultingRange;
Similar to the NSString API, except that only the specified range will be modified (however the transform may look at portions of the string outside that range for context). If supplied, resultingRange is modified to reflect the new range corresponding to the original range.

The following transforms are provided:
NSString * const NSStringTransformLatinToKatakana;
NSString * const NSStringTransformLatinToHiragana;
NSString * const NSStringTransformLatinToHangul;
NSString * const NSStringTransformLatinToArabic;
NSString * const NSStringTransformLatinToHebrew;
NSString * const NSStringTransformLatinToThai;
NSString * const NSStringTransformLatinToCyrillic;
NSString * const NSStringTransformLatinToGreek;
NSString * const NSStringTransformToLatin;
NSString * const NSStringTransformMandarinToLatin;
NSString * const NSStringTransformHiraganaToKatakana;
NSString * const NSStringTransformFullwidthToHalfwidth;
NSString * const NSStringTransformToXMLHex;
NSString * const NSStringTransformToUnicodeName;
NSString * const NSStringTransformStripCombiningMarks;
NSString * const NSStringTransformStripDiacritics;

The following two new methods are the most appropriate methods for doing user-level string searches, similar to how searches are done generally in the system. The search is locale-aware, case and diacritic insensitive. As with other APIs, "standard" in the name implies "system default behavior," so the exact list of search options applied may change over time. If you need more control over the search options, please use the rangeOfString:options:range:locale: method. You can pass [NSLocale currentLocale] for searches in user's locale.
- (BOOL)localizedStandardContainsString:(NSString *)str;
- (NSRange)localizedStandardRangeOfString:(NSString *)str;

The following are new convenience methods that do the case mappings in a locale-aware fashion.
- (NSString *)localizedUppercaseString;
- (NSString *)localizedLowercaseString;
- (NSString *)localizedCapitalizedString;

NSStringGenderRuleType Bugfix

We fixed a longstanding bug in stringsdict's NSStringGenderRuleType. A properly-formatted example of this is below:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "">
<plist version="1.0">
        <string>%@ is %#@pronoun_gender@ name</string>
NSString *gendered = [NSString localizedStringWithFormat:NSLocalizedStringFromTable(@"test", @"gender", @"comment"), @"Nat", 0];
Nat is his name

If instead you call:
NSString *gendered = [NSString localizedStringWithFormat:NSLocalizedStringFromTable(@"test", @"gender", @"comment"), @"Nat", 1];
You get:
Nat is her name

NSString *gendered = [NSString localizedStringWithFormat:NSLocalizedStringFromTable(@"test", @"gender", @"comment"), @"Nat", 2];
You get:
Nat is their name

Tagged Pointer NSStrings

Starting with iOS 9 certain strings (ones with a suitable length and encoding) on 64 bit architectures will now use a “tagged pointer” format where the string contents are stored directly in the pointer. This matches behavior introduced on OS X in 10.10 Yosemite.

Similarly to the OS X targets, passing a tagged NSString to functions such as CFStringGetCStringPtr or CFStringGetCharactersPtr will return NULL in cases where it may not have before. As before it is important to check for the NULL return value and use the corresponding buffer fetching function:
char buffer[BUFSIZE];
const char *ptr = CFStringGetCStringPtr(str, encoding);
if (ptr == NULL) {
if (CFStringGetCString(str, buffer, BUFSIZE, encoding)) ptr = buffer;
In addition, this change enables index and range checking to be performed more often when working with strings. So you may see runtime exceptions due to this change. In almost all cases these exceptions point to bugs in code, so please take them seriously.

This change will also break any code which treats NS/CFStrings objects as pointers and attempts to dereference them.

NSString's +stringEncodingForData: API Enhancements

In OS X 10.11 and iOS 9, if you called +[NSString stringEncodingForData:encodingOptions:convertedString:usedLossyConversion:] with a suggested encoding via NSStringEncodingDetectionSuggestedEncodingsKey and allowed lossy detection via NSStringEncodingDetectionAllowLossyKey you will always get a result. Previously in OS X 10.0 and iOS 8, the API could fail to find an encoding in such circumstances.


NSPersonNameComponentsFormatter is a new formatter which enables formatting and displaying person names properly in different localizations. It formats objects of type NSPersonNameComponents, which allows specifying different parts of names.

NSError Value Provider

We recommend that NSErrors are as rich as possible, with localized description, failure reason, recovery attempter, etc.  This in turn may make the creation of NSErrors more expensive, and tight loops where expected errors are being encountered could be an issue. To help with this, NSError now allows you to specify a block as the userInfoValueProvider for a domain. With this, at the time you create an NSError, you will provide the minimal amount of info needed, often just the domain and the code, and in some cases a userInfo value or two. Then, the provider can provide the other info to present great NSErrors lazily, on-demand:
+ (void)setUserInfoValueProviderForDomain:(NSString *)errorDomain
provider:(id __nullable (^ __nullable)(NSError *err, NSString *userInfoKey))provider;
+ (id __nullable (^ __nullable)(NSError *err, NSString *userInfoKey))userInfoValueProviderForDomain:(NSString *)errorDomain;
Specify a block which will be called from the implementations of localizedDescription, localizedFailureReason, localizedRecoverySuggestion, localizedRecoveryOptions, recoveryAttempter, and helpAnchor, when the underlying value for these is not present in the userInfo dictionary of NSError instances with the specified domain. The provider will be called with the userInfo key corresponding to the queried property: For instance, NSLocalizedDescriptionKey for localizedDescription. The provider should return nil for any keys it is not able to provide and, very importantly, any keys it does not recognize (since we may extend the list of keys in future releases).

It’s important that the provider return nil if an appropriate result for the requested key cannot be provided, rather than choosing to manufacture a generic fallback response such as "Operation could not be completed, error 42." A nil return will enable NSError to look for other ways to present the needed info (for instance, asking for NSLocalizedFailureReasonErrorKey in addition to NSLocalizedDescriptionKey). If nothing succeeds NSError will generate a properly localized fallback message.

The specified block will be called synchronously at the time when the above properties are queried. The results are not cached.

This provider is optional. It enables localization and formatting of error messages to be done lazily; rather than populating the userInfo at NSError creation time, these keys will be fetched on-demand when asked for.

It is expected that only the “owner” of an NSError domain specifies the provider for the domain, and this is done once. This facility is not meant for consumers of errors to customize the userInfo entries. This facility should not be used to customize the behaviors of error domains provided by the system.

NSError and Swift

Swift 2 introduces a new error handling mechanism which uses terminology such as throw, catch, etc. Although these terms are similar to terms used with exceptions in other contexts, Swift’s error handling is not exception handling in the traditional Objective-C or Cocoa sense. Swift’s error handling is a mechanism for reporting expected errors and properly cleaning up after them. As such, Swift’s error handling is designed to interoperate well with NSError and Cocoa error handling patterns, and Swift’s ErrorType is bridged to NSError using “as NSError,” for instance in catch statements:
do {
try fileManager.removeItemAtURL(URL)
} catch let error as NSError {
NSApp.presentError(error) // A simplified approach to presenting an error to the user on OS X
Objective C and Swift code can still raise exceptions in the traditional sense (using NSException.raise()), and in fact APIs will continue to react to programming errors (such as “array index out of bounds”) by raising traditional exceptions. Such exceptions are often not meant to be dealt with, and are also not caught by the Swift error handling mechanism.


There have been some changes in the ways NSErrors are formatted. The most significant change is that -[NSError description] and NSErrors formatted with %@ no longer make an extra effort to localize, although they may still return localized results in cases where only a localized value is available. Since the results of -[NSError description] and %@ are already not user presentable, unless your application parses the output of -[NSError description] or NSErrors formatted with %@, this change shouldn’t impact anything. Note that APIs such as -[NSError localizedDescription] and presentError: will of course continue to still localize where localizations are available.