Creating a Framework for iOS

@cerniuk Thanks for your comment.

Please let me know what donā€™t you understand exactly or what you find complex when you get a chance. Thank you!

Using this tutorial as a basis for a custom project and framework, Iā€™m encountering an issue when trying to archive a project with an embedded binary .framework. The project works great when testing in the simulator, but once I switch to Generic iOS Device and select Product > Archive, all the classes within the .framework binary become opaque, triggering ā€œMyClass is unavailableā€ compile errors. I need to archive this project for distribution via TestFlight.

To clarify, I have two projects. One is the pure Cocoa Touch Framework project that produces a .framework product. The second project is completely isolated. I am just linking in a copy of the framework file to the second project using the option outlined in the tutorial note (ā€œyou could just add the KnobControl.framework output.ā€ approach).

This has all the smell of the fat framework problem that Internet folks complain about with Xcode framework output for iOS, but Iā€™m not sure of the appropriate fix as most tutorials are heavily outdated, including the one here (the provided build run script does not work for me) - https://www.raywenderlich.com/2430-how-to-create-a-framework-for-ios

This is a great tutorial though! More like this are needed, and Apple sorely needs to make framework binaries and package management first class citizens in iOS.

Thanks for your feedback @plasticbrain.

Maybe I havenā€™t understood your question correctly, but here you can find some useful info about stripping out simulator slices from your archive: Deep dive into Swift frameworks.

Hope it helps.

[UPDATE] Solved! See my post below.

original ranty post:

@lorenzoboaro Thank you for this link. Thereā€™s some great information there. Unfortunately it only goes so far, as the script there (and in the aforementioned article on raywenderlich) is very specific and fails to work for crafting a universal framework file. Iā€™m encountering build error after build error.

I even tried using just the source from this article, creating a .framework file and importing it in the use project. I cannot figure out the build magic needed.

An updated article focused just on creating and utilizing a .framework file for independent distribution is needed. Problems to solve in such an article:

  • Build an iOS .framework for independent distribution (e.g. on github).
  • Make a .framework that works only on iOS 11 or later targets (64-bit only).
  • Embedding and utilizing a .framework in an archived project, published in App Store or via TestFlight.

@plasticbrain Are you able to provide a sample (e.g. GitHub)?

@lorenzoboaro Hereā€™s the project page for my Cocoa Touch Framework project: GitHub - plasticbraindotcom/SnapNavigation: Composable view navigation for iOS

After several days of work on making a universal framework target, I finally managed to solve all my problems. Iā€™ll try to outline it here for those suffering a similar fate.

Use this ā€œiOS universal frameworkā€ article as the starting guideline for crafting your framework project: iOS universal framework - Yarik Arsenkin

For structural/organization, I followed some of Eric Cerneyā€™s tips in his Building Reusable Frameworks talk, particularly as it relates to Info.plist: https://www.raywenderlich.com/4319-building-reusable-frameworks

To make it all work, I had to tweak the run script from the ā€œiOS universal frameworkā€ article in a couple of ways. Since Iā€™m only offering support for iOS 10.0+, which enforces 64-bit compliance, I had to remove older 32-bit architecture references: armv7, armv7s, i386. I was also encountering an aggravating build error which required that I prefix the build commands with ā€œenv -iā€ (problem, along with solution outlined in commend by Werner Altewischer on stackoverflow: ios - error: unable to load standard library for target 'arm64-apple-ios10.0-simulator'? - Stack Overflow). Finally, I had to also sprinkle in the bitcode directive to bulletproof the binary for inclusion in TestFlight distributions.

Key edits to the runtime script:
env -i xcodebuild -target ā€œ${FRAMEWORK_NAME}ā€ ENABLE_BITCODE=YES BITCODE_GENERATION_MODE=bitcode -configuration Release -arch arm64 only_active_arch=no defines_module=yes -sdk ā€œiphoneosā€

env -i xcodebuild -target ā€œ${FRAMEWORK_NAME}ā€ ENABLE_BITCODE=YES BITCODE_GENERATION_MODE=bitcode -configuration Release -arch x86_64 only_active_arch=no defines_module=yes -sdk ā€œiphonesimulatorā€

The result is that I now have a framework that [ostensibly] works if added manually to a project, or is added with CocoaPods or Carthage. Carthage in particular will utilize any pre-compiled .framework.zip added to a release version target on github, which was the start of the initial challenge for me. This seems to be good, but Iā€™m still testing it. I think I have to utilize a finishing build run script for projects utilizing the .framework file when distributed via App Store / TestFlight (as outlined in the addendum in the ā€œiOS universal frameworkā€ article).

This is a lot of song and dance just for packaging my code for distribution and sharing it with the world! Thanks for the nudging help, and I apologize for any ranting tone I had :). Apple really needs to provide support Swift Package Manager for iOS, watchOS, tvOS.

Hi @plasticbrain! Thanks for sharing this info. Itā€™s valuable and (for sure) it could help other people.

Lorenzo

@lorenzoboaro Hello I have build a framework which uses storyboardā€¦ Now the client has our storyboard and he edited design in that fileā€¦How can he override the storyboard which is in our project into his new, edited oneā€¦ I have tried many things and it is still now workingā€¦ I have tried either building a compiled framework or not compiledā€¦ framework is distributed via cocoaPodsā€¦ I feel desperate please help

@wellbranding Sorry for the delay. Are you able to provide more info on this? What dow you mean with ā€œthe client has edited the Storyboard fileā€? Thanks, Lorenzo

Hi, I have one doubt

Is it possible to use the external dependencies[like Alamofire] inside the Framework. How should we use locally and release the framework with external dependencies.

@lorenzoboaro Can you please help with this when you get a chance? Thank you - much appreciated! :]

Hello, thanks for the article.

I have spent the last few days trying to get a framework project to work, in order to share code. However, i wanted to have some third-party dependencies in there, and also a prefix header file.

I have gotten it to work, but one real drawback of this approach, if i have understood it, is that every time i make a code change to my framework project, it will not be reflected in any other projects until i do a ā€œpod updateā€., and then build? Itā€™s kind of slow and error prone compared to just having all the code in one workspace. Or am i missing something?

Hi, nice tutorial.

Do you know if it is possible use an image from a framework into the actual application in Storyboard? I havenā€™t managed to do it, only programatically with UIImage(named: String, in: Bundle?, compatibleWith: UITraitCollection?).

@sathish95 Sorry for the delay.

Yes, itā€™s possible using vendored_frameworks property provided by CocoaPods.

Lorenzo

@mathiasaf Sorry for the delay.

If you are developing a framework you can have your local projects without the need to do pod update every time. Just do the change and, when done, publish the changes to GitHub or somewhere else.

You can see a configuration Iā€™m using at https://github.com/flexaddicted/ToastKit.

@anieduard sorry for the delay.

Iā€™m not sure about it. Hereā€™s a link on the subject: https://useyourloaf.com/blog/loading-resources-from-a-framework/.

@lorenzoboaro Yeah, Iā€™ve seen this but didnā€™t manage to do it from Interface Builder.

HELLO @lorenzoboaro thank you for this tutorial.
I want to ask you about a problem, for my cocoa touch framework I want to show my classes but only methods declarationsā€¦ I donā€™t want to show the implementation.

When I generate the framework only a projectNameSwift.h class is generated without my classes.
And when I create a cocoa Pod all the content and implementation of my classes is shown.
How can I hide implementation without hiding classes and ā€œInterfacesā€
Is it possible? can you help please?

@lorenzoboaro Can you please help with this when you get a chance? Thank you - much appreciated! :]

I want to do something similar to this but I canā€™t find any good documentation. All I want to do is modularize my code by creating embedded frameworks because I donā€™t want to release source code to the public. These frameworks will need pods and my current hang up is getting the embedded framework talking to cocoapods. How would you recommend going about this?