Not Easy as PIE
I was submitting a new app to the App Store. I didn’t use TestFlight for beta testing. So new app, new id, new everything.
Archive and validate. Once validation passes I usually think I am done. So I start uploading and bragging about it. Until … the upload fails. Must be a glitch, I retry. Failed again. I try many times and I end up with this on iTunes connect.
I went to sleep, disappointed. I have been working on web services for almost two years now. The freedom of changing them whenever I want with no convoluted process doubled the frustration is this case. Plus it was around midnight, maybe my brain was tired.
I woke up in the morning. The situation on iTunes connect was still the same, processing. I created a new archive, just changing the build version, and started uploading and … bam!
WARNING ITMS-90080: "The executable 'FrameworkName.framework' is not a Position Independent Executable. Please ensure that your build settings are configured to create PIE executables. For more information refer to Technical Q&A QA1788 - Building a Position Independent Executable in the iOS Developer Library."
Ok I got an error, now I can look for a solution. PIE (position independent executable) is way to generate programs that can be loaded anywhere in memory. It was introduced in iOS 4.3. The Q&A page is not completely helpful though. For example new Xcode projects, created with Xcode 7, don’t have a Don't Create Position Independent Executables
field in the build settings. I kept on searching.
I discovered that people using Alamofire are having the same issue. I don’t use Alamofire for my app, so I thought I was “safe”. Then I stumbled upon a very detailed discussion on the Cocoapods repo. I am using Cocoapods in my app. The plot thickens.
There are so many objects intertwining here and I have no controls on any of them:
- The Swift compiler
- Cocoapods (with the
use_frameworks
flag turned on) - The libraries I am using via Cocoapods
- iTunes Connect
I found somebody saying that it was a problem solved. Then I discovered he uploaded a TestFlight beta release. I discovered that people using Carthage had the same problem, so it’s not exclusive to Cocoapods. Then somebody told me that he had successfully uploaded an app a few hours before, but it was an update, not a brand new app.
I made sure bitcode was enabled also for the frameworks. I tried. Same error. I turned off bitcode and it worked.
I always thought that bitcode was opt-in for plain old iOS-only apps. It’s not. It’s opt-out. I turned it off everywhere I could:
- in the Xcode project
- in the App uploader
- in iTunes connect
I discovered the third one while fiddling in iTunes Connect.
I didn’t know it existed. I’d be curious to know what happens if I provide inconsistent values to some of the three options above. But honestly I have no time for that.
I have been kind of lucky. My app is iOS only so, according to the App Thinning documentation, bitcode is optional. But for watchOS and tvOS apps bitcode is mandatory.
Honestly I don’t want to be in the shoes of a developer that:
- signed a contract with a client for a project that includes a watch app
- has met the deadline
- cannot submit the app to the App store because of the above
- has problems explaining the client that it is an issue out of his/her competence
Erik Kerber pointed out an interesting coincidence. Since June 1st Apple is forcing watch apps to be watchOS2 only. Might be relevant or not, but the PIE problems began to show up consistently 4-5 days ago.
I think the intent of bitcode is noble. Stripping down a binary to include only what’s needed by a specific device is a good thing. I just don’t think it’s a ripe technology yet. WWDC is around the corner. Maybe this issue will be fixed. My radar has been duped. One can hope.