Xcode12.4 - iOS Umbrella xcframework framework with xcframework sub projects
Some things to try:
Make sure to have
BUILD_LIBRARY_FOR_DISTRIBUTION
set.Link the sub frameworks statically. If you are including the other frameworks using CocoaPods, make sure you specify
use_frameworks! :linkage => :static
.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.
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:-
- 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.
- Create a
Static iOS Framework
and change theTarget-> Build Settings-> Architectures-> Architectures
settings to Standard architectures. This will create the framework with all the Standard Architectures.
- Adjust Public Header files in
Target-> Build Phase-> Copy Headers
. We can set the header file visibility here.
- 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.
- We may also need to add Bundle Resources in
Target-> Build Phase-> Copy Bundle Resources
if we need.
- We may also need to add
-ObjC
toTarget-> 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.
- Add
Copy File
usingTarget-> Build Phases-> +-> New Copy File Build Phase
.
- Change it’s Destination to
Frameworks
and add SubFramework.framework there. This will copy SubFramework to Umbrella Framework.
- For the demo I Added two demo methods in UmbrellaFramework class. One to demonstrating umbrella framework method call and one for calling subFramework method.
- Select
iOS Device
and Archive the UmbrellaFramework project fromMenu->Product->Archive
. This will create our umbrella framework and that’s all.
- Now it’s time to create a new demo project, and link it with UmbrellaFramework.
- Just import UmbrellaFramework header and call the two methods. It will show the Hello messages in log window.
Why are umbrella frameworks discouraged?
Umbrella frameworks only make sense if you are the only distributor of all the involved frameworks, and you will be packaging all the frameworks together as a single versioned package which will be upgraded together. If that is your situation, then that's fine, but this is a very unusual situation. In the Cocoa development world, it is exceedingly unusual for anyone but Apple to be in this situation.
To the first point, umbrella frameworks only make sense if you are the only distributor of the given frameworks. For example, say that you wanted to include libcurl as part of your umbrella framework. Now some other packager also wants to include libcurl as part of his umbrella framework. Now we have a link-time collision that can lead to either link errors or worse, undefined runtime behavior. I've chased these down myself. They're extremely unpleasant. The only way to avoid this is for there to be only a single version of each framework/library. Umbrella frameworks encourage the opposite.
Even if you are just breaking up your own code into subpieces, this means that other vendors might use your sub-frameworks in their own umbrella frameworks, leading back to the same problem. Remember, if you say it's ok for you as a third party to use umbrella frameworks, then it's ok for other vendors too.
To the second point, umbrella frameworks only make sense if you control the versioning of all the sub-frameworks. Trying to patch one piece of an inter-dependent set of frameworks is almost always a disaster in my experience.
The OS vendor has an unusual situation due to the size and ubiquity of their system. Things that make sense at one scale often do not make sense at another. NSResponder is completely correct about that. The trade-offs are different when you're providing a complete, multi-thousand package environment that is the basis of every program written for the platform. But even Apple has only a handful of large umbrella frameworks, and they are always wrappers around libraries that they provide and control the version of. This is mostly to simplify the work of developers who would otherwise have to chase down dozens of libraries and frameworks to get something to compile. No third party has that situation, and so it is very rare that a third-party needs this solution. Asking your customer to link two libraries is completely different then asking them to link 20. If you're providing 20 frameworks that all work together and you control, then maybe you should use an umbrella, but also maybe you have too many frameworks for a third party.
Most of my discussion here is in terms of OS X. On iOS it is a non-issue for third-parties. Static libraries must never link other static libraries due to the collisions that will certainly occur.
In theory, most of the issues I've discussed here a fundamentally technical limitations of the linker. The linker doesn't have a good way to manage multiple versions of libraries and so collisions are a serious problem. .NET assemblies try to provide more flexibility around this. I'm not familiar enough with .NET development to say whether this has been successful or not. My experience with large multi-component systems is that simpler, less flexible solutions are best for most problems. (But then, the grass is always greener....)
Related Topics
iOS 7 Uitextview Vertical Alignment
Programmatically Add Centerx/Centery Constraints
How to Switch to Different Storyboard for iPhone 5
Custom Font Sizing in Xcode 6 Size Classes Not Working Properly with Custom Fonts
Programmatically Dial a Phone Number and Pass Dtmf Using the iPhone Sdk
Best Way to Parse Url String to Get Values for Keys
Check If Uicolor Is Dark or Bright
Usage of Protocols as Array Types and Function Parameters in Swift
How to Disable/Enable the Sleep Mode Programmatically in iOS
Since Xcode 8 and iOS10, Views Are Not Sized Properly on Viewdidlayoutsubviews
How to Create a Simple Checkbox in iOS
Objective-C 101 (Retain VS Assign) Nsstring
Using Custom Font in a Uiwebview
Alternative iOS Layouts for Portrait and Landscape Using Just One .Xib File