abhimuralidharan
abhimuralidharan

Reputation: 5939

iOS: How to add different frameworks for device and simulator in the same code xcode swift?

I have a third party framework with different versions for simulator and real device.

What I am doing: Right now I maintain two different targets for simulator and device respectively. I need to add the framework to the target as well as to the embedded binaries section. I also have to import the header in the bridging header section as these are objc frameworks ( I have added swift compiler flags for each targets and import the necessary headers in bridging header section). If I add both frameworks in same target, it will give duplicate symbols error.

NB: I Don't have the source code for these frameworks. So I cannot build a universal framework and use.

Question: How can I use these frameworks such that , without changing any code or settings, I should be able to run the code on simulator as well as on a real device?

Upvotes: 2

Views: 2570

Answers (1)

Ben Gottlieb
Ben Gottlieb

Reputation: 85522

I do this using an aggregate build target for the framework that runs a shell script. That script uses xcodebuild to create a framework for both the sim and the device, and then uses lipo to combine them into a single framework that can be included in any project, and work on both platforms. Here's a simplified version:

#!/bin/sh

BASE_BUILD_DIR=${BUILD_DIR}
FRAMEWORK_NAME="FrameworkName"
PROJECT_NAME="Framework"
CONFIG=$CONFIGURATION
UNIVERSAL_OUTPUTFOLDER="Build/${CONFIG}-universal"


# make sure the output directory exists
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"

# Step 1. Build Device and Simulator versions
xcodebuild -target "${PROJECT_NAME}" -configuration ${CONFIG} -sdk iphoneos ONLY_ACTIVE_ARCH=NO  BUILD_DIR="${BASE_BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
xcodebuild -target "${PROJECT_NAME}" -configuration ${CONFIG} -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO BUILD_DIR="${BASE_BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build

# Step 2. Copy the framework structure (from iphoneos build) to the universal folder
echo "copying device framework"
cp -R "${BASE_BUILD_DIR}/${CONFIG}-iphoneos/${FRAMEWORK_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/"

# Step 3. Copy Swift modules (from iphonesimulator build) to the copied framework directory
echo "integrating sim framework"
cp -R "${BASE_BUILD_DIR}/${CONFIG}-iphonesimulator/${FRAMEWORK_NAME}.framework/Modules/${FRAMEWORK_NAME}.swiftmodule/" "${UNIVERSAL_OUTPUTFOLDER}/${FRAMEWORK_NAME}.framework/Modules/${FRAMEWORK_NAME}.swiftmodule/"

# Step 4. Create universal binary file using lipo and place the combined executable in the copied framework directory
echo "lipo'ing files"
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}" "${BASE_BUILD_DIR}/${CONFIG}-iphonesimulator/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}" "${BASE_BUILD_DIR}/${CONFIG}-iphoneos/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}"

# Step 5. Convenience step to copy the framework to the project's directory
mkdir -p "${PROJECT_DIR}/iOS Framework/"
rm -rf "${PROJECT_DIR}/iOS Framework/${FRAMEWORK_NAME}.framework"
cp -R "${UNIVERSAL_OUTPUTFOLDER}/${FRAMEWORK_NAME}.framework" "${PROJECT_DIR}/iOS Framework"

Upvotes: 4

Related Questions