views:

846

answers:

3

I wrote a script that uses xcodebuild to generate an AdHoc build of an iPhone application.

I would like to edit this script to output the name of the Provisioning Profile used to sign the build.
This would allow me to include the Provisioning Profile in the zip that is automatically generated. This way, I could automatically send the archive to the AdHoc testers and be sure that they have the right Provisioning Profile to install the app.

Is there any way to extract the Provisioning Profile name or file used to sign the application:

  • from the builded and signed application
  • from the Xcode project (I don't want to manually parse the project.pbxproj file, as this solution might break in the next Xcode update)
  • any other way that is scriptable

Unforgiven suggested to use the command security to get the name of the certificate used to sign the app. Once you have this information, is there any way to then find the name of the Provisioning Profile?


Here is what I tried:

Sadly, the output of xcodebuild during the build does not contain this information. During the CodeSign step, there is the line:

/usr/bin/codesign -f -s "iPhone Distribution: My name" ...

but I can't match this with a certificate.

I looked into using codesign, and the command

/usr/bin/codesign -d -vvv --entitlements - -r - /Users/lv/Desktop/TicTacBoo.app/TicTacBoo
looked promising, but it doesn't give me the information I need.
I haven't found any useful option in xcodebuild either.

+1  A: 

You can use the "security" command from the terminal; unfortunately, at least on my MBP with Snow Leopard it appears to cause a segmentation fault in one of the commands you need to issue. For more information, issue from the terminal

man security

Anyway, here is what you can try, assuming your development/production certificates are stored in the login keychain:

security unlock-keychain login.keychain;
security find-certificate -a -c "iPhone Distribution: Your name"  -p > cert.pem;

The second command causes the segmentation fault (caused by the -c argument), but it should be exactly what you need. Alternatively, you can use

security find-identity -p codesigning -v;

to get a list of all of the valid certificates you can use to code sign your applications. For each certificate, the output also contains the SHA1 message digest, so that you can easily search the certificate in the keychain matching the SHA1 digest associated to "iPhone Distribution: Your name". This however, requires that you write your own application using the keychain APIs.

Let me know if this works on your mac or if you experience the same segmentation fault issue.

EDIT/UPDATE: I have verified the bug on other machines and filed a bug to Apple.

unforgiven
The three commands run fine on my machine (Mac OS X 10.6.2 - SDKs 3.1.3 and 3.2 beta 3 installed). No segfault.I realized I have not been very clear, but my final goal is to get the Provisionning Profile file (or filename). I have edited the question.
Guillaume
I am sorry, actually I was answering a strictly related question, how to retrieve the actual certificate used to sign the application, not the provisioning profile!
unforgiven
A: 

How about looking in the _CodeSignature/CodeResources plist file (of the built application) for files of type "mobileprovision"?

Here's a way to do that using defaults(1) to read the plist file. You have to copy the CodeResources file to something with the ".plist" suffix to keep defaults happy...

cp /build/Distribution-iphoneos/MyApp.app/_CodeSignature/CodeResources /tmp/defaults.plist
defaults read /tmp/defaults files |grep .mobileprovision |grep -v embedded.mobileprovision

(in my test case, there were 2 .mobileprovision entries there; ignore the one named "embedded.mobileprovision")

David Gelhar
Interesting. I only get 1 entry, which looks like that: "embedded.mobileprovision" = <d31e7825 222e71c0 83188040 37e4eec8 8b599d17>; But how do you match this string with the Provisioning Profile name?
Guillaume
+2  A: 

The provisioning profile is already in the application. You don't need another copy in your zip file (unless your testers do not understand how to use the copy inside of the application.)

It's named YourApplication.app/embedded.mobileprovision

This doesn't answer your question because the original filename is lost, however it does seem to solve your bigger problem.

Jon-Eric
Brilliant! And the file name is kept in the file, under the key "Name"
Guillaume
Here is a quick and hacky way to get the file name: strings path_to_embedded_file.mobileprovision | grep -A1 '<key>Name</key>' | tail -n1 | awk -F'<string>' '{print $2}' | awk -F'</string>' '{print $1}'
Guillaume