ios10 Xcode8打包framework的正確姿勢(shì)

目前我們公司所有的SDK都采用了framework的方式,不再采取靜態(tài)庫(kù)的姿勢(shì),所以我今天也利用工作之余的時(shí)間學(xué)習(xí)一下這個(gè)創(chuàng)建framework的姿勢(shì),雖然這個(gè)過(guò)程非常非常簡(jiǎn)單,但是沒(méi)人指導(dǎo)你,自己摸索還是需要浪費(fèi)點(diǎn)時(shí)間的,走更著我的腳步一起去看看怎么打包自己的第一個(gè) framework.
先聲明本文都屬于操作部分,并且最基礎(chǔ),至于理論部分是參考文檔的,還有其他的理論都會(huì)在后面更新!

理論基礎(chǔ): 大神請(qǐng)?zhí)^(guò)

1. 庫(kù)

庫(kù)是源代碼經(jīng)過(guò)編譯弯囊,形成的二進(jìn)制代碼停忿,別人項(xiàng)目中使用我們的庫(kù)的時(shí)候潘悼,庫(kù)在參與編譯的時(shí)候,直接link就OK了,按照l(shuí)ink的方式贾陷,可以把庫(kù)分為靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)

2. 靜態(tài)庫(kù)

靜態(tài)庫(kù)在編譯的時(shí)候會(huì)被直接拷貝一份疮绷,復(fù)制到目標(biāo)程序里,這段代碼在目標(biāo)程序里就不會(huì)再改變了。
一般以.a 和 .framework為文件后綴名
這種做法是犧牲應(yīng)用“體量”來(lái)節(jié)省編譯時(shí)間唤锉。

3. 動(dòng)態(tài)庫(kù)

與靜態(tài)庫(kù)相反世囊,動(dòng)態(tài)庫(kù)在編譯時(shí)并不會(huì)被拷貝到目標(biāo)程序中,目標(biāo)程序中只會(huì)存儲(chǔ)指向動(dòng)態(tài)庫(kù)的引用窿祥。等到程序運(yùn)行時(shí)株憾,動(dòng)態(tài)庫(kù)才會(huì)被真正加載進(jìn)來(lái)。
動(dòng)態(tài)庫(kù)的優(yōu)點(diǎn)是壁肋,不需要拷貝到目標(biāo)程序中号胚,不會(huì)影響目標(biāo)程序的體積,而且同一份庫(kù)可以被多個(gè)程序使用(因?yàn)檫@個(gè)原因浸遗,動(dòng)態(tài)庫(kù)也被稱作共享庫(kù))猫胁。
同時(shí),編譯時(shí)才載入的特性跛锌,也可以讓我們隨時(shí)對(duì)庫(kù)進(jìn)行替換弃秆,而不需要重新編譯代碼。動(dòng)態(tài)庫(kù)帶來(lái)的問(wèn)題主要是髓帽,動(dòng)態(tài)載入會(huì)帶來(lái)一部分性能損失菠赚,使用動(dòng)態(tài)庫(kù)也會(huì)使得程序依賴于外部環(huán)境。如果環(huán)境缺少動(dòng)態(tài)庫(kù)或者庫(kù)的版本不正確郑藏,就會(huì)導(dǎo)致程序無(wú)法運(yùn)行
以.tbd(之前叫.dylib) 和 .framework 為文件后綴名
蘋果系統(tǒng)為我們提供了很多動(dòng)態(tài)鏈接庫(kù)衡查,我們可以在我們項(xiàng)目工程中查看一下

177C31E7-5036-4C34-A9ED-31A402D2B5D0.png

4. Framework

Framework 是一種打包方式,將庫(kù)的二進(jìn)制文件必盖,頭文件和有關(guān)的資源文件打包到一起拌牲,方便管理和分發(fā)。
Framework只是一種打包方式歌粥,其本身和靜態(tài)塌忽、動(dòng)態(tài)無(wú)關(guān)!
但Cocoa Touch Framework 的實(shí)際內(nèi)容為 Header + 動(dòng)態(tài)鏈接庫(kù) + 資源文件

5. 對(duì)Framework認(rèn)識(shí)的誤區(qū)

誤區(qū)①:.framework是動(dòng)態(tài)庫(kù)失驶,.a是靜態(tài)庫(kù)土居,前面已經(jīng)講過(guò),不再贅述
誤區(qū)②:有人說(shuō)“自定義的動(dòng)態(tài)庫(kù)蘋果審核不通過(guò)”嬉探,那我打的framework是不是通不過(guò)審核擦耀?
任何沒(méi)有時(shí)間前提的結(jié)論都是耍流氓!<撞觥埂奈!
在 iOS 8 / iOS6之前,iOS 平臺(tái)不支持使用動(dòng)態(tài) Framework定躏,開發(fā)者可以使用的 Framework 只有系統(tǒng)的framework账磺,這種限制可能是出于安全的考慮
換一個(gè)角度講芹敌,因?yàn)?iOS 應(yīng)用都是運(yùn)行在沙盒當(dāng)中,不同的程序之間不能共享代碼垮抗,同時(shí)動(dòng)態(tài)下載代碼又是被蘋果明令禁止的氏捞,沒(méi)辦法發(fā)揮出動(dòng)態(tài)庫(kù)的優(yōu)勢(shì),實(shí)際上動(dòng)態(tài)庫(kù)也就沒(méi)有存在的必要了
但是冒版,碼農(nóng)總是喜歡折騰的液茎,一方面骨子里面有一種“你不讓我做我偏要做的倔強(qiáng)”,另一方面用framework確實(shí)比用.a加頭文件的方式簡(jiǎn)單辞嗡,所以這一時(shí)期的開發(fā)者用了很多“奇淫技巧”來(lái)制作framework捆等,這就有了Fake Framework 和 Real Framework的區(qū)分
在 iOS 8 / iOS6后,iOS平臺(tái)添加了動(dòng)態(tài)庫(kù)的支持续室,同時(shí)栋烤, Xcode 6 也原生自帶了 Framework 支持,注意挺狰,前后兩個(gè)維度的不同是兩件事明郭,不要混淆。丰泊。薯定。

那么,為什么 iOS 8 要添加動(dòng)態(tài)庫(kù)的支持瞳购?
主要的理由大概就是 Extension 的出現(xiàn)话侄。Extension 和 App 是兩個(gè)分開的可執(zhí)行文件,同時(shí)需要共享代碼学赛,這種情況下動(dòng)態(tài)庫(kù)的支持就是必不可少的了满葛。但是這種動(dòng)態(tài) Framework 和系統(tǒng)的 UIKit.Framework 還是有很大區(qū)別;還有就是為了支持swift
雖然同樣是動(dòng)態(tài)框架罢屈,但是和系統(tǒng) framework 不同,app 中的使用的 Cocoa Touch Framework 在打包和提交 app 時(shí)會(huì)被放到 app bundle 中(App 和 Extension 的 Bundle 是共享的)篇亭,運(yùn)行在沙盒里缠捌,而不是系統(tǒng)中。也就是說(shuō)译蒂,不同的 app 就算使用了同樣的 framework曼月,但還是會(huì)有多份的框架被分別簽名,打包和加載柔昼,因此蘋果又把這種 Framework 稱為 Embedded Framework哑芹,也正是代碼簽名機(jī)制,通過(guò)AppStore發(fā)布的APP是無(wú)法通過(guò)替換服務(wù)端下發(fā)framework的方式來(lái)進(jìn)行熱更新捕透!



正文:
今天我們將采取“Aggregate+腳本”制作framework,配置選中手動(dòng)配置的方式,后面會(huì)考慮使用 xcconfig 來(lái)默認(rèn)設(shè)置

1, 配置環(huán)境,開源頭文件

打開xcode 創(chuàng)建framework項(xiàng)目


44AB0935-E961-49E5-82AD-E03DC95F43AC.png
07D7A1BD-E9F6-4BC4-BC5D-29A577B82B7F.png
606913CA-35D5-4314-8AB0-689DD2B4E8F2.png

必須更改的兩個(gè)注意點(diǎn):

3FCD6DB8-5505-4720-9528-F5214CACF394.png
597EC445-25AD-4A6C-BDEA-2945F0A366BE.png

最后你還要更改SDK最低支持的版本,這個(gè)和項(xiàng)目更改系統(tǒng)支持的版本一樣,不再贅述
到此基本配置基本完成,也實(shí)現(xiàn)了項(xiàng)目的閉源

2, 添加自動(dòng)打包腳本環(huán)境,實(shí)現(xiàn)自動(dòng)打包

E44CD8EE-0618-45E7-81BD-4D84185D3639.png
0E1796A9-4893-42AC-B02B-59C27D72A670.png
06E693D7-6ED0-488B-BEF3-D14744F69C2E.png
60C7C4FA-87B1-4ACB-A058-E719E007B4BE.png
F0D97DDB-A0D2-4C7F-890D-6AFE992842DD.png
D9F6BE79-76AA-4C2C-891D-AA35AB4DF777.png

常見的錯(cuò)誤:
1, 沒(méi)有改成靜態(tài),不支持動(dòng)態(tài)


75229607-E8BD-445E-8759-D034C0E56E5C.png

2, Defines Module 必須改成NO
3, 支持bitcode的frame操作

如果自己想要制作支持 Bitcode 的 Framework聪姿,
1, 工程中開啟 Enable Bitcode 
2, Build Setting 中 Other Linker Flags 中加入 -fembed-bitcode碴萧。
3, Build Setting 中 Other C Flags 中加入 -fembed-bitcode。

同時(shí)支持模擬器真機(jī)的配置
09D9AD5076E38257F8398340E801E019.jpg

靜態(tài)庫(kù)和自己項(xiàng)目同時(shí)開發(fā)的方案
6211AA11499C3FB2A3E25532AD8DCFE6.jpg

上文中會(huì)用到自動(dòng)打包的 shell 腳本,我使用的是公司其他大神寫的根據(jù)項(xiàng)目需求配置的腳本,這里就不開源了, 大家可以使用以下腳本,也可以實(shí)現(xiàn)自動(dòng)打包

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

#合并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}"
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末盟榴,一起剝皮案震驚了整個(gè)濱河市曹质,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌擎场,老刑警劉巖羽德,帶你破解...
    沈念sama閱讀 221,888評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異迅办,居然都是意外死亡宅静,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門礼饱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)坏为,“玉大人,你說(shuō)我怎么就攤上這事镊绪≡确” “怎么了?”我有些...
    開封第一講書人閱讀 168,386評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵蝴韭,是天一觀的道長(zhǎng)够颠。 經(jīng)常有香客問(wèn)我,道長(zhǎng)榄鉴,這世上最難降的妖魔是什么履磨? 我笑而不...
    開封第一講書人閱讀 59,726評(píng)論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮庆尘,結(jié)果婚禮上剃诅,老公的妹妹穿的比我還像新娘。我一直安慰自己驶忌,他們只是感情好矛辕,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,729評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著付魔,像睡著了一般聊品。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上几苍,一...
    開封第一講書人閱讀 52,337評(píng)論 1 310
  • 那天翻屈,我揣著相機(jī)與錄音,去河邊找鬼妻坝。 笑死伸眶,一個(gè)胖子當(dāng)著我的面吹牛惊窖,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播赚抡,決...
    沈念sama閱讀 40,902評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼爬坑,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了涂臣?” 一聲冷哼從身側(cè)響起盾计,我...
    開封第一講書人閱讀 39,807評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎赁遗,沒(méi)想到半個(gè)月后署辉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,349評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡岩四,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,439評(píng)論 3 340
  • 正文 我和宋清朗相戀三年哭尝,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片剖煌。...
    茶點(diǎn)故事閱讀 40,567評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡材鹦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出耕姊,到底是詐尸還是另有隱情桶唐,我是刑警寧澤,帶...
    沈念sama閱讀 36,242評(píng)論 5 350
  • 正文 年R本政府宣布茉兰,位于F島的核電站尤泽,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏规脸。R本人自食惡果不足惜坯约,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,933評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望莫鸭。 院中可真熱鬧闹丐,春花似錦、人聲如沸被因。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)氏身。三九已至,卻和暖如春惑畴,著一層夾襖步出監(jiān)牢的瞬間蛋欣,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工如贷, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留陷虎,地道東北人到踏。 一個(gè)月前我還...
    沈念sama閱讀 48,995評(píng)論 3 377
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像尚猿,于是被迫代替她去往敵國(guó)和親窝稿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,585評(píng)論 2 359

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

  • 靜態(tài)庫(kù)與動(dòng)態(tài)庫(kù)的區(qū)別 首先來(lái)看什么是庫(kù),庫(kù)(Library)說(shuō)白了就是一段編譯好的二進(jìn)制代碼庄萎,加上頭文件就可以供別...
    吃瓜群眾呀閱讀 11,970評(píng)論 3 42
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,302評(píng)論 25 707
  • 僅以方便自己查閱記錄前言1.靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)有什么異同踪少?靜態(tài)庫(kù):鏈接時(shí)完整地拷貝至可執(zhí)行文件中,被多次使用就有多份冗...
    190CM閱讀 4,227評(píng)論 0 4
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理糠涛,服務(wù)發(fā)現(xiàn)援奢,斷路器,智...
    卡卡羅2017閱讀 134,702評(píng)論 18 139
  • Gson的混淆里面要對(duì)Gson解析的 自己寫的 bean 進(jìn)行混淆保護(hù)。 要不然Gson不識(shí)別混淆后的代碼砸脊,會(huì)出現(xiàn)...
    Bui_vlee閱讀 3,718評(píng)論 0 0