Preparing iOS apps for App Store submission in IBM MobileFirst Foundation 8.0

Update : The steps provided below are applicable only if your Xcode version is 8.2.1 / cocoapod version 1.1.0 or below and the MobileFirst iOS SDK is manually added to your project. If the MobileFirst iOS SDK is added to your project using cocoapods with version 1.1.1 or later, the i386 and x86_64 architecture slices of dynamic frameworks are automatically removed during IPA generation.

Starting IBM MobileFirst Foundation 8.0, the iOS Client SDK for Cordova and Native applications was modified to be a dynamic framework. When an archive/IPA files are generated using Test Flight or iTunes Connect for store submission/validation, this might cause a runtime crash/fail with following error:

validation errors

This is because the i386 and x86_64 architecture slices are bundled within IBMMobilefirstPlatformfoundation.framework. These architecture slices are bundled so that an application with the SDK could run on simulators as well. iTunes Connect and TestFlight do not support applications which include unused binary slices, hence while publishing to the App Store or while using Archives for testing, the app crashes during runtime or fails during validation. This is a known Xcode defect for dynamic frameworks.

The following steps mentioned by Daniel Kennett in his blog post will help resolve the above issue by removing unused/unsupported architectures (i386/x86_64) from dynamic frameworks and will ensure that the application will work as expected without any crash/failures.

  1. Select Build Phases tab in Xcode project settings

  2. Add new Run Script Phase

  3. Paste the following script inside Run Script tab

APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"

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"

    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
Inclusive terminology note: The Mobile First Platform team is making changes to support the IBM® initiative to replace racially biased and other discriminatory language in our code and content with more inclusive language. While IBM values the use of inclusive language, terms that are outside of IBM's direct influence are sometimes required for the sake of maintaining user understanding. As other industry leaders join IBM in embracing the use of inclusive language, IBM will continue to update the documentation to reflect those changes.
Last modified on June 28, 2017