Fat binaries e Xcode 11

A partir do Xcode 11, o processo de exportar um ipa agora pode gerar um erro se o desenvolvedor tentar exportar um app que contenha fat binaries. Antes, descobririamos isso apenas no momento de enviar para a App Store, agora parece que o Xcode “resolveu” dar uma mão.

Se você já tentou fazer isso na versão 11, pode ter se deparado com esse erro:

#PraCegoVer: a imagem mostra a tela de Distribuição do App, com a mensagem de erro em inglês ‘IPA processing failed’.

Checando os logs, encontramos essa informação valiosa:

2020-03-22 22:14:41 +0000  /Applications/Xcode.app/Contents/Developer/usr/bin/ipatool exited with 1
2020-03-22 22:14:41 +0000  ipatool JSON: {
    alerts =     (
                {
            code = 3620;
            description = "Configuration issue: platform AppleTVSimulator.platform doesn't have any non-simulator SDKs; ignoring it";
            info =             {
            };
            level = WARN;
        },
                {
            code = 3620;
            description = "Configuration issue: platform WatchSimulator.platform doesn't have any non-simulator SDKs; ignoring it";
            info =             {
            };
            level = WARN;
        },
                {
            code = 3620;
            description = "Configuration issue: platform iPhoneSimulator.platform doesn't have any non-simulator SDKs; ignoring it";
            info =             {
            };
            level = WARN;
        }
    );
}

O problema dos fat binaries

Temos alguns problemas aqui. Além da rejeição do binário pela Apple, exportar um app com fat binaries acaba aumentando consideravelmente o tamanho do seu ipa exportado. Veja o exemplo abaixo:

Fat Binaries:

#PraCegoVer: a imagem mostra uma lista de arquivos, com o arquivo ipa do aplicativo selecionado, com o tamanho de 112 KB.

Striped archs:

#PraCegoVer: a imagem mostra uma lista de arquivos, com o arquivo ipa do aplicativo selecionado, com o tamanho de 57 KB.

Podemos ver que o ipa com fat binaries aumenta em 96% o tamanho do arquivo exportado em um exemplo simples, com apenas um Framework embbedado.

Remover as arquiteturas de simulador irá reduzir o tamanho do nosso ipa e fazer com a que a Apple aceite o upload do nosso app.

Removendo arquiteturas de simulador no build do seu app

Na Build Phase do seu app principal, adicione um novo run script e cole o código abaixo:

#PraCegoVer: a imagem mostra o editor de projeto do Xcode, com o target do aplicativo selecionado, na aba Build Phase, com o botão de mais clicado, exibindo uma lista em dropbox com a opção ‘New Run Script Phase’ selecionada.
APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"

# This script loops through the frameworks embedded in the application and
# removes unused architectures.
# If some frameword doesn't have an invalid architecture, the script does 
# nothing to it and just goes to the next one
find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK
do
    FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
    FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
    echo "Executable is $FRAMEWORK_EXECUTABLE_PATH"

    if xcrun lipo -info "${FRAMEWORK_EXECUTABLE_PATH}" | grep -v --silent "i386\|x86_64"; then
        echo "This framework does not contain simulator archs: $FRAMEWORK_EXECUTABLE_NAME"
        continue
    fi

    EXTRACTED_ARCHS=()

    for ARCH in $ARCHS
    do
        echo "Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME"
        lipo -extract "$ARCH" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$ARCH"
        EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$ARCH")
    done

    echo "Merging extracted architectures: ${ARCHS}"
    lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[@]}"
    rm "${EXTRACTED_ARCHS[@]}"

    echo "Replacing original executable with thinned version"
    rm "$FRAMEWORK_EXECUTABLE_PATH"
    mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"

done

Baseado no script original de Daniel Kennett, disponível em: https://medium.com/@maximbilan/ios-submission-unsupported-architectures-issues-733917a98cc3