Submit to App Store issues: Unsupported Architectu

2019-01-02 16:43发布

So i am trying to use the shopify API. When i archive the app and validate it then there are no issues but when i submit it to the app store then it gives me the following issues.

  1. ERROR ITMS-90087: "Unsupported Architecture. Your executable contains unsupported architecture '[x86_64, i386]'."
  2. ERROR ITMS-90209: "Invalid segment Alignment. The App Binary at SJAPP.app/Frameworks/Buy.framework/Buy does not have proper segment alignment. Try rebuilding the app with the latest xcode version." (I am already using the latest version.)
  3. ERROR ITMS-90125: "The Binary is invalid. The encryption info in the LC_ENCRYPTION_INFO load command is either missing or invalid, or the binary is already encrypted. This binary does not seem to have been built with Apple's Linker."
  4. WARNING ITMS-90080: "The Executable Payload/..../Buy.framework is not a Position Independent Executable. Please ensure that ur build settings are configured to create PIE executables."

标签: ios xcode
15条回答
妖精总统
2楼-- · 2019-01-02 16:54

If you are using Carthage make sure your Embed Frameworks Build Step is before the Carthage copy-frameworks


In some unusual cases (example: Lottie-iOS framework):

  • you will have it simply in "Link Library" as usual.

  • However you have to also explicitly add it in "Embed Frameworks" (even though that seems pointless, since it works perfectly when you have it only in "Embed Frameworks"),

  • and put it in copy-frameworks

  • and ensure copy-frameworks is after "Embed Frameworks"

查看更多
余生请多指教
3楼-- · 2019-01-02 16:55

If you're using Carthage then you may experience this issue because the project is:

  • Missing the carthage copy-frameworks build phase.
  • Or the build phase doesn't include all the frameworks (incomplete list).

This action filters frameworks to a list of valid architectures (code).

Setting up the copy-frameworks build phase

From the Carthage building for iOS steps:

On your application targets’ “Build Phases” settings tab, click the “+” icon and choose “New Run Script Phase”. Create a Run Script in which you specify your shell (ex: bin/sh), add the following contents to the script area below the shell:

/usr/local/bin/carthage copy-frameworks

and add the paths to the frameworks you want to use under “Input Files”, e.g.:

$(SRCROOT)/Carthage/Build/iOS/Box.framework $(SRCROOT)/Carthage/Build/iOS/Result.framework $(SRCROOT)/Carthage/Build/iOS/ReactiveCocoa.framework

This script works around an App Store submission bug triggered by universal binaries and ensures that necessary bitcode-related files and dSYMs are copied when archiving.

查看更多
墨雨无痕
4楼-- · 2019-01-02 16:55

I will add my 2 cents here (in a less scary way :-). I have encountered quite a number of fat libraries from Vendors that (for some reason) do not work the normal way by adding them to the Frameworks directory as documented by Apple. The only way we have been able to make them work is by pulling the .framekwork right into the project directory and linking the Embedded Frameworks and Link Binary with Libraries manually in Build Settings. This seem to have worked without any issues, however, as with any fat library they come with the extraneous Simulator Architectures i386 and x86_64 along with the arm architectures.

A quick way to check the architectures on the fat library is

$ cd 'Project_dir/Project'
$ lipo -info 'YourLibrary.framework/YourLibExec`

Which should spit an output something like this

Architectures in the fat file: YourLibrary.framework/YourLibExec are: i386 x86_64 armv7 arm64

This confirms that you will need to "trim the fat" (namely i386 & x86_64) from your framework prior to iTunesConnect Archival upload, which doesn't allow these architectures (since they are unsupported for iOS).

Now, all the answers (or atleast some of the answers) here provide these wonderful Run Scripts that I am sure works really well, but only if your Framework resides in the Frameworks directory. Now unless you are a shell script junkie, those scripts without modifications, won't work for the scenario I explain above. However, there is a very simple way to get rid of the i386 & x86_64 architectures from the framework.

  1. Open terminal in your project's directory.
  2. Change directory directly into the .framekwork, like

    cd YourProjectDir/YourProject/YourLibrary.framework

  3. Run the series of commands as shown below-

    $ mv YourLibrary YourLibrary_all_archs

    $ lipo -remove x86_64 YourLibrary_all_archs -o YourLibrary_some_archs

    $ lipo -remove i386 YourLibrary_some_archs -o YourLibrary

    $ rm YourLibrary_all_archs YourLibrary_some_archs

A few things to note here - lipo -remove has to be done once for each architecture to remove. lipo does not modify the input file, it only produces a file so you have to run lipo -remove once for x86_64 and i386. The commands above is simply doing that by first renaming the executable and then eventually removing the desired archs, and then cleaning up the left over files. And that's it, you should now see a green check mark in Application Loader Archival upload to iTunesConnect.

Things to keep in mind : The above steps should only be done while production build, since the .framework will be stripped off the simulator architectures, builds on simulators will stop working (which is expected). In development environment, there should be no need to strip the architectures off of the .framework file since you want to be able to test on both Simulator and a physical device. If your fat library resides in the Frameworks folder in the project then please look at the accepted answer.

查看更多
无色无味的生活
5楼-- · 2019-01-02 17:02

Answer given by pAkY88 works, but I faced the same problem as Mario A Guzman in https://stackoverflow.com/a/35240555/5272316: once we cut off unused architectures we can't run script any more since it tries to remove not existing slices, because xcode doesn't re-embed binary every time. Idea was - just remove i386 and x86_64 slices when building for archive, so I modified script:

echo "Target architectures: $ARCHS"

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"
echo $(lipo -info "$FRAMEWORK_EXECUTABLE_PATH")

FRAMEWORK_TMP_PATH="$FRAMEWORK_EXECUTABLE_PATH-tmp"

# remove simulator's archs if location is not simulator's directory
case "${TARGET_BUILD_DIR}" in
*"iphonesimulator")
    echo "No need to remove archs"
    ;;
*)
    if $(lipo "$FRAMEWORK_EXECUTABLE_PATH" -verify_arch "i386") ; then
    lipo -output "$FRAMEWORK_TMP_PATH" -remove "i386" "$FRAMEWORK_EXECUTABLE_PATH"
    echo "i386 architecture removed"
    rm "$FRAMEWORK_EXECUTABLE_PATH"
    mv "$FRAMEWORK_TMP_PATH" "$FRAMEWORK_EXECUTABLE_PATH"
    fi
    if $(lipo "$FRAMEWORK_EXECUTABLE_PATH" -verify_arch "x86_64") ; then
    lipo -output "$FRAMEWORK_TMP_PATH" -remove "x86_64" "$FRAMEWORK_EXECUTABLE_PATH"
    echo "x86_64 architecture removed"
    rm "$FRAMEWORK_EXECUTABLE_PATH"
    mv "$FRAMEWORK_TMP_PATH" "$FRAMEWORK_EXECUTABLE_PATH"
    fi
    ;;
esac

echo "Completed for executable $FRAMEWORK_EXECUTABLE_PATH"
echo $(lipo -info "$FRAMEWORK_EXECUTABLE_PATH")

done

This script simply removes i386 and x86_64 slices from fat binary (if they exist) if running not for simulator (that means destination folder isn't like "Debug-iphonesimulator").

Sorry, I'm not familiar with shell scripts, so may be someone could write it more elegant way. But it works)

查看更多
十年一品温如言
6楼-- · 2019-01-02 17:03

Thanks to all above answers. Here is script working with swift 4.2

APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
FRAMEWORK_NAME="Your_Framework_Name.framework"
# Check if Framework is present.
FRAMEWORK_LOCATION=$(find "$APP_PATH" -name "$FRAMEWORK_NAME" -type d)
if [ -z $FRAMEWORK_LOCATION ]; then
echo "Couldn't find Your_Framework_Name.framework in $APP_PATH. Make sure 'Embed Frameworks' build phase is listed before the 'Strip Unused Architectures' build phase."
exit 1
fi
# This script strips unused architectures
find "$APP_PATH" -name "$FRAMEWORK_NAME" -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
查看更多
梦寄多情
7楼-- · 2019-01-02 17:05

I had same issue even after adding the script and updating the framework a few times.

Make sure in xCode the script is added at the end, after the embed. I think I accidentally moved the script before the embedded framework.

enter image description here

Note: I have xCode 9.1

查看更多
登录 后发表回答