Why are umbrella frameworks discouraged?

Objective CMacosCocoa

Objective C Problem Overview


I want to distribute Framework A. Framework A depends on Framework B. I want a user of my framework to only need to include Framework A, but still have programmatic access to Framework B.

Apple does this all the time using the concept of "Umbrella Frameworks", but there is this topic in the docs:

> Don't Create Umbrella Frameworks > > While it is possible to create umbrella frameworks using Xcode, doing > so is unnecessary for most developers and is not recommended. Apple > uses umbrella frameworks to mask some of the interdependencies between > libraries in the operating system. In nearly all cases, you should be > able to include your code in a single, standard framework bundle. > Alternatively, if your code was sufficiently modular, you could create > multiple frameworks, but in that case, the dependencies between > modules would be minimal or nonexistent and should not warrant the > creation of an umbrella for them.

Why is this approach discouraged? What makes it a good solution for Apple's problem of interdependent frameworks but not for mine?

Objective C Solutions


Solution 1 - Objective C

Umbrella frameworks only make sense if you are the only distributor of all the involved frameworks, and you will be packaging all the frameworks together as a single versioned package which will be upgraded together. If that is your situation, then that's fine, but this is a very unusual situation. In the Cocoa development world, it is exceedingly unusual for anyone but Apple to be in this situation.

To the first point, umbrella frameworks only make sense if you are the only distributor of the given frameworks. For example, say that you wanted to include libcurl as part of your umbrella framework. Now some other packager also wants to include libcurl as part of his umbrella framework. Now we have a link-time collision that can lead to either link errors or worse, undefined runtime behavior. I've chased these down myself. They're extremely unpleasant. The only way to avoid this is for there to be only a single version of each framework/library. Umbrella frameworks encourage the opposite.

Even if you are just breaking up your own code into subpieces, this means that other vendors might use your sub-frameworks in their own umbrella frameworks, leading back to the same problem. Remember, if you say it's ok for you as a third party to use umbrella frameworks, then it's ok for other vendors too.

To the second point, umbrella frameworks only make sense if you control the versioning of all the sub-frameworks. Trying to patch one piece of an inter-dependent set of frameworks is almost always a disaster in my experience.

The OS vendor has an unusual situation due to the size and ubiquity of their system. Things that make sense at one scale often do not make sense at another. NSResponder is completely correct about that. The trade-offs are different when you're providing a complete, multi-thousand package environment that is the basis of every program written for the platform. But even Apple has only a handful of large umbrella frameworks, and they are always wrappers around libraries that they provide and control the version of. This is mostly to simplify the work of developers who would otherwise have to chase down dozens of libraries and frameworks to get something to compile. No third party has that situation, and so it is very rare that a third-party needs this solution. Asking your customer to link two libraries is completely different then asking them to link 20. If you're providing 20 frameworks that all work together and you control, then maybe you should use an umbrella, but also maybe you have too many frameworks for a third party.

Most of my discussion here is in terms of OS X. On iOS it is a non-issue for third-parties. Static libraries must never link other static libraries due to the collisions that will certainly occur.

In theory, most of the issues I've discussed here a fundamentally technical limitations of the linker. The linker doesn't have a good way to manage multiple versions of libraries and so collisions are a serious problem. .NET assemblies try to provide more flexibility around this. I'm not familiar enough with .NET development to say whether this has been successful or not. My experience with large multi-component systems is that simpler, less flexible solutions are best for most problems. (But then, the grass is always greener....)

Solution 2 - Objective C

One issue is that the version of framework B is now tied to the version of framework A. This may be what you want in some cases and not others. If framework B is likely to be used independently by an app that also wants to use framework A that app may find itself in a situation where the version of B included in A is not the version that it needs or wants.

Is framework B a framework that an app could use independently of A? If so then you may run into this scenario. If B is framework that is not available outside of A then you should not run into this scenario.

Solution 3 - Objective C

In Apple's case, they're delivering a huge amount of code, and those sub-frameworks are often revised separately. If you're delivering several gigs of frameworks, then you might want to go ahead and make an umbrella framework. If not, you probably don't need the hassle.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBen DolmanView Question on Stackoverflow
Solution 1 - Objective CRob NapierView Answer on Stackoverflow
Solution 2 - Objective CJon SteinmetzView Answer on Stackoverflow
Solution 3 - Objective CNSResponderView Answer on Stackoverflow