ChatGPT解决这个技术问题 Extra ChatGPT

Submit to App Store issues: Unsupported Architecture x86

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.

ERROR ITMS-90087: "Unsupported Architecture. Your executable contains unsupported architecture '[x86_64, i386]'." 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.) 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." 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."

The first message sounds as if it's a simulator build.
When i create an archive for submission i choose the iOS devices in the devices options then create an archive, if thats what u are asking
I agree with @PhillipMills. Concentrate on your first error. Why do you have a x86_64 binary in your iOS app? Either you've done something weird with your build settings... or you uploaded a Simulator build.
@pAkY88. I was not able to. I recently posted in the Shopify API forum and am awaiting a response. Will definitely post something if I come across one
I had this behaviour when I uploaded using Application Loader 3.5

K
Koen.

The problem is that the Buy framework contains a build for both the simulator (x86_64) and the actual devices (ARM).

Of course, you aren't allowed to submit to the App Store a binary for an unsupported architecture, so the solution is to "manually" remove the unneeded architectures from the final binary, before submitting it.

Daniel Kennett came up with a nice solution and provides this script to add to the build phase:

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

# This script loops through the frameworks embedded in the application and
# removes unused architectures.
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

I used it and it worked perfectly.

EDIT: make sure you look at the modified script posted by Varrry, as this one has some minor issues.


@pAkY88 I've used this script in my Xcode project to fix up the App Store Issues mentioned above, but now when I go to Build, I have alot of fatal errors -> fatal error: lipo: input file (/...Frameworks/Bolts.framework/Bolts) must be a fat file when the -extract option is specified. Any ideas how to fix this?
I think it's pretty stupid: you have to combine arm+x86 to allow your app runs on both simulator and device, and have to strip x86 out to submit to app store. Why Apple doesn't do the strip on their end as long as x86 is detected? They can help a lot of technical reasons to defend this, but none business reason since it's not user friendly at all.
@Skoua Select the relevant target, then "Build Phases" and put it after the "Embed Frameworks" action
The above script is helpful but nowhere mentioned about steps to run the script in Xcode. To run this script goto TARGETS --> select Build Phases then upper header in Xcode tap on Editor --> Add build phases --> Add run script Build phases and you will get an column in Build Phase section of TARGET. Here you can copy paste above script and upload it to Appstore successfully.
Not working in Xcode 11.2 - anyone found a solution?
V
Varrry

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)


Thank you for the idea. I've simply added a check to the code from the accepted answer inside the while loop case "${TARGET_BUILD_DIR}" in *"iphonesimulator") echo "Skip simulator target"; continue ;; esac and it worked like a charm.
I am adding this script in TARGET -> Build Phases -> [CP] Embedded Pods Frameworks but it doesn't work and I have still upload to iTunesConnect errors. How to run this script?
PiterPan, add it as separate RunScript phase
I just checked the "Run script only when installing" option and it gets skipped except then archiving.
Did everything suggested here, managed to clear the Carthage error; but needed to upload it the App Store without validation to get some useful information as to why it failed. Managed to fix that and moving forward...
o
odlp

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.


As an additional note, I recently ran into this problem having switched from using an old, pre-compiled version of a third-party framework to a new version of the same framework installed using Carthage. Even once Carthage was fully set up I continued to get this error. For me, the fix was to entirely remove the framework from the project and add it back again. If you're using Carthage and this answer doesn't fix it for you, try doing that.
Indeed, a great post. Note, often your best bet is simply remove all frameworks, and start again adding all your frameworks from Carthage. Cheers
I'm using Carthage and Marshal and adding $(SRCROOT)/Carthage/Build/iOS/Marshal.framework did the work
in modern iOS, 99% of the time this is the problem - you just forgot the copy-frameworks. (100% of projects now use Carthage.)
B
Bart van Kuik

I resolved the error ITMS-90080 by removing a framework (the excellent SVProgressHUD) from the Embedded Binaries section (Xcode target -> General tab).

https://i.stack.imgur.com/lhxWI.png


This answer should have many more upvotes. I suspect it's the root cause for many people using Carthage.
If you're trying to embed a dynamic framework then removing it results in this error message for me: "Reason: image not found"
This worked for me. You have to remove the framework from Embedded Binaries and just add it to the Linked Frameworks and Libraries. Also, you have to do the other stuff like running the script that you find in the other answers.
F
Fattie

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"


This way my issue. Thank you.
M
MAhipal Singh

Remove [x86_64, i386] from the framework using below step. [x86_64, i386] is used for simulator.

Open Terminal open your project drag path of respective framework to Terminal example : cd /Users/MAC/Desktop/MyProject/Alamofire.framework set your Framework name in below command and run

lipo -remove i386 Alamofire -o Alamofire && lipo -remove x86_64 Alamofire -o Alamofire

Now open your project again, Clean, Build & Run and Create Archive...


@mahipal Singh .. after removing using lipo command. app is not working in simulator. got error like x84_64 missing for iphone simulator. but working fine in real device.
It's because simulator support only debug framework
This works for any downloaded framework, just renaming Alamofire with the framework you're having trouble with. Thanks for this answer.
C
Community

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.

Open terminal in your project's directory. Change directory directly into the .framekwork, like cd YourProjectDir/YourProject/YourLibrary.framework 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.


Simple solution for those that don't feel like scripting.
just run the command above, the arch size reduced to half. hopefully make some difference.
Even though i have deployed the script to make everything work as normal but this has to be a proper description on how to resolve the issue.
love the nature of this answer. clean and concise
G
Gurjinder Singh

Thanks to all the above answers. Here is a script working with swift 4.2 and 5. Replace Your_Framework_Name string with your Framework's original name.

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

Thank you! This worked for me, while the accepted answer did not.
F
Florin Dobre

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.

https://i.stack.imgur.com/e62J1.png

Note: I have xCode 9.1


This worked for me. Where just @pAkY88's script was enough last time i did a release nearly a year ago.
I had the same issue and this worked for me. Make sure to check the position of the run script every time a framework is removed and added (only necessary when there is only one framework that was removed).
You save my day. Just to add script after embedded framework.
Thanks it worked for me, just add this scrip at the end of all scripts
K
Kiran Jadhav

Updated for Xcode 10.1, Below solution worked for me :

Just you have to remove the framework from Embedded Binaries and just add it to the Linked Frameworks and Libraries.

Refer below screenshot;

https://i.stack.imgur.com/9Xy3N.png


Working solution for me (y)
it removes the same from linked frameworks and libraries
o
objectively C

This issue was resolved for me by slightly modifying the run script from pAky88's answer and executing after embedding frameworks. Also be sure to uncheck the box for "Run Script only when installing".

/usr/local/bin/carthage copy-frameworks

#!/usr/bin/env bash

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

# This script loops through the frameworks embedded in the application and
# removes unused architectures.
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"

if [ ! -f "${FRAMEWORK_EXECUTABLE_PATH}" ]; then
continue
fi

if xcrun lipo -info "${FRAMEWORK_EXECUTABLE_PATH}" | grep --silent "Non-fat"; then
echo "Framework non-fat, skipping: $FRAMEWORK_EXECUTABLE_NAME"
continue
fi

echo "Thinning framework $FRAMEWORK_EXECUTABLE_NAME"

EXTRACTED_ARCHS=()

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

echo "Merging extracted architectures: ${ARCHS}"
xcrun 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

M
Mihai Erős

I removed architectures i386 & x64_86 from Build Settings - Valid Architectures - Release, and everything worked just fine.

https://i.stack.imgur.com/UoE1A.png

Now the only issue would be that you can't run a RELEASE build for testing purposes on a SIMULATOR. But as easily as you removed the archs, you can add them back if you want to.


YES, that the solution.
C
Community

the simple solution that worked for me was

1- remove the framework from embedded frameworks. 2- add the framework as a linked framework

done!


A
A.Badger

This error (ITMS-90240) can also be caused by a static (.a) library. heres a script to strip the excess architectures. In Xcode add this to Target > BuildPhases > Click the + and select Run Script. Then paste this into the script box.

The script searches for .a files, checks to see if it contains an offending architecture, then if it does makes a new .a file without that architecture.

For macOS:

APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
STRIPARCHS="armv7 armv7s arm64"
for t in $STRIPARCHS
do

if find "$APP_PATH" -name '*.a' -exec lipo -info {} \; | grep $t ; then
    find "$APP_PATH" -name '*.a' -exec lipo -remove $t {} -output {}2 \; -exec rm {} \; -exec mv {}2 {} \; ;
fi

done

exit 0

For iOS :

APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
STRIPARCHS="x86_64 i386"
for t in $STRIPARCHS
do

if find "$APP_PATH" -name '*.a' -exec lipo -info {} \; | grep $t ; then
    find "$APP_PATH" -name '*.a' -exec lipo -remove $t {} -output {}2 \; -exec rm {} \; -exec mv {}2 {} \; ;
fi

done

exit 0

M
MD.

I had same issue. Even it was not working after adding the given Run Script. It was Xcode related issue. I was using the Xcode version 9.0 but latest version was 9.2.

So i installed latest Xcode (9.2) and it worked.


M
MAhipal Singh

Your framework contains both ARM and x86 code, which allows you to use it on a device or in the simulator. If you intend to submit your app to the App Store, run the following script to strip the inactive code from the binary.

1.Select your target in the Project Navigator, and click Build Phases at the top of the project editor.

2.From the Editor menu, select Add Build Phase, then Add Run Script Build Phase (or click the + button in the upper-left corner of the Build Phases editor).

3.Expand the disclosure triangle next to the new Run Script build phase that was just added. In the script editor box, paste the following: bash

${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/"YourframeworkName.framework"/strip-frameworks.sh


This assumes that the strip-frameworks.sh script happens to be there...
k
keaplogik

Here is a script I used to specifically remove just one framework's architecture from the executable file.

# Remove unused Framework architecture from "YourApp" framework.

FRAMEWORK_EXECUTABLE_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}/Frameworks/YourApp.framework/YourApp"

echo "$FRAMEWORK_EXECUTABLE_PATH"

cp "$FRAMEWORK_EXECUTABLE_PATH" "${FRAMEWORK_EXECUTABLE_PATH}_X86_64"

echo "Executing following command to remove x86_64 arch from YourApp framework executable"
echo "lipo -remove x86_64 \"$FRAMEWORK_EXECUTABLE_PATH\" -o \"${FRAMEWORK_EXECUTABLE_PATH}_X86_64\""

lipo -remove x86_64 "${FRAMEWORK_EXECUTABLE_PATH}_X86_64" -o "$FRAMEWORK_EXECUTABLE_PATH"

rm "${FRAMEWORK_EXECUTABLE_PATH}_X86_64"

Add this script to your projects "Build Phases" of your project target. Be sure to check the box: "Run script only when installing"

https://i.stack.imgur.com/Xqqww.png


关注公众号,不定期副业成功案例分享
Follow WeChat

Success story sharing

Want to stay one step ahead of the latest teleworks?

Subscribe Now