If you have code to package as a framework which has a 3rd party dependency, what can you do given that iOS doesn't support umbrella frameworks

I've got a large and complex app which has several dependencies upon 3rd party libraries (installed as pods).

The app is structured according to Model-View-Controller design and there is a requirement to implement the Model part as an .xcframework so it can be included and used in the original app along with a few new apps.

However, Apple documentation states that umbrella frameworks are not supported (Technical Note TN2435).

The Model code has several dependencies which would be totally unfeasible to replace or remove, for example it uses RealmSwift for database storage. Obviously it would be impossible to write one's own database storage scheme in place of using Realm.

However, if my framework uses Realm as a dependency, then its now become an umbrella framework.

So therefore not supported according to Apple documentation. So what are options/solutions?

Answered by DTS Engineer in 829463022

There are basically two strategies here:

  • Completely hide these dependencies from your framework’s clients.

  • Completely expose these dependencies to your framework’s clients.

In the first strategy, you statically link these dependencies into your framework. However, that may not be the only necessary step. If one of your dependencies exposes types via the Swift or Objective-C language runtimes, you can run into problems if a client of your framework brings in their own copy of that dependency. The standard way around this is for you to rename these types within your copy of this framework. This isn’t fun.

Note Historically this strategy was tricky because Xcode didn’t support static frameworks. That’s no longer an issue. Xcode now supports both static frameworks and mergeable frameworks, which greatly simplify the static linking story.

In the second strategy, you expose these dependencies to your clients by shipping them as separate frameworks. That’s a bit more hassle for your clients, but it avoids the need for renaming. However, that doesn’t mean it’s completely sans drawbacks. If one of your clients uses one of your dependencies directly, you and they need to agree on what version to you. And that raising questions about both API and ABI stability.


Written by mungbeans in 776743021
its now become an umbrella framework.

An umbrella framework has a very specific technical meaning, and that’s not what you’re talking about here. The term you’re looking for is nested framework.

Notably, the ability to nest frameworks isn’t a critical factor here. Sure, it helps tidy things up when you’re using the second strategy, but it doesn’t actually resolve the most significant issue with the second strategy, that is, agreeing on what version to use.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Accepted Answer

There are basically two strategies here:

  • Completely hide these dependencies from your framework’s clients.

  • Completely expose these dependencies to your framework’s clients.

In the first strategy, you statically link these dependencies into your framework. However, that may not be the only necessary step. If one of your dependencies exposes types via the Swift or Objective-C language runtimes, you can run into problems if a client of your framework brings in their own copy of that dependency. The standard way around this is for you to rename these types within your copy of this framework. This isn’t fun.

Note Historically this strategy was tricky because Xcode didn’t support static frameworks. That’s no longer an issue. Xcode now supports both static frameworks and mergeable frameworks, which greatly simplify the static linking story.

In the second strategy, you expose these dependencies to your clients by shipping them as separate frameworks. That’s a bit more hassle for your clients, but it avoids the need for renaming. However, that doesn’t mean it’s completely sans drawbacks. If one of your clients uses one of your dependencies directly, you and they need to agree on what version to you. And that raising questions about both API and ABI stability.


Written by mungbeans in 776743021
its now become an umbrella framework.

An umbrella framework has a very specific technical meaning, and that’s not what you’re talking about here. The term you’re looking for is nested framework.

Notably, the ability to nest frameworks isn’t a critical factor here. Sure, it helps tidy things up when you’re using the second strategy, but it doesn’t actually resolve the most significant issue with the second strategy, that is, agreeing on what version to use.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

@eskimo @DTS Engineer

Hello, thank you. Have you got any thoughts on this related issue I'm encountering:

https://developer.apple.com/forums/thread/776838

No, sorry. I saw that go by but didn’t respond because I have zero expertise in CocoaPods )-:

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Hello @eskimo @DTS Engineer

In the response, There are basically two strategies here: Completely hide these dependencies from your framework’s clients. Completely expose these dependencies to your framework’s clients. In the first strategy, you statically link these dependencies into your framework.

How should a framework be statically linked into its parent framework, which setting in Xcode controls this?

Written by mungbeans in 829701022
How should a framework be statically linked into its parent framework, which setting in Xcode controls this?

There are three basic strategies for this:

  • Build a static library.

  • Build a static framework.

  • Build a mergeable framework and then choose to statically link it.

Honestly, I’m a big fan of the last option because it gives your clients the most flexibility.

Regardless, the exact process depend on a variety of factors, including the build system you use to create the library and the build system you use to consume it. For Xcode, there are various articles in Xcode > Bundles and frameworks and Xcode > Build system.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

@DTS Engineer / @Eskimo

Thank you for your answers on this topic.

There's something I'm not clear on - above you say "An umbrella framework has a very specific technical meaning, and that’s not what you’re talking about here. The term you’re looking for is nested framework." and outline possible approaches.

But in this post https://developer.apple.com/forums/thread/748419

You state: "You’re correct that iOS doesn’t support nested frameworks."

So what is exactly meant by the term nested framework therefore?

Thank you

iOS doesn’t supported nested frameworks. We call that out in Placing Content in a Bundle.

iOS also doesn’t support umbrella frameworks. Umbrella frameworks were already considered a legacy feature by the time we started developing iOS.

We’ve never supported third-party developers creating umbrella frameworks. See Don’t Create Umbrella Frameworks.

The purpose of an umbrella framework is to have a single framework that your code references. It then pulls in all the necessary headers. It also affects the link phase, where you only need to link to the umbrella’s stub library and the linker finds the necessary symbols in the subframeworks.

The classic example of an umbrella is Cocoa.framework, which groups together Foundation, AppKit and Core Data.

Umbrella frameworks made some sense back in the day. They’re somewhat convenient at the source code level but, more importantly, they had both compile- and load-time performance benefits when using the old school tools that we started the Mac OS X project with. None of that matters today.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

@DTS Engineer / @Eskimo

What is the situation outlined this ticket called?

Where app A is using a Framework F which in turn contains dependencies upon other(3rd party) frameworks?

If that is possible (which it must be as you're making reccommendations on approaches), how is it different from nested frameworks?

Than you

Written by mungbeans in 830226022
What is the situation outlined this ticket called?

Frameworks and their dependencies, I guess. I’m not really sure what you’re asking here.

The iOS restriction on nested frameworks is all about the nesting. It’s fine for framework F to depend on frameworks G, H, and I, it’s just that you can’t nest G, H, and I within F. You have to flatten out the hierarchy, so all the frameworks appear within the Frameworks directory of app A.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

If you have code to package as a framework which has a 3rd party dependency, what can you do given that iOS doesn't support umbrella frameworks
 
 
Q