285

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."
mfaani
  • 33,269
  • 19
  • 164
  • 293
Saurabh Jain
  • 3,013
  • 3
  • 11
  • 9
  • 4
    The first message sounds as if it's a simulator build. – Phillip Mills May 30 '15 at 14:25
  • 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 – Saurabh Jain May 30 '15 at 14:27
  • 2
    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. – Stephen Darlington May 30 '15 at 15:08
  • @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 – Saurabh Jain Jun 16 '15 at 08:19
  • I had this behaviour when I uploaded using Application Loader 3.5 – SudoPlz Jul 09 '16 at 16:33
  • For better context see [here](https://stackoverflow.com/questions/28033635/why-does-the-ios-simulator-require-i386-and-x86-64-symbols-even-though-im-on-an) – mfaani Jan 29 '21 at 23:08

17 Answers17

417

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.

Koen.
  • 25,449
  • 7
  • 83
  • 78
pAkY88
  • 6,262
  • 11
  • 46
  • 58
  • 6
    @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? – SamoanProgrammer Feb 05 '16 at 16:08
  • 65
    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. – superarts.org Mar 22 '16 at 04:05
  • 1
    @fancy yes, check out my post on how I fixed my issue http://stackoverflow.com/questions/35240330/errors-building-xcode-project-after-adding-in-run-script-fatal-error-lipo-inpu – SamoanProgrammer Mar 22 '16 at 20:38
  • I'm not sure where should I put this script. Should I edit the Build scheme and add it in Post-actions? – Skoua Jun 15 '16 at 23:27
  • 5
    @Skoua Select the relevant target, then "Build Phases" and put it after the "Embed Frameworks" action – Piotr Tobolski Jul 11 '16 at 17:43
  • @SamoanProgrammer Has a valid point, to run the script only for specific framework for which you get x86_64 error and not for all frameworks. – AtWork Jul 15 '16 at 18:45
  • Works great but I get the following message when I send the binary to iTunes connect: Too many symbol files - These symbols have no corresponding slice in any binary. Then I have to uncheck the upload symbol files to avoid the warnings. – rockdaswift Sep 19 '16 at 10:40
  • I am getting the error "find: ftsopen: No such file or directory" when I use this script, any ideas? I've create a question for it - http://stackoverflow.com/questions/40655588/xcode-remove-architectures-run-script-is-showing-find-ftsopen-no-such-file-or – AndyW Nov 17 '16 at 13:02
  • Is it possible to add this script within framework that is vender side? – Nazish Ali Nov 28 '16 at 13:20
  • To extract arm64 slice, lipo from the iOS toolchain should be used, not from the host system: xcrun -sdk iphoneos lipo -info FILENAME – Vadim Dec 22 '16 at 22:06
  • 1
    Worked perfectly. Is it a fair assumption that anyone using a third party framework who wants to upload their build to iTunes Connect needs this script? – simioliolio Dec 28 '16 at 13:15
  • WHAT ARE THE STEPS? Should i change the Script's "APP_PATH"? APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}" can anyone write an example please? what are the steps? should i run it from the "Terminal?" @pAkY88 – Ofir Malachi Jun 06 '17 at 14:49
  • 1
    Its not working when i archive the build. It says unsupported architectue i386 i.e. the script is not stripping the simulator architecture. – iAviator Jun 13 '17 at 10:52
  • 1
    Make sure this run script is the last item in your Build Phases. – Sean Jul 10 '17 at 18:16
  • @James111 I'm struggling to remember. Something like if you check framework search paths in build settings and make sure all the folders actually exist. – AndyW Sep 18 '17 at 13:18
  • 1
    have you tested on Xcode 9? I test in Xcode9 and it´s not working (archiving), any idea how make it work? – magofdl Sep 25 '17 at 14:24
  • Followed all the steps still doesnt work for me. I am trying on xcode 8.1 and using AdobeCreativeSDKCore. Can anyone suggest what could be wrong in my case? – Milan Gupta Dec 14 '17 at 06:49
  • yeeh you saved my time.. Its worked for me... just for specific framework also just replace * with framework name.. Thank you so much – Jon Striker Mar 05 '18 at 10:38
  • 1
    Nice touch to this, MiTek copied your script, added it to their FAQ and added line breaks ... Guess someone "copied" your work badly – Evils Apr 03 '18 at 19:44
  • 8
    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. – shashi Gupta Jul 23 '18 at 12:38
  • Hey, this script caused me huge headaches recently. If you include a watch app in Xcode 10 _this script nukes your watch app frameworks_! That's because the `ARCHS` variable doesn't include the watch architectures and starting in Xcode 10, watch frameworks are fat. So this script will completely remove them. – Max Jan 19 '19 at 00:04
  • 6
    Not working in Xcode 11.2 - anyone found a solution? – JMIT Nov 05 '19 at 14:57
  • Thanks for pointing this out. I haven't had the chance (and I hope I never will) to test this workaround on XCode 11.2, hope someone can post an update solution. – pAkY88 Nov 06 '19 at 00:22
  • 1
    I dont understand one thing, if apple rejects unused architectures, so how popular frameworks manage to do this? like Alamofire or swiftyJson. They both run in simulator and device and no any error while submitting app to app store which included this frameworks. Thank you. – Yucel Bayram Dec 24 '19 at 10:41
  • 2
    Hi friends, above mentioned answer's script is correct, the tricky part is where to place it, that work for upload app using archive with strip and slice. Edit Scheme -> Archive -> open dropdown -> post actions -> + to add new script -> copy and paste enjoy. :) – Ravi Kumar Oct 22 '20 at 13:43
  • 2
    @pAkY88 IMPORTANT: Now in the new M1 macs the simulator architecture is arm64, so this script removes everything from new xcframeworks and frameworks. Thats why IPA will always fail to install. !!!!!WARNING!!!!! – Abhishek Maurya Jun 02 '21 at 13:50
210

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)

Varrry
  • 2,647
  • 1
  • 13
  • 27
  • 1
    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. – Michael Radionov Jan 04 '17 at 08:41
  • 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 Jan 28 '17 at 11:02
  • 2
    PiterPan, add it as separate RunScript phase – Varrry Feb 02 '17 at 08:46
  • 1
    I just checked the "Run script only when installing" option and it gets skipped except then archiving. – Rivera Feb 17 '17 at 11:26
  • 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... – user3069232 Jun 09 '17 at 14:04
  • have you tested on Xcode 9? I test in Xcode9 and it´s not working (archiving), any idea how make it work? – magofdl Nov 16 '17 at 22:06
  • @magofdl, I currently can't check this, could you provide more details on issue? – Varrry Nov 17 '17 at 14:15
  • @Varrry I have notice that the TARGET_BUILD_DIR has changed while archiving in Xcode 9, I don't know if thats correct or a bug in Xcode 9, so the script can't find the frameworks on that path – magofdl Nov 17 '17 at 19:41
  • @magofdl, since frameworks are inside app wrapper (*.APP dir), script shouldn't depend on target build dir location. I think your problem lays somewhere else; need more details: errors, logs, etc. – Varrry Nov 17 '17 at 21:19
  • @Varrry you can fin the log from the script [here](https://jpst.it/17J92) , I added the app path to the log before the find command, I have notice that on the archive the script is not logging the "Executable is ..." only the app path. – magofdl Nov 20 '17 at 15:38
  • @magofdl from logs I see you use original script posted by pAkY88, not this script above. Anyway, I'd advice you to create new question with reference to this answer and mentioning me (or pAkY88 if you wish), to avoid overflowing comments here with side question. In your question you can provide full info on your issue: what frameworks do you use, which archs, what are you doing and what happens as a result. – Varrry Nov 21 '17 at 10:06
  • @Varrry thank you, I have posted a new question [here](https://stackoverflow.com/questions/47577524/shell-script-for-remove-the-unneeded-architectures-while-archiving-not-working) – magofdl Nov 30 '17 at 16:03
  • add this script in Project --> Run Script. Reinstall pods, clean existing data/user data. Now it's working – Urvish Modi Mar 07 '18 at 08:33
  • I have problems using this when building for my device. "... must be a fat file when the -extract option is specified". – Joris Mans Jun 27 '18 at 07:20
  • @JorisMans are you sure you use this script and not original one? This script is specially to avoid problem you mentioned. – Varrry Jun 27 '18 at 10:46
  • Yes. Your script solves the problem when building for the simulator. Not for the actual device : case "${TARGET_BUILD_DIR}" in *"iphonesimulator") – Joris Mans Jul 04 '18 at 07:36
  • @JorisMans, there aren't problems building for simulator, simulator allows using binaries with not supported archs; problem appears only when building for AppStore and this is the case \*), where all work is done; error you mentioned sometimes appears running original script (see comment by SamoanProgrammer to original script) and shouldn't appear while running *this* script since -extract option is not used there. This script doesn't *extract* slices but only *removes* slices from binary, so I can't understand how you could face such error. – Varrry Jul 04 '18 at 11:11
  • I am not talking about the simulator. i am talking about running it on the device, in debug build – Joris Mans Jul 13 '18 at 15:41
  • @JorisMans, ok, what else do you see in script's output? Did you find at which point it fails? – Varrry Jul 13 '18 at 19:57
  • Sorry, can't help anymore with that. We've since removed the third party library that required using this script so I don't use it anymore. – Joris Mans Jul 15 '18 at 15:04
  • I had to add it again: This is when building in debug for a device: Extracting arm64 from Protobuf fatal error: lipo: input file (/Debug-iphoneos/***.app/Frameworks/Protobuf.framework/Protobuf) must be a fat file when the -extract option is specified – Joris Mans Aug 08 '18 at 08:11
  • I managed to fix it by adding: if lipo -info "$FRAMEWORK_EXECUTABLE_PATH" | grep 'Non-fat file'; then continue fi – Joris Mans Aug 08 '18 at 08:29
  • @JorisMans did you get which string in the script causes error? I don't understand, -extract option isn't used there – Varrry Aug 08 '18 at 12:12
  • @Varrry If my framework contains another supporting framework, will the script also delete an unsupported arch from it? – Harshal Wani Oct 18 '19 at 05:26
  • @HarshalWani if supporting framework is just a dependency for your framework, then it'll be linked to app separately and archs will be deleted. Else if it's included in your framework's binary, I suppose it's slices are merged with your framework's slices, and so they'll be deleted while processing your framework; but can't say for sure, better if you check your binaries after processing. – Varrry Oct 18 '19 at 08:57
  • Getting the error "fatal error: lipo: input file... must be a fat file when the -remove option is specified" which leads to "ERROR ITMS-90085: "No architectures in the binary. Lipo failed to detect any architectures in the bundle executable."" – Daniel Ryan May 20 '20 at 23:31
  • The error was caused because the library I used had two framework files, one built for the simulator and one for devices. – Daniel Ryan May 21 '20 at 03:47
91

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.

odlp
  • 4,984
  • 2
  • 34
  • 45
  • 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. – Ash Jan 23 '17 at 16:07
  • 1
    Indeed, a great post. Note, often your best bet is simply remove all frameworks, and start again adding all your frameworks from Carthage. Cheers – Fattie May 08 '17 at 17:58
  • I'm using Carthage and Marshal and adding `$(SRCROOT)/Carthage/Build/iOS/Marshal.framework` did the work – Ricardo Mutti Aug 11 '17 at 16:53
  • in modern iOS, 99% of the time this is the problem - you just forgot the copy-frameworks. (100% of projects now use Carthage.) – Fattie Sep 21 '17 at 23:07
42

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

enter image description here

Bart van Kuik
  • 4,704
  • 1
  • 33
  • 57
  • 5
    This answer should have many more upvotes. I suspect it's the root cause for many people using Carthage. – mm2001 Oct 12 '16 at 05:23
  • 15
    If you're trying to embed a dynamic framework then removing it results in this error message for me: "Reason: image not found" – electronix384128 Oct 19 '16 at 20:55
  • 1
    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. – SmileBot Mar 12 '17 at 18:12
34

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"

Fattie
  • 27,874
  • 70
  • 431
  • 719
Maciej Swic
  • 11,139
  • 8
  • 52
  • 68
21

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

  1. Open Terminal

  2. open your project drag path of respective framework to Terminal

    example : cd /Users/MAC/Desktop/MyProject/Alamofire.framework

  3. set your Framework name in below command and run

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

  1. Now open your project again, Clean, Build & Run and Create Archive...
MAhipal Singh
  • 4,745
  • 1
  • 42
  • 57
  • @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. – Hitarth Nov 12 '19 at 10:36
  • It's because simulator support only debug framework – MAhipal Singh Nov 12 '19 at 14:22
  • This works for any downloaded framework, just renaming `Alamofire` with the framework you're having trouble with. Thanks for this answer. – Vitor May 05 '22 at 16:11
16

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.

Community
  • 1
  • 1
Anjan Biswas
  • 7,746
  • 5
  • 47
  • 77
15

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
Gurjinder Singh
  • 9,221
  • 1
  • 66
  • 58
14

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

Florin Dobre
  • 9,872
  • 3
  • 59
  • 93
9

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;

enter image description here

Kiran Jadhav
  • 3,209
  • 26
  • 29
6

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
objectively C
  • 960
  • 9
  • 25
5

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

enter image description here

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.

Mihai Erős
  • 1,129
  • 1
  • 11
  • 18
3

the simple solution that worked for me was

1- remove the framework from embedded frameworks.

2- add the framework as a linked framework

done!

Community
  • 1
  • 1
DeyaEldeen
  • 10,847
  • 10
  • 42
  • 75
1

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
A.Badger
  • 4,279
  • 1
  • 26
  • 18
1

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.

MD.
  • 1,157
  • 11
  • 18
0

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

MAhipal Singh
  • 4,745
  • 1
  • 42
  • 57
0

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"

Preview of where to insert sample script

keaplogik
  • 2,369
  • 2
  • 25
  • 26