IOS開發(fā)有些時(shí)候通過(guò)制作SDK進(jìn)行組件化, 封裝化開發(fā)很方便, 那么怎么制作一個(gè)可用的SDK呢? 直接上干貨
當(dāng)前環(huán)境:
MacOS 12.3.1
Xcode13.4.1
Intel Core i9
xcode → File → New → Project

Frame & Library → Framework → Next

Product Name 中填寫SDK名字 → Next 之后選個(gè)自己能找的到的地方保存工程

創(chuàng)建好了最終是這個(gè)樣子

先修改Deployment info部署信息, 這個(gè)要根據(jù)自己的目標(biāo)工程配置。例如 我加入的目標(biāo)工程支持到 ios10.0, 不支持iPad, Mac, 那么我創(chuàng)建的SDK也要對(duì)應(yīng)修改

圖片中測(cè)試項(xiàng)目是 IOS面試題(設(shè)計(jì)模式相關(guān)) --- 工廠設(shè)計(jì)模式一個(gè)demo , 評(píng)論區(qū)有對(duì)應(yīng)Demo地址,
其實(shí)自己隨便一個(gè)項(xiàng)目加進(jìn)去即可, 留意下版本號(hào)對(duì)應(yīng)即可


接下來(lái) Command + N創(chuàng)建一個(gè)類便于后面調(diào)用

例如我這邊創(chuàng)建一個(gè)SpriteFactory類, 類型是NSObject, 并寫入一個(gè)實(shí)例方法factoryProductSprite


建好之后, 在公共文件ProductSprite.h(第一個(gè), 你自己建的那個(gè)名字), 引入頭文件. 留意下引入文件格式即可

接下來(lái)我們需要修改一下Build Settings中部分內(nèi)容
-
Targets→Build Settings→Mach-O Type為Static Library靜態(tài)庫(kù) (動(dòng)態(tài)庫(kù)有點(diǎn)區(qū)別, 方法在最下面)

-
Targets→Build Settings→Build Active Architecture Only僅構(gòu)建活躍體系為No
修改 Build Active Architecture Only -
Build Settings→Enable Bitcode啟用位代碼為No
修改 Enable Bitcode -
Build Phases→Headers測(cè)試頭文件需要移動(dòng)到Public
移動(dòng)前

-
Edit Scheme→Run→Info→Build Configuration為Release
Build Configuration

接下來(lái)我們建立個(gè)組群, 管理下SDK
-
Targets點(diǎn)擊+→Other→Aggregate老版本位置不一樣的, 需要留意下
管理SDK

建完之后如下, 多了一個(gè)這個(gè)

添加framework的腳本文件, Build Phases 點(diǎn)擊 + 選擇New Run Script Phase

之后會(huì)這樣

把這個(gè)復(fù)制進(jìn)去
#!/bin/sh
#要build的target名
TARGET_NAME=${PROJECT_NAME}
if [[ $1 ]]
then
TARGET_NAME=$1
fi
UNIVERSAL_OUTPUT_FOLDER="${SRCROOT}/${PROJECT_NAME}/"
#創(chuàng)建輸出目錄,并刪除之前的framework文件
mkdir -p "${UNIVERSAL_OUTPUT_FOLDER}"
rm -rf "${UNIVERSAL_OUTPUT_FOLDER}/${TARGET_NAME}.framework"
#分別編譯模擬器和真機(jī)的Framework
xcodebuild -target "${TARGET_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
xcodebuild -target "${TARGET_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphonesimulator BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
#拷貝framework到univer目錄
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${TARGET_NAME}.framework" "${UNIVERSAL_OUTPUT_FOLDER}"
lipo "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${TARGET_NAME}.framework/${TARGET_NAME}" -remove arm64 -output "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${TARGET_NAME}.framework/${TARGET_NAME}"
#合并framework,輸出最終的framework到build目錄
lipo -create -output "${UNIVERSAL_OUTPUT_FOLDER}/${TARGET_NAME}.framework/${TARGET_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${TARGET_NAME}.framework/${TARGET_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${TARGET_NAME}.framework/${TARGET_NAME}"
#刪除編譯之后生成的無(wú)關(guān)的配置文件
dir_path="${UNIVERSAL_OUTPUT_FOLDER}/${TARGET_NAME}.framework/"
for file in ls $dir_path
do
if [[ ${file} =~ ".xcconfig" ]]
then
rm -f "${dir_path}/${file}"
fi
done
#判斷build文件夾是否存在,存在則刪除
if [ -d "${SRCROOT}/build" ]
then
rm -rf "${SRCROOT}/build"
fi
rm -rf "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator" "${BUILD_DIR}/${CONFIGURATION}-iphoneos"
#打開合并后的文件夾
open "${UNIVERSAL_OUTPUT_FOLDER}"

上方選擇新加的Targets 選擇Any iOS Device運(yùn)行

由于我們剛才已經(jīng)寫腳本了, 所以會(huì)自動(dòng)生成模擬器真機(jī)的SDK, 并且自動(dòng)彈開, 如下

其他項(xiàng)目如果想使用, 把.framework拖進(jìn)去或者復(fù)制項(xiàng)目再add進(jìn)去即可

加入之后如下, 留意下General中Frameworks, Libraries, and Embedded Content這快, 如果沒有(老版本), 需要手動(dòng)加進(jìn)去.framework

在合適地方調(diào)用, 引用頭文件格式 #import "ProductSprite/ProductSprite.h", 下面寫進(jìn)去對(duì)應(yīng)方法

運(yùn)行可看到

動(dòng)態(tài)庫(kù)如果正常按上面方式處理會(huì)報(bào)錯(cuò), 例如
Targets → Build Settings → Mach-O Type 為Dynamic Library

運(yùn)行時(shí)候會(huì)這樣Crash

目標(biāo)文件: Build Phases點(diǎn)擊+, 選擇New Copy File Phase

點(diǎn)擊+, 選擇對(duì)應(yīng)動(dòng)態(tài)庫(kù)加進(jìn)去, Destination 留意選擇Frameworks

修改Targets → Build Settings → Build Options → Validate Workspace為Yes

-
Validate Workspace-Yes: 那么在構(gòu)建版本的過(guò)程中將對(duì)工作區(qū)配置進(jìn)行驗(yàn)證檢查。
配置完之后再運(yùn)行, 正常打印





