Manually Signing Embedded Swift Runtime
• 2 minute read
Sometimes the Swift runtime ends up in a built product as well and needs to be (re)signed just like the rest.
I am working on a macOS app which ships with an embedded app as an Autostart Helper and a Finder Sync extension. Because we offer branded builds to our customers a lot is parameterized in this Xcode project. The deliverable app bundles for our customers are unsigned, too. Customers have to sign the received deliverables themselves. We implemented this to simplify the delivery process. Otherwise our customers are required to provide development signing assets. Over time it turned out that this often poses a challenge. Also customers are reluctant to provide production signing assets for an app or even access to their development team, no matter the role.
One day we shipped an app bundle to one of our customers and they had problems uploading it to App Store Connect. Shortly after upload and validation they received a mail about signing errors in the uploaded app bundle. It listed a lot of dynamic libraries. This was odd and we previously did not have the problem with other customers.
It turned out that for a still unknown reason some customer builds have the “Framework” folder in their app bundle. It is filled with some Swift runtime libraries, in example for AppKit. Because all brandings are based on the same Xcode project having the same configuration (except for some basic deviations like product bundle name) the idea of mismatching build settings can quickly be discarded. Whatever.
After some back and forth and tinkering the simple solution appeared to be to sign those framework binaries, too. It is clear once you get the idea, then it makes sense. As the official documentation states, all executable code in an app bundle must be signed by you. This also includes Swift runtime libraries by Apple which you have not contributed but Xcode.
The signing could be achieved by this single terminal command:
codesign -vv -f -s "Apple Distribution: Example Inc. (123A4BC5DE)" "Product.app/Contents/Frameworks/*.dylib"
Besides finding another error with the app group ID this resolved the blocking issue and the app could be submitted successfully.