15

iOS applications built with Xcode 6 or higher allow embedding dynamic iOS frameworks within them. I am building a shared framework and would like to embed a sub-framework. How can I accomplish this?

Note: This is possible and is being used in production (for e.g., with Swift frameworks in CocoaPods).

Vatsal Manot
  • 17,695
  • 9
  • 44
  • 80

3 Answers3

12

Found the answer. Here's how it's done:

  • Navigate to Target > Build Phases
  • Click the small "+" icon and select "New Run Script Build Phase"
  • Paste the following:

    cd $BUILT_PRODUCTS_DIR
    
    mkdir $PROJECT_NAME.framework/Frameworks &>/dev/null
    
    for framework in *.framework; do
        if [ $framework != $PROJECT_NAME.framework ]; then
            cp -r $framework $PROJECT_NAME.framework/Frameworks/ &>/dev/null
        fi
    done
    
Vatsal Manot
  • 17,695
  • 9
  • 44
  • 80
  • 4
    This does work, but just to add that a framework which embeds sub-frameworks is known as an "umbrella framework" and is discouraged by Apple. See this question for an excellent answer of why this is the case: http://stackoverflow.com/questions/7365578/why-are-umbrella-frameworks-discouraged What you should be doing: instead of embedding sub-frameworks, you should preferably just distribute your framework along with its dependencies separately. – Jonathan Ellis Jul 14 '15 at 21:51
  • 1
    @JonathanEllis This is not always ideal. For example I've added WebP support using WebP.framework. I don't want my main app, photo editing extension and iMessage extension to all have to include a separate copy of WebP.framework. Wastes space... – jjxtra Oct 07 '16 at 14:20
  • @jjxtra If you're building WebP as a static framework, then yes you're wasting space by linking it 3 times. But you should not be building it as a static framework for you use-case. Dynamic frameworks need only be included once and all the other consumers link and resolve the library at run-time. You don't need an umbrella framework to get this behavior - indeed Apple discourages it. – James H Jan 24 '19 at 18:13
7

@Vatsal Manot's answer was very helpful for me. I modified it a bit and also had a need to sign the copied embedded framework. My script is below.

cd $BUILT_PRODUCTS_DIR/$PRODUCT_NAME.app/Frameworks/Custom.framework/Frameworks
for framework in *.framework; do
    mv $framework $BUILT_PRODUCTS_DIR/$PRODUCT_NAME.app/Frameworks/
    /usr/bin/codesign --force --sign "iPhone Developer" --preserve-metadata=identifier,entitlements --timestamp=none $BUILT_PRODUCTS_DIR/$PRODUCT_NAME.app/Frameworks/$framework
done
Justin Domnitz
  • 3,217
  • 27
  • 34
2

To create a Umbrella Framework that contains a Sub-Framework you can follow the step-by-step guide written down here: Umbrella framework

Community
  • 1
  • 1
ehrpaulhardt
  • 1,607
  • 12
  • 19