Correct way to sign an embedded app bundle in Xcode 7?

I have a large project I'm trying to bring up to date with Xcode 7.


The main deliverable app (direct distribution, this is not for the App Store) has a large number of embedded resources, including background (faceless) Cocoa apps, helper tools, a Finder service, spotlight plugin, and embedded frameworks.


I had previously been not signing any of the sub-components as they were built, and was using the --deep option on the enclosing app to sign everything inside the bundle with the same signature.


I've been reading about this and I get the feeling that this method is not recommended, so I rejiggered the project to sign each individual target (adding some build phase scripts to sign the binary frameworks). But now I can't get past the following error:


error: Embedded binary's bundle identifier is not prefixed with the parent app's bundle identifier.
  Embedded Binary Bundle Identifier: com.qrecall.service
  Parent App Bundle Identifier: com.qrecall.client


Either my embedded app is signed (and I get this error) or it isn't signed and I get an error that is has to be signed.


I've pored over TN2206, but it only briefly mentions identifier prefixes, and only in the context of an App Store app. I can find no mention of this problem in the troubleshooting section, or even a discussion of the identifier requirements for embedded app bundles when signing with a Developer ID.


So has anyone run into this, and is there an easy fix? Or should I just go back to using --deep?

Well, I've made no progress on this.


In the "What to Sign" section of the Code Signing Guide, it states:


"If your application consists of a big UI part with one or more little helper tools that try to present a single face to the user, you can make them indistinguishable to code signing by giving them all the exact same code signing identifier. (You can do that by making sure that they all have the same CFBundleIdentifier value in their Info.plist, or by using the -i option in the codesign command, to assign the same identifier.)"


However, in the man page for the codesign tool, the description for the -i/--identifier option says "It is a very bad idea to sign different programs with the same identifier" (emphasis theirs).


Ignoring the codesign man page, I set up the two embedded helper apps to be signed with my Developer ID: * and added the --identifier com.qrecall.client so both embedded apps will be signed with the same identifier as the parent app bundle.


Yet, the ValidateEmbeddedBinary build step still spits out "error: Embedded binary's bundle identifier is not prefixed with the parent app's bundle identifier" and reports the identifier of the embedded app bundle (com.qrecall.monitor), not the identifier used to sign the embedded app. (I checked the embedded app by running "codesign --display -vvv" on the intermediate product and verified that its 'Identity' was the same as the host app bundle.)


If I don't sign the embedded app at all, the ValidateEmbeddedBinary build step dies with "error: Embedded binary is not signed with the same certificate as the parent app" and is shows that the embedded apps isn't signed at all.


I'm beginnig to suspect that this is a bug in the ValidateEmbeddedBinary build step, and I've filed a bug report (#21843204).

Never minde. The whole code signing issue was a red herring.


As it turns out, Xcode 7 apparently adds new validity checks to the build phases. My "helper" Cocoa apps were part of the Copy Helpers build phase, along with my other command-line tools. That was a mistake. Apparently Xcode 7 makes assumptions about what an app bundle in this build phase should conform to. I'm not sure what those assumptions are, but they certainly don't apply to these apps.


The "solution" was to move my helper apps to the Copy Resources build phase. There, Xcode 7 ignores them and treats them like any other resource.


*sigh*

Correct way to sign an embedded app bundle in Xcode 7?
 
 
Q