Hello everyone, I'm creating an umbrella module wi...
# swift-export
g
Hello everyone, I'm creating an umbrella module with several other modules to export a single framework for my iOS app to consume, but the .xcframework is exceeding 400 MB, even with few modules and little complexity. The tendency is to add more modules and grow. Do you have any recommendations for reducing the size of the .xcframework and consequently the size of the static .framework? (I'm generating the release framework using the podPublishReleaseXCFramework task)
g
See if this helps. I share a few techniques that may help. I also have a sample.
I’m using, Koin, SQLDelight, and non of these are being exported into the umbrella
it all comes down with interfaces hiding the implementation logic, and some other stuff 🙂 hope it helps!
f
Ah the famous explicitAPI 😄
g
Hey guys, I tested the implementation of @Guilherme Delgado and @François, but the .xcframework is still big enough that I can't commit it to git, I'll try to look for some other way to distribute the .xcframework to consume via cocoapods
f
Just by curiosity, did you manage to reduce the size?
g
Yes, I declared everything that wasn't used outside of the shared code internal or private, leaving only those consumed in the native as public and I removed all the "exports" from the modules within the umbrella, I had a considerable reduction, but the .framework within the .xcframework still exceeded GitHub's 100mb limit
f
Sharing xcframework doesn’t require GitHub but a public mirror. Are you building a dynamic or static framework?did you find a change?
Did you try to compress (zip) your xcframework?
How about the target? What target do you use?
g
I'm generating the framework with isStatic = true for release. I tried uploading the zipped .xcframework as a release tag on GitHub to be able to consume it. My project can be built locally (devs) and can also be built via Jenkins (generate releases for Firebase and Testflight).
f
How much is the size of a single target? I guess your xcframework has 2 iOSArm and iOSArmSimulator?
g
ios-arm64 is 125.9mb, .xcframework.zip is 113.5mb and .xcframework (ios-arm64 and ios-arm64_x86_64-simulator) is 373.5mb
f
You should use x86 arch if you really need it. It’s only for macOS using intel processors.
Remove x86_64 if you don’t use macOS intel based processors
g
Yes, in the next steps I will leave only ios-arm64, as my module will only support iOS, but I am already mitigating possible future problems with framework size (the tendency is for my umbrella module to scale and become quite large, as I intend to add other feature modules)
f
Yes, of course. Did you try to build as dynamic framework instead of static and see if the size change?
g
Yes, today the dynamic .framework is on average half the size of the static .framework, as the dSYMs are generated separately and reduce the size of the framework.
m
One related question do we really need umbrella framework with swift export? can't we create independent frameworks for each module. What i mean is instead of creating umbrella module which internally have two module foo and bar. Can we publish foo and bar as two different .xcframework in swift export. Till now I was publishing umbrella. Is it worth exploring or not recommended? still we need to use umbrella.
g
So, my dependency tree looks like this: module_base • no dependencies module_networking • no dependencies module_A • depends on module_base • depends on module_networking module_B • depends on module_base • depends on module_networking The problem I was facing was when I imported the ModuleA and ModuleB pods, I implemented ModuleNetworking and injected it directly into ModuleA and ModuleB, but I was getting an incompatibility error. ModuleA and ModuleB were creating a framework with a different internal dependency on ModuleNetworking. When I did something like: let networking = ModuleNetworkingImpl(...) ModuleA.setNetworking(networking) ModuleB.setNetworking(networking) It gave an error, saying that networking was not compatible.
That's why I ended up implementing the umbrella, to generate a single framework with the same references and not have to create a ModuleA.ModuleNetworkingImpl(...) and a ModuleB.ModuleNetworkingImpl(...)
✅ 1