Category Archives: Xcode

Isolating Xcode Builds

I maintain an extensive array of automated builds with Jenkins. The automatic reporting of inadvertent build failures empowers me to stay much more on top of the quality of my own code, which is shared across many projects and targets many platforms and OS releases.

Unfortunately, I have frequently run into trouble with “false negative” builds. Builds which fail for perplexing reasons that I can usually only chalk up to “welp, something changed in Xcode.”

Sometimes the problem has seemed to be rooted in its finicky behavior with respect to paths that have spaces in them. Fine, I’ve removed all the spaces from my paths.

Other times, the problems have been much more nuanced, having to do with the problematic (I guess) sharing of cached data between builds. I don’t know how much of this should be chalked up to the fact that I’m building multiple projects at once, or that I’m building multiple problems of the same name, but with different dependencies and platform target. In any case, I have come to realize that the key to making sure my builds, you know, build when they should is to isolate each build as much as possible from the others.

To this end, over the years I have taken advantage of Xcode build settings such as SYMROOT, the setting that defines where your “Built Products” should be stored. But that only affects where the final products are saved. To make sure intermediate files that are used to build a product don’t get mixed and matched, I also override OBJROOT.

Overriding those two gets you a long way towards isolating a build from other builds that may have happened recently, or that may be happening right now. But, as it turns out, they don’t get you far enough.

Apple has increasingly moved towards some valuable changes in their approach to handling “cache” type data, including precompiled headers, header maps, module caches, etc. To the extent that Apple can use these caching strategies to enable faster builds, I’m all for it. But on my build server, it’s inevitably led to confusion and disarray.

Recently I’ve run up against confounding build errors that I can’t quite trace to specific problems. All I know is that “wiping out the Derived Data folder” solves it. Adding yet more build setting overrides to my build process also seems to solve some of the issues. For example, faced with a litany of precompiled header errors along the lines of:

fatal error: file 'BlahBlah.h' has been modified since the precompiled header 'WhooHah_Prefix-fmvtpvxgevrsamfytqmaabjnyjyx/WhooHah_Prefix.pch.pch' was built

I have found some relief by adding another override, this time for the SHARED_PRECOMPS_DIR. Recently, I ran up against a similar kind of failure, presumably related to the fact that I have started taking advantage of Apple’s support for “modules”:

fatal error: malformed or corrupted AST file: 'Unable to load module "[...]/DerivedData/ModuleCache/LQKN4K4Q4BR6/Foundation-1SPG61SLRK6SC.pcm": module file out of date'

That’s fine, but where is the “modules” equivalent of SHARED_PRECOMPS_DIR? It probably exists, though it’s not documented on the aforelinked build settings reference. Worse, since the advent of the DerivedData folder, it seems some of the claims in the build settings reference about default values are no longer true.

“Fine,” I thought, “how the heck do I override the Derived Data folder location altogether?” I don’t know why it took me so long to pursue this line of thinking. Perhaps my allegiance to the idea of saving effort through shared caching was too strong for my own good. When it comes down to it: I don’t mind that builds take a little longer or use more disk space, so long as they are an utmost reliable reflection of the current status of my source bases.

But how do you override the Derived Data folder location? If there is a build setting for it, then like the module caches folder, is evidently too new to be well-documented. Examining the build process in Xcode, it seems to be defined at a higher level than any of the other environment-variable based settings that can be observed in the build log e.g. for custom build phases.

I know you can set the Derived Data folder location in Xcode’s UI, but that, I assumed, only affects the builds that happen within the app. The brilliant idea finally dawned on me to check the xcodebuild man page, and what do you know?

-derivedDataPath path

Overrides the folder that should be used for derived data when performing a build action on a scheme in a workspace.

Since the vast majority, if not all, of the various cache and cache-like folders I’m trying to override are in fact located by default within the “Derived Data” folder, overriding just it could be the lynchpin that ensures my builds are isolated from one another.

I adjusted my build scripts to no longer override OBJROOT, CACHE_ROOT, or SHARE_PRECOMPS_DIR. Instead, they simply pass -derivedDataPath to xcodebuild with a suitably unique path:

xcodebuild -project MyProj.xcodeproj -scheme "MyScheme" -derivedDataPath "./MyCache"

You know what? Suddenly all my Jenkins builds are passing all their tests. Son of a gun.

Brent’s Feedback

I love Brent Simmons’s style of responding to my last post, in which I described a cover class for NSURLSession that makes is easier for me to adopt it gradually throughout my source base. Brent:

This is the right way to do it. The callers – including the unit tests – don’t have to know anything about the implementation, since the interface is the same. That’s just good programming.

That’s just good etiquette. When responding to somebody with whom you have a fundamental difference of opinion, lead with a compliment. Brent goes on to say:

It’s also not how I would do it in this specific case.

Brent argues that cover classes have their place when it comes to adapting APIs that are not native to the frameworks or language being developed in. But when there is no impedance mismatch, he says:

I’d rather just use a thing directly, rather than write a class that wraps a built-in class.

All good food for thought. I will add here that in the particular case of my “RSLegacyHTTPRequest” class, I decided to make it a subclass of the working title for my previously mentioned “RSSpiffyRequest,” which is the much less glamorous “RSHTTPSession.” RSHTTPSession is a subclass of NSObject, and happens to own a subsystem of objects that “don’t matter to you” but deeply involve NSURLSession. In fact, interacting with RSHTTPSession will feel a lot like interacting with NSURLSession.

The idea, longer term, is that clients of RSLegacyHTTPRequest will move away from that antiquated interface and towards RSHTTPSession. The argument for subclassing in this case is I like the pattern when it allows me to gradually move good logic upwards, from an antique class to a modern class. Is it awkward that it’s called RSHTTPSession, instead of RSHTTPSessionManager? Maybe. I’ll change it if things get weird.

So I’m doing things my way, adapting an antique class to the future by providing a cover class that translates an old-and-busted interface to NSURLSession, and doing things Brent’s way, by basing the future of my “spiffy” NSURLSession convenience classes on a base class that inherits from NSObject, provides a stable interface, but fully embraces and exposes the NSURLSession philosophy to its clients.

Same Tests, Different Class

I recently decided to tackle a long-postponed refactoring of my source base: to move from my own, custom CFNetwork-based “URL request” class, to something based on the modern NSURLConnection or NSURLSession classes from Apple.

When I first started writing networking code for OS X, NSURLConnection didn’t exist yet. If you wanted a class that approximated the convenience of NSURLConnection as we know it today, you had to write your own wrappers around the lower-level CFNetwork HTTP library functions. If you needed to have precise control over the loading of network resources from the web, you simply had to use CFNetwork (or the 3rd-party open-source libcurl library, which some folks did do!.)

When I acquired MarsEdit from NewsGator in early 2007, I wasn’t surprised to learn that Brent Simmons (the original author) had also implemented his own CFNetwork-based HTTP class: RSHTTPDownloader. I took a look at it and my own class, RSHTTPRequest, and ended up migrating the best parts of his with the best parts of mine, keeping the name I had grown accustomed to: RSHTTPRequest. (It was a great convenience that Brent’s Ranchero Software and and my Red Sweater adopted the same class-name prefix).

Fun fact: I actually worked briefly on the CFNetwork team at Apple, and learned the ropes of that somewhat-daunting, low-level API. Suffice to say, I was less scared off by CFNetwork than some people, but even I didn’t consider it to be perfectly simple to use. However, it worked well enough and when NSURLConnection debuted later in 2007, I found it somewhat wanting. I can’t remember the details but there were little things that I’d come to appreciate about having direct access to the “streams” and I lost that by moving to NSURLConnection. So I stuck with RSHTTPRequest.

Fast-forward more than seven years and I’m still on RSHTTPRequest. But now, it’s clearly to my detriment. Not only has Apple been improving NSURLConnection and the rest of the networking stack all this time, a couple years ago they introduced the all new NSURLSession, which makes the whole setup easier to use and more powerful at the same time. Capping off the incentives is the fact that new functionality such as background network loading sessions are essentially required if you want to make good use of recent technologies such as Share Extensions. In short, it’s a great time to switch to NSURLSession.

Just Switch to NSURLSession!

The only problem is I’ve spent more than seven years building a pretty complex network-oriented app around this one, I hesitate to say little anymore, this one disgusting evolution of what started out as a simple wrapper around CFNetwork’s HTTP loading mechanism. RSHTTPRequest has every manner of convenience method, special cases, not to mention subclasses covering highly specialized networking operations such as POST’ing HTTP forms, communicating with most blogging APIs on the planet, etc. You get the idea: I can’t just switch to NSURLSession. So what am I going to do?

I’m a very paranoid person when it comes to code, and it soothes me to take small, predictable, measurably safe steps when it comes to situations like this. I already have a number of unit tests on RSHTTPRequest that verify its behavior to a reasonable extent. The basics are covered, and as I’ve discovered and addressed bugs over the years, I’ve usually taken the time to add unit tests covering the nuances. So to be perfectly clear, the main impediments to my switching to NSURLSession are:

  1. The interface to NSURLSession is totally different from my custom class.
  2. The default behavior of NSURLSession is totally different from my custom class.

So I could hunker down for a long weekend, write a new NSURLSession-based helper, RSSpiffyRequest, and then change every single line of code that deals with RSHTTPRequest to instead use the pertinent methods on the new class. One problem with this approach is that I have to come up with the all new RSSpiffyRequest interface from scratch, before I change a single line of code. The other problem is even if I come up with the perfect interface for my new class, I’ll inherit all the unpredictably different behaviors of NSURLSession. Things will randomly not work. Crashes will probably happen. It will suck.

The only way forward, to my paranoid mind, is to find a way to slow down the transition so that fewer parts are changing at once. Since RSHTTPRequest already satisfies a contract with countless clients, and because it’s already covered by a moderate number of unit tests, the safest way forward is to change RSHTTPRequest so that it’s based on NSURLSession.

But hold on, that’s too fast for me, too. I don’t want to reimplement RSHTTPRequest’s whole interface at once, hold my breath, and hope that all the code still works. Instead, I need a new class that implements the interface of RSHTTPRequest, can be tested like RSHTTPRequest, and can be moved to by client code gradually, as the expected behavior is confirmed.

Parallel Request Classes

The approach I decided to take is to add a new class, RSLegacyHTTPRequest. The name is future-proofed: the presence of the word “Legacy” in the name is to remind me that it’s not the end-all be-all NSURLSession subclass. It’s not the ideal, convenient networking object that should be used across my source base. Instead, it’s the nasty, pragmatic, full-of-history class interface of RSHTTPRequest that happens to be implemented on top of NSURLSession.

This gives me the freedom to willy-nilly switch client code from RSHTTPRequest to RSLegacyHTTPRequest, just to see what happens. A great place to start was in the RSHTTPRequest unit tests class I mentioned. It currently verifies the behavior of RSHTTPRequest for most all niggling network details I’ve encountered over seven years. I switched it from testing RSHTTPRequest to testing RSLegacyHTTPRequest by simply adding this to the top of the test file:

#define RSHTTPRequest RSLegacyHTTPRequest

Boom! Everything fails. That’s a nice start, and makes for an easy challenge to chip away at. Pick a failing unit test, and make it work. In my case this involved discovering how to simulate or approximate the interface of the old RSHTTPRequest, but on top of NSURLSession. Slowly but surely, I came to a point where I had a new RSLegacyHTTPRequest class, completely based on NSURLConnection, that passes all my existing tests.

I was far from done. I have other classes that use RSHTTPRequest, and themselves have unit tests of their own. I pulled a similar trick to uncover other unit testing edge cases that should have been in RSHTTPRequest, but weren’t. I was beefing up my test class, in some cases even finding residual bugs from my old implementation.

I got to a point today where I realized I had a more-or-less “fully” functional RSLegacyHTTPRequest class, but I am still not ready to abandon RSHTTPRequest. I have other clients to meander through, verifying that they behave as expected when switched over to the new class. In the mean time, I was stuck wondering whether the unit tests, those golden unit tests, should be left testing the old RSHTTPRequest or testing the new RSLegacyHTTPRequest? Answer: they’re both in use, so both should be tested.

Multi-Class Unit Tests

Finally we get to the namesake of this article’s title: how do I use the same precious collection of unit testing code but apply it to two (or more!) classes that happen to share the same interface? The answer is to subclass. When you implement and run unit tests in an Xcode project, the testing system looks at runtime for any classes in the test bundle that “have methods that start with -test”. What this means is that, if you wanted to, you could redundantly run all the unit tests in one of your test cases twice simply by subclassing it and leaving the subclass empty. If “MyTests2” is a subclass of “MyTests”, then at runtime, it’s going to find and execute all the tests in each of the classes, which will happen to be exactly the same tests.

For my situation, I want to run all the tests twice, but I want to run them on instances of different class. I decided to accomplish this by making some modest edits to the test class, replacing every alloc/init pair for RSHTTPRequest:

[[RSHTTPRequest alloc] init...]

With a bottleneck method that instantiates the class from an overridable Class object:

- (Class) classForHTTPRequestInstances
{
	return [RSHTTPRequest class];
}

- (RSHTTPRequest*) requestForTestingWithURL:(NSURL*)theURL
{
	return [[[self classForHTTPRequestInstances] alloc] init...];
}

I then added a new unit test class called “RSLegacyHTTPRequestTests”, which merely implements -classForHTTPRequestInstances to return RSHLegacyHTTPRequest. Now when I build and run unit tests, every single, painstakingly collected unit test gets run twice, once for each of the super-important URL request wrapper classes in my framework.

Over time, hopefully over a short period of time, I’ll move away from RSHTTPRequest to RSLegacyHTTPRequest. And then, hopefully over a similarly short period of time, I’ll start moving to RSSpiffyRequest. All the while, however, I’ll rest easy at night, knowing that to a very great extent, all the functionality I’ve come to expect over years of developing this code is being constantly confirmed by this glorious set of unit tests.

Product Packaging Oversign

For a long time I have used a custom script phase to deliberately code sign all the bundles, helper tools, frameworks, etc., that are bundled into a final shipping product. The idea behind this approach was to overcome limitations in Xcode’s built-in code signing flags, which e.g. made it difficult to be sure that subsidiary projects would be built with the same code signing identity.

Recently I started looking at the possibility of switching to Apple’s relatively new “Code Sign On Copy” option for Copy Files build phases that involve code. For example if you’re copying files to a Frameworks, Plugins, or similarly obvious target for code resources, a friendly checkbox appears to offer code signing “as it’s copied in.”

Screenshot showing code sign on copy for copy files phase.

Xcode’s default code signing behavior gets some things right: for example, it takes care to preserve the metadata and entitlements of the original code signing, if any. This means that subsidiary product that e.g. are aware of specific sandboxing rules that should be applied to them can sign themselves as part of their build process, and the “Code Sign On Copy” action later will only update the identity associated with the code signing.

But I noticed a problem which relates to my recent obsession with script phase performance. The problem is that Xcode’s default code signing occurs too often. In fact in my projects, every single time I build, it re-signs every code object that had been copied, even though it hasn’t changed. This isn’t a big deal for one or two small frameworks, but for an app with dozens or hundreds of code objects, it becomes a noticeable time lag every time you rebuild to test a small fix.

The specific issue I discovered boils down to:

  1. Having entitlements for your target. E.g. being sandboxed.
  2. Modifying the Info.plist file in a build phase. E.g. to update the build number for the bundle.

If your target meets these criteria, then by my estimation Xcode will resign all the “Code Sign On Copy” files every time you build, regardless of whether they’ve changed. I reported this as Radar #19264472. Until Apple fixes it, the only workarounds I know are to suck it up and wait out the code signing every build, stop modifying your Info.plist, or go back to a manual code signing script that can take finer care about how and when to sign subsidiary code.

Explicit Requirement Satisfied

If you do any fine-tuned customization to your app’s code signing “designated requirement,” you may come across situations where the code appears to be signed correctly, but codesign verification nonetheless yields a cryptic, terse failure message:

./Your.app: valid on disk
./Your.app: does not satisfy its designated Requirement

This problem is pretty insidious, because the failure of an app to meet its designated requirement does not actually prevent you distributing it and having users run it. The code is still signed by you, it just doesn’t identify itself to the code signing system in such a way that it will be considered trusted by the system as being “itself.” This is bad.

How bad? The most likely to affect your users if the app uses the system keychain at all to store secure data. Even data placed in the keychain by the app itself will be denied to the app unless the user approves of the access. Worse, even if the user approves the access with “Always Allow,” the system will continue to prompt the user each and every time it tries to access the data.

The reason for the failure is that the “designated requirement” serves as a test of identity for your app. If your app doesn’t meet that test, the system assumes you no longer have any business accessing the data that you previously placed in the keychain. So an app that starts out not even meeting its own designated requirement is invalid from the start. We need our apps to meet their own designated requirements.

For most apps this is a no-brainer: just let the code signing system provide a default designated requirement. Typically, the default asserts that the bundle identifier and certificate signing chain used when signing the app are later the same. In short: unless an app is signed with the same certificate and has the same bundle ID as it had when it stored the data, it will not be allowed to access the data now.

Why customize the designated requirement? The reasons are probably too varied for me to imagine, but one common scenario that happens to affect me is one in which two different bundle IDs may effectively refer to the same “app.” For example instances of MarsEdit may possess either the “com.red-sweater.marsedit” or “com.red-sweater.marsedit.macappstore” identifiers, depending upon whether they were built for the Mac App Store or for direct sale. Another scenario where a custom designated requirement would be appropriate is if an application changed developers and either of the old developer’s and new developer’s certificate is meant to be considered legitimate. If you’re curious, poke around at the designated requirements of some of the apps on your Mac:

codesign -d -r- /Applications/Google\ Chrome.app
designated => (identifier "com.google.Chrome" or identifier "com.google.Chrome.canary") and certificate leaf = H"85cee8254216185620ddc8851c7a9fc4dfe120ef"

In this case it appears that Google wants to confirm that a very specific certificate was used to sign Chrome, but wants the pre-release “Canary” builds to be treated as authentic copies of the app, even though they have a different bundle identifier.

Customizing the designated requirement can lead to a pretty lengthy specification string that can be hard to process mentally. When such a string produces an app that doesn’t meet its own requirement, it can be hard to guess at which specific clause is failing. The codesign tool’s error message is of no help, but you can take advantage of a useful option related to the tool’s verification functionality. Pass “-R” along with a specific requirement string, and it will be evaluated separately from the designated requirement. The long and short of this is you can feed the codesign tool pieces of the larger requirement string, and see which ones pass and fail. To provide a string right on the command line, start it with an “=”:

codesign -vv -R '=identifier "com.apple.mail"' /Applications/iTunes.app 
/Applications/iTunes.app: valid on disk
/Applications/iTunes.app: satisfies its Designated Requirement
test-requirement: code failed to satisfy specified code requirement(s)

In this contrived case, we ask codesign to confirm that iTunes has Mail’s bundle identifier, and of course it fails. When we instead provide a requirement string that makes sense…

codesign -vv -R '=identifier "com.apple.iTunes"' /Applications/iTunes.app
/Applications/iTunes.app: valid on disk
/Applications/iTunes.app: satisfies its Designated Requirement
/Applications/iTunes.app: explicit requirement satisfied

…the codesign tool confirms that it passes.

In the past I have been at a loss for how to more easily debug designated requirements issues. I only discovered the “-R” option today, but I’m sure it will be a great help in the months and years to come.

Speeding Up Custom Script Phases

Some Xcode projects use a handy feature for extending the build process called a Run Script build phase. These build phases can be added to the linear list of steps that Xcode steps through when building a target, such that custom tasks such as preparing dynamically generated source code, verifying build results, etc., can call be done as part of Xcode’s standard build routine.

A problem you might run into is that a long-running script phase can be a real drag to wait through every single time you build. You can work around this problem in a few ways, depending on what makes sense for your project. Two of the simplest options are:

  1. Check the box to run the script only “when installing.”
  2. This is particularly handy if the stuff that’s happening in the build phase really doesn’t need to be there until the final release build, or if you are willing to manually perform the steps during development.

  3. Add logic to your build phase script to detect the build configuration, and either perform a more expedient version of the task, or skip it altogether. For example, a build phase that does laborious profiling of your finished product may not need to be done on “Debug” builds, so you could add a clause to the script:
    if [ ${CONFIGURATION} == Profiling ] ; then
    	echo "Running a very long profiling task!"
    	...
    	echo "Finished running a very long profiling task!"
    else
    	echo "Skipping long profiling task! Whoo!"
    fi
    

    (Note: you don’t have to use bash for your shell script phases. In fact, you can run whatever interpreter you like. I typically use Python, but used bash here as a canonical example).

These tricks work out fine when a script phase is clearly only needed under special circumstances, but what about script phases that have to be done every time you build, rely upon files that may change over time, and take a considerable amount of time to finish? For this we can take advantage of another nuanced feature of Xcode script phases, which is the ability to specify arbitrary input and output files for the script. I think it’s time for an illustrative screenshot:

Screenshot of a configured Xcode script phase

Here’s the low down on the impact of specifying input and output files with script phases in Xcode:

  1. Lack of modification to any of the listed input files encourages Xcode not to run the script phase. Hooray! Fastness!
  2. Non-existence of any listed output file compels Xcode to run your script phase.
  3. The number of input and output file paths is passed to the script as ${SCRIPT_INPUT_FILE_COUNT} and ${SCRIPT_OUTPUT_FILE_COUNT} environment variables.
  4. Each input and output path is passed as e.g. ${SCRIPT_INPUT_FILE_0}, ${SCRIPT_OUTPUT_FILE_1}, etc.

In practice, what does this mean when you go looking to speed up your script phase? It means you should:

  1. List as an input every file or folder that may affect the results of your script phase.
  2. List at least one output, even if your script doesn’t leave any reliable artifacts.

One frustrating bug I should point out here is that Xcode (as of at least Xcode 6.0 and including 6.2 betas) is not as attentive as it should be about changes to the the input and output file lists. If you make changes to these lists, rebuild several times, and don’t see the efficiencies you expect being applied, you should close and reopen your Xcode project document. It seems to cache its notion about script phase dependencies, and will stubbornly stick to those rules until forced to re-evaluate them from scratch. I reported this to Apple as Radar #19233769.

Referring back to the screenshot above, you can that in this contrived example I have listed two input “files,” but in this case they are actually directories. This is to illustrate that if you list a directory, Xcode will trigger a re-running of your script phase whenever any shallow change occurs in that directory. For example, if I add, delete, or modify any files in ImportantStuff”, the script will run on the next build. However, if I modify a file within “ImportantStuff/Goodies”, it will not trigger the script to run because Xcode does not monitor for changes recursively.

You will also see that I’ve gone to the trouble of artificially adding a bogus file to the derived files folder, indicating the script has run. That has the effect of causing a “clean” of the project to wipe out the artificial file and thus cause the script phase to run again even though none of the input files may have changed. If I wanted to ensure that the script phase is skipped as aggressively as possible, I could provide e.g. a path to an output file that is guaranteed to exist, such as a stable file in my project like “$(SRCROOT)main.m”. Because the designation “Output File” in this case is only a hint to the Xcode build system, you don’t have to worry (and can’t expect) that the file will be created or altered unless you do so yourself in the script. This feels a little dodgy to me though, because Apple could choose to change the behavior in the future to e.g. imply that “clean” should delete all listed output files for a script phase.

Script build phases are a woefully under-documented, incredibly useful component of the Xcode build system. They are especially useful when they run blazingly fast or are skipped completely if not needed. I hope this information gives you the resources you need to take full advantage of them.

Xcode Consolation

One of the best things any Mac or iOS developer can do to improve their craft is to simply watch another developer at work in Xcode. Regardless of the number of years or the diversity of projects that make up your experience with the tool, you will undoubtedly notice a neat trick here or there that changes everything about the way you work.

If you were sitting in my office on a typical workday, looking over my shoulder, that would be a little creepy. But one thing you’d notice that differentiates me from many others is the amount of time I spend typing into the Xcode debugger console.

In my experience, other developers fall into three groups when I mention that I use the console almost exclusively when interacting with the debugger:

  1. Those who share this approach. We exchange high-fives and move on.
  2. Those who appreciate the console for occasional tricks, but rely mostly on the variables view.
  3. Those who have never heard of or noticed the console.

Let’s assume for the sake of argument that you fall into group 3. You can show the console while debugging any process by selecting View -> Debug Area -> Activate Console from the menu bar. In fact, I do this so often that that the keyboard shortcut, Cmd-Shift-C, is completely second-nature to me.

Xcode window with console highlighted.

In fact I find the console so useful that it’s not unusual for me to hide much of the other junk, so I can have a mainline connection to the debugger.

Xcode window with large console area

So let’s go back again to the uncomfortable assumption that you’re sitting in my office, looking over my shoulder. What would you see me do in the console? All manner of things: For one thing I rarely click those visual buttons for stepping through code. Instead, I use these terse keyboard aliases, inherited from the bad old Gdb days. In lldb, these all come as standard abbreviations of more verbosely named commands:

  • n – step over the next line of source
  • s – step into the first line of source of a function
  • ni – step over the next instruction of assembly code
  • si – step into the first instruction of a function
  • c – continue
  • fin – continue until return from current stack frame

Those are the basics, but another trick, I believe it was called ret in Gdb, comes in handy often:

  • thread return – return immediately from the current stack frame

You could use this if you are stuck in some function that is crashed, for example, but you know that returning to the caller would allow the process to continue running as normal. Or, you could use it to completely circumvent a path of code by breaking on a function and bolting right out, optionally overriding the return value. Just to pick an absurd example with flair, let’s stub out AppKit’s +[NSColor controlTextColor]:

(lldb) b +[NSColor controlTextColor]
Breakpoint 1: where = AppKit`+[NSColor controlTextColor], address = 0x00007fff8fb05572
(lldb) break command add
Enter your debugger command(s).  Type 'DONE' to end.
> thread ret [NSColor redColor]
> c
> DONE
(lldb) c

Here we have opted to break on every single call to controlTextColor, returning to the caller with a fraudulent color that is apparently not consulted by the label for this popup menu in MarsEdit:

MarsEdit screenshot with labels drawn in red

In fact, mucking about with system symbols is one of the great tricks of the console, and lldb’s built-in “breakpoint” command brings with it superpowers that can’t be touched by Xcode’s dumbed down GUI-based controls. For example, what if we wanted to set a breakpoint that would catch not only +controlTextColor, but any similar variation? Using lldb’s support for regular expression breakpoints, it’s a snap:

(lldb) break set -r control.*Color -s AppKit
Breakpoint 1: 20 locations.

Here we request that a breakpoint be set for any symbol in the AppKit framework that contains the lower-cased “control,” followed by anything, then capitalized “Color.” And lldb just set 20 breakpoints at once. To see them all, just type “breakpoint list” and you’ll see all the variations listed out as sub-breakpoints:

(lldb) break list
Current breakpoints:
1: regex = 'control.*Color', locations = 20, resolved = 20, hit count = 0
  1.1: where = AppKit`+[NSColor controlTextColor], address = 0x00007fff8fb05572, resolved, hit count = 0 
  1.2: where = AppKit`+[NSDynamicSystemColor controlTextColor], address = 0x00007fff8fb05670, resolved, hit count = 0 
  1.3: where = AppKit`+[NSColor controlBackgroundColor], address = 0x00007fff8fb1465d, resolved, hit count = 0 
  1.4: where = AppKit`+[NSDynamicSystemColor controlBackgroundColor], address = 0x00007fff8fb1475d, resolved, hit count = 0 
  (etc...)

One major shortcoming of all this goodness is Xcode has a mind of its own when it comes to which breakpoints are set on a given target. Anything you add from the lldb prompt will not register as a breakpoint in Xcode’s list, so you’ll have to continue to manipulate it through the console. You can enable or disable breakpoints precisely by specifying both the breakpoint number and its, umm, sub-number? For example to disable the breakpoint on +[NSColor controlBackgroundColor] above, just type “break disable 1.3”.

Regular expressions can be very handy for setting breakpoint precisely on a subset of related methods, but they can also be very useful for casting about widely in the vain pursuit of a clue. For example, when I’m boggled by some behavior in my app, and suspect it has to do with some system-provided API, or even an internal framework method, I’ll just throw some verbs that seem related at a breakpoint, and see what I land on. For example, it seems like some delegate, somewhere should be imposing this behavior:

(lldb) break set -r should.*:
Breakpoint 5: 735 locations.

That’s right, set a breakpoint for any ObjC method that includes the conventional “shouldBlahBlahBlah:” form in its selector name. Or if you are really at your wit’s end about an event related issue, why not capture the whole lot and see where you stand?

(lldb) break set -r [eE]vent
Breakpoint 10: 9520 locations.

Sometimes I’ll set a breakpoint like this and immediately continue, to see what I land on, but often I’ll use lldb’s breakpoint system as a quick way of searching the universe of symbol names. After setting a breakpoint like the one above, I’ll do a “break list” and then search through the results for other substrings I’m interested in. This often gives me a clue about the existence of methods or functions that are pertinent to the problem at hand.

I’ve scratched the surface here of all the powerful things you can use Xcode’s debugger console for, but I hope it has brought you some increased knowledge about the tools at your disposal. If you’ve never used the console before, or only use it occasionally, perhaps I’ve pushed you a bit farther down the path of having its Cmd-Shift-C shortcut feel like second-nature to you as well.

Share Extension Iterations

One of the many big surprises at WWDC this year was the news that iOS 8 and Mac OS X 10.10 would support app extensions, which give developers a variety of new ways in which data and services can be shared between apps.

One of these new types of extension, called a Share extension, essentially allows apps that generate user data provide content to apps that publish user data. As a developer whose main app, MarsEdit, is a blog-publishing tool for the Mac, you can imagine how this might be of interest to me.

The first thing I noticed upon digging into app extension development is that it’s fairly fiddly to get set up, and the default build, run, invoke iteration loop is fraught with administrative overhead.

First of all, when you add a Share extension target to an existing project, you’ll discover that the new target can’t be run directly. To test or debug it, you have to invoke the Share extension from some app that supports … sharing. There are many default apps on the Mac and iOS that support sharing data of various formats. For example on Mac OS X the system Preview app makes a canonical sharing source for photo data, while the Notes app is one of many suitable test apps for sharing text. If you don’t do anything special after adding a Share extension target to your project, the auto-generated Xcode scheme will be configured to ask every time you run:

ChooseAnApp

This will get old fast, and 99% of the time what you’ll want to run is exactly the same dang app you just ran. Luckily, this is easily addressed in the scheme settings, where you can change the “Executable” selection in the “Info” section of the “Run” tab from “Ask on Launch” to a specific application of your choosing.

OtherApp

That’s all well and good, but you still have to go through the tedious task of selecting some suitable content in the target app, clicking the share button, and choosing your extension from the list, before you even have the luxury of examining your own code’s behavior.

Wouldn’t it be great if you could make changes to your app extension’s appearance or behavior, click Run, and moments later be looking at your Share extension’s UI without having to do anything else? Good news: you can, and I’m about to explain how to achieve it for both Mac and iOS targets.

Automatic Invocation

The problem with all the targets on your Mac or iOS that may or may not support sharing pertinent data to your extension, is you have to walk them through the process of invoking you. When you’re deep into the development of a particular aspect of the user interface or mechanical behavior of your extension, what you really want is to repeatedly invoke the extension with the same, predictable kinds of data. Luckily, it’s possible on both Mac and iOS platforms for a host app to invoke sharing extensions programmatically, so you just need to choose a Run target that will predictably invoke your extension upon launching.

The only way I know to guarantee this is to write your own code that invokes the extension, and put it in a custom debugging-purposed target, or else put it into your main app as conditional code that only runs when building Debug variants and when prompted to take effect. I can imagine a sophisticated version of this approach involving a multi-faceted extension-debugging target that would be capable of fast-tracking extension invocation for a variety of data formats. But for the simplest solution, I recommend adding the ability to invoke your extension to the very app that hosts it. Then your simple test mode behavior will always coexist in the same source base as your extension code.

The way I approached this was to add an environment variable, “RSDebugAppExtension” to the scheme configuration for my app extension, which is also configured now to target the main app as its Executable target. So when I build and run the app extension scheme, may main app runs with these environment variables set:

Screenshot 11 24 14 3 12 PM

Now in the main app’s applicationDidFinishLaunching: method, I just have to add the appropriate code for invoking the app extension’s UI. Without the platform-specific voodoo, it looks something like this:

#if DEBUG
	// Check for flag to invoke app extension
	NSDictionary* env = [[NSProcessInfo processInfo] environment];
	NSString* appExtensionDebug = [env objectForKey:@"RSDebugAppExtension"];
	if (appExtensionDebug != nil)
	{
		// RUN MY EXTENSION
	}
#endif

The #if DEBUG just ensures that I will never inadvertenly ship this code in a release version of my app. The environment variable ensures I won’t be plagued by my extension’s UI appearing whenever I’m working on other aspects of my app besides the extension.

Now we just have to dig into the specifics of how to “RUN MY EXTENSION.” I’ll show you how that works for both Mac and iOS based Share extensions.

Invoking a Mac-based Share Extension

If you’re working on a Mac-based Share extension, the key to invoking it at runtime is to enlist the help of the NSSharingService infrastructure. You simply ask it for a service with your identifier, and ask it to “perform.”

NSString* serviceName = @"com.red-sweater.yeehaw";
NSSharingService* myService = [NSSharingService sharingServiceNamed:serviceName];
[myService performWithItems:@[@"Hello world"]];

Now when I build and run with the aforementioned environment variable set up, it pops up my Share extension, pre-populated with the text “Hello world.”

Invoking an iOS-based Share Extension

Unfortunately, iOS doesn’t support the same NSSharingService infrastructure that the Mac has. This seems like an area where we might be lucky to see more unification over the years, but for the time being the iOS notion of a sharing service is tied up with the existing “Social.framework” and its SLComposeViewController class. This is the interface that is supposed to be used to invoke a sharing panel for Facebook, Twitter, Tencent Weibo, etc. And luckily, although I don’t believe it’s documented, you can also pass in the extension identifier for your custom Share extension to instantiate a suitable view controller for hosting your extension:

NSString* serviceName = @"com.red-sweater.yeehaw";
SLComposeViewController* myController = [SLComposeViewController composeViewControllerForServiceType:serviceName];
[myController setInitialText:@"Hello World"];
[[self navigationController] presentViewController:myController animated:YES completion:nil];

You can see the basic gist of it is similar to the Mac, but you have to configure the view controller directly as opposed to providing a list of arbitrary input values. Also bear in mind that because the iOS-based solution above relies upon [self navigationController] being non-nil, you’ll need to add the special debugging code at a point in your app’s launch process when this is already set up, or else find another way of ensuring you can meaningfully present view controllers to your app’s main window.

Going Further

Notice that I hinge all the invocation on simply whether the RSDebugAppExtension environment variable is non-nil. Basically while I’m debugging I have to go in and change the code in applicationDidFinishLaunching to invoke the extension in the way I want. This works OK for me at least at this stage, but I can imagine down the road wanting to be able to fine-tune the behavior of how the extension is invoked. For this purpose, why not encode into the value of the environment variable itself certain clues about how to invoke the extension? It could specify for example what text should be passed the extension, or other configuration as desired.

My intent in sharing this blog post is both to point out some potentially time-saving tricks that will help those of you developing Share app extensions, but also to encourage you to look for creative ways to cut out the tedious aspects of whatever you work on. When all is said and done, the few monotonous steps during each iteration of work on a Share extension probably don’t add up to all that much in sheer time, but they take a lot of the joy and immediacy out of development, which frankly puts me in a bad mood. Clicking Run and seeing my work, including my latest changes, pop up instantly on the screen makes me feel a lot happier about my job.

Burn After Releasing

I am pretty diligent about following up on crash reports, probably because when it comes down to it, chasing crashes is one of the funner aspects of software development to me. Sure, when I’m hours into a frustrating problem and can’t make heads or tails of why something’s blowing up, it’s exhausting, and I wish to hell I could simply find the solution, but upon finally unwinding the riddle of a failure, it’s all those hours of toil that pay back dividends as the thrill of success.

Recently I had an odd MarsEdit crash report come in with a brief but ultimately very meaningful comment attached to it:

“I just updated a post with a PDF embedded from OneDrive.”

I love it when customers take the time to write something about the circumstances surrounding a crash. Often even a little clue can be enough to lead to the unique series of steps that will ultimately reproduce the problem. In this case though, I was confused. I know OneDrive is Microsoft’s cloud storage solution, but is the customer uploading a PDF from their mounted OneDrive, or … ?

Luckily the customer in this case also left an email address, so I got in touch and, after a few rounds of zeroing in on the meaning of the expression “embedded from OneDrive,” I learned that the issue was specifically to do with pasted HTML source code that Microsoft offers to customers who wish to literally embed a OneDrive document into another web page.

So I created a OneDrive account, added a PDF document to my storage, copied the “embed code” for the item, and pasted it into a new MarsEdit post. To my great surprise and satisfaction, when I pressed Send and published the post to my blog, MarsEdit crashed with exactly the same stack trace as the customer had submitted.

Well, I’ll be darned.

Pointing The Finger

The stack trace in this case was pretty cryptic, and implied that a private Apple class, NSURLConnectionInternal, was crashing while trying to message what I could only assume was its delegate. Here’s the gist of the very tip of the crashing thread’s trace:

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0  libobjc.A.dylib	objc_release
1  libobjc.A.dylib	AutoreleasePoolPage::pop(void*)
2  com.apple.CFNetwork  -[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:]
3  com.apple.CFNetwork	-[NSURLConnectionInternal _withActiveConnectionAndDelegate:]

Usually, when you see something like this where a thread is crashing while trying to release an object, the first thing to suspect is that you’ve screwed something up. Probably by over-releasing some object or neglecting to nil-out a delegate attribute when one of your objects is destroyed. But in the case of logs like this where the crash occurs with a backtrace that is separate from your own code’s control (it’s a run loop callback to Apple’s own networking code), it can be hard to trace it back to specific code in your app. In this case, I can tell by the NSURL clues that a network request is probably being serviced, but which one? And which object was its delegate? Luckily, the clue about OneDrive had led me to a working test case, so I could dig into this question with more care.

The first step I like to take is to hopefully separate the crashing issue from my own app’s code, by creating a stripped-down test app that exhibits the problem. If I couldn’t achieve that, then the bug probably did rest somewhere in MarsEdit, and if I could create such a test case, then the problem of poking at it to deduce what is going wrong is made much simpler.

I created a new document based application whose document windows possess a single WebView. When a new document is created, the document does one thing: load one of those OneDrive embedded documents as the HTML content of the view. Armed with this test app, I was able to create new WebView instanced with the presumably problematic HTML code, and observe the behavior of each WebView in isolation from other junk that might have been going on in a more complex app such as MarsEdit.

The only problem was that my test app didn’t seem to exhibit any problems. I could load 10, 20 WebViews with the OneDrive embed code in it, and they all ran like butter. Damn it, there was no bug here! Until, that is, I deigned to close one of those windows. Blam! The test app crashes, yielding an identical stack trace to the one provided by my customer and reproduced in MarsEdit.

It started to make sense: when you publish a post from MarsEdit, the default setting is to also then close the window associated with that post. The reason the customer experienced the crash after sending the post to their blog was only because that happened to correlate with MarsEdit subsequently closing the window, and thus destroying the WebView that had held the OneDrive embed content.

Whose Zombie Is This?

Armed with a simple test case that reproduces the bug at will, the first thing I did was to enable Apple’s built-in facility for debugging so-called “zombie” objects. These are perfectly named because they are objects that have been deallocated but which some code within your app treats as though they were still alive. When you message a zombie object, the behavior is unpredictable because all the data that had been associated with the object is now correlated with whatever other use the system has found for that area of memory. Xcode has a convenient checkbox that makes it easy to turn on zombie detection. Just open the scheme editor and look for the Diagnostics tab under the Run configuration:

Screenshot 11 6 14 5 25 PM

This option instructs the Objective-C runtime to abstain from completely deallocating objects. In doing so, it transforms deallocated objects into a special kind of placeholder object that can detect when it has been messaged, and scream to high hell about it. When I run with zombie objects enabled, and reproduce the crash, I also see this message in the console log:

*** -[WebView release]: message sent to deallocated instance 0x6080001273a0

Ah ha! So the object in question, the one being delegated to by NSURLConnection, is probably the instance of the WebView itself. But, I don’t set a WebView as a delegate of any NSURLConnection, and certainly this simplified test case doesn’t. So it must be WebKit itself that is setting itself as an NSURLConnection’s delegate. Not my problem, I can file the bug and move on … or can I?

Going The Extra Mile

This is where the open-sourced nature of WebKit is both a blessing and a curse. If this issue had been revealed to exist somewhere deep within AppKit, or any of Apple’s other closed-source frameworks, I most certainly would have thrown up my arms, filed a bug, and hoped for the best. But Apple’s WebKit framework is something I can download, build, and debug. Sure, it takes nearly all day to build, and there is a steep learning curve to debugging it, but why did I become a software developer if I’m not up for a challenge?

Since I knew that the issue at its core appeared to be the over-release of an object, specifically of the WebView, I moved up from the basic utility of zombie objects to the high-octane “Zombies” flavored analysis configuration of Apple’s Instruments tool. Like the runtime flag we set earlier in Xcode, this makes it easy to detect attempts to message zombie objects, but it also goes a step further by correlating that knowledge with a recorded history of a given object, and all the memory-management related manipulations of that object.

Simpler

The tail end of a very long table shows the running retain count for an object, in this case the WebView itself, as well information about which library, method, or function was responsible for the call that affected the object’s memory management status.

To make a long, long, long, long, story very short: I used Instruments and its “pairing” functionality, which lets you hide balanced pairs of retain/release calls so that you are left with a more manageable subset of calls to examine and scrutinize. After scratching my head over this for hours and not making much headway, I finally came upon a specific call stack that had a very suspicious heritage. I confirmed through Instruments and then by direct examination of WebKit source code, that the WebView instance in question was in fact retaining and then autoreleasing itself as part of its dealloc method.

In this era of ARC, some of you may not be so intricately familiar with Cocoa memory management to see at a glance why that’s a very bad thing. Here it is a nutshell:

  1. By the time an object’s dealloc method is done running, the object is gone. I mean, literally gone, or else being managed as a zombie object for debugging purposes.
  2. An object can be retained and released as much as you like, but if you’re already in the midst of dealloc’ing the object, it won’t make a bit of difference.
  3. Autoreleasing an object postpones release until a later time, when the active autorelease pool is released.
  4. Thus, autoreleasing an object in the midst of being dealloc’d guarantees that it will later be sent a release message. Oops, that would be bad. It could even cause a crash like the one we’re seeing…

How in the heck does WebView manage to autorelease itself as a consequence of dealloc’ing itself? And what unique relationship does that possibility have to the embedding of Microsoft OneDrive documents? I’ll try to be as brief as possible:

Microsoft’s OneDrive support installs JavaScript callbacks that run on a periodic basis, constantly fetching data from Microsoft’s servers via xmlHTTPRequest. The calls are made with such frequency that, especially while an embedded document is in the process of loading, there’s a good chance that closing a WebView and dealloc’ing it will catch Microsoft at a time when it thinks sending such a request is a good idea. The process of cleaning up the WebView has a side-effect of cleaning up the JavaScript runtime environment, and callbacks such as Microsoft’s might get one last chance to send a network request.

Sending the request would be fine, except for WebView’s own conscientious behavior which takes care to retain and autorelease itself whenever a new batch of network requests is made on its behalf. This guarantees that the WebView won’t disappear while an open request is running. But of course, it can’t make that guarantee when the WebView is in the process of being destroyed.

Short story shorter: WebView inadvertently adds itself to the autorelease pool when it’s on the verge of being destroyed, and subsequent release of that autorelease pool causes a zombie message to be sent to the deallocated instance.

I reported the bug, and submitted a patch to the WebKit team. My proposed fix works around the problem by wrapping the bulk of WebView’s -dealloc method with a separate autorelease pool, such that any inadvertent autoreleasing of the WebView will be tidied up before the object is literally destroyed. Because WebKit is open source, I was able to make the change, build and test it, and confirm that the crashes disappear both in my test app and in MarsEdit.

I would like to thank Alexey Proskuryakov for taking the time to help dig into the issue in parallel with me. He was on to the nut of the problem long before I was, but I glossed over some key hints in his analysis. He also helped in guiding me through the steps of submitting a proper patch with my bug report.

In The Mean Time

Hopefully Apple will accept my patch, or come up with a smarter way of fixing the problem for a future update to WebKit. In the mean time, I want my app to be as reliable as possible for the widest variety of users as possible. Yes, that even means Microsoft OneDrive users. How can I work around the problem today?

The simplest solution, requiring neither subclassing of WebView, swizzling, or anything like that, is simply to take care before releasing a WebView in your app, to manually call -[WebView close] on it first. This takes care of all the complicated business that runs the risk of autoreleasing the WebView, such that when WebView’s own dealloc method is reached, it won’t have any such complexities to expose itself to.

Tracking down and fixing this bug has been an incredibly tiresome yet rewarding experience. I hope you have learned a thing or two from the approach I took here, and that I have inspired you to take crash reports with the seriousness they deserve. Your customers will thank you for it, and you might even get a kick out of occasionally coming out on top!

What To Do About Code Signing

I wrote about the confusion arising from Apple’s poor communication about new code signature requirements, and then just earlier today I wrote about the revelation that many apps have been reprieved by an Apple whitelist.

I tend to write long, so let’s cut to the chase: what do you need to do if you are a Mac developer who ships software directly to customers or via the Mac App Store?

  1. You must ensure your next software release is signed with a Version 2 code signature. The easiest way to do this is to build and sign your product on Mac OS X 10.9 or later.
  2. You must test your existing, published apps to see that they can be downloaded and opened without issue on 10.9.5 and 10.10. To be safe, try to test once from a machine/install that has never seen the app before. If you’re concerned, read the details in my previous posts to assure yourself that your existing app was whitelisted.
  3. If your existing app does not open or in particular if it receives an “obsolete resource envelope” assessment from the “spctl” tool, you must either release a new version of your app signed with a Version 2 code signature, or re-sign your existing app. Otherwise, people who download the app will be greeted by a warning that the software is “not trusted.”

That’s it, folks. Everybody has to start signing with the modern code-signing infrastructure. In the interim, there’s a good chance your app has been whitelisted to operate as usual during the transition, but that courtesy will probably not extend to your next release.