Why Don’t My Pods Compile With Mac Catalyst and How Can I Solve It?
By: Fernando Moya De Rivas
Tags: Programming, iOS, Cocoapods, Mobile, Macos

Building Issues

If you’ve already clicked the Mac checkbox to port your iOS app to macOS and tried to run the app for you Mac, you’ll have noticed that the portability isn’t as straightforward as thought.

You’ll find two different errors: linking errors and compiling errors.

Linking error

ld: in Pods/Crashlytics/iOS/Crashlytics.framework/Crashlytics(CLSInternalReport.o), building for Mac Catalyst, but linking in object file built for iOS Simulator, file 'Pods/Crashlytics/iOS/Crashlytics.framework/Crashlytics' for architecture x86_64clang: error: linker command failed with exit code 1 (use -v to see invocation)

Compiling error

Undefined symbols for architecture x86_64:

"_OBJC_CLASS_$_UIWebView", referenced from:

objc-class-ref in BNCDeviceInfo.o

objc-class-ref in BranchViewHandler.o

ld: symbol(s) not found for architecture x86_64

clang: error: linker command failed with exit code 1 (use -v to see invocation)

Why is this happening?

Some Pods you’re using, or any of their dependencies, aren’t or can’t be compiled for Mac architecture, that is, x86_64. Therefore, static libraries won’t be linked and dynamic frameworks won’t be compiled.

How can I solve this?

You can determine which of your Pod’s targets shouldn’t be included in your Mac Catalyst version and manually remove them. Let’s say you’ve included FBSDKCoreKit in your Podfile . You’d need to go to your Pods Project, find FBSDKCoreKit target, go to Build Settings, and look up OTHER_LDFLAGS. Here, you’ll need to filter all those dependencies you’ve identified as iOS-only so that they’re not linked for macOS architectures:

Then, go to the Build Phases tab and add iOS as a platform filter to:

Dependencies

Headers

Compile Sources

Binaries

Bundle Resources

Is that all? We haven’t even started, yet! You’d have to repeat the same process for any dependencies your Pod might have (in this case, it didn’t have any) which aren’t needed for any other installed pod and also for the autogenerated targets Pods-MyAppTarget1, Pods-MyAppTarget2, and so on. Depending on how the library’s Podspec is defined, the links might be in the Pod’s target or the autogenerated “Pods-” target.

Now, this is what the previous article covered: running and archiving. But what about submitting to the App Store?

App Store submission issues

The archiving process is different from the running process. So far, we’re not compiling sources, resources, frameworks, and headers defined in the pod target’s Build Phases. We’re also unlinking unsupported libraries. That’s fine, but there’s an additional issue. If you tried to submit your app at this point to the App Store, you’d run into an error similar to this:

ERROR ITMS-90276: "Missing Bundle Identifier. The application bundle contains a tool or framework ${PRODUCT_NAME} [com.myapp.myapp.pkg/Payload/MyApp.app/Contents/Resources/GoogleSignIn.bundle] that is missing the bundle identifier in its Info.plist file."

Why is this happening?

If you go to your project folder and navigate to Pod/Target Support Files/Pods-MyAppTarget you’ll see a bash script called Pods-MyAppTarget-frameworks.sh . If there’s any resource to be installed in the archive, you might see another script called Pods-MyAppTarget-resources.sh . These two scripts are called from your app’s target Build Phases in these steps:

[CP] Embed Pods Frameworks

[CP] Copy Pods Resources

The first step will include the framework into the archive and the second will include bundle resources. Frameworks might come with a precompiled dependency with bundle resources in it, so both scripts potentially include unnecessary unsigned bundle resources in your Mac app archive.

How can I solve this?

You can open these two scripts, look up the resources or frameworks that shouldn’t be included, and modify the script so that they’re not installed for the Mac architecture:

if [[ "$CONFIGURATION" == "Release" ]]; then

if [ "$ARCHS" != "x86_64" ]; then

install_framework "${BUILT_PRODUCTS_DIR}/FBSDKCoreKit/FBSDKCoreKit.framework"

fi

fi

for frameworks and:

if [[ "$CONFIGURATION" == "Release" ]]; then

if [ "$ARCHS" != "x86_64" ]; then

install_resource "${PODS_ROOT}/GoogleSignIn/Resources/GoogleSignIn.bundle"

fi

fi

for resources. If you archive again, go to the generated file, and right-click to show its contents. You can check this out by navigating to Product/Applications/MyApp/Contents/Frameworks and Product/Applications/MyApp/Contents/Resources and verifying that these two folders don’t include the framework or resource.