Alex Nadein

Mar 26, 2021

4 min read

Undefined symbols and where to find them

Now when the Swift Package Manager is here, and the whole infrastructure becomes much better, we face fewer problems with integrating third-party libraries in our projects. But back in the day and even now, Cocoapods users can get into confusing situations with their libraries. Let’s have a look at one of the trickiest of those problems.

It’s the “Undefined symbols for architecture x” error. I faced it many times, but an example I’ll show related to the StackOverflow discussion with confused people trying to fix their projects but breaking things even more.

So imagine you decided to integrate into your mobile app a shiny third-party tool like AWSMobileHub. You follow the instructions steps and copy framework files to your Xcode workspace.

Add it to embedded binaries and linked frameworks.

Everything looks fine and even compiles successfully.

Then you decide to add Cocoapods dependencies. You update your podfile.

Run “pod install” and after installation trying to build your project. And here we go. You got a long list of errors.

At this point, people start to analyze what could go wrong. So after juggling frameworks and trying to add them somehow alternatively, which gives the same list of errors, they try to see what changes in the project could be fatal. Happily, we got version control systems like git, which help us track changes on every step.

They see that pod installation added new lines to the Xcode project file. Like OTHER_LDFLAGS (Other Linker Flags in project settings). Here is a list of -framework”Name” entries. It’s expected because the linker needs to link your frameworks to app executable. But one of those seems suspicious: the -ObjC flag.

After some trial and error, it becomes obvious that -ObjC flag is the root of the problem. After removing it, errors vanish, and the project compiles successfully. What a quick and elegant solution.

But it was a great mistake.

An app built without -ObjC flag starts crashing in runtime. It happens because the linker is trying to link frameworks and their dependencies in runtime and fails.

Removing -ObjC in the xcconfig file will not fix this issue and not the right way to fix it. Pods script adds it on purpose.

The right way to fix it is on the surface - just read the description of the error provided by Xcode:

That means that AWSMobileHubHelper’s class AWSContentManager has a dependency and calls AWSS3PreSignedURLBuilder object methods. You need to find out what is AWSS3PreSignedURLBuilder and how to add it to your project.

The easiest way is to search it on Github. And we find out that AWSS3PreSignedURLBuilder is part of the AWSS3 framework. So add pod ‘AWSS3’ to your podfile, and it fixes the error.

Repeat this for every Undefined symbol in the linker error message, and you’ll be able to build your project successfully.

In this particular case, it seems we need to add pods of AWS-SDK-iOS and pods:

Be attentive adding pods — it may require a specific version of the pod to support your target iOS version and Swift version (read the README provided with pod). For example:

You can see by yourself how many people were tricked by a fast and simple solution into the trap of runtime crashes. StackOverflow discussion.

Please be attentive, read error descriptions, and learn your tools. Happy coding, everyone!