We have an iOS app which is built using a series of Bash scripts run by Jenkins. As things are today, we build an xcarchive using this command:
xcodebuild archive -workspace "..." -scheme "..." -configuration "Release" -archivePath "..."
This builds the app and signs it using the certs specified in the provisioning profile which is set using an xcconfig. Once it is complete, we then turn it into an IPA using:
xcodebuild -archivePath "..." -exportArchive -exportOptionsPlist "${export_options_plist}" -exportPath "..."
This IPA can then be uploaded to Hockey or to the App store depending on the xcconfig we use (we swap them out to create different builds).
We now want to make sure our certificates are kept safe as much as possible. This means we want to perform the build on one machine, but the signing on another. In order to do that, we need to do this:
Step 2 can be ignored for now though, so lets just focus on steps #1 and #3.
Creating the unsigned xcarchive can be done by adding the arguments CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO
to the archive
command.
Signing the IPA is much trickier though. We assumed we could just create the IPA again and use the codesign
command to sign the binary in the IPA. This had a couple of problems though. The first is that the .entitlements
file we had for the app wasn't respected. We had to pass this as a flag to the signing command. Then we realised that we had to correct all the variables in the .entitlements
file since Xcode was no longer replacing them with the correct values. Then we realised that we had to do this for each extension we had.
We finally got this all working, with the correct entitlements, replacing the variables and everything was signed, but when I tried uploading the new signed IPA to Hockey it rejected it. The error message wasn't helpful either.
We diff'ed a build with the previous system with the new system and each binary was different. We're not sure if this is a codesigning issue, or just a timestamp change, but there are changes. Furthermore, we discovered that my extensions are all missing archived-expanded-entitlements.xcent
files, plus possibly more issues.
It definitely seems like we are going about this the wrong way. We clearly shouldn't have to re-do everything just to sign on a different machine, so where are we going wrong? How are we supposed to build on one machine and sign on another?
P.S. Our current tools use xcodebuild
directly, but we have support for fastlane
for other parts of our build process, so we are happy to use it if needed.
Update: We have a "solution" to this which is to sign the Release builds with a dev cert, then resign them using the distribution one. This solves all the problems with entitlements being populated etc. but still requires each binary to be resigned and entitlements combined, etc. so I'm curious if there is a better solution.
You can useTestFlight to distribute iOS, tvOS, and watchOS beta builds to testers and collect feedback. If you want to distribute your app to registered devices, to beta testers using TestFlight, or through the App Store, you need to join the Apple Developer Program.
Developers can sign their apps through certificate validation (through the Apple Developer Program). They can also embed frameworks inside their apps and have that code validated with an Apple-issued certificate (through a team identifier string).
You cannot develop iOS apps without a Mac computer, but you can set up CI/CD to handle building and publishing!
In the sidebar, click Profiles. Then, next to the heading Profiles, click the + button to create a new provisioning profile. Under Distribution, select Ad Hoc. Click Continue.
Please follow the steps to create an unsigned xcarchive
• Select Targets (‘’) -> Build Settings and find the ‘Signing’ section.
• Set ‘Code Signing Identity’ = ‘Don’t Code Sign’
Set Version = 1.0 //That you need to send
Set Build = 5 //That you need to send
Remove ‘Automatically manage singing’ flag.
xcodebuild -workspace <ProjectName>.xcworkspace -scheme <ProjectName> -configuration Release clean archive -archivePath buildArchive/<ProjectName>.xcarchive CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO
You can Zip that ‘.xcarchive’ file and transfer the xcarchive to the signing machine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With