HERE IS AN DEMO PROJECT:
Umbrella Framework Demo
All answers under this line are wrong, cause they just do the thing that manually copy sub frameworks into "umbrella framework"
Embedding a framework within a framework (iOS 8+)
How to create an umbrella framework in iOS SDK?
How to add a framework inside another framework (Umbrella Framework)
Umbrella framework
First thing we should know that "umbrella framework" is a conception in Mac OS not in iOS, the official document is here
https://developer.apple.com/library/content/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/CreationGuidelines.html#//apple_ref/doc/uid/20002254-BAJHGGGA
if you want to create an un-recommend "UmbrellaFramework", you must do these process step by step, and know details during the compile and link periods
- Change all sub frameworks Mach-O to Static Library, it means compile this target as Static Library(.a)
- Manually copy all sub-Framework into UmbrellaFramework during the build phase(Like other answers did)
- Add "FakeBundleShellScript" to Target "UmbrellaFramework", it makes all sub frameworks package itself resources as bundle to join "UmbrellaFramework"
- Change the framework load function, you must load the sub-framework resources via path or url, cause it became an bundle, this step means you should have the supreme control of all codes both sub-frameworks & umbrella
!!Here is an example of "FakeBundleShellScript" you can refer
APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK
do
FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
BUNDLE_IN_ROOT="$APP_PATH/${FRAMEWORK_EXECUTABLE_NAME}.bundle"
if [[ -e "$FRAMEWORK_EXECUTABLE_PATH" ]]; then
FRAMEWORK_MACH_O="$(otool -a "$FRAMEWORK_EXECUTABLE_PATH" | head -n 1)"
FRAMEWORK_FAT_ARCH="$(lipo -info "$FRAMEWORK_EXECUTABLE_PATH")"
else
FRAMEWORK_MACH_O="NO EXIST"
FRAMEWORK_FAT_ARCH="NO EXIST"
fi
echo "FRAMEWORK_EXECUTABLE_NAME is $FRAMEWORK_EXECUTABLE_NAME"
echo "FRAMEWORK_EXECUTABLE_PATH is $FRAMEWORK_EXECUTABLE_PATH"
echo "FRAMEWORK_MACH_O is $FRAMEWORK_MACH_O"
echo "FRAMEWORK_FAT_ARCH is $FRAMEWORK_FAT_ARCH"
echo "BUNDLE_IN_ROOT is $BUNDLE_IN_ROOT"
if [[ "$FRAMEWORK_MACH_O" =~ "Archive :" ]]; then
echo "Rmove Static-Mach-O is $FRAMEWORK_EXECUTABLE_PATH"
rm "$FRAMEWORK_EXECUTABLE_PATH"
defaults write "$FRAMEWORK/Info.plist" CFBundlePackageType "BNDL"
defaults delete "$FRAMEWORK/Info.plist" CFBundleExecutable
if [[ -d "$BUNDLE_IN_ROOT" ]]; then
rm -rf "$BUNDLE_IN_ROOT"
fi
mv -f "$FRAMEWORK" "$BUNDLE_IN_ROOT"
elif [[ "$FRAMEWORK_FAT_ARCH" =~ "Architectures in the fat file" ]]; then
#statements
EXTRACTED_ARCHS=()
for ARCH in $ARCHS
do
echo "Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME"
lipo -extract "$ARCH" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$ARCH"
EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$ARCH")
done
echo "Merging extracted architectures: ${ARCHS}"
lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[@]}"
rm "${EXTRACTED_ARCHS[@]}"
echo "Replacing original executable with thinned version"
rm "$FRAMEWORK_EXECUTABLE_PATH"
mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"
fi
done
http://alanli7991.github.io/2017/07/17/%E6%A8%A1%E5%9D%97%E5%8C%9617Framework%E4%B8%8EStaticFramework%E4%BC%AA%E8%A3%85Bundle/
As all I said, the key point of to make an un-recommend "UmbrellaFramework" is !!!! [Compile the sub-frameworks as Static, process the resources via fake a bundle], REMEMBER!! Apple always said DONT'T CREATE AN UmbrellaFramework
if you can understand Chinese, more details to make an "UmbrellaFramework" can be obtained from my blog
Alan.li 2017年的文章