Re-signing iOS apps

I am occasionally presented with a packaged iOS .ipa archive by a third-party developer, which is intended for in-house distribution (using an Apple Developer Enterprise certificate), or for App Store distribution using a different developer account.

Re-signing is a quick and simple way of delivering an app when a developer won’t provide you with their Xcode project source from which to spin your own build.

I previously used the iReSign utility to accomplish this, but found that this wouldn’t work in all cases, in particular when the app includes linked frameworks or libraries (which results in errors such as “DYLD, Library not loaded“).

To solve this I wrote the shell script below. It takes an existing .ipa archive, embeds your own developer provisioning profile, replaces any existing code signatures and packages it again for distribution.

Please use with my compliments and leave a comment if this helps you out.

(Note: This script has a dependency on command line tools such as PlistBuddy and codesign, so you will likely need to install Apple’s Xcode developer tools)

Replace DEVCERT with the Common Name of your own Apple developer certificate.

#!/bin/bash
# Re-sign an IPA with specified developer certificate (present in keychain)

DEVCERT="iPhone Distribution: Your Developer Cert Name"
TMPDIR="tmpwork"
SOURCEIPA="$1"
MOBILEPROV="$2"
BUNDLEID="$3"

if [ $# -eq 0 ]

then
  echo "Usage: $0 [app.ipa] [provprofile] [bundleid]"
else
  if [ ! -e "$SOURCEIPA" ]
  then
    echo "Error: $SOURCEIPA not found"
    exit
  fi

  if [ ! -e "$MOBILEPROV" ]
  then
    echo "Error: $MOBILEPROV not found"
    exit
  fi

  SIGNEDAPP=`echo $SOURCEIPA | awk -F".ipa" '{ printf ("%s-signed.ipa", $1) }'`
  unzip -qo "$SOURCEIPA" -d $TMPDIR
  APP=$(ls ${TMPDIR}/Payload/)

  if [ ! -z "$BUNDLEID" ]
  then
     echo "Changing Bundle ID to ${BUNDLEID}";
     /usr/libexec/PlistBuddy -c "Set:CFBundleIdentifier $BUNDLEID" "${TMPDIR}/Payload/${APP}/Info.plist"
  fi

  cp "$MOBILEPROV" "${TMPDIR}/Payload/${APP}/embedded.mobileprovision"
  security cms -D -i "${TMPDIR}/Payload/${APP}/embedded.mobileprovision" > Entitlements_full.plist
  /usr/libexec/PlistBuddy -x -c 'Print:Entitlements' Entitlements_full.plist > Entitlements.plist
  echo "Re-signing with certificate: $DEVCERT"

  for folder in `find -d ${TMPDIR} \( -name "*.app" -or -name "*.appex" -or -name "*.framework" -or -name "*.dylib" \)`; do
    /usr/bin/codesign --continue -f -s "$DEVCERT" --entitlements "Entitlements.plist" "$folder"
  done

  echo "Package the signed IPA"
  cd $TMPDIR
  zip -qry ../${SIGNEDAPP} *
  cd ..
  rm -rf $TMPDIR
  rm Entitlements_full.plist

fi
Advertisements

Xcode freezing when opening a project?

A possible solution to Xcode 4 freezing after you open a project:

If your Xcode project source path contains a space then rename it and try opening the project again. This is the most likely cause.

If it still freezes after renaming then do the following:

1. (Force) Close Xcode
2. Delete these cache files:

rm ~/Library/Caches/com.apple.dt.Xcode
rm ~/Library/Preferences/com.apple.Xcode.plist

3. Restart Xcode & keep your fingers crossed!