How to Create an Umbrella Framework in iOS Sdk

How to create an umbrella framework in iOS SDK?

We all know that creating umbrella framework is highly discouraged by Apple. But apple also says it’s possible via Xcode. https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/CreationGuidelines.html#//apple_ref/doc/uid/20002254-BAJHGGGA

I achieved creating umbrella framework via these simple approach on Xcode 5.1. We just need to do take care of some special configuration to linking sub-framework to umbrella framework. Here was my approach:-

  1. Install real Static iOS Framework on Xcode 5.1 from the method described here:- https://github.com/kstenerud/iOS-Universal-Framework.

Now the ‘Static iOS Framework’ can be created using the new option in Xcode.

Sample Image


  1. Create a Static iOS Framework and change the Target-> Build Settings-> Architectures-> Architectures settings to Standard architectures. This will create the framework with all the Standard Architectures.

Sample Image


  1. Adjust Public Header files in Target-> Build Phase-> Copy Headers. We can set the header file visibility here.

Sample Image


  1. Link SubFramework to UmbrellaFramework in Target->Build Phase -> Link Binary With Libraries. We may also need to link other standard framework depending on our use.

Sample Image
Sample Image


  1. We may also need to add Bundle Resources in Target-> Build Phase-> Copy Bundle Resources if we need.

Sample Image


  1. We may also need to add -ObjC to Target-> Build Settings->Linking-> Other Linker Flag, as we may need to load a large subFramework where there are many categories to load or need to load additional frameworks also.

Sample Image


  1. Add Copy File using Target-> Build Phases-> +-> New Copy File Build Phase.

Sample Image


  1. Change it’s Destination to Frameworks and add SubFramework.framework there. This will copy SubFramework to Umbrella Framework.

Sample Image
Sample Image


  1. For the demo I Added two demo methods in UmbrellaFramework class. One to demonstrating umbrella framework method call and one for calling subFramework method.

Sample Image
Sample Image


  1. Select iOS Device and Archive the UmbrellaFramework project from Menu->Product->Archive. This will create our umbrella framework and that’s all.

Sample Image


  1. Now it’s time to create a new demo project, and link it with UmbrellaFramework.

Sample Image


  1. Just import UmbrellaFramework header and call the two methods. It will show the Hello messages in log window.

Sample Image

Xcode12.4 - iOS Umbrella xcframework framework with xcframework sub projects

Some things to try:

  1. Make sure to have BUILD_LIBRARY_FOR_DISTRIBUTION set.

  2. Link the sub frameworks statically. If you are including the other frameworks using CocoaPods, make sure you specify use_frameworks! :linkage => :static.

  3. In your source files where you use the sub-frameorks, write @_implementationOnly import SomeFramework .

iOS Umbrella Framework - codesign problem

The Solution

The problem is that the script was starting when the pod wasn't already attached.
The script should be run when all the pod jobs are done.

I wrote a full guide to build an iOS Umbrella framework!

The solution I found is the following:

1) Step one:

In the podfile of the integration project (not the umbrella project) add the following line of code where you add dependencies:

script_phase :name => 'Sign', :script => './sign.sh'

like this:

target 'yourTarget' do

# Pods for sdkInteTest
#your pods goes here

script_phase :name => 'Sign', :script => './sign.sh'
end

2) Step two:

Than in the terminal at the root of your test Integration project:

In the terminal type:

touch sign.sh
chmod 777 sign.sh
open sign.sh

And in the script file add this code:

echo "Signing subframeworks"
pushd "${TARGET_BUILD_DIR}"/"${PRODUCT_NAME}".app/Frameworks/YOURFRAMEWORKNAME.framework/Frameworks
for EACH in *.framework; do
echo "-- signing ${EACH}"
/usr/bin/codesign --force --deep --sign "${EXPANDED_CODE_SIGN_IDENTITY}" --entitlements "${TARGET_TEMP_DIR}/${PRODUCT_NAME}.app.xcent" --timestamp=none $EACH
done
popd

echo "BUILD DIR ${TARGET_BUILD_DIR}"

remember to rename your framework name.

In this way you are telling to CocoaPods to run a script phase after the pod installation.
Unfortunately this is a "client" solution, I tried to find a solution to apply at framework level without any luck.



Related Topics



Leave a reply



Submit