command-line build - Xcode "Construir y archivar" desde la línea de comandos




project from (16)

Xcode 3.2 ofrece una característica nueva e impresionante en el menú Crear, "Crear y archivar", que genera un archivo .ipa adecuado para la distribución Ad Hoc. También puede abrir el Organizador, ir a "Aplicaciones archivadas" y "Enviar aplicación a iTunesConnect".

¿Hay alguna forma de usar "Crear y archivar" desde la línea de comandos (como parte de un script de compilación)? xcodebuild que xcodebuild estaría involucrado de alguna manera, pero la página de man no parece decir nada sobre esto.

ACTUALIZACIÓN Michael Grinich solicitó una aclaración; esto es exactamente lo que no puede hacer con las compilaciones de línea de comandos, características que SOLO puede hacer con el Organizador de Xcode después de "Construir y archivar".

  1. Puede hacer clic en "Compartir aplicación ..." para compartir su IPA con los probadores beta. Como señala Guillaume a continuación, debido a la magia de Xcode, este archivo IPA no requiere un archivo .mobileprovision distribuido por separado que los probadores beta necesitan instalar; eso es magico Ningún script de línea de comandos puede hacerlo. Por ejemplo, el guión de Arrix (presentado el 1 de mayo) no cumple con ese requisito.
  2. Y lo que es más importante, una vez que haya probado la versión beta de una compilación, puede hacer clic en "Enviar solicitud a iTunes Connect" para enviar esa misma compilación EXACTA a Apple, el mismo binario que probó, sin reconstruirla. Eso es imposible desde la línea de comandos, porque firmar la aplicación es parte del proceso de compilación; puede firmar bits para la prueba beta Ad Hoc O puede firmarlos para enviarlos a la App Store, pero no a ambos. Ninguna IPA construida en la línea de comandos puede ser probada en versión beta en teléfonos y luego enviarse directamente a Apple.

Me encantaría que alguien viniera y me demostrara que estoy equivocado: estas dos funciones funcionan muy bien en la GUI de Xcode y no se pueden replicar desde la línea de comandos.


Answers

Actualizando mi respuesta con Xcode 9 y Swift

Archivo

xcodebuild -workspace <ProjectName>/<ProjectName>.xcworkspace -scheme <schemeName> clean archive -configuration release -sdk iphoneos -archivePath <ProjectName>.xcarchive

Exportación IPA ( tenga en cuenta el plist de opción de exportación )

xcodebuild -exportArchive -archivePath  <ProjectName>.xcarchive -exportOptionsPlist  <ProjectName>/exportOptions.plist -exportPath  <ProjectName>.ipa

Para aquellos que no conocen exportOptions.plist, https://blog.bitrise.io/new-export-options-plist-in-xcode-9

Aquellos que usaron esto para construir proyectos en herramientas de CI / CD como teamcity / jenkins, asegúrese de estar usando el código x correcto instalado en el agente de compilación para archivar y exportar.

Puede utilizar cualquiera de las 2 opciones siguientes para esto.

  1. Utilice la ruta completa a xcodebuild,

/Applications/Xcode 9.3.1.app/Contents/Developer/usr/bin/xcodebuild

  1. Utilice xcode-select,

xcode-select -switch /Applications/Xcode 9.3.1.app

Abajo esta la vieja respuesta

Aquí está la secuencia de comandos de línea de comandos para crear el archivo y el ejemplo de IPA. Tengo un proyecto xcode para iPhone, que se encuentra en la carpeta Desktop / MyiOSApp.

Ejecutar los siguientes comandos uno por uno.

cd /Users/username/Desktop/MyiOSApp/

xcodebuild -scheme MyiOSApp archive \
    -archivePath /Users/username/Desktop/MyiOSApp.xcarchive

xcodebuild -exportArchive -exportFormat ipa \
    -archivePath "/Users/username/Desktop/MyiOSApp.xcarchive" \
    -exportPath "/Users/username/Desktop/MyiOSApp.ipa" \
    -exportProvisioningProfile "MyCompany Distribution Profile"

Esto se prueba con Xcode 5 y funciona bien para mí.


En realidad, PUEDES renunciar a una compilación, al igual que XCode, para que puedas probar y enviar el mismo binario. Por ejemplo, en mi script (similar a los anteriores) compilo mi versión de lanzamiento firmada como una compilación AdHoc, luego la archivo como una API para la prueba, luego renuncio a mi certificado de distribución y creo un archivo zip, que es lo que envío a Manzana. La línea relevante es:

codesign -f -vv -s "$DistributionIdentity" "$APPDIR"

La herramienta xcodebuild puede crear y exportar productos de archivo con el indicador -exportArchive (a partir de Xcode 5). Anteriormente, el paso de exportación solo era posible a través de la interfaz de usuario de Xcode Organizer.

Primero archiva tu aplicación:

xcodebuild -scheme <scheme name> archive

Dado $ARCHIVE_PATH (la ruta al archivo .xcarchive ), exporte la aplicación desde el archivo con uno de los siguientes:

archivo .ipa de iOS:

xcodebuild -exportArchive -exportFormat ipa -archivePath "$ARCHIVE_PATH" -exportPath "myApp.ipa" -exportProvisioningProfile "My App Provisioning profile"

Archivo .app de Mac:

xcodebuild -exportArchive -exportFormat app -archivePath "$ARCHIVE_PATH" -exportPath "myApp.app" -exportSigningIdentity "Developer ID Application: My Software Company"

En ambos comandos, los argumentos -exportProvisioningProfile y -exportSigningIdentity son opcionales. man xcodebuild para detalles sobre la semántica. En estos ejemplos, el perfil de aprovisionamiento para la compilación de iOS especificó un perfil de aprovisionamiento de distribución AdHoc, y la identidad de firma para la aplicación Mac especificó un ID de desarrollador para exportar como una aplicación de terceros (es decir, no se distribuyó a través de la Mac App Store).


Descubrí cómo automatizar el proceso de compilación y archivo desde la línea de comandos. Acabo de escribir un artículo de blog que explica cómo se puede lograr eso.

El comando que tienes que usar es xcrun :

/usr/bin/xcrun -sdk iphoneos PackageApplication \
-v "${RELEASE_BUILDDIR}/${APPLICATION_NAME}.app" \
-o "${BUILD_HISTORY_DIR}/${APPLICATION_NAME}.ipa" \
--sign "${DEVELOPER_NAME}" \
--embed "${PROVISONING_PROFILE}"

Encontrarás todos los detalles en el artículo . Si tiene alguna pregunta, no dude en preguntar.


Xcode 8:

Formato IPA:

xcodebuild -exportArchive -exportFormat IPA -archivePath MyMobileApp.xcarchive -exportPath MyMobileApp.ipa -exportProvisioningProfile 'MyMobileApp Distribution Profile'

Exporta el archivo MyMobileApp.xcarchive como un archivo IPA a la ruta MyMobileApp.ipa utilizando el perfil de aprovisionamiento MyMobileApp Distribution Profile.

Formato de APP:

xcodebuild -exportArchive -exportFormat APP -archivePath MyMacApp.xcarchive -exportPath MyMacApp.pkg -exportSigningIdentity 'Developer ID Application: My Team'

Exporta el archivo MyMacApp.xcarchive como un archivo PKG a la ruta MyMacApp.pkg usando la aplicación de aplicación de identificación de cationes Identificación de desarrollador Aplicación: Mi equipo. Identidad de firma del instalador Instalador de ID de desarrollador: Mi equipo se usa implícitamente para firmar el paquete exportado.

Página del manual de Xcodebuild


¿Te refieres a las opciones de validar / compartir / enviar? Creo que son específicos de Xcode y no son adecuados para una herramienta de compilación de línea de comandos.

Con algo de astucia, apuesto a que podrías hacer un guión para hacerlo por ti. Parece que solo están almacenados en ~/Library/MobileDevice/Archived Applications/ con un UUDI y un plist. No puedo imaginar que sea tan difícil hacer una ingeniería inversa del validador tampoco.

El proceso que me interesa automatizar es enviar compilaciones a los probadores beta. (Como el envío de la App Store es poco frecuente, no me importa hacerlo manualmente, especialmente porque a menudo necesito agregar un nuevo texto de descripción). Al hacer un pseudo Build + Archive utilizando la CLI de Xcode, puedo activar compilaciones automáticas desde cada confirmación de código, cree archivos IPA con perfiles de aprovisionamiento integrados y envíelos por correo electrónico a los evaluadores.


He estado usando mi propio script de compilación para generar el paquete ipa para la distribución ad hoc.

die() {
    echo "$*" >&2
    exit 1
}

appname='AppName'
config='Ad Hoc Distribution'
sdk='iphoneos3.1.3'
project_dir=$(pwd)

echo using configuration $config

echo updating version number
agvtool bump -all
fullversion="$(agvtool mvers -terse1)($(agvtool vers -terse))"
echo building version $fullversion

xcodebuild -activetarget -configuration "$config" -sdk $sdk build || die "build failed"

echo making ipa...
# packaging
cd build/"$config"-iphoneos || die "no such directory"
rm -rf Payload
rm -f "$appname".*.ipa
mkdir Payload
cp -Rp "$appname.app" Payload/
if [ -f "$project_dir"/iTunesArtwork ] ; then
    cp -f "$project_dir"/iTunesArtwork Payload/iTunesArtwork
fi

ipaname="$appname.$fullversion.$(date -u +%Y%m%d%H%M%S).ipa"
zip -r $ipaname Payload

echo finished making $ipaname

El script también incrementa el número de versión. Puede eliminar esa parte si no es necesario. Espero eso ayude.


Encontré algunas de las otras respuestas aquí difíciles de seguir. Este artículo lo hizo si para mí. Es posible que algunos caminos deban ser absolutos, como se menciona en las otras respuestas.

El comando:

xcrun -sdk iphoneos PackageApplication \
    "/path/to/build/MyApp.app" \
    -o "output/path/to/MyApp.ipa" \
    --sign "iPhone Distribution: My Company" \
    --embed "/path/to/something.mobileprovision"

Desarrollamos una aplicación para iPad con XCode 4.2.1 y queríamos integrar la compilación en nuestra integración continua (Jenkins) para la distribución OTA. Aquí está la solución que se me ocurrió:

# Unlock keychain
security unlock-keychain -p jenkins /Users/jenkins/Library/Keychains/login.keychain

# Build and sign app
xcodebuild -configuration Distribution clean build

# Set variables
APP_PATH="$PWD/build/Distribution-iphoneos/iPadApp.app"
VERSION=`defaults read $APP_PATH/Info CFBundleShortVersionString`
REVISION=`defaults read $APP_PATH/Info CFBundleVersion`
DATE=`date +"%Y%m%d-%H%M%S"`
ITUNES_LINK="<a href=\"itms-services:\/\/?action=download-manifest\&url=https:\/\/xxx.xxx.xxx\/iPadApp-$VERSION.$REVISION-$DATE.plist\">Download iPad2-App v$VERSION.$REVISION-$DATE<\/a>"

# Package and verify app
xcrun -sdk iphoneos PackageApplication -v build/Distribution-iphoneos/iPadApp.app -o $PWD/iPadApp-$VERSION.$REVISION-$DATE.ipa

# Create plist
cat iPadApp.plist.template | sed -e "s/\${VERSION}/$VERSION/" -e "s/\${DATE}/$DATE/" -e "s/\${REVISION}/$REVISION/" > iPadApp-$VERSION.$REVISION-$DATE.plist

# Update index.html
curl https://xxx.xxx.xxx/index.html -o index.html.$DATE
cat index.html.$DATE | sed -n '1h;1!H;${;g;s/\(<h3>Aktuelle Version<\/h3>\)\(.*\)\(<h3>&Auml;ltere Versionen<\/h3>.<ul>.<li>\)/\1\
${ITUNES_LINK}\
\3\2<\/li>\
<li>/g;p;}' | sed -e "s/\${ITUNES_LINK}/$ITUNES_LINK/" > index.html

Luego, Jenkins carga los archivos ipa, plist y html en nuestro servidor web.

Esta es la plantilla de plist:

<?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>items</key>
    <array>
        <dict>
            <key>assets</key>
            <array>
                <dict>
                    <key>kind</key>
                    <string>software-package</string>
                    <key>url</key>
                    <string>https://xxx.xxx.xxx/iPadApp-${VERSION}.${REVISION}-${DATE}.ipa</string>
                </dict>
                <dict>
                    <key>kind</key>
                    <string>full-size-image</string>
                    <key>needs-shine</key>
                    <true/>
                    <key>url</key>
                    <string>https://xxx.xxx.xxx/iPadApp.png</string>
                </dict>
                <dict>
                    <key>kind</key>
                    <string>display-image</string>
                    <key>needs-shine</key>
                    <true/>
                    <key>url</key>
                    <string>https://xxx.xxx.xxx/iPadApp_sm.png</string>
                </dict>
            </array>
            <key>metadata</key>
            <dict>
                <key>bundle-identifier</key>
                <string>xxx.xxx.xxx.iPadApp</string>
                <key>bundle-version</key>
                <string>${VERSION}</string>
                <key>kind</key>
                <string>software</string>
                <key>subtitle</key>
                <string>iPad2-App</string>
                <key>title</key>
                <string>iPadApp</string>
            </dict>
        </dict>
    </array>
</dict>
</plist>

Para configurarlo, debe importar el certificado de distribución y el perfil de aprovisionamiento en el llavero del usuario designado.


Ve a la carpeta donde está la raíz de tu proyecto y:

xcodebuild -project projectname -activetarget -activeconfiguration archive

Para Xcode 7 , tienes una solución mucho más simple. El único trabajo adicional es que tiene que crear un archivo plist de configuración para exportar el archivo.

(En comparación con Xcode 6, en los resultados de xcrun xcodebuild -help , -exportFormat y -exportProvisioningProfile opciones no se mencionan más; el primero se elimina y el último se reemplaza por -exportOptionsPlist .)

Paso 1 , cambie el directorio a la carpeta que incluye el archivo .xcodeproject o .xcworkspace.

cd MyProjectFolder

Paso 2 , use Xcode o /usr/libexec/PlistBuddy exportOptions.plist para crear un archivo plist de opciones de exportación. Por cierto, xcrun xcodebuild -help le dirá qué claves debe insertar en el archivo plist.

Paso 3 , cree el archivo .xcarchive (carpeta, de hecho) como sigue (Xcode creará automáticamente el directorio / compilación en este momento),

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

Paso 4 , exportar como un archivo .ipa como este, que difiere de Xcode6

xcrun xcodebuild -exportArchive -exportPath build/ -archivePath build/MyApp.xcarchive/ -exportOptionsPlist exportOptions.plist

Ahora, obtienes un archivo ipa en el directorio build /. Simplemente envíalo a Apple App Store.

Por cierto, el archivo ipa creado por Xcode 7 es mucho más grande que por Xcode 6.


Yendo un paso más allá, subiendo a iTunesConnect a través de la línea de comandos con Xcode 7 . (Suponiendo que está comenzando con una .ipa firmada con el perfil de lanzamiento y la identidad de firma correctos).

Ingrese altool , la interfaz CLI para el Cargador de aplicaciones ( docs , página 38). Oculto en la estructura de Xcode.app, es una función útil que nos permite cargar directamente a ItunesConnect.

/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/altool

Simplemente ejecute $ altool --upload-app -f file -u username [-p password] para cargar su .ipa recién acuñado directamente a Apple. La contraseña es opcional y se la solicitará si la deja fuera del comando.

Si hay algún problema con la aplicación durante el paso de verificación, la consola los imprimirá.

Es probable que tenga que exportar la ruta a altool si no desea guardar su ubicación.

export PATH=$PATH:/Applications/Xcode.app/Contents/Applications/Application\ Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/

¡Eso es! Simplemente inicie sesión en iTunesConnect.com y seleccione su nueva versión para probarla con testflight.

Nota final: si recibe un error que dice Exception while launching iTunesTransporter: Transporter not found at path: /usr/local/itms/bin/iTMSTransporter. You should reinstall the application Exception while launching iTunesTransporter: Transporter not found at path: /usr/local/itms/bin/iTMSTransporter. You should reinstall the application , puede seguir la sugerencia en esta respuesta SO , para ejecutar un enlace simbólico a la ubicación correcta:

ln -s /Applications/Xcode.app/Contents/Applications/Application\ Loader.app/Contents/itms /usr/local/itms

Con Xcode 4.2 puedes usar la bandera -scheme para hacer esto:

xcodebuild -scheme <SchemeName> archive

Después de este comando, el archivo se mostrará en el organizador de Xcode.


He dado una breve descripción de los pasos a seguir y los parámetros que se deben pasar al generar un ipa utilizando terrminal a continuación:

  1. Vaya a la carpeta que contiene el archivo MyApp.xcodeproject en el terminal

  2. Al utilizar el comando que se proporciona a continuación, obtendrá todos los objetivos de la aplicación.

    /usr/bin/xcodebuild -list 
    
  3. Después de que se ejecute el comando anterior, obtendrá una lista de objetivos de los cuales debe seleccionar un objetivo específico que necesita generar .ipa

    /usr/bin/xcodebuild -target $TARGET -sdk iphoneos -configuration Release
    
  4. El comando anterior construye el proyecto y crea un archivo .app. La ruta para ubicar el archivo ./build/Release-iphoneos/MyApp.app es ./build/Release-iphoneos/MyApp.app

  5. Una vez que la compilación sea exitosa, ejecute el siguiente comando para generar .ipa de la aplicación usando el nombre de desarrollador y el perfil de aprovisionamiento usando la siguiente sintaxis:

    /usr/bin/xcrun -sdk iphoneos PackageApplication -v “${TARGET}.app” -o “${OUTDIR}/${TARGET}.ipa” –sign “${IDENTITY}” –embed “${PROVISONING_PROFILE}”
    

Explicación de cada parámetro en la sintaxis anterior:

${TARGET}.app                == Target path (ex :/Users/XXXXXX/desktop/Application/build/Release-iphoneos/MyApp.app)
${OUTDIR}                    == Select the output directory(Where you want to save .ipa file)
${IDENTITY}                   == iPhone Developer: XXXXXXX (XXXXXXXXXX)(which can be obtained from Keychain access)
${PROVISONING_PROFILE}   == Path to the provisioning profile(/Users/XXXXXX/Library/MobileDevice/Provisioning Profiles/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.mobileprovision”)
  1. ipa se generará en el directorio de salida seleccionado " $ {OUTDIR} "

Si usa la siguiente herramienta: https://github.com/nomad/shenzhen

Entonces esta tarea es muy fácil:

which ipa 1>/dev/null 2>&1 || echo 'no shenzhen. to install use: sudo gem install shenzhen --no-ri --no-rdoc'
ipa build --verbose --scheme "${schemeName}"

source


Me encontré con una situación similar. Sin embargo, mi solución fue de alguna manera diferente.

Al darse cuenta de que está intentando enviar la siguiente compilación, asegúrese de que su compilación anterior esté excluida del formulario de envío de App Store antes de cargar una nueva compilación.

No estoy seguro de por qué esto tiene que ser un problema, pero parece que el formulario de envío se debe borrar antes de recibir una nueva versión.







xcode command-line build