BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage Articles What’s New in iOS 9: Xcode 7 and Other Developer Tools

What’s New in iOS 9: Xcode 7 and Other Developer Tools

At WWDC 2015, Apple introduced iOS 9. Although the new SDK does not introduce as many new or enhanced features as iOS 8, which included more than 4,000 new APIs, it does still provide a wealth of new functionality and enhancements. Along with the new SDK, iOS 9 is also marked by new developer tools to support some of its features, and new releases of Apple’s major programming languages, Swift and Objective-C.

This series aims at introducing all that is essential for developers to know about building apps for the latest release of Apple’s mobile OS. It comprises five articles that will cover what’s new in iOS 9 SDK, new features in Swift, Objective-C, and developer tools, and Apple’s new bitcode.
This InfoQ article is part of the series “IOS 9 For Developers ”. You can subscribe to receive notifications via RSS.

In the previous installments of this series, we reviewed new and enhanced frameworks included with iOS 9 SD, changes to Swift and Objective-C, and the new Safari content blocking API. In this article, we will describe what is new within Apple Developer Tools, including Xcode Playgrounds, LLDB, UI testing, Interface Builder, etc.

Xcode 7 is Apple’s new major release of developer tools for Mac, iPhone, iPad and Apple Watch apps and it goes associated with OS X El Capitan, iOS 9, and watchOS. Xcode 7 introduces major new features such as support for watchOS 2, more advanced Playgrounds, App Thinning and Bitcode, new debugging and UI testing capabilities.

Playgrounds

Playgrounds were introduced with Xcode 6 to provide a Swift REPL to make it easier to explore and play with language features. New playground features in Xcode 7 are aimed to making it possible to explain a concept or idea associated with some piece of code by adding styled textual information that tells what is going on in the surrounding code, including web links or images. To make the presentation even richer, it is also possible to display the result of some code execution inline with the code that is generating it.

Playground rich content

Furthermore, playgrounds now support folders where developers can keep companion source files that are used in the playground. This has the benefit of keeping the playground cleaner and more focused, but it also improves performance, because companion source files are not evaluated each time that the playground changes and can be compiled down.

Finally, playgrounds can be now segmented in pages so it is possible to create content that progresses through a topic and that the user can browse as chapters in a book.

watchOS 2

Xcode 7 introduces support for native watch apps, i.e. apps that are made of two parts, one running on the iPhone and the other on the watch proper. Any existing project for the Apple Watch can be easily converted to watchOS by Xcode. So, if you have a watch app that uses a non-native watch extension, as it was required under the original release of Apple Watch OS, you can convert its watch extension into a native extension that can run on the watch iself.

App Thinning

App Thinning is a new feature that allows the App Store to deliver the smallest possible app version to each specific device. This goes to prevent apps bloating due to having to include resources for all kind of supported devices. This means that if you install an app for an armv8 device such as the iPhone 6, you will not get to also download the armv7 binary image, nor any non-retina artwork that is not required.

There are three parts to App Thinning:

  • Bitcode: this is an intermediate representation for an app’s binary that is stored in the App Store and that is used to deliver an optimized version to a specific device. This should also make it possible for an app to support new processor capabilities, or compiler improvements, without any need for the developer to rebuild it.

  • Slicing: this addresses the requirement of including artwork for multiple resolutions in a universal binary, i.e., 2x and 3x artwork both for iPhone and iPad. Thanks to slicing, the App Store will include only the most optimized artwork for each device, e.g., and iPhone 6+ will only get 3x artwork, while an iPhone 6 will only get 2x artwork.

To take advantage of slicing, developers will just need to use Asset Catalogs. Besides enabling slicing based on display resolution, Asset Catalogs have been extended to allow developers to define alternate versions for any kind of asset, e.g. a 3D model or an audio file, and specify for each asset version for what kind of device they are to be used based on available memory, processor capabilities, GPU, etc.

Slicing will cut 30 to 40% off the size of an app.

  • On-demand resources: this will allow developers to exactly control when to download new assets. The key idea here is to tag individual assets, as well as asset collections during development, so they can be then identified and downloaded when necessary through the NSBundleResourceRequest class, which allows to inform the system when the resources associated with a tag are needed and when they can be disposed of.

When resources are needed, developers can call the beginAccessingResourcesWithCompletionHandler(_:) method providing a tag and a completion block. Interestingly, resources downloaded this way can be used just the same as any other resources bundled with the app, e.g., by using the usual pathForResource(_:ofType:), imageNamed(_:), etc. methods. When the on-demand resources are not required any more, they can be freed through endAccessingResources(), which leaves them available and marks them as purgeable in case the system runs out of space.

On-demand resources face the limitations inherent to the real world, where download bandwidth is limited, no interent connection might be available at all, or a download can fail. Therefore, Apple suggests adopting a few design patterns that can help making everything work in a smooth way, and follow appropriate policies as to how and when to access on-demand resources, checking download progress etc.

Interestingly, Xcode is able to simulate the App Store behavior with on-demand resources. So, when it installs an app to a device, it will not include on-demand resources, and will provide them only when required.

Debugging and Profiling

Xcode 7 introduces the Energy gauge for iOS apps to give developers a real-time view of energy consumption during app execution and help ensure that an app has no energy impact when idle and a low energy impact when in use. Additionally, whenever an anomalous report is spot, developers can jump right into Instruments from the gauge pane and profile their app.

Another new feature related with debugging is the Address Sanitizer, which is aimed at making it possible to detect any improper memory usage as early as possible. This usually leads to crashes that are difficult to analyze, since the crash itself happens at a time and place which is not usually related to the time and place where the incorrect memory usage happened. In such cases, Xcode does only provide a useless stack trace pointing to main with no further information.

A typical example is accessing some piece of memory after its deallocation: when the Address Sanitizer option is on, Xcode will stop right at the place where the program attempted to access the deallocated memory but, more importantly, also where the memory was freed in the first place. Address sanitizer is not only about memory, though. It will also detect heap buffer overflow or underflow, and it provides a generic undefined behavior sanitizer, which can help, e.g., with integer overflows and other cases of undefined behavior.

For those cases where Xcode cannot help to fix memory problems and developers face crash logs reported by users, Xcode 7 also improves TestFlight’s crash reports usability by integrating fully symbolicated crash logs in its Organizer window.

UI testing and code coverage

Xcode 7 improves support for unit testing by adding UI testing and code coverage.

UI testing in Xcode is based on the idea of recording the sequence of events that a human tester generates while using an app, and then replaying it to confirm that there are no issues. While the human tester interacts with the app, Xcode will translate all generated events in terms of calls to an API that can be then customized. The UI testing API is, according to Apple, defined in a way to be easily readable and easily modifiable. When a recorded test passes, it entails a kind of implicit validation. Indeed, to be able to carry a test through, all referenced UI elements, e.g., a button or a table row that you tap, must be in place. A more explicit validation is also possible using assertions that allow to check for the status of specific UI elements, e.g., images, label, etc.

LLDB Enhancements

LLDB has been improved in Xcode 7 on many accounts.

Now, it is possible to use named breakpoints. Names given to breakpoints need not be unique, so they actually work more like tags and allow developers to apply commands to groups of breakpoints based on their name, e.g. enabling, disabling, or deleting them.

Furthermore, it is now possible to define default breakpoints in ~/.lldbinit, which are available in any debug target. So, it is possible, e.g., to create a named breakpoint set called memory to set breakpoints on malloc and free and store it in ~/.lldbinit, so it is available in any of your targets, and disable it when needed by a simple command:

breakpoint set -n malloc -N memory
breakpoint set -n free -N memory
breakpoint disable memory

In Xcode 7, LLDB improves support for Swift 2 as well as Objective-C module support. Some of those improvements have a real impact mostly under the hood of LLDB, such as allowing it to avoid replicating module debug information, or C++ type information. This will both reduce the size of .dSYM files and improve compilation time.

Data formatting has been improved in a lot of ways, so now vector types get automatic data formatting for both Objective-C and Swift. Additionally, you can customize the way Swift types are presented just by writing Swift code.

Address Sanitizer support has been integrated into LLDB, so LLDB will tell you when a memory reference is invalid, but it can also be asked questions about memory, such as accessing the history of memory (memory history) and see where some piece of memory was allocated or deallocated.

LLDB now supports type lookup commands that provide a header-like representation of any type right in the debugger. So, you can type type lookup ErrorType to get a quick description of that type:

protocol ErrorType {
    var _domain: Swift.String {get}
    var _code: Swift.Int {get}
}

Xcode 7 LLDB also delivers improved support for Objective-C expressions, putting it on a par with Swift’s. In Swift it is possible to reference any symbol belonging to a framework and print it out on the console, e.g. p NSApplication.sharedApplication() will peek into your app’s NSApplication object and return the relevant info. This does not work automatically in Objetive-C because the LLDB Objective-C compiler has no visibility of method signatures or macros defined in SDK frameworks and most methods are implied to return a generic id type. Thus, you cannot run something like the following out of the box:

p NSMakeRect(0, 0, 10, 10)

But in Xcode 7 LLDB supports a new expr command which allows to pull in all the definitions that belong to a given framework, such as expr @import AppKit or expr @import UIKit, so the above becomes possible.

The new LLDB in Xcode 7 also improves Swift error support. First off, there is no need to wrap a method that may throw an exception in a try block. LLDB will automatically catch the exception and output an error variable that contains the thrown error. Furthermore, it is possible to set an exception breakpoint as with Objective-C. Executing:

br s -E swift

will make the debugger stop whenever the program is about to throw a Swift exception. Besides this, in Swift you can even stop on specific types of error. This is a feature not available with Objective-C that will allow you to stop only when a specific error type is thrown:

br s -E swift -O EnumError

Finally, in Xcode 7 Apple has published the API that controls in-process Swift formatting. This is based on four protocols:

Interface Builder

Among the most relevant changes introduced within Interface Builder in Xcode 7 are stack views and storyboard references.

Stack views are an abstraction built on top of auto layout constraints that allows UI designers to define relationships between views by nesting them together. A stack view can layout its subviews either horizontally or vertically and allows to easily control the way they align, distribute, and their spacing. Stack views make it easier to define layouts that can dynamically adapt to the device's orientation, screen size, and changes in the available space.

As mentioned, stack views use auto layout constraints under the hood, so it is possible to mix them with constraints. Apple is now recommending to start defining an app’s UI through stack views and only revert to constraints when more fine-grained control is required or when dealing with views that cannot be made into a stack view, such as a UITableViewCell.

Stack views do also support the specification of size classes, so you can for example define a stack view with a horizontal distribution axis when your device has a full width, and then add a size class to use vertical distribution axis when the device has a compact width, e.g., when another app is opened side-by-side.

Storyboard references are a new feature that aims to make it possible to refactor storyboard designs. This can be helpful when you have a storyboard which has grown in complexity and you wish to group related scenes out of it into a new, separate storyboard.

Creating a storyboard reference in Interface Builder is as easy as selecting the scenes you want to factor out, and then choosing Editor

Refactor to Storyboard. This will create a new storyboard and reference it from the original one.

Next Article in Series

The next article in the series will introduce Bitcode, a new intermediate binary representation for apps that will allow Apple to provide an optimized app version for the specific device where it is going to be downloaded.

About the Author

Sergio de Simone  is a software engineer. Sergio has been working as a software engineer for over fifteen years across a range of different projects and companies, including such different work environments as Siemens, HP, and small startups. For the last few years, his focus has been on development for mobile platforms and related technologies. He is currently working for BigML, Inc., where he leads iOS and OS X development.

 

At WWDC 2015, Apple introduced iOS 9. Although the new SDK does not introduce as many new or enhanced features as iOS 8, which included more than 4,000 new APIs, it does still provide a wealth of new functionality and enhancements. Along with the new SDK, iOS 9 is also marked by new developer tools to support some of its features, and new releases of Apple’s major programming languages, Swift and Objective-C.

This series aims at introducing all that is essential for developers to know about building apps for the latest release of Apple’s mobile OS. It comprises five articles that will cover what’s new in iOS 9 SDK, new features in Swift, Objective-C, and developer tools, and Apple’s new bitcode.
This InfoQ article is part of the series “IOS 9 For Developers ”. You can subscribe to receive notifications via RSS.

Rate this Article

Adoption
Style

BT