Wednesday, October 12, 2011

Arrggh! Invalid Binary on app submission

Remember when I was so pleased I was able to submit my app the other day? Well, I happened to check into iTunes connect today out of pure luck, when I saw that I had an "invalid binary". There wasn't any email, nor any error message in the submission process. It could have been a week or two before I went to in to check. Why is apple so frikking unhelpful??

Anyway, so, the first thing to do is change the status back to prepare for upload, which is something you have to do by pressing a button on your app in the itunes connect version details.

Then, as soon as your app finishes uploaded, refresh the the browser, and you'll see immediately if it's an invalid binary.

They seem not to send out emails to most people, but some do get them. It's a form email that give some ideas. Someone posted an image on SO:




So, this seems like a good post to check try:



Your not using the correct certificates when building your app. Delete your certificates in Provisioning Portal and create new ones and update them in Xcode.

// which certificates? Development? Distribution?

Goto Organizer / Provisioning Profiles / Refresh and allow Xcode to fetch the latest ones.

Again, clean all of your targets. You can even go to /Users/%USERNAME%/Library/Developer/Xcode/DerivedData and delete all of the directories in there (mainly your app in question).

Then Under TARGET in Xcode, goto Build Settings and choose the NEW certificates.

Also, use Archive *(under Product in Xcode 4.0+)* in Xcode. When the build is complete, Organizer should open to your Application Archives, if not, go there and click on Archives. Select your app and choose Validate..., once your app is validated, click Submit....

Another thing to note is that Entitlements.plist is no longer needed, so that is not an issue for you.



I wish I had a better understanding of the *model* of the certificates. When do you need a developer vs. a distribution certificate? What key am I supposed to sign them with? Why would recreating the certificates make a difference? What's the difference between a certificate signing request, a certificate, and a signed certificate? Where and what is the key they get signed with? Are they stored in XCode? What's the difference between a provisioning profile and a certificate? What is the ".mobileprofile" for? Are the profile and the certificate the same thing? How does Xcode know what profile it's using? Where does it store it?

With these question in mind, let's again go here:

http://developer.apple.com/library/mac/#documentation/ToolsLanguages/Conceptual/Xcode4UserGuide/DistApps/DistApps.htm

This is XCode 4's version of how to submit an app.


Before submitting an application to the App Store or share it with others, you create an application archive.


You can then share your application archive with application testers and other application developers or distribute it to users.

To have the application considered for inclusion on the App store, you submit the archive to iTunes Connect.

To ensure your application archive passes essential iTunes Connect validation tests, you can have Xcode validate it before you submit it.



Archive Your Application

Before archiving your application, ensure that the binary is self contained. That is, if it relies on static libraries, ensure that those libraries are part of the application binary by setting the Skip Install build setting to Yes in the Release build configuration of the target that builds and archives the application.



Why is this called "Skip Install"? This varies with other advice to set that setting to "no", and set the actual static libraries to "yes". But how do you set the actual static librararies to yes? I just created a folder for them - there doesn't seem to be anything I can set the actual static library to.

This is one possible issue in submitting my binary.

To archive your application . . .

From the Scheme pop-up menu, choose a scheme.

From the same menu, choose Edit Active Scheme to display the scheme dialog.

In the left column, select Archive.

Choose a build configuration.

Specify a name for the archive and click OK.

Choose Product > Archive.


Ok, this isn't a problem. I can do this, although the helpful (snicker) documentation doesn't bother telling you where the scheme pop-up menu is (click the bar on the upper left where you specify the app name and where it's going to run).



An archive is a bundle that includes your product along with symbol information. You can build an archive to seed an application for testing or to validate and submit an application to iTunes Connect.

Your new archive appears in the Archives list in the Organizer window, unless you turn off this option. Each archive is identified in the archives organizer with the date and time it was created. For more information, see the related article on the archives organizer.


Ok, to look at the organizer, you can click on the organizer icon. I did have a problem with getting it to show up there, but that had something to do with the Skip something build setting mentioned above.

Validate Your Application and Submit It to the App Store

When you’re ready to publish your application to users on the App Store, you need to enter information about it in iTunes Connect. You should also validate your application on your computer to ensure it passes essential iTunes Connect validation tests. Before you can validate your application or submit it to the App Store, you must archive it, as described in “Archive Your Application.”

Before validating your application or submitting it to iTunes Connect:

Ensure an application record for the application exists in iTunes Connect. The information in this record must match the application you want to validate or submit to the App Store.

These are the main matching criteria:

Application Name

Bundle ID

Version


Ok, this bundle id is a bit confusing. There is the iTunes record. Which originally required a bundle id, plus the bundle id suffix when entering it, and the bundle id suffix was actually com.kanjisoft.jlptvocabquiz, although I managed to screw that up.

But now, when I look at the itunes application information, the Bundle ID com.kanjisoft.jlptvocabquiz, so presumably that's when the bundle ID has to be. I'm also assuming that the bundle id in the applications plist needs to match that. I change the bundle id in my application's plist, and got through that problem - I think.


Ensure the application record status in iTunes Connect is at least Waiting for Upload.


Ok, this works. All I need to do for this is press the button, something like "prepare for upload" on the version details page in iTunes.

For more information about iTunes Connect, visit https://itunesconnect.apple.com.

Submit your application to iTunes Connect for publication on the App Store. Before submitting your application for publication, you should validate it to ensure that it passes standard iTunes Connect checks


Yeah, this isn't going to be very helpful. It validated my app, but I got invalid binary anyway. Well, at least it caught a couple of issues.

To validate and submit your application to the App Store . . .

In the archives organizer, select the application archive, and click Validate or Submit.

Enter your iTunes Connect credentials, and click Next.

Choose the application to share and the appropriate signing identity, and click Next.

Review validation issues found, if any, and click Finish.



Ok. So, this lame documentation doesn't really give much info as to what you really need to do. It doesn't even refer you to the iOS developer's portal, and its horrifically complex process for getting developer certificates, profiles, signing requests, and incorporating them into the submission process.

Ok, so, let's go to the developer's portal now review all that mess.

The link we want to review there is the provisioning portal, on the upper right.

What? Now that I'm taking my time, instead of rushing desperately to get it done like I usually do, I see a few videos off to the right.

"Obtaining Certificates" (nice), "Assigning Devices" (I think I've already done this), "Creating your App ID's" (I already have one), and "Creating Provisioning Profiles" (nice).

Ok, so let's check out obtaining certificates.

Well, it's not exactly You-Tube.

Ok, here it is. Ok, so, they're talking about developer certificates for running on a device. A certificate has information - a digital identity - which has information like your company name.

This digital identity consists of a secret private key and a public key.

XCode4 use this to sign your app.

So, this is a connect from XCode 4 to your certificate.

The first step is to create a certificate signing request (why not a certificate creation request? then a csr).

You first need to launch keychain access. (This is all for the developer certificate to run on your iPhone)

Got to preferences, certificates, set protocols off.

Then, go to Certificate Assistant and select Request a certificate from a certificate authority.

Ok, so this make more sense - requesting the actual certificate.

Give your email address and name - maybe company name? No, they say team leader. Whatever.

You don't need to enter the CA authority email - it's being uploaded directly.

The old specify save to disk, and let me specify key pair information. This is to make sure you are requesting 2048 key size and RSA.

Ok, now save to disk. The suffix is actually .CertificateSigningRequest.

This immediately creates your private key, which can be viewed under "keys" in the KeyChain access.

The CSR needs to be uploaded to the program portal - Certificates (left column) and the "Development" tab, then click "Add Certificate" (why not name up submit CSR? anyway, this video is pretty good).

Ah, ok, next you click on the upload CSR button. Or, choose file and submit.

Then, you watch this to see if the CSR is approved. If it's approved, you click download.

It's called "developer_identity.cer".

When you double click on that, it installs it into keychain.

When you click on ok, the certificate gets installed into keychain.

And that's it. What a nice, crystal clear video. Btw, if you click on "myCertificates" you'll just see the ones you created personally.

Ok. Let's try the provision profile.

First of all, it's something that ties your app and development team and something else together so you can run your app on other machines? I'll have to re-listen to that. I don't really get why they don't give a rewind button. Every video player ever invented provides that. What's their issue? At least they give a pause button.

This has to be on every machine that you run your app on.

It has an app id, certificates, and the device id. Ok, that's interesting. What kind of certificate did he say - development or distribution?

Because of the multiple apps, a single device can have multiple provisioning profiles.

So, this one's apparently for development. So, in other words, creating the certificate is step one, the provisioning is step 2 - even for just the development, forget about uploading to the app store for now. This is just to get it onto your machine.

So, you have to go to provisioning, development tab, then click add profile. This is the id of the provisioning profile on your device.

So, it will show you the certificate you just created, the app id (where did that come from - probably one of the previous steps I skipped over) and the devices (also added previously, no doubt). You select the relevant choices, and click submit to generate the provision profile.

You need to download and install it to get the app running on your device.

All team members are allowed to do this.

Once you've downloaded it, drag it to Organizer / devices, or drag it to xcode.

Ok, that's fine. However, that doesn't cover distribution.

My question is, why this grid:

Certificates: Developer Distribution
Provisioning Developer Distribution
Distribution Distribute Application

Ok, well, under the third entry, here are the steps:


Obtaining your iOS Distribution Certificate
Create and download your iOS Distribution Provisioning Profile for App Store Distribution
Creating and Downloading a Distribution Provisioning Profile for Ad Hoc Distribution
Building your Application with Xcode for Distribution
Verifying a Successful Distribution Build
Updating your Application


Ok, so I guess a distribution certificate is different than the developer id certificate.

The same way the provisioning profile is different for developer and distribution.

So, let's redo these steps and see if it makes any difference.

First, let's create the CSR:

Generating a Certificate Signing Request

To request an iOS Distribution Certificate, you first need to generate a Certificate Signing Request (CSR) utilizing the Keychain Access application in Mac OS X Leopard. The creation of a CSR will prompt Keychain Access to simultaneously generate your public and private key pair establishing your iOS Distribution identity. Your private key is stored in the login Keychain by default and can be viewed in the Keychain Access application under the ‘Keys’ category. To generate a CSR:

In your Applications folder, open the Utilities folder and launch Keychain Access.
In the Preferences menu, set Online Certificate Status Protocol (OSCP) and Certificate Revocation List (CRL) to “Off”.
OCSP Preferences
Choose Keychain Access -> Certificate Assistant -> Request a Certificate from a Certificate Authority. Note: If you have a private key highlighted in the Keychain during this process, the resulting Certificate Request will not be accepted by the Provisioning Portal. Confirm that you are selecting “Request a Certificate From a Certificate Authority...” and not selecting “Request a Certificate From a Certificate Authority with …”

Request a Certificate

In the User Email Address field, enter your email address. Please ensure that the email address entered matches the information that was submitted when you registered as an iOS Developer.
In the Common Name field enter your Company/Organization/Department name. Please ensure that the name entered matches the information that was submitted when you registered as an iOS Developer.
No CA Email Address is required.
Select the ‘Saved to Disk’ radio button and if present, select ‘Let me specify key pair information’ and click ‘Continue’.
Save Certificate to Disk
If ‘Let me specify key pair’ was selected, specify a file name and click ‘Save’. In the following screen select ‘2048 bits’ for the Key Size and ‘RSA’ for the Algorithm. Click ‘Continue’.
Key Pair Information
The Certificate Assistant will create a CSR file on your desktop.



This whole process is designed to create the CSR, then download it and add it to the keychain. This will be a distribution certificate.


Ok, well, I tried deleting the build directory and recreating, but that didn't work. I still get the invalid binary.

Well, I could try deleting the certificates, as suggested here:

Your not using the correct certificates when building your app. Delete your certificates in Provisioning Portal and create new ones and update them in Xcode. Goto Organizer / Provisioning Profiles / Refresh and allow Xcode to fetch the latest ones.

Again, clean all of your targets. You can even go to /Users/%USERNAME%/Library/Developer/Xcode/DerivedData and delete all of the directories in there (mainly your app in question).

Then Under TARGET in Xcode, goto Build Settings and choose the NEW certificates.

Also, use Archive *(under Product in Xcode 4.0+)* in Xcode. When the build is complete, Organizer should open to your Application Archives, if not, go there and click on Archives. Select your app and choose Validate..., once your app is validated, click Submit....

Another thing to note is that Entitlements.plist is no longer needed, so that is not an issue for you.



Well, I tried replacing the distribution certificate/profile. That didn't work. I also tried zipping up the .app file and submitting it through the application loader, but that didn't work. So, I guess I'm just going to create a new project from scratch, and create a new app. That ought to do the trick.

What's the matter with Apple? Why don't they at least tell you why the app won't submit? Harummph.

No comments:

Post a Comment