I am distributing a proprietary iOS SDK as a binary xcframework. The SDK includes some features that require other, external dependencies (also xcframeworks) to work.
The external dependencies are quite large in size, and not many SDK clients use the features that require them. So we decided to distribute a version of the SDK that does not include those features that require those big dependencies. Right now, this is controlled by a compilation flag, e.g.
#if EXTERNAL_DEPENDENCY
import SomeDependency
#endif
class SomeSDKComponent {
// ... other code
#if EXTERNAL_DEPENDENCY
func thisMethodUsesTheExternalDependencies() { ... }
#endif
// ... other code
}
If the SDK client wants to use the features that require those external dependencies, we’d build the SDK with the EXTERNAL_DEPENDENCY turned on.
In Xcode, these dependencies are set to “Do Not Embed”, so that the size of the xcframework stays small, and we distribute the dependencies separately if the client needs them.

While this works, I would great if I can remove the compilation flag.
That is, I want to be able to compile the SDK without all the #ifs:
import SomeDependency
class SomeSDKComponent {
// ... other code
func thisMethodUsesTheExternalDependencies() { ... }
// ... other code
}
and I expect 3 things:
- if the client never uses
thisMethodUsesTheExternalDependencies, their app should work regardless of whether they included the external dependencies or not. - if the client calls
thisMethodUsesTheExternalDependencies, and includes the external dependencies, their app should work as expected. - if the client calls
thisMethodUsesTheExternalDependencies, but does not include the external dependencies, their app should crash when the call is made.
How can I do this?
If I simply remove the #ifs, the client app will crash immediately after launch if they don’t include the external dependencies. The error says
dyld[48209]: Library not loaded: @rpath/ExternalDependency.framework/ExternalDependency
Referenced from: <9F14FB92-BA4C-31E7-A4C9-7C04941377AA> /private/var/containers/Bundle/Application/D81D65F6-81C5-4696-B1BD-854B39473EB2/ClientApp.app/Frameworks/MyProprietarySDK.framework/MyProprietarySDK
…followed by a list of paths that it tried to search for.
So it seems like the app always tries to load these libraries upon launch.
Since the external dependencies are dynamically linked, my understanding is that the linking can theoretically happen when the first time thisMethodUsesTheExternalDependencies is called, instead of at the start of the app. Is there a build setting for this?