iOS builds / ipa creation no longer works from the command line

Apple got back to me with a solution. As of Xcode 7 we should use xcodebuild instead of PackageApplication to produce the .ipa file.

xcodebuild has a new -exportArchive option to create an .ipa that works more like Xcode Organizer.

So we should now:

  1. build an archive with xcodebuild archive
  2. create the .ipa with xcodebuild -exportArchive

We now build the archive like this:

xcodebuild -workspace myApp.xcworkspace -scheme myApp -sdk iphoneos -configuration AppStoreDistribution archive -archivePath $PWD/build/myApp.xcarchive

We now export the .ipa like this:

xcodebuild -exportArchive -archivePath $PWD/build/myApp.xcarchive -exportOptionsPlist exportOptions.plist -exportPath $PWD/build

These two command create the files build/myApp.xcarchive and build/myApp.ipa

Note that xcodebuild -exportArchive requires a -exportOptionsPlist argument that points to a .plist file with export options. For a complete list of what you can put in that plist, run xcodebuild -help. The minimal contents of the file looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>method</key>
    <string>app-store</string>
    <key>teamID</key>
    <string>YOUR_TEN_CHARACTER_TEAM_ID</string>
</dict>
</plist>

In Xcode 9, you now have to specify more details in exportOptions.plist like below:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>compileBitcode</key>
  <false/>
  <key>method</key>
  <string>ad-hoc</string>
  <key>provisioningProfiles</key>
  <dict>
    <key>my.bundle.identifier</key>
    <string>My Provisioning Profile Name</string>
  </dict>
  <key>signingCertificate</key>
  <string>iPhone Distribution</string>
  <key>signingStyle</key>
  <string>manual</string>
  <key>stripSwiftSymbols</key>
  <true/>
  <key>teamID</key>
  <string>YOURTEAMID</string>
  <key>thinning</key>
  <string>&lt;none&gt;</string>
</dict>
</plist> 

Steps to make iPA Usig terminal

Clean Project:

Release

xcodebuild clean -project ProjectPath/myApp.xcodeproj -configuration  ReleaseAdhoc  -alltargets

Debug

xcodebuild clean -project ProjectPath/myApp.xcodeproj -configuration Debug -alltargets

Archive Project:

Debug

xcodebuild archive -project  ProjectPath/myApp.xcodeproj  -scheme “myApp” -configuration Debug  -archivePath  pathForArchiveFolder/myApp.xcarchive

Release

xcodebuild archive -project  ProjectPath/myApp.xcodeproj  -scheme “myApp”  -archivePath  pathForArchiveFolder/myApp.xcarchive

Export IPA

Older Version: This may give A signed resource has been added, modified, or deleted. Error

xcodebuild -exportArchive -archivePath  projectPath/myapp.xcarchive  -exportPath  projectPath/myApp.ipa  -exportFormat ipa  -exportProvisioningProfile  “provisioning profile”

New version:

xcodebuild -exportArchive -archivePath  ProjectPath/myapp.xcarchive  -exportPath  projectPath/myApp.ipa  -exportOptionsPlist  ProjectFolder/exportPlist.plist

Go to project folder:

Archive:

for DEBUG:

xcrun xcodebuild -scheme MyApp -configuration Debug archive -archivePath build/MyApp.xcarchive

for Release:

xcrun xcodebuild -scheme MyApp -configuration Release archive -archivePath build/MyApp.xcarchive

Fetch iPA:

xcrun xcodebuild -exportArchive -exportPath build/ -archivePath build/MyApp.xcarchive/

Here's a quick tip in case you need to create the exportOptions.plist file as part of your build process (maybe Jenkins).

You can use the plutil tool to turn JSON into a plist. Example:

echo "{\"method\":\"app-store\"}" | plutil -convert xml1 -o /tmp/exportOptions.plist -- -

Enjoy!