[Update] Xcode 10.2 Beta 1 does not change the behavior that is described below.
Learn how to distribute your iOS app with the arm64e CPU architecture slice.
Introduction
This yearâs incarnation of Appleâs iOS devices features the new Apple A12 Bionic CPU. Performance improvements aside, it is the first commercially available 7nm silicone, and the first CPU with the arm64e CPU architecture (as usual, AnandTech covers Appleâs new CPU extensively). Its new security extensions might require you to make adjustments to your code. Apple explains the various usecases and provides necessary steps in their documentation. The new pointer authentication requirements of arm64e resulted in additional work for my team at App Center as well.
It turns out to be quite challenging to distribute an app with an arm64e slice today. While Xcode 10.1 added support for developers to test their app with new architecture, it is not possible to submit an app to the App Store or TestFlight. In fact, the arm64e architecture will be stripped away if you use Xcodeâs Organizer window. This happens even when exporting for AdHoc or Enterprise distribution (see the Xcode 10.1 release notes), and even when exporting from the commandline via xcodebuild.
In this post, I will show you how you can circumvent this limitation and export an iOS app with the arm64e slice. You can distribute it to your testers (using one of the alternatives to TestFlight of course).
Export the .xcarchive with the new architecture
First, you need Xcode 10.1 installed on your machine. Open your appâs project or workspace in Xcode 10.1 and add the arm64e architecture as described in the documentation.

Once you have done that, archive your application the same way you normally would.
This assumes that your app’s dependencies support the arm64e architecture. We recently added arm64e support to the App Center SDK for iOS. I plan on covering our journey in another post.
After Xcode has finished archiving the app, the Organizer window will open. Right-click on the archive that you just created and select âShow in Finderâ.

I prefer to copy the .xcarchive package somewhere where I can find it easily. For my example, Iâm choosing a folder on the desktop. To check if the binary in your .xcarchive package contains the slice for the arm64e architecture, run
lipo -info $PATH_TO_THE_BINARY_INSIDE_THE_XCARCHIVE.
The easiest way to get the path to the binary is: right-click on the .xcarchive package that you created, select âShow Package Contentsâ, and locate your .app package inside Products/Applications/. Then right-click on the .app package, select âShow Package Contentsâ once more, and find your appâs binary.
In my example, I need to run:
lipo -info /Users/benny/Desktop/AwesomeApp/AwesomeApp.xcarchive/Products/Applications/AwesomeApp.app/AwesomeApp.
This prints out the following:
Architectures in the fat file: /Users/benny/Desktop/AwesomeApp/AwesomeApp.xcarchive/Products/Applications/AwesomeApp.app/AwesomeApp are: arm64 arm64e
Awesome, the .xcarchive already contains the arm64e slice!
Create the .ipa file
The next step is to create the .ipa file that you can install on your new iPhone/iPad.
My initial idea was to switch back to Xcode 9.4.1, run xcodebuild -exportArchive -archivePath ./AwesomeApp.xcarchive/ -exportPath ./ -exportOptionsPlist ExportOptions.plist, and trick xcodebuild into exporting an .ipa file which contains the arm64e slice.
Unfortunately, this doesn’t work; signing the .dylibs and .frameworks will fail because Xcode 9.4.1âs code_sign tool will not be able to do itâs job â the .xcarchive was created in Xcode 10.1, after all.
Luckily, I learned about the ditto tool from a co-worker the other day. cd into the folder that contains your appâs .xcarchive and create a temporary directory structure:
mkdir -p tmp/app/Payload.
Copy your .app package into the directory using:
ditto AwesomeApp.xcarchive/Products/Applications/AwesomeApp.app tmp/app/Payload/AwesomeApp.app,
followed by:
ditto -ck --rsrc --sequesterRsrc --keepParent tmp/app/Payload/ AwesomeApp.ipa
Congratulations, you’re pretty much done. Use lipo -info on the appâs binary inside the .ipa package (unzip the .ipa, then use âShow Package Contentsâ ) to verify that it contains the arm64e architecture. It should print something like this:
/Users/benny/Desktop/AwesomeApp/Payload/AwesomeApp.app/AwesomeApp is architecture: arm64 arm64e
Now, go distribute your .ipa with the new arm64e architecture to your testers and squash all those bugs!