52

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?

Ben Dolman
  • 3,165
  • 3
  • 25
  • 25
  • I want to know this too. Setting up automated build with git repository, symlinks in dependent projects, framework/header search paths and all that fun stuff can get pretty mind-numbing when the number of frameworks and projects grows. – Minthos Jan 17 '13 at 14:50
  • 9
    You're assuming without evidence that umbrella frameworks *are* "a good solution for Apple's problem(s)". My uninformed opinion is that the opposite is true: Comparing iOS to the older OSX, or newer versions of OSX to older versions, I see frameworks such as CoreGraphics moving *out* of the umbrellas into standalone frameworks. I think the idea of "umbrellas" was a nice kludge to ease Cocoa's growing pains, but never a "good solution for Apple's problem"; and perhaps they're warning you away from getting yourself caught in the same mess. – Quuxplusone Jan 18 '13 at 00:33
  • I'm voting to close this question as off-topic because this topic is too old. Currently, iOS SDK 8.0 and above, provide the dynamic framework, and swift syntax. So, this question is no longer useful. – AechoLiu Feb 23 '16 at 08:56

3 Answers3

67

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....)

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • What if I just want my framework to use a third-party framework? How do I make sure that *my* users link to it too? – zneak Oct 03 '14 at 05:39
  • 3
    By instructing your user to include and link to it. With dynamic libs (OS X and iOS 8), it's fine to link to system-level frameworks yourself. But first third-party frameworks, the only sensible approach is to have all linking be done at the app level under the control of the app developer. To auto-link for your caller, there must be a dependency management system, and there isn't one built in. CocoaPods provides one if both you and your caller choose to use it. But something must handle dependency at the app level. You can't do it from the framework for your caller. – Rob Napier Oct 03 '14 at 12:49
  • What are the possible dynamic link time collisions? If the dylibs are linked recursively and they have install paths to their embedded path, along with two level linking wouldn't that remove the possiblity of any link time collisions? – Garrigan Stafford Sep 22 '22 at 19:55
6

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.

Jon Steinmetz
  • 4,104
  • 1
  • 23
  • 21
  • That's an excellent point, thanks. In my case it wouldn't be an issue, but I can certainly see how that's a factor. – Ben Dolman Sep 12 '11 at 16:53
1

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.

NSResponder
  • 16,861
  • 7
  • 32
  • 46
  • 3
    That makes it seem simply a question of scale. If it's a good solution for many frameworks, why is not also a good solution for a few frameworks? It's like saying that OO design is only a good idea if you have a huge amount of code. Yes, it's good for that case, but it's also good even if you only have a couple classes. – Ben Dolman Sep 09 '11 at 20:53
  • 1
    If a container ship is a good solution for tons of cargo, why is it not also a good solution for a few bags of groceries? – NSResponder Sep 10 '11 at 23:22
  • 4
    Look, I really don't want to get into a war of analogies here. My primary question is this: I want to distribute multiple frameworks as one framework. Apple has a good solution for it, but they discourage its use. Why? A good answer to this question will tell me what is problematic about an umbrella framework that makes it viable only for Apple's frameworks. Your answer explains why umbrella frameworks are good for Apple, but you don't explain why they are bad for me. – Ben Dolman Sep 11 '11 at 02:52
  • @NSResponder The usage of umbrella frameworks has nothing to do with the size of the package you are distributing. I would say it is acceptable for Apple because these frameworks are distributed through their distribution mechanisms purely and so conflicts are somewhat predictable. In other words, it is unlikely that you would inadvertently include conflicting Apple frameworks in your application, but it is not unrealistic to think that a user of YOUR framework may include, separately, conflicting versions of one of your underlying dependencies. Imagine if you had 100 umbrella frameworks. – josephrider Jul 19 '16 at 06:27