Error upon app archive: Found an unexpected Mach-O header code: 0x72613c21 - ios

Im trying to archive our app to appstore. But when i do i'm receiving above error.
Platform: iOS
OS version: 14.4.2
Device manufacturer / model: iphone SE
React Native version (react-native -v): 0.64
xcode version: 12.4
I've been in touch with the guy behind the library react-native-background-fetch and asked him about the issue but i'm thinking there is another reason behind the problem.
This is the first time i'm getting this error so i'm not sure what to do.
IDEDistrubution.verbose.log
2021-04-22 14:55:50 +0000 Unable to determine platform from macho "/Users/joakimwennergren/Library/Developer/Xcode/Archives/2021-04-22/ActiveQuiz 2021-04-22, 16.54.xcarchive/Products/Applications/ActiveQuiz.app/ActiveQuiz-mobile-app/node_modules/react-native-background-fetch/ios/RNBackgroundFetch/TSBackgroundFetch.xcframework/ios-arm64_x86_64-maccatalyst/TSBackgroundFetch.framework". Failed with error: "Failed to discover platform for executable /Users/joakimwennergren/Library/Developer/Xcode/Archives/2021-04-22/ActiveQuiz 2021-04-22, 16.54.xcarchive/Products/Applications/ActiveQuiz.app/ActiveQuiz-mobile-app/node_modules/react-native-background-fetch/ios/RNBackgroundFetch/TSBackgroundFetch.xcframework/ios-arm64_x86_64-maccatalyst/TSBackgroundFetch.framework/TSBackgroundFetch"

TL;DR: I made a video to show how to fix the problem https://www.youtube.com/watch?v=Ah9aXs9lTD0 -- the following is a shorter version of the details that are shared in this article: https://christiantietze.de/posts/2021/07/mach-o-0x72613c21-static-library/
Code 0x72613c212 indicates that you are embedding a static library in your app bundle. That's not necessary, because static libraries already are merged with your app binary at build time by the linker.
Usually, .framework bundles are embedded into app bundles and then loaded when you run the app. These are dynamic libs; static libs are already 'in' the app binary, so they don't need to be shipped with the app bundle again. That's why Xcode complains.
How to Diagnose
An Apple Technical Note (TN2435) explains this:
This [Found an unexpected Mach-O header code: 0x72613c21] is caused by placing a static library in a bundle structure that looks like a framework; this packaging is sometimes referred to by third party framework developers as a static framework. Since the binary in these situations is a static library, apps cannot embed it in the app bundle.
From the Technical Note, here's how you can find out if a binary is a static library:
file <PathToAppFramework>/<FrameworkName>.framework/<FrameworkName>
The output could be like:
Mach-O universal binary with 2 architectures
<PathToLibrary> (for architecture armv7): current ar archive random library
<PathToLibrary> (for architecture arm64): current ar archive random library
For dynamic libraries that do need to be embedded in the app, the output instead says something like Mach-O 64-bit dynamically linked shared library x86_64
How to Fix
If your file output looks similar, the solution is to link but not embed:
This will include the static library in the build product right away.

Related

Can't submit iOS app to iTunes connect when using a SPM package

When I try to submit an iOS app that includes an SPM package which uses the new binary target the submission fails with the following two errors:
Invalid Swift Support. The file MyApp.app/Frameworks/libHello.a doesn’t have the correct file type for this location. Ensure you’re using the correct file, rebuild your app using the current public (GM) version of Xcode, and resubmit it.
Invalid Bundle Structure - The binary file 'MyApp.app/Frameworks/libHello.a' is not permitted. Your app can’t contain standalone executables or libraries, other than a valid CFBundleExecutable of supported bundles. Refer to the Bundle Programming Guide at https://developer.apple.com/go/?id=bundle-structure for information on the iOS app bundle structure.
I believe it's to do with SPM as when I manually drag the Hello.xcframework package to the project it allows me to submit successfully.
Trying to do other things like changing Xcode build settings, customising the package.swift and using lipo to make sure the architecture slices are valid doesn't lead to anyway.
I looked at the embed framework in Build phases, it's not been included only in the link framework phase. One thing I noticed is when I archived the app the static library libHello.a was in the app's framework folder, which is weird since it shouldn't be there as they are integrated with the app binary. When I delete that file I can continue the app submission without any issues. But I don't think this workaround would be ideal long term.
I've created a simple static library with one class and method to keep thing simple. I then use Xcode archive the resulting static library in an XCFramework using xcodebuild -create-xcframework. See Github Repo: https://github.com/shams-ahmed/Hello
Steps to reproduce:
Create a new Xcode project
Add the Hello SPM package using the SPM interface with URL: https://github.com/shams-ahmed/Hello
Archive the project
Validate the App
You can deselect all the options
Fails with the above error message
What do I need to do to get SPM working with a static library? This is now meant to be supported with Xcode 12 and Swift 5.3
Info:
Xcode 12.0
Swift 5.3
Using a new Xcode project
P.S must use a static library
Looks like it's not possible with static libraries (.a files) because .binaryTarget with a xcframework is associated with dynamic frameworks and XCode just copy a platform depended entity from the xcframework to Frameworks folder of your .app instead of linking to your application's binary.
XCode build log:
PBXCp .../Hello.xcframework/ios-x86_64-simulator/libHello.a .../Test.app/Frameworks/libHello.a
There are two solutions:
Compile library sources as dynamic frameworks and make the xcframework from them.
If you have .a files only you can make dynamic frameworks wrappers which link static libraries and provides API access to them and then make the xcframework.

Proper way of embedding dylib into an iOS app

I have a project which consist of three elements:
C source code that is compiled to .dylib
Swift framework used to provide user-friendly swift API for .dylib
iOS app consuming both .dylib and swift proxy
I have added both swift proxy and .dylib as "Framework and libraries" dependency to iOS app project. Things work as expected on my iPhone. However when I attemt to send my app to Apple Store Connect I get following error:
ITMS-90429: Invalid Swift Support - The files libswiftDarwin.dylib, libswiftDispatch.dylib, libswiftCoreGraphics.dylib, libswiftCoreFoundation.dylib, libswiftCore.dylib, libswiftFoundation.dylib, libswiftObjectiveC.dylib aren’t at the expected location /Payload/Runner.app/Frameworks. Move the file to the expected location, rebuild your app using the current public (GM) version of Xcode, and resubmit it.
I figured this can be caused by .dylib file being embedded directly in iOS app, so I tried to embed .dylib into swift framework. Then I made iOS app embedding only swift framework, which consist of .dylib file. However I am getting following error in this configuration:
dyld: Library not loaded: #rpath/libX.dylib
Referenced from: /private/var/containers/Bundle/Application/.../swiftProxy.framework/swiftProxy
Reason: no suitable image found. Did find:
/private/var/containers/Bundle/Application/.../swiftProxy.framework/Frameworks/libX.dylib: code signature in (/private/var/containers/Bundle/Application/.../swiftProxy.framework/Frameworks/libX.dylib) not valid for use in process using Library Validation: mapped file has no cdhash, completely unsigned? Code has to be at least ad-hoc signed.
This doesn't make sense for me, but I figured this is not the right way.
So the question is: how do I properly embed dylib so that it can be put on Apple Store Connect and then on Testflight?
I'm aware that this question was asked at least once, but there is no decent answer. Here for example: How to properly embed 3rd party .dylib files in iOS app project for App Store release?
Thank you

How to create a dynamic framework without using a script to strip out simulator slices

I would like to create a dynamic framework and distribute it. It needs to work when running on simulator, an iPhone device, and be able to submit to the App Store.
I am aware of lipo thanks to this guide. It shows how we can combine the simulator architectures with the iphone architectures into a single dynamic framework that can be distributed without distributing the source code. It allows me to use the framework for both simulator and iPhone device. However, it fails when I try to send it to the App Store because of the simulator build.
Carthage provides an interesting solution. It creates a framework that works for both simulator and iPhone. But when it is time to send it to the App Store we need to run a script to rip out the simulator slices.
However, the creators of DoubleClick for Publishers (DFP) have found a way to create a framework that works on both simulator and device; Passes the App Store submission; And doesn't require any script to rip out the simulator slices (AFAIK). All I really have to do is drag the GoogleMobileAds.framework file into Linked Frameworks and Libraries. It is a little surprising that I don't need to add it to Embedded Binaries like most dynamic frameworks)
I created a sample project that uses DFP that demonstrates this.
// clone repository
git clone --recursive https://github.com/wh1pch81n/DoubleClickGoogleExample.git
// Move to correct branch
git submodule foreach 'git checkout master'
git submodule foreach 'git pull origin master'
Now you can choose the Simulation_mate scheme and run the app. The app will show a single advertisement banner at the bottom to show that the ad is actually working.
The dependency graph looks like this.
Simulation_mate.app
-> Mate.framework
-> DFP.framework
-> GoogleMobileAds.framework
Again, I can run Simulation_mate on simulator, iPhone, and can submit it to the App Store.
My question is how in the world did they create GoogleMobileAds.framework like this? What steps need to be followed to create a framework like this?
As suspected, the GoogleMobileAds.framework is a static framework, rather than a dynamic framework.
> file GoogleMobileAds
GoogleMobileAds: Mach-O universal binary with 5 architectures: [arm_v7: current ar archive] [arm_v7s] [i386] [x86_64] [arm64]
GoogleMobileAds (for architecture armv7): current ar archive
GoogleMobileAds (for architecture armv7s): current ar archive
GoogleMobileAds (for architecture i386): current ar archive random library
GoogleMobileAds (for architecture x86_64): current ar archive random library
GoogleMobileAds (for architecture arm64): current ar archive
Whereas, running file on a dynamic framework, you get a different result:
> file AppKit
AppKit: Mach-O universal binary with 2 architectures: [i386: Mach-O dynamically linked shared library i386] [x86_64]
AppKit (for architecture i386): Mach-O dynamically linked shared library i386
AppKit (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64
Unfortunately, the problem you describe is a known limitation of the App Store distribution system. In theory, the correct way to distribute your dynamic framework should be to distribute the full fat binary with all architectures, and let either the build system throw out the the unneeded architectures when building, or let the App Store distribution system do that when slicing the app for specific devices ("slicing"). If I had to guess, the App Store distribution fails with such frameworks due to iOS 8 and below support, since those systems do not support slicing from the App Store.
The reason Google creates static libraries is in order to support iOS 7. A silly reason at this day and age, it has created many issues for developers, since Google also insists on using CocoaPods. Static frameworks, while superficially seem like a silver bullet at first ("no scripts for lipoing out archs; no embedding"), are actually not that great. For instance, if you'd like to include non-compiled resources, a static framework will not do the trick (dynamic frameworks are bundles, while static frameworks are not).

Application builded using Dynamic framework not submitted to app store

I have created Dynamic Framework , While importing this dynamic framework into Application it needs to be add in Embedded Binaries.
it is working with Both Device and Simulator but when i archive and make .IPA file to submit , I got Below error while submitting app to app store.
1) ERROR ITMS-90087: "Unsupported Architectures. The executable for sample.app/Frameworks/customFramework.framework contains unsupported architectures '[x86_64, i386]'."
2) ERROR ITMS-90209: "Invalid Segment Alignment. The app binary at 'sample.app/Frameworks/customFramework.framework/CustomFramework' does not have proper segment alignment. Try rebuilding the app with the latest Xcode 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/sample.app/Frameworks/customFramework.framework' is not a Position Independent Executable. Please ensure that your build settings are configured to create PIE executables. For more information refer to Technical Q&A QA1788 - Building a Position Independent Executable in the iOS Developer Library."
Any insights into this would be really helpful.
This is normal if you make fat dynamic framework, they don't let the simulator architecture to be submitted (but it work with static library), the easiest way to solve it is to borrow the solution from other framework, eg Realm, they provide a script to strip out the simulator architectures out of the framework, so that the app can be submitted to appstore, check out their installation for framework version to include and use the script for your framework

Sudden Error when Uploading to iTunesConnect: ITMS-90635 Invalid Mach-O Format / ENABLE_BITCODE

Last week i was able to upload my ipa to iTunesConnect just fine. But as of today I am getting the following error when uploading via Application Loader:
ERROR ITMS-90635: "Invalid Mach-O Format. The Mach-O in bundle "Application.app/Frameworks/PSPDFKit.framework" isn’t consistent with the Mach-O in the main bundle. The main bundle Mach-O contains armv7(machine code) and arm64(machine code), while the nested bundle Mach-O contains armv7(bitcode and machine code) and arm64(bitcode and machine code). Verify that all of the targets for a platform have a consistent value for the ENABLE_BITCODE build setting."
I am aware of the solutions proposed here: Xcode - Error ITMS-90635 - Invalid Mach-O in bundle - submitting to App store and in many others.
I have however no idea how to apply any of the proposed solutions to a Xamarin iOS project. I am not using any pods, instead I am using a Binding library for PSPDFKit, which I have created as described in the official documentation https://pspdfkit.com/guides/ios/current/other-languages/xamarin/.
As far as I can see there are two ways for me to go, either to enable bitcode in my project (which I have no idea how to do) OR to disable bitcode in the binding project for PSPDFKit (which I have also no Idea how to do).
I am grateful for any help or propositions.
I finally was able to do it, with one of the solutions from this post https://stackoverflow.com/a/37624641/2702513
What I had do do, was stripping the Bitcode from my library, which can be done with this command:
$ xcrun bitcode_strip -r {PATH_TO_LIBRARY} -o tmp.dylib
The command extracts the machine code from the library into the tmp.dylib file which then can be used instead of the library itself. In case of PSPDFKit the library is inside the framework.

Resources