iOS构建framework
原因:同种业务需要在不同的客户端项目中使用。
问题:
1.代码只能存在一个项目中,便于维护。
2.对业务依赖很大
几种构建的方式
1. 选择pod构建私有库的形式(略)
pod lib create ""
配置等东西自行查找
注意:在podfile里面有一个use_frameworks! 注释掉,这个选项会使生成的结构变成在[nsbundle mainbundle]/framework/xxx.framework/xxx.bundle,导致一般使用xxx.bundle/xxx.png找不到路径
配置s.subspec的时候,如果里面的文件依赖了什么,都需要s.dependency,所以,如果不是依赖关系很大的可以使用,这样会使文件结构很清晰
2. 选择library和bundle构建形式
1.创建static library
new->project->framework & library -> 任选 一个包含uikit,一个包含foundation,可后面引入
在这个target的build phases加入一个run script phases,然后加入如下代码,目的:使输出的frame拥有如下结构:
image
set -e
export FRAMEWORK_LOCN="${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.framework"
# Create the path to the real Headers die
mkdir -p "${FRAMEWORK_LOCN}/Versions/A/Headers"
# Create the required symlinks
/bin/ln -sfh A "${FRAMEWORK_LOCN}/Versions/Current"
/bin/ln -sfh Versions/Current/Headers "${FRAMEWORK_LOCN}/Headers"
/bin/ln -sfh "Versions/Current/${PRODUCT_NAME}" \
"${FRAMEWORK_LOCN}/${PRODUCT_NAME}"
# Copy the public headers into the framework
/bin/cp -a "${TARGET_BUILD_DIR}/${PUBLIC_HEADERS_FOLDER_PATH}/" \
"${FRAMEWORK_LOCN}/Versions/A/Headers"
2.创建一个能生成bundle的target
new->target-> OS X->framework & library -> bundle
选择这个target,然后在buildsettings里面,找到baseSDK删除,会出现变成iOS的版本
加入图片等资源是,在选择的时候选择options,勾选这个bundle的target
3.创建一个管理上面bundle和frame的target
new->target->other->Aggregate
选择此target->build phases. 在target dependencies里面添加依赖的其他两个target
在这里我们需要导出.framework和.bundle,并且需要对不同平台进行编译
创建run script,添加如下代码
set -e
# If we're already inside this script then die
if [ -n "$RW_MULTIPLATFORM_BUILD_IN_PROGRESS" ]; then
exit 0
fi
export RW_MULTIPLATFORM_BUILD_IN_PROGRESS=1
RW_FRAMEWORK_NAME=${PROJECT_NAME}
RW_INPUT_STATIC_LIB="lib${PROJECT_NAME}.a"
RW_FRAMEWORK_LOCATION="${BUILT_PRODUCTS_DIR}/${RW_FRAMEWORK_NAME}.framework"
function build_static_library {
# Will rebuild the static library as specified
# build_static_library sdk
xcrun xcodebuild -project "${PROJECT_FILE_PATH}" \
-target "${TARGET_NAME}" \
-configuration "${CONFIGURATION}" \
-sdk "${1}" \
ONLY_ACTIVE_ARCH=NO \
BUILD_DIR="${BUILD_DIR}" \
OBJROOT="${OBJROOT}" \
BUILD_ROOT="${BUILD_ROOT}" \
SYMROOT="${SYMROOT}" $ACTION
}
function make_fat_library {
# Will smash 2 static libs together
# make_fat_library in1 in2 out
xcrun lipo -create "${1}" "${2}" -output "${3}"
}
# 1 - Extract the platform (iphoneos/iphonesimulator) from the SDK name
if [[ "$SDK_NAME" =~ ([A-Za-z]+) ]]; then
RW_SDK_PLATFORM=${BASH_REMATCH[1]}
else
echo "Could not find platform name from SDK_NAME: $SDK_NAME"
exit 1
fi
# 2 - Extract the version from the SDK
if [[ "$SDK_NAME" =~ ([0-9]+.*$) ]]; then
RW_SDK_VERSION=${BASH_REMATCH[1]}
else
echo "Could not find sdk version from SDK_NAME: $SDK_NAME"
exit 1
fi
# 3 - Determine the other platform
if [ "$RW_SDK_PLATFORM" == "iphoneos" ]; then
RW_OTHER_PLATFORM=iphonesimulator
else
RW_OTHER_PLATFORM=iphoneos
fi
# 4 - Find the build directory
if [[ "$BUILT_PRODUCTS_DIR" =~ (.*)$RW_SDK_PLATFORM$ ]]; then
RW_OTHER_BUILT_PRODUCTS_DIR="${BASH_REMATCH[1]}${RW_OTHER_PLATFORM}"
else
echo "Could not find other platform build directory."
exit 1
fi
# Build the other platform.
build_static_library "${RW_OTHER_PLATFORM}${RW_SDK_VERSION}"
# If we're currently building for iphonesimulator, then need to rebuild
# to ensure that we get both i386 and x86_64
if [ "$RW_SDK_PLATFORM" == "iphonesimulator" ]; then
build_static_library "${SDK_NAME}"
fi
# Join the 2 static libs into 1 and push into the .framework
make_fat_library "${BUILT_PRODUCTS_DIR}/${RW_INPUT_STATIC_LIB}" \
"${RW_OTHER_BUILT_PRODUCTS_DIR}/${RW_INPUT_STATIC_LIB}" \
"${RW_FRAMEWORK_LOCATION}/Versions/A/${RW_FRAMEWORK_NAME}"
# Ensure that the framework is present in both platform's build directories
cp -a "${RW_FRAMEWORK_LOCATION}/Versions/A/${RW_FRAMEWORK_NAME}" \
"${RW_OTHER_BUILT_PRODUCTS_DIR}/${RW_FRAMEWORK_NAME}.framework/Versions/A/${RW_FRAMEWORK_NAME}"
# Copy the framework to the user's desktop
ditto "${RW_FRAMEWORK_LOCATION}" "${HOME}${PROJECT_AUCTION_DIR}/${RW_FRAMEWORK_NAME}.framework"
ditto "${BUILT_PRODUCTS_DIR}/${RW_FRAMEWORK_NAME}.bundle" \
"${HOME}${PROJECT_AUCTION_DIR}/${RW_FRAMEWORK_NAME}.bundle"
写在最后:
本人推荐使用pod的形式去做,原因:framework是静态库,也就是在编译的时候就把实现等链接进来了,这样会使所有链接到的其它库编译进来,导致framework很大,而且每次其它库有更改需要重新生成。pod的模式和动态链接库很相似。
项目中可导入config文件,手动配置一些路径名字等
new->other->configuration setting file
里面放入
PROJECT_NAME = xxx
那么你在target里面的buildsetting里最下面可以看到User-Defined,在buildsetting其他地方使用,只需要输入PROJECT_NAME。
最后选择项目project不是target,选择configurations,选择你要使用的config文件.
网友评论