IOS
Frameworks
Framework with hidden dependencies
10 min
when developing a framework other developers will use, we may need to include another framework to ours as a dependency if we use the included framework just for the implementation details, we don't want it to be visible (re export) to the developers that integrate our framework in their app that's why we need to find a way to “hide” internal dependencies from the clients of our framework this is something that is being discussed over swift forums, and currently it's partly implemented, but apple does not officially support it it may introduce breaking changes in future versions of swift how to follow up we have three separate pieces that we will mention through the article framework that we are developing for the clients — ourframework framework that we are including in our framework as dependency — frameworka client's app that integrates our framework — clientapp integrate frameworka we will do it manually with no dependency manager to make it transparent what we are doing drag and drop frameworka xcframework to the ourframework project import frameworka somewhere in ourframework code and that would be it, right? well, not exactly, let's export ourframework xcframework and try to use it from the test project xcode won't build the test project because it fails with the following error failed to build module 'ourframework' from its module interface; it may have been damaged, or it may have triggered a bug in the swift compiler when it was produced failed to build module click on ourframework in folder structure in xcode select build settings tab set framework search paths to the directory where frameworka xcframework is located export ourframework xcframework again and add it to the test project this time there are no errors and the project builds but the problem is that now we can import included frameworka as well, which may not be behavior that we want framework visibility ⚠️ as already mentioned in introduction, this is not fully supported by apple and may be buggy as stated in https //forums swift org/t/update on implementation only imports/26996 if we want to hide the framework that is included in your framework as dependency for whatever reason we need to import the included framework differently instead of standard import frameworka we need to use @ implementationonly import frameworka add @ implementationonly annotation to the imports of frameworka // myframework swift @ implementaitononly import dependencyframework export ourframework add ourframework to the test project now if we try import frameworka in the test project, xcode will throw an error that it can't find the module frameworka by using @ implementationonly import , frameworka won't be added to the swiftinterface file quote from harlan haskins https //twitter com/harlanhaskins from swift forums post https //forums swift org/t/challenges creating an xcframework for native libraries/41600 this is where the somewhat unsupported but still very useful @ implementationonly import comes in @ implementationonly import x hidden the import of x from your clients (one way that it does this is by not printing the import in the swiftinterface file)it also requires that you do not use the types from x in any of your public api or abi surface, since that would require your clients to be able to see into x and without library evolution turned on, using any type from x inside any of your public types, even if they're private, means they're part of your type's abis the safest thing is to combine @ implementationonly import with library evolution for your framework and since declarations in @ implementationonly imported libraries are not part of your library's abi, those libraries do not need to maintain abi stability or be compiled with library evolution support limitations public api of ourframework can't use any api from frameworka — enforced by the compiler public types of ourframework can't conform to the protocols of frameworka — enforced by the compiler if the public type of ourframework overrides type from frameworka , we must use @ implementationonly annotation on that public type as well @testable import myframework can be buggy because it does not include ourframework as it would normally do without @ implementationonly references https //forums swift org/t/challenges creating an xcframework for native libraries/41600 https //forums swift org/t/challenges creating an xcframework for native libraries/41600 https //forums swift org/t/update on implementation only imports/26996/17 https //forums swift org/t/update on implementation only imports/26996/17 https //forums swift org/t/exported and fixing import visibility/9415 https //forums swift org/t/exported and fixing import visibility/9415 https //medium com/@anuragajwani/modular ios guide 60810f5a7f97 https //medium com/@anuragajwani/modular ios guide 60810f5a7f97