Hi there! I’m new to creating and distributing binary frameworks so thanks in advance for your patience if I’ve overlooked known solutions.
My goal is to distribute a single Swift XCFramework to customers that requires only a single import
to allow access to all public classes and methods.
The current structure is an Xcode 12-backed workspace created by CocoaPods, which integrates one project that contains a binary framework (FrameworkA) and one project that is just raw code (FrameworkB). Within that workspace are three other projects, each dedicated to a single framework (frameworks C, D, and E), and a final project that is used to gather all these other dependencies and act as the single point of access (CustomerFramework).
There is an additional project (TestHarness) within the workspace to act as a basic way to run tests, confirm functionality, etc.
The structure looks something like this:
Workspace
- CocoaPods static binary framework (FrameworkA)
- CocoaPods normal code projects (FrameworkB)
- FrameworkC project
- FrameworkD project
- FrameworkE project
- CustomerFramework project
- Test harness project
CustomerFramework works as expected when run within TestHarness. Additionally, I can successfully create an XCFramework that contains Simulator and devices frameworks of CustomerFramework.
However, compilation fails when I try to use CustomerFramework.xcframework in a separate demo app. The swiftinterface shows imports for the expected modules (FrameworkA, FrameworkB, etc.) but Xcode raises an error of “No such module ‘FrameworkA’”.
import CustomerFramework <-- “ Failed to build module 'CustomerFramework' from its module interface”
I’ve changed the dependent frameworks from dynamic to static, I’ve attempted to set custom header search paths to the dependent frameworks in the CustomerFramework project, I’ve tried to set custom framework search paths, I’ve tried (and failed) to create a custom modulemap, and I’ve tried what feels like every tip or trick found here, in the Apple dev forums, StackOverflow, and various blog posts.
I can’t use @_implementationOnly
because CustomerFramework purposefully exposes types from dependent frameworks.
Is what I’m trying to do possible? Does anyone have reference values for how to correctly set header search paths? Maybe a real-world project example of something similar to this?
References:
- iOS include third-party static library in Swift dynamic framework - #25 by simonpierreroy
- How can I include my dependent framework's objects to my framework - #10 by erhnby
- @_exported and fixing import visibility
- Can't properly build a dynamic framework containing a static one · Issue #2618 · Carthage/Carthage · GitHub
- https://medium.com/allatoneplace/challenges-building-a-swift-framework-d882867c97f9
- Sub modules in Framework | Apple Developer Forums
- Swift Objective C interoperability, Static Libraries, Modulemap etc… | by Ashis Laha | Medium
- Adding a third party framework inside a first party framework in Xcode | by Colin Chan | John Lewis Partnership Software Engineering | Medium
- Add Xcode 12 compatible support for debug symbols in XCFrameworks · Issue #10111 · CocoaPods/CocoaPods · GitHub