iOS構建framework

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文件.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容