Category Archives: Bug Reports

Xcode GitHub Integration

Apple’s beta release of Xcode 9 features impressive improvements to its source control features, including streamlined integration with GitHub. There’s even a fancy “Open in Xcode” button when you go to clone a project:

Screen capture of the GitHub interface for cloning a project

This integration is amazing. You just click the button, specify a save folder in Xcode, and boom! You’re off and …

Screen capture of build failure indicating a missing signing certificate

Oh, right. Code signing. The otherwise stellar GitHub integration in Xcode underscores a longstanding deficiency in how it manages code signing identities for multi-team, collaborative projects. Precisely the kinds of projects you’re liable to find on GitHub.

The problem could be solved, or at least diminished greatly, by providing some mechanism for declaring that a project should be code signed “with the user’s own default developer team.” The default branch of any open source project targeting Apple platforms, would specify the DEVELOPMENT_TEAM as something like:

DEVELOPMENT_TEAM = Automatic

Xcode would provide a user-level setting for “Default Development Team”, and in the absence of any overriding setting, that team would be used whenever a project was configured as above.

I wrote about this problem once before, but with all the work being put into streamlining the experience of cloning from and pushing to GitHub, now is an ideal time for Apple to embrace a fix. Radar #32614751.

Another issue that stops short the cloning, and immediate building and running, of open source projects, is the need to fulfill external dependencies. In some cases this might require manually downloading and installing libraries, or cloning projects, but in the vast majority of cases the dependencies will be specified using built-in Git submodule support, or a popular package manager. In each of these cases, it should be trivial for Xcode to detect that the project it has just cloned also has dependencies:

  • Git submodules: there is a .gitmodules directory.
  • Carthage: there is a Cartfile file.
  • CocoaPods: there is a Podfile file.
  • Swift Package Manager: there is a Swift.package file.

If Xcode sees evidence of any of these techniques at play, it could do the favor of checking them out immediately after cloning the project. Radar #32615265.

The GitHub integration coming in Xcode 9 provides a nearly effortless capability for cloning, building, and running open source projects that target Apple platforms. Ideally it would also go the extra mile and provide for variable, dynamic development teams, as well as conduct a rudimentary check for dependencies that must be checked out before commencing work on the project.

Implicit Swift Dependencies

If you’re developing in Swift for Mac or iOS, you need to ensure that any standard Swift libraries are also copied into your app bundle. Typically this is handled automatically by Xcode when it detects the presence of any Swift files in your app. If your app is entirely Objective-C, but you link against your own frameworks that themselves depend on Swift, you have to ensure the required libraries are embedded. This can be done by setting the “Always Embed Swift Standard Libraries” checkbox in your target’s build settings to “Yes”:

AlwaysEmbed

When this option is set, Xcode scans the bundled frameworks in your app and, if any of them contains Swift code, it copies the pertinent libraries into your app’s bundle.

This approach falls down a bit when it comes to Unit Testing targets. Because a Unit Test bundle doesn’t typically copy the framework it is testing into its own bundle, Xcode seems to deduce dependencies by examining the list of frameworks the test bundle links to. If you enable the “Always Embed” option above for a Unit Testing bundle, then any framework the bundle links against will be examined for Swift code, and the required libraries copied in.

But what if none of the linked frameworks themselves require Swift, but they depend upon other frameworks that do? In projects of a substantial size, you may have higher-level frameworks implemented entirely in Objective-C, that depend upon lower level frameworks that use Swift. In this scenario, Xcode’s CopySwiftLibs build phase does not identify the deeper dependency, and neglects to embed the required Swift libraries. When your unit tests run, you’ll see a runtime error like this:

The bundle "RSTextFilteringTests" couldn’t be loaded because it is damaged or missing necessary resources. Try reinstalling the bundle.
(dlopen_preflight([...]/RSTextFilteringTests): Library not loaded: @rpath/libswiftAppKit.dylib
  Referenced from: [...]/RSAppKit.framework/Versions/A/RSAppKit
  Reason: image not found)
Program ended with exit code: 82

So “Always Embed Swift Standard Libraries” doesn’t always embed them. I’ve filed Radar #30832923, requesting that the CopySwiftLibs build phase look harder for Swift dependencies. In my opinion it should look not only at the directly linked frameworks, but at any developer-supplied frameworks that those in turn depend upon. This would cause “Always Embed” to behave as expected when a developer adds Swift dependencies to frameworks at any level of their code base.

There are many possible workarounds to the problem, and each has its own drawbacks. Here are a few:

  1. Add a Swift-based unit test file to your test bundle. This simple workaround will work in most situations, because the test itself will impose many Swift library dependencies on your bundle. There is a shortcoming, though: if the test code doesn’t generate all the Swift dependencies that your frameworks do, you’ll still be left with missing Swift libraries. For example if a dependent library requires the Swift library for Apple’s Contacts.framework, your Swift test file is not sufficient to cue Xcode to copy the required libSwiftContacts library.
  2. Manually link to Swift-dependent frameworks. Suppose your unit tests target HighLevel.framework, and LowLevel.framework depends upon Swift. By adding LowLevel.framework to the list of linked libraries for your testing bundle, you will cue Xcode to also embed the required Swift libraries for that framework. This has the advantage of ensuring that whatever Swift libraries are required get copied, but it has the drawback of requiring explicit dependency on a lower level framework from your unit test bundle.
  3. Stop! Abort mission! Revert to Objective-C only. Many Swift dabblers probably feel this emotion from time to time. The unexpected costs of adding a modest amount of Swift to a project are frustrating, and one can’t help but wonder whether they would be better off waiting until Swift support is more baked in to the system. The obvious downside of this approach is that Apple’s progress with Swift is moving quickly, and the longer you put off testing the waters, the harder it may be for you to catch up when ignoring it is no longer a viable option.

The workaround I’ve settled on for now is #2. Adding unnecessary direct dependencies to my test bundle feels a little inappropriate, but it is both easily undone in the future, and unlikely to cause any real problems in practice.

In the course of investigating this problem, it also occurred to me that unit test bundles in particular are such a special case, that Apple should probably give them special treatment to eliminate a number of pitfalls. I filed Radar #30832983 suggesting that unit test bundles should default to “Always Embed Swift Standard Libraries,” on the assumption that Swift code may be present in some library.

Thinking further on that point, it seems that Unit Tests could be safely run in an environment in which all Swift support libraries are available at runtime to be resolved by DYLD. Because test bundles are not built to be shipped to customers, it’s of primary that they link and run successfully. Such an approach would do away with the need for Unit Test bundles to either specify that Swift libraries be bundled, or to fret about which of those libraries in particular need to be copied.

Interface Builder: View Is Clipping Its Content

If you have Xcode’s “Show live issues” enabled, you’re used to seeing (usually) helpful warnings and notices about your source code and interface files. These notices appear even if you haven’t yet built your project:

Image of Xcode Interface Builder warning about a view clipping its content.

If you click the “View is clipping its content” notice, it takes you right to the view in question:

Image of a popup button on the Interface Builder canvas.

At this point you can usually just “size to fit” and Interface Builder will use its knowledge of the control’s class, and that class’s ability to size itself to suit its content. Or, if you’re using Auto Layout, it might mean that you need to ask Interface Builder to update the items’s frame, allowing Auto Layout to essentially size to fit for you.

In this case however I have a conundrum: both “size to fit” and AutoLayout insist this is the proper size and placement for the control, yet Interface Builder is still convinced the control will clip its content (the text of the menu item title).

What happens if I naively attempt to increase the width of the popup button?

Image of a popup button with error messages indicating it is the wrong width.

The clipping area is gone, as Interface Builder is convinced the button is now wide enough, but that width is in conflict with what Auto Layout is convinced is the right width.

I can’t win: if I let Auto Layout have it’s way, I get an annoying clipping notice. If I let the clipping notice have its way, Auto Layout throws a fit.

One workaround, when working with Auto Layout, is to provide a bogus constraint that forces the width of the popup button to the width that I’ve manually imposed. By setting it to “Remove at Build Time” it should not have any effect on the behavior of your interface, except in Xcode itself.

WidthConstraint

See that empty “Identifier” field? I have actually taken advantage of that field as an opportunity to add a memo to myself for future reference: “Work around bug 25938”. This references my internal bug tracking the issue, so I can re-acquaint myself with the problem if I find myself wondering about this bogus constraint in the future.

It seems to me the bug here is either that NSPopUpButton sizes to fit at too narrow a size, technically causing “clipping” of its subviews. Alternatively, Interface Builder’s deduction of a view’s size causing clipping has some bug in it. Either way, I’ve filed the issue as Radar #30222922.

Update, January 28, 2017: Thanks to a tweet from Mark Lilback, I discovered the notice about clipping is a bit less pervasive than I thought. The notice only seems to appear when Xcode has the xib file actively open for editing with Interface Builder. What this means practically is that you have to click on the xib file at some point and have the editor appear for it, before the notice appears. It also means that if you cause Xcode to close the file for editing, the notice disappears. You can close any file in Xcode by focusing on its editor and then selecting File -> “Close <filename>”, or by pressing Cmd-Ctrl-W.

I have always found these kinds of notices in Xcode to be somewhat unpredictable. The fact that the file has to be actively opened for editing, combined with the fact that files remain open in Xcode after their editor is visually swapped out, explains most of the apparent inconsistencies I’ve seen.

Installing Symbols For WatchOS

For months I have been plagued by Xcode’s persistent failure to successfully install WatchOS device support on my Mac. If I open Xcode, and my iPhone (paired with an Apple Watch) is attached to the Mac, I am greeted by a progress indicator such as this:

InterfaceController swift

Because I don’t actually do any watchOS development, this has mostly been a mild annoyance. The bug doesn’t seem to affect the performance of my Mac, and other actions I perform in Xcode continue without delay. However, for those of you who are actually doing Watch development, if you run into this problem, you’ll be perpetually greeted by this error when you try to debug on a real device:

Xcode panel refusing to install on a device because of missing Apple Watch symbols.

The worst side-effect of this bug for me, and the problem that finally encouraged me to hunker down and solve the issue, is the fact that each attempt to “Install Symbols” is associated with a fresh download of a larger-than-200MB file from Apple to my Mac. This is no big deal on my home network, but when I’m roaming and tethered to my bandwidth-metered iPhone, it can lead to costly overage charges.

I’ve been to hell and back tracking down exactly how Xcode installs these symbols, where it fails, and how to work around the problem. I’ll give an overview of how Xcode’s symbol installation process works, and walk you through one concrete method for working around the problem, getting those precious symbols installed, and breaking the cycle of perpetual failed installations.

Symbol Installation Overview

First I want to give you a high level idea of how Xcode downloads and installs symbols. Here are the steps that take place:

  1. A device suitable for development is connected.
  2. Xcode looks for existing symbols in the suitable home directory location
  3. If symbols are not already installed, the symbol-installation process begins.
  4. A disk image file containing the required materials is downloaded to a temporary folder.
  5. The disk image file is copied to a Caches subfolder in your home directory.
  6. The disk image is mounted at a temporary location on your Mac
  7. A macOS Installer package on the disk image is used to install symbol files directly into your home folder.
  8. The temporary disk image is unmounted.
  9. The cached disk image file is deleted.

In my tests, the failure to successfully install watchOS symbols broke down in step 7, where the package is supposed to successfully copy symbol files into my home folder. I was able to determine that the Apple infrastructure responsible for the installation is failing on my Mac with a cryptic authentication error:

Could not download and install Symbols for watchOS 3.1 (14S471). Authorization is required to install the packages

The failure is not happening in Xcode per se, but in a helper tool that is part of the private PackageKit.framework. I filed Radar #29568241, in the hopes that somebody at Apple will have insight as the root cause of the problem, and how it can be fixed for good in either Xcode, or in the configurations of affected users’ Macs.

Fix It Yourself

To manually accomplish what Xcode is failing to do, we need to:

  1. Get a copy of the downloaded disk image.
  2. Copy the pertinent files out of the disk image’s installer package.
  3. Copy the pertinent files into the correct installation path in ~/Library/Developer/Xcode/

Because simply creating the directory at the installation path is enough to stop Xcode attempting to install symbols, I’m going to cover that first. Folks who don’t need or want the symbols for Watch development will solve the problem sufficiently after this step.

Determine the Installation Path

Unfortunately, the path is quite specific to the Watch device at hand, and may be difficult to guess. Here’s one way of figuring it out. Making sure you have an iPhone connected that triggers the symbol installation in Xcode, do the following:

  1. Quit Xcode.
  2. From the Terminal, navigate to Xcode’s binary executable folder:
    cd /Applications/Xcode.app/Contents/MacOS/
  3. Run Xcode with a special flag to cause additional logging to display:
    ./Xcode -DVTDownloadableLogLevel 3
  4. Wait for Xcode to launch and start installing symbols.
  5. Scan the output in Terminal for a line like this:
    Starting a download for Watch1,2 3.1 (14S471), to file path /Volumes/Data/daniel/Library/Developer/Xcode/watchOS DeviceSupport/Watch1,2 3.1 (14S471)/Symbols

    Of course, your output will be slightly different, but depending on the version of Watch and watchOS you have, the important part is relative to your home folder. In my case, I need to make sure this folder exists:

    ~/Library/Developer/Xcode/watchOS DeviceSupport/Watch1,2 3.1 (14S471)/Symbols

If you don’t care about Watch development, this is your big chance: just create that folder now. Quit and relaunch Xcode again, and you’ll see that your problems are over. No more symbol installations required. If you skim the logging output from above you’ll see that the “InstalledIfAllPathsArePresent” key in one of the dictionaries indicates that the path merely being present is enough to convince Xcode it’s “installed.”

If you do care about Watch development, you’re going to want those symbols. Let’s tackle that problem next.

Getting the Disk Image

Remember back in “Symbol Installation Overview,” I described the installation failing in step 7: where a package on a mounted volume is attempted to be installed. Unfortunately, this failure does not prevent steps 8 and 9 from proceeding, so when the whole procedure is over, there are no obvious artifacts left around to work with. The disk image, that was copied to ~/Library/Caches/com.apple.dt.Xcode/Downloads in step 5, is available for such a short period of time, you’re unlikely to nab it before Xcode deletes it upon failure.

You may have noticed in the Xcode logging output that many URLs to web resources are passed around. It’s likely that one of these contains the required disk image content, but I thought it would be safer to catch Xcode in the act and use precisely the disk image file that it itself was intending to use.

Yet another “secret” Xcode user default key can help us here. Once again, navigate to the Terminal to execute Xcode manually. This time, we’ll pass a flag that instructs it explicitly not to delete the coveted disk image file after it’s done:

./Xcode -DVTDownloadableLeaveTemporaryFiles 1

This time you’ll have to wait again until the process tries, and fails, but when you’re done you should find a suitable disk image file waiting for you at:

~/Library/Caches/com.apple.dt.Xcode/Downloads/Xcode.Symbols.Watch1,2.14S471-3.1.dmg

(Or with whatever name is suitable for the version of Watch and OS you are accommodating.)

Copying the Symbol Files Out

Double-click the disk image to mount it on your Mac. You’ll find a volume appears with a suitable device-oriented name, and a matching file within called e.g. “Watch1,1_Watch1,2.pkg”.

Warning: Do not open and install this package willy-nilly without reading the following carefully. This is a standard Installer package, and double-clicking it on your Mac will launch the system-standard Installer application. However, agreeing to let it “just install” on your Mac could have unintended consequences. The files in this package are named very similarly to many system files on your Mac, but of course these files are binaries for a ARM based Watch device, and not an x86_64 personal computer.

There are many techniques for getting the files out of an Installer Package without actually, you know, installing. You could use an app like Pacifist to extract them directly to a folder on your disk. There may also be a way to invoke the command-line “installer” tool in such a way that it simply spits the files out where you want them. For that matter, it might be safe to simply “Choose Folder…” from the Installer app, and trust that it will install everything in that folder instead of on the root of the volume.

Me? I decided to strike a semi-paranoid compromise. I used the Installer app, but instead of installing to my Mac’s main volume, I created a writable disk image in Disk Utility, and targeted that volume explicitly:

WatchHack

When the installation was complete, I had a mounted volume, filled with the contents that Xcode has presumably been intending to copy into my home folder.

WatchHack

Finish the Job

At this point you know correct install location in your home folder, and you have a copy of all the files that should be there. It should be as simple as selecting the files from “WatchHack” and dragging them to the “Symbols” folder in the appropriate ~/Library/Developer subfolder.

When the symbol files have been copied in, quit and relaunch Xcode. Not only should it avoid that nasty “Installing Symbols” phase, but building and running on your physical watchOS device should once again work as expected.

Touch Bar Crashers

Since the MacBook Pro with Touch Bar was released, I’ve noticed a small but steady influx of new crash reports against my apps. Typically, the crashes in something CALayer related, and the correlated crash log often descends from “-[DFRElement dealloc]”:

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libobjc.A.dylib               	0x00007fffea5211cf objc_class::demangledName(bool) + 33
1   com.apple.CoreFoundation      	0x00007fffd58b6c20 ___forwarding___ + 144
2   com.apple.CoreFoundation      	0x00007fffd58b6b08 _CF_forwarding_prep_0 + 120
3   com.apple.QuartzCore          	0x00007fffdb7012a8 -[CALayer actionForKey:] + 95
4   com.apple.QuartzCore          	0x00007fffdb6fbccf CA::Layer::mark_visible(CA::Transaction*, bool) + 345
5   com.apple.QuartzCore          	0x00007fffdb6fbe8c CA::Layer::set_visible(unsigned int) + 306
6   com.apple.QuartzCore          	0x00007fffdb6eef21 CA::Context::invalidate() + 75
7   com.apple.framework.DFRFoundation	0x00007fffe180c7bd -[DFRElement dealloc] + 113
[...]

That DFR prefix rang a bell for me, because it’s the same prefix as some of Apple’s private frameworks that support the Touch Bar simulator in Xcode, which I also use in my free, standalone Touch Bar simulator, Touché.

User comments associated with these crashes often mentioned connecting or disconnecting an external monitor, or with waking their MacBook from sleep.

I speculated that the crashes might represent some subtle bug that is only likely to happen when the Touch Bar infrastructure on the Mac is forced to stop and start again. I would be surprised if, when the computer goes to sleep, the physical Touch Bar on the MacBook didn’t also stop streaming content from the computer. When the computer wakes, it would make sense for it to trigger a resumption of that streaming.

Hmm, if only I had a Touch Bar Mac, so I could try to reproduce these crashes. I would open my apps, then I would close the laptop lid, and open it again, say 100,000 times or so, until I reproduce the problem.

Since I had already written a Touch Bar simulator app, which itself has the ability to stop and start streaming of the Touch Bar content, I speculated that I might be able to provoke the same crashes from within my app. Indeed, some of my users who reported these crashes were not using Touch Bar Macs, but were running Touché.

I rigged up a special version of my app that would simply show and hide the Touch Bar simulator window repeatedly, perhaps thousands of times per second. Maybe that would trigger the crashing bug that only rarely affects my customers.

It crashes my apps all right, usually in less than a second. The funny thing is it seemed to only crash my apps. None of Apple’s apps seemed to be dying. Other 3rd party apps on my Mac were also holding up fine.

Finally I came across another app that also crashed, and came up with a theory: only apps that are built with a suitably older SDK are crashing. For reasons I won’t go into, most of my apps are still built on a Mac OS X 10.6 Mac running Xcode 6. Sure enough, as I went out scouting for apps that I suspected were of a similar vintage, I was able to crash them in “less than a second” as well.

If you’re on a Touch Bar Mac, or running Touché, and seeing crashes in apps that culminate in CALayer, I think there’s a very good chance it represents a bug in Apple’s Touch Bar support on the Mac. I’ve filed a bug with a reprodeucable test case: Radar #29537507.

Window Tabbing Pox

macOS Sierra introduces a new system-wide window tabbing feature, which by default enables tabs within the windows of most document-based apps. Apple’s own TextEdit is a canonical example: open the app and select View -> Show Tab Bar to see how it looks.

Unfortunately, the default tabbing behaviors doesn’t make sense in all apps, even if they are document-based. I’ve had to disable the functionality in both MarsEdit and Black Ink, at least for the time being. Doing so is easy. Just add the following line somewhere early in the lifetime of your app:

NSWindow.allowsAutomaticWindowTabbing = NO;

This class property on NSWindow shuts the whole window tabbing system out of your app, so you don’t have to fuss with how to disable it on a window-by-window basis. Handy!

Unfortunately, setting that property to NO doesn’t do anything about windows that may already have been created, and which have their tab bar visible. I added the line to my app delegate’s applicationDidFinishLaunching: method, assuming that would take care of everything. After all, any documents will be instantiated later in the app’s lifetime, right? Right?

Wrong. Not with window restoration, at least, which causes a freeze-drying and restoration of open document windows when a user quits and relaunches the app. The window in this circumstance is actually created before applicationDidFinishLaunching. If it had its tab bar visible when you quit, it will have the tab bar visible when it’s restored, even if you’ve since disabled all window tabbing for the app.

What’s worse? Showing or hiding the tab bar on any window sets that choice as the default for all future windows in the app. So even new documents that are created by users, and which don’t have their tab bar visible because you’ve disabled it app-wide, will have a tab bar appended when they are restored at launch time, because “Show Tab Bar” was the last user action before disabling tabbing altogether.

The long and short of it? An app stuck in this situation will not have a View -> Show/Hide Tab Bar, and none of its windows will support tabbing, except for any document that is restored at launch time. Even new documents that are created without tab bars will have the tab bar imposed the next launch.

I filed Radar 28578742, suggesting that setting NSWindow.allowsAutomaticWindowTabbing=NO should also turn off window tabbing for any open windows that have it enabled.

If your app gets stuck in this predicament, one workaround is to move the NSWindow.allowsAutomaticWindowTabbing=NO line to an even earlier point in your app’s lifetime, such as in your app’s main.m or main.swift file.

Dynamic Development Team

The first Xcode 8 beta was released at WWDC, and includes a major revision to the way code signing is handled by default. You can watch the video or read the slides on Apple’s WWDC Videos page.

A major change from Xcode 7 is that Xcode now requires that every target in your project specify a development team, even when the manual code signing option is selected.

This is a nuisance to developers who have fine-tuned their code signing process such that signing is configured elsewhere: for example, in a centralized Xcode configuration file that imparts signing information to all projects in an organization.

The problem is worse for open source projects, where a project may be expected to be checked out and built by a variety of organizations. In this scenario, each organization will have to somehow automate the insertion of a valid team name and ID in the project file after every checkout or update.

The DevelopmentTeam and DevelopmentTeamName values are stored in the Xcode project file, so they can’t be defined in Xcode configuration files the way so many other settings that affect build behaviors can.

Xcode needs some mechanism for providing these values without manually, permanently altering the affected project files. I would welcome either a mechanism for specifying the values in the Xcode configuration file specified for the project, or a wildcard type value that can be selected to indicate the “default team” should be used.

(Radar #26892618)

Update: It turns out my wishes are already answered. The new PROVISIONING_PROFILE_SPECIFIER build setting will impart the desired team information to Xcode, even if provisioning profiles are not used. So, something like this in my Xcode configuration file:

PROVISIONING_PROFILE_SPECIFIER = 493CVA9A35/

Quiets all of Xcode’s gripes about requiring a team name, and doesn’t require that I tediously update every last target with explicit team information. This doesn’t exactly solve the challenge for open source projects, because organizations using an open source project will still have to override the configuration file or build settings for the projects they check out. As far as I know there is no way to define PROVISIONING_PROFILE_SPECIFIER generically, the way you can specify code signing identities as e.g. “Mac Developer”. It would be great if open source projects could declare a PROVISIONING_PROFILE_SPECIFIER (when needed) as:

PROVISIONING_PROFILE_SPECIFIER = Automatic/

And allow the host project’s prevailing team identity automatically apply. But, I am satisfied to know this at least doesn’t need to be manually set everywhere in order to continue building my projects successfully.

Careful What You Wish For

I am a well-known proponent of bug filing. In fact, I filed a bug last year that argued Xcode should apply the custom Code Signing Flags for a project when code signing the bundled Swift libraries that are installed in in an app’s bundle.

I noticed that at some point along the way, Apple did fix the bug! Exciting! Time to rejoice, no? Well, no. Because while the fix for the bug addressed my original complaint, it brought a new headache which I hadn’t anticipated.

For my app MarsEdit, I supply a custom designated requirement for the code signing phase. The long and short of this approach is that through careful specification of a designated requirement, you can arrange it so that if the user stores an item in the keychain from one version of your app (say the Mac App Store version), then the same app can access the data later without prompting the user, even if it has a different bundle ID, or is signed by a different identity (say, because it’s a direct sale version).

The problem I’m running into now, as I dabble with adding Swift-based code to MarsEdit, is the bundled Swift libraries are being signed with my app’s custom designated requirement. Oops. This never would have happened if Apple hadn’t … fixed the bug I reported.

I’m not sure what the right solution is, or even how to best approach a workaround. The copying of Swift libraries and their subsequent signing is not only opaque to developers, but it happens after the entire user-configurable build process is done. It seems as though to work around the problem in such a way that I can still supply a designated requirement for my app, I may need to avoid adding the flag to OTHER_CODE_SIGNING_FLAGS, and amend the designated requirement on my own sometime after the Xcode build process is complete.

I find the code signing configuration options to be pretty troubling for this reason, among others. The highest level code signing identity (and now flags) are used implicitly by Xcode for some code signing operations that are opaque to developers. It puts us in a bind when something subtle turns out to be not quite right with the resulting built product.

I filed a new bug, Radar #25579693, to raise the issue with Apple about the can of worms that fixing my previous report has caused. In the mean time, I’m on the hunt for workarounds! I’ll update this post when I feel I’ve got something good.

NSURLSession Authentication Challenge Disparity

Thanks to a bunch of my networking-related unit tests failing on 10.11, I came to the conclusion that NSURLSession’s authentication challenge mechanism changed from 10.11 with respect to the way HTTP Basic Auth challenges are handled.

In 10.10 a data task that is created for a resource protected by HTTP Basic Auth will result in a callback whose protection space method is identified as “NSURLAuthenticationMethodDefault”, while in 10.11 the same code accessing the same resource yields a protection space method “NSURLAuthenticationMethodHTTPBasic”.

The problem here is that existing challenge-handling code may have been written to handle the 10.10 behavior, looking for HTTP Basic Auth challenges like this:

if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodDefault)
{
	// Handle the challenge
	...
}

While on 10.11 the “Handle the challenge” code will never be reached, so this shipping code will fail to function.

I think a robust workaround (that unfortunately requires re-compiling and re-shipping) is to test HTTP authentication challenges for either NSURLAuthenticationMethodDefault or NSURLAuthenticationMethodHTTPBasic, and treat them both as equivalent.

I filed this as Radar #21918904, and wrote a message in the developer forums in case people want to discuss the issue or the merits of various workarounds.

Swift Libraries Code Signing

I wrote last year about problems arising from Developer ID signed apps and their dependence upon an Apple “timestamp server” during the code signing phase. In the article, I describe a workaround for scenarios where the timestamp server is either down or there is no internet connection: disable the functionality by adding “–timestamp=none” to the OTHER_CODE_SIGN_FLAGS Xcode build setting.

Swift based apps currently install a complete copy of the Swift standard libraries in the built app’s bundle, and during this phase, Xcode implicitly signs the Swift libraries with whatever code signing identity is defined by the project and/or target. Unfortunately in doing so, it ignores the OTHER_CODE_SIGN_FLAGS build setting, removing the opportunity to finesse code signing of the Swift libraries in the way I described.

The long and short of it? You can’t build a Developer ID based Swift application when you’re offline. I discovered this recently when I dug into a Swift application in a jet, high above the Pacific. Hours of uninterrupted, focused development time lay before me, but I was met with this annoying build failure:

The timestamp service is not available.
*** error: Couldn't codesign [...]/My.app/Contents/Frameworks/libswiftCore.dylib: codesign failed with exit code 1
Command [...]/XcodeDefault.xctoolchain/usr/bin/swift-stdlib-tool failed with exit code 1

The workaround is to turn off code signing completely, or to switch to a Mac App Store code signing identity (which doesn’t rely upon the timestamp service feature of the code sign tool). I filed this bug as a Radar #21891588.