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 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.
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)
case "${TARGET_BUILD_DIR}" in *"iphonesimulator") echo "Skip simulator target"; continue ;; esac
and it worked like a charm.
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?
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.
$(SRCROOT)/Carthage/Build/iOS/Marshal.framework
did the work
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
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"
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...
Alamofire
with the framework you're having trouble with. Thanks for this answer.
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.
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
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
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
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
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.
the simple solution that worked for me was
1- remove the framework from embedded frameworks. 2- add the framework as a linked framework
done!
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
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.
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
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
Success story sharing