1

I have a project with multiple framework targets, that also have pods dependencies.

I have:

  • No circular dependencies between targets
  • Everything, including pods, is in Objective-C, no Swift at all.
  • use_frameworks! in Podfile, so all pods are frameworks, not libraries.

Here is my structure:

  • TUSystemKit depends on TUModels (which is a framework).
  • TUModels depends on Pods_TUModels (generated by pods).
  • Pods_TUModels depends on JSONModel
  • TUModels is automatically linked with its own pod framework (which contains JSONModel).
  • TUSystemKit has TUModels as target dependency.
  • TUSystemKit is linked with TUModels.

Visually, the dependencies are like this:

TUSystemKitTUModelsPods_TUModelsJSONModel

When I select MyModels as the build target in Xcode, build succeeds. However, when I select TUSystemKit, the build fails, saying that module JSONModel is not found while building module TUSystemKit (TUUser in screenshot belongs to TUModels):

enter image description here

What am I doing wrong? Obviously I shouldn't be explicitly linking against all the frameworks in the dependency tree. Why does TUModels build perfectly but TUSystemKit errs on a module import inside a linked framework's code? Do I need to change something with pods?

2 Answers 2

1

After hours of refactoring, I've managed to build my project. I can't tell what exactly was wrong as it took me literally a day to organize all the dependencies and frameworks and it kept failing at a different point, more than a 100 times, but here are some observations to lead to a successful build:

  • All the public-facing classes are added as public headers to the target, and not to any other target.
  • All the code (.m files) are in Compile Sources section of the target, and not in any other target.
  • All the public facing classes' headers are included at umbrella header (a header with the exact same name with the framework)
  • The application embeds all the custom frameworks (not the pods).
  • All the files inside a framework target only #import required files within the same target or a file listed on any targets umbrella header that the framework has a dependency on.
  • Obvious, redundant, but worth noting again: no classes between frameworks should have circular dependencies (e.g. ClassA in FrameworkA depends on ClassB in FrameworkB, while some class in FrameworkB depends on some class on FrameworkA). I had some, and created delegates. Do whatever pattern fits your design: IoT/dependency injection, notifications/publisher-subscriber etc. But do it: separate the concerns clearly.
  • Try to avoid using same classes in multiple targets. Instead, have it in one target, and make the other target depend on the containing target, creating a dependency chain.

After refactoring many files and playing with project settings, I managed to build and run everything again. My previous setup had various number of combinations of the issues that I mentioned above, messing everything up. After cleaning all the bits and grouping code into functional, modular frameworks, I could build it.

Sign up to request clarification or add additional context in comments.

Comments

0

If you came here due to the parse error -> module not found, in certain occasions you may be forced to add the path manually. This is...

  • go to your project at the top
  • select your project target
  • select build settings
  • search the parameter Framework Search Paths under the title Search Paths
  • add the one where yours is located. Example: (using cocoa pods) $(SRCROOT)/Pods
  • indicate/set it to be recursive (access to the option by double-clicking your previously added path)

The problem should have been resolved by the 3erd party lib with commands like install / update / build or similar but if it fails and you are stuck, this is an option in order to continue.

In the same tone, if you get an error from pods indicating that The sandbox is not in sync with the Podfile because the builder is unable to find files like Podfile.lock, then you may consider to go in the same direction adding some user-defined settings:

  • select build settings
  • press the '+' symbol, "Add User-Defined Setting".
  • add this pair:
    • param= PODS_PODFILE_DIR_PATH value = ${SRCROOT}/.
    • param = PODS_ROOT value = ${SRCROOT}/Pods

Cheers

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.