iOS制作framework靜態(tài)庫-避坑指南

關(guān)于ios制作靜態(tài)庫众旗,網(wǎng)上篇幅一大堆罢杉,這里重點(diǎn)介紹下遇到的坑。

一.如何制作framework

1.創(chuàng)建Framework項(xiàng)目
image.png
2.更改Xcode配置

2.1 修改支持版本以及平臺(tái)


image.png

2.2 修改編譯設(shè)置
鏈接類型贡歧,Mach-O Type 選擇Static Library(靜態(tài)庫)

image.png

2.3 修改 Dead Code Stripping
將Build Settings中Link下面的Dead Code Stripping設(shè)置為NO滩租。
注:Dead Code Stripping:舍棄無用代碼,編譯器會(huì)對一些沒有引用的無效代碼進(jìn)行丟棄利朵,這里我們可以設(shè)置未NO律想,盡量保證我們的源代碼的完整性,避免一些額外的錯(cuò)誤绍弟。


image.png

2.4.編譯架構(gòu)

image.png

2.5 修改Link With Standard Library
將Build Settings中Link下面的Link With Standard Libraries關(guān)閉蜘欲,我想可能是為了避免重復(fù)鏈接


image.png
3.修改頭文件的訪問權(quán)限
image

或者從Build Phases中修改,將需要公開的頭文件拖到Public下面

image.png

在Framework的頭文件中導(dǎo)入需要公開的頭文件【這里有坑晌柬,下文會(huì)講】

image.png
4.合并靜態(tài)庫

至此就可以分別選擇模擬器和Any iOS Device進(jìn)行編譯姥份,得到模擬器下的架構(gòu)和真機(jī)下的架構(gòu)郭脂。然后通過lipo命令進(jìn)行合并。下面簡要介紹下相關(guān)lipo命令

// 查看庫信息
lipo -info xxx.framework/xxxxFramework(庫地址)
// 分離架構(gòu)
lipo XXXX.framework/XXXX -thin arm64 -output XXXX.framework/XXXX-arm64
//-output 輸出命令可以簡寫成 -o
//lipo XXXX.framework/XXXX -thin arm64 -o XXXX.framework/XXXX-arm64
// 合并架構(gòu)
lipo -create XXXX.framework/XXXX-armv7 XXXX.framework/XXXX-arm64 -output XXXX.framework/XXXX
// 刪除某個(gè)結(jié)構(gòu)
lipo XXXX.framework/XXXX -remove i386 -output XXXX.framework/XXXX
5.添加生成Framework的腳本

鑒于以上手動(dòng)合并庫的形式較為low澈歉,可以創(chuàng)建一個(gè)腳本自動(dòng)輸出合并之后的庫

image
image.png
image
#!/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}"

#刪除編譯之后生成的無關(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}"

選擇Shell target莹弊,直接編譯則生成Debug模式的Framework,Archive則生成Release模式的Framework

image.png

編譯成功后將自動(dòng)打開Framework所在的目錄

image.png
二.避坑指南
坑1:公開的頭文件import的時(shí)候使用雙引號涡尘,外部使用的時(shí)候報(bào)找不到頭文件

解決思路:一定要用尖括號的形式引用忍弛。因?yàn)榇虬伸o態(tài)庫之后,文件會(huì)打包在靜態(tài)庫資源包里考抄,如果通過雙引號引用導(dǎo)入细疚,在靜態(tài)庫的項(xiàng)目里不會(huì)報(bào)錯(cuò),但是外部使用進(jìn)行編譯的時(shí)候會(huì)從主項(xiàng)目中找頭文件川梅,那么肯定會(huì)報(bào)找不到頭文件的error疯兼。

//一定要用#import <xxxx/xxxx.h> 引導(dǎo)編譯器本模塊尋找頭文件
#import <aaaa/aaaa.h>
#import <bbbb/bbbb.h>
#import <cccc/cccc.h>
坑2:所有暴露為public的頭文件中,存在部分頭未暴露的文件引用贫途。

比如aaaa.h設(shè)為public了吧彪,aaaa.h中引用了dddd.h,但是dddd.h并沒有暴露出來丢早,靜態(tài)庫內(nèi)部編譯沒問題姨裸,但是外部使用會(huì)報(bào)sdk編譯錯(cuò)誤。

解決思路:暴露出來的頭文件中怨酝,如有相關(guān)聯(lián)的頭文件也要一定暴露啦扬。或者將原本在.h文件中的引用放入.m文件中凫碌。

坑3:靜態(tài)庫中包含category扑毡,外部使用crash,報(bào)方法找不到盛险。

解決方案(以下2點(diǎn)都要設(shè)置):
1.靜態(tài)庫中存在category時(shí)瞄摊,在 Framework 文件中添加 target --> Build setttings --> linking --> Other linker flags 添加 -Objc,同時(shí)支持-all_load苦掘,保證分類能打包進(jìn)去换帜。
2.外部使用的時(shí)候,也需要在 target --> Build setttings --> linking --> Other linker flags 添加 -Objc鹤啡,同時(shí)支持-all_load惯驼。

image.png

這里關(guān)于other Link Flags中的-ObjC,-all_load,-force_load祟牲,這里有詳細(xì)說明:http://www.reibang.com/p/f7b0aa817cff

坑4:庫中有第三方庫的引用隙畜,外部使用時(shí)會(huì)報(bào)存在重復(fù)的.o文件

解決方案:
方案A:通過rename修改類名,變成自己的私有框架
在打包成framework之前说贝,在每個(gè)第三方框架的類名的前面议惰,通過Xcode的rename操作對類名、系統(tǒng)分類的方法名乡恕,枚舉言询,結(jié)構(gòu)體進(jìn)行統(tǒng)一修改,比如加一個(gè)前綴(隨便你加什么)傲宜。 這是個(gè)細(xì)活运杭,但是一勞永逸,這個(gè)框架以后就是屬于你自己的了函卒,隨便你怎么去修改辆憔。跟其他工程中的類,也不會(huì)有任何沖突谆趾。


image.png

優(yōu)點(diǎn):一勞永逸,不會(huì)對外界產(chǎn)生影響叛本。
缺點(diǎn):會(huì)增加包的體積沪蓬,同時(shí)rename是個(gè)細(xì)致活,尤其是對系統(tǒng)的一些分類的方法名来候、枚舉值進(jìn)行組個(gè)rename跷叉,比較麻煩。
方案B:制作靜態(tài)庫時(shí)對三方庫只是添加單純添加引用营搅,不導(dǎo)入到模塊中來云挟。外部項(xiàng)目使用該的時(shí)候,由外部對該三方庫進(jìn)行手動(dòng)導(dǎo)入或者pod引入转质。
優(yōu)點(diǎn):包體積小园欣,不存在代碼相同功能代碼造成的代碼冗余。
缺點(diǎn):需要外部使用的時(shí)候添加三方庫的依賴休蟹,中間可能會(huì)存在一些報(bào)錯(cuò)沸枯,接入成本較高。


image.png

參考:
http://www.reibang.com/p/a80ce7d25ddf
http://www.reibang.com/p/f7b0aa817cff
http://www.reibang.com/p/e5726852bb82
http://www.reibang.com/p/b92912216d65
http://www.reibang.com/p/d79f6c866fdb

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末赂弓,一起剝皮案震驚了整個(gè)濱河市绑榴,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌盈魁,老刑警劉巖翔怎,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡赤套,警方通過查閱死者的電腦和手機(jī)飘痛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來于毙,“玉大人敦冬,你說我怎么就攤上這事∥ň冢” “怎么了脖旱?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長介蛉。 經(jīng)常有香客問我萌庆,道長,這世上最難降的妖魔是什么币旧? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任践险,我火速辦了婚禮,結(jié)果婚禮上吹菱,老公的妹妹穿的比我還像新娘巍虫。我一直安慰自己,他們只是感情好鳍刷,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布占遥。 她就那樣靜靜地躺著,像睡著了一般输瓜。 火紅的嫁衣襯著肌膚如雪瓦胎。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天尤揣,我揣著相機(jī)與錄音搔啊,去河邊找鬼。 笑死北戏,一個(gè)胖子當(dāng)著我的面吹牛负芋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嗜愈,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼示罗,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了芝硬?” 一聲冷哼從身側(cè)響起蚜点,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎拌阴,沒想到半個(gè)月后绍绘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年陪拘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了厂镇。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,981評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡左刽,死狀恐怖捺信,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情欠痴,我是刑警寧澤迄靠,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站喇辽,受9級特大地震影響掌挚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜菩咨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一吠式、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧抽米,春花似錦特占、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至查辩,卻和暖如春胖笛,著一層夾襖步出監(jiān)牢的瞬間网持,已是汗流浹背宜岛。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留功舀,地道東北人萍倡。 一個(gè)月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像辟汰,于是被迫代替她去往敵國和親列敲。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容