I have an SDK that I built into a CocoaTouch Framework. This SDK uses CocoaPods, because it depends on some other libraries. I build the framework using this build script:
# 1
# Set bash script to exit immediately if any commands fail.
set -e
# 2
# Setup some constants for use later on.
FRAMEWORK_NAME="MyFrameworkName"
OUTPUT_DIR="${SRCROOT}/framework/build"
# 3
# If remnants from a previous build exist, delete them.
if [ -d "${OUTPUT_DIR}" ]; then
rm -rf "${OUTPUT_DIR}"
fi
# 4
# Build the framework for device and for simulator (using
# all needed architectures).
xcodebuild -workspace "${FRAMEWORK_NAME}.xcworkspace" -scheme "${FRAMEWORK_NAME}" -configuration Release -arch arm64 -arch armv7 -arch armv7s only_active_arch=no defines_module=yes -sdk "iphoneos" -derivedDataPath "${OUTPUT_DIR}"
xcodebuild -workspace "${FRAMEWORK_NAME}.xcworkspace" -scheme "${FRAMEWORK_NAME}" -configuration Release -arch x86_64 -arch i386 only_active_arch=no defines_module=yes -sdk "iphonesimulator" -derivedDataPath "${OUTPUT_DIR}"
# 5
# Remove .framework file if exists from previous run.
if [ -d "${OUTPUT_DIR}/${FRAMEWORK_NAME}.framework" ]; then
rm -rf "${OUTPUT_DIR}/${FRAMEWORK_NAME}.framework"
fi
# 6
# Copy the device version of framework.
cp -r "${OUTPUT_DIR}/Build/Products/Release-iphoneos/${FRAMEWORK_NAME}.framework" "${OUTPUT_DIR}/${FRAMEWORK_NAME}.framework"
# 7
# Replace the framework executable within the framework with
# a new version created by merging the device and simulator
# frameworks' executables with lipo.
lipo -create -output "${OUTPUT_DIR}/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}" "${OUTPUT_DIR}/Build/Products/Release-iphoneos/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}" "${OUTPUT_DIR}/Build/Products/Release-iphonesimulator/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}"
# 8
# Copy the Swift module mappings for the simulator into the
# framework. The device mappings already exist from step 6.
cp -r "${OUTPUT_DIR}/Build/Products/Release-iphonesimulator/${FRAMEWORK_NAME}.framework/Modules/${FRAMEWORK_NAME}.swiftmodule/" "${OUTPUT_DIR}/${FRAMEWORK_NAME}.framework/Modules/${FRAMEWORK_NAME}.swiftmodule"
This all works fine, also using the framework is not a problem. But since this framework is built using other dependencies, for example Alamofire and Firebase, there are traces of this in the MyFrameworkName.framework
.
When I run an app that uses this my framework, and CocoaPods to add the needed dependencies to the project, I get these errors:
objc[7299]: Class APMPBDynamicFilterResultTimestamp is implemented in both /private/var/containers/Bundle/Application/9966CA12-11F5-42FE-91FF-BB7A91C07571/MyProject.app/Frameworks/MyFrameworkName.framework/MyFrameworkName (0x101b34158) and /var/containers/Bundle/Application/9966CA12-11F5-42FE-91FF-BB7A91C07571/MyProject.app/MyProject (0x1007416e8). One of the two will be used. Which one is undefined.
How would I go about building the framework with the dependencies (otherwise it won't build of course), but without including any of it in the framework?
Thanks
The problem comes from the fact you are using cocoapods dependencies in your SDK. As you mentioned, everything works fine, until the host app has the same dependencies. Unfortunately, there is no simple way to fix the problem, due to symbols for the same dependencies were linked into both SDK and the app. However, there are a few approaches you might consider.
I hope that helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With