背景
最近入職了一家新公司,進(jìn)來(lái)之后分配到的任務(wù)是為公司APP和客戶做插件化服務(wù)(勘誤:在ios中說(shuō)插件化,怕是要翻水水
),也就是做SDK開發(fā).之前開發(fā)APP的時(shí)候總是吐槽別人家的SDK很難用,各種使用上的坑.現(xiàn)在輪到自己來(lái)做了,心里難免會(huì)有一種翻水水的感覺,哈哈......
初識(shí)SDK
iOS中SDK開發(fā)通常有兩種方式:
StaticLibrary
Framework
至于如何創(chuàng)建StaticLibrary和Framework的方法這里就不細(xì)說(shuō)了.我這里采用的Framework的方式來(lái)開發(fā),原因是Framework只會(huì)加載一次,比較省空間(移動(dòng)設(shè)備的內(nèi)存通常都是比較珍貴的).
其中Framework工程的BuildSetting中Mach-O Type 設(shè)置為 Static Library
;
開發(fā)過(guò)程
-
當(dāng)我創(chuàng)建好一個(gè)framework工程之后,我編寫了一些簡(jiǎn)單的代碼用來(lái)測(cè)試,如下圖:
功能是:電話號(hào)碼和密碼有為空的情況就彈出一個(gè)警告框,并且回調(diào)一個(gè)bool值判斷是否登錄成功.
-
經(jīng)過(guò)編譯之后在Products文件下可以看到framework已經(jīng)生成了:
然后找到framework的生成文件,拖入到實(shí)現(xiàn)準(zhǔn)備好的測(cè)試demo項(xiàng)目.
- 在測(cè)試demo的ViewController.m文件中,我導(dǎo)入了測(cè)試的頭文件MenuSDK.h,調(diào)用了framework中的方法,然后運(yùn)行.
點(diǎn)擊登錄之后按道理應(yīng)該會(huì)有彈窗的出現(xiàn)提示為空的,這里卻并沒有顯示,這里是用sb拖入控件的方式.
那么問(wèn)題來(lái)了
- 問(wèn)題一:利用xib或者sb拖入的UITextField控件默認(rèn)值是
@""
,而不是nil
,所以我判斷的方式if(!text)
有問(wèn)題,于是加了不為@""
的情況,然后我在framework工程中更改代碼之后,重新編譯,然后又拖到demo工程中,運(yùn)行之后點(diǎn)擊,效果出現(xiàn)了.嗯,很開心. - 問(wèn)題二:在這個(gè)過(guò)程中,每次修改完framework代碼之后都需要重新編譯并且將包拖入到demo工程中,如此反復(fù)幾次之后,簡(jiǎn)直深惡痛絕,這樣搞會(huì)讓人崩潰的!
如果把framework工程和demo工程一起管理,編譯demo工程的時(shí)候framework工程就自動(dòng)更新好了
那該多好!
問(wèn)題二解決方式:
(1) 打開demo工程,File->New->Workspace,新建一個(gè)workspace,用來(lái)管理demo和framework.
(2) 這時(shí)候會(huì)出現(xiàn)一個(gè)空白的workspace界面,先不動(dòng)它.關(guān)掉demo和framework工程,將兩者根目錄下的xcodeproj拖入到剛剛新建的workspace工程中,如下圖:
(3)在demo的target中Embedded Binaries
和Linked Frameworkd and Libaries
都要添加MenuSDK.framework
(4) 這時(shí)運(yùn)行會(huì)報(bào)錯(cuò),找不到頭文件MenuSDK.h
,因?yàn)樵赿emo的build setting中沒有指定header search paths
,雙擊后面的空格,將MenuSDK.framework
的Headers
路徑拖入其中即可,因?yàn)樵趂ramework中頭文件都是在Headers
目錄下:
最后成功運(yùn)行!于是就完成了demo和framwork的統(tǒng)一管理,極大方便了SDK的開發(fā)和調(diào)試.
- 問(wèn)題三:本來(lái)以為將兩者統(tǒng)一到workspace中就基本沒啥問(wèn)題了,但是后來(lái)手賤搞了
一個(gè)分類
到framework中,然后呢,奇怪的一幕發(fā)生了,當(dāng)我將分類import到.m文件里時(shí),編譯沒問(wèn)題.后來(lái)想到improt到.h中更好,于是順利的按照提示import了,但這時(shí)候報(bào)錯(cuò)了,說(shuō)找不到分類文件......氣哭!好吧,還是import到.m中,這下總沒問(wèn)題了吧.運(yùn)行,報(bào)錯(cuò),定位到使用分類方法的位置,提示:Unrecognize selector......
.
這里有兩個(gè)點(diǎn):
1.為啥import到.h文件中找不到分類
2.導(dǎo)入.m文件中后方法未識(shí)別.
解決方式:
咨詢了一位搞SDK的老司機(jī)之后,他回復(fù)了一句話:-ObjC,專治分類
.恍然大悟,于是立馬去framework的buildSetting中設(shè)置other link flag
為-ObjC
,問(wèn)題解決,分類也可以使用了.心中一萬(wàn)只那啥跑過(guò)......猜測(cè)一下原因應(yīng)該是分類是屬于OC獨(dú)有的語(yǔ)法特性,所以需要指定-ObjC
,額,我能想到就只有這么多了.
- 問(wèn)題四:framework通常是搭配bundle來(lái)使用的,
并且蘋果不允許將bundle打進(jìn)framework包里
.那如何使用bundle管理資源文件(圖片,音頻等)呢?
創(chuàng)建bundle有兩種方式:
(1) xcode里面setting bundle
(2) 新建一個(gè)文件夾,放入資源文件,然后修改后綴為.bundle
這里我采用的是第二種方式.將bundle拖入到項(xiàng)目中.但是由于是將資源放入了bundle中,那么讀取文件的方式就不同了,以圖片為例:
就需要取到bundle的path來(lái)讀取了.
以上就是這兩天研究SDK開發(fā)遇到的一些實(shí)際問(wèn)題,路才剛剛開始,希望自己以后的SDK開發(fā)之路一(坎
)路(坷
)順(不
)利(斷
).
最后鳴謝羅老板給與的無(wú)私幫助!
9-4日更新:
當(dāng)我們需要在SDK中集成其他sdk的時(shí)候,例如我的sdk中接入微信支付的SDK,那么這個(gè)時(shí)候我們需要將wxpay.a以及header拖入到我們項(xiàng)目中,引入依賴庫(kù)即可.
但是,如果需要集成的是framework的話,親測(cè),直接拖入framework集成暫時(shí)不可行(不知道是我哪里搞錯(cuò)了沒),于是乎查閱了網(wǎng)上的資料,發(fā)現(xiàn)framework只是對(duì).a文件的一次封裝,我們只需要將framework中的二進(jìn)制文件:
添加一個(gè)后綴.a,同時(shí)將這個(gè)轉(zhuǎn)換的.a文件拖入Headers中,最后將這個(gè)Headers文件拖入你的SDK項(xiàng)目中,添加依賴文件即可引用.如下圖效果:
2018-3-27補(bǔ)充:framework中如何做到不直接依賴AFN等三方庫(kù)
1.首先我們新建一個(gè)Lib的framework,里面放入AFN等三方框架,建議是直接拖入代碼.如下圖:
此時(shí)我們需要去target里面配置Build phases,將AFN所有的頭文件全部設(shè)置為public(很重要):
2.我們?cè)俳⑽覀冏约旱膄ramework Task
,里面放入業(yè)務(wù)代碼.然后建立一個(gè)workspace
,workspace位置可以放在Task
工程目錄中,同時(shí)導(dǎo)入lib和Task:
并且Task中關(guān)聯(lián)lib.framwork:
接著在build setting里面設(shè)置framwork search path lib的framwork地址,header search path為lib framwork的headers地址.
最后在我們的業(yè)務(wù)里面可以直接導(dǎo)入三方的頭文件,使用即可: