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.”
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:
- Having entitlements for your target. E.g. being sandboxed.
- 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.