使用CocoaPods開(kāi)發(fā)lib庫(kù)

cocoapods.png

一漏设、前言

上篇文章主要介紹了如何在App中使用CocoaPods引入第三方庫(kù),本篇文章將介紹怎樣使用CocoaPods進(jìn)行lib庫(kù)的開(kāi)發(fā)(lib庫(kù)指靜態(tài)庫(kù)或動(dòng)態(tài)庫(kù))。

二盟榴、CocoaPods lib 創(chuàng)建

如果還未進(jìn)行開(kāi)發(fā),需要利用CocoaPods從零開(kāi)始創(chuàng)建婴噩,那么恭喜你擎场,CocoaPods會(huì)為你搭建好整個(gè)開(kāi)發(fā)環(huán)境。利用pod lib create MyLibrary命令几莽,通過(guò)一些向?qū)Ш笱赴欤瑫?huì)自動(dòng)幫你生成lib工程及demo工程。

pod-lib-create.png

生成的工程目錄如下:

MyLibrary目錄結(jié)構(gòu).png

MyLibrary.xcworkspace中的結(jié)構(gòu)如下:

MyLibrary.xcworkspace工程目錄.png

通過(guò)一個(gè)小小的命令章蚣,我們的工程框架就搭好了站欺,可以在Pods工程里添加代碼和文件,來(lái)實(shí)現(xiàn)我們的功能纤垂,然后在MyLibrary工程里可以添加對(duì)lib庫(kù)的測(cè)試代碼矾策。

三、利用已有工程搭建CocoaPods lib工程

有時(shí)候峭沦,我們的lib庫(kù)已經(jīng)開(kāi)發(fā)很久了贾虽,也有相應(yīng)的demo,只不過(guò)想升級(jí)一下逼格或xxx的原因吼鱼,想通過(guò)CocoaPods來(lái)管理蓬豁,而不是傳統(tǒng)的.xcodeproj.xcworkspace绰咽。
這種情況下,我們可以直接模仿上面的工程目錄地粪,通過(guò)編寫(xiě)Podfilepodspec取募,就可以了。

四驶忌、podspec

  • podspec簡(jiǎn)介

podspecpod specification的縮寫(xiě)矛辕。通過(guò)上面的展示,已經(jīng)可以知道podspec是對(duì)lib庫(kù)的配置文件付魔,Podfile會(huì)根據(jù)該文件進(jìn)行文件的加載聊品,所以,podspec的編寫(xiě)也是非常重要的几苍。

  • podspec創(chuàng)建

podspec的創(chuàng)建跟Podfile一樣翻屈,可以自己手動(dòng)新建一個(gè)文件,然后后綴改為.podspec妻坝。也可以命令行執(zhí)行pod spec create MyLibrary伸眶。

  • podspec編寫(xiě)

Podfile一樣,podspec也有一套自己的語(yǔ)法(官網(wǎng)介紹)刽宪。

#一個(gè)podspec文件包含一個(gè)Spec和若干個(gè)subspec厘贼,podfile可以引入整個(gè)podspec或subspec
Pod::Spec.new do |s|

  #Pod的名稱(chēng),必填圣拄,如Podfile中pod 'AFNetworking'嘴秸,AFNetworking就是name
  s.name         = "MyLibrary"      s.version      = "0.0.1"  #版本,必填

  #簡(jiǎn)介庇谆,必填
  s.summary      = "A short description of library."  

  #詳細(xì)的描述岳掐,支持多行字符串,必填
  s.description  = <<-DESC
                Add long description of the pod here.
                   DESC  

  #主頁(yè)饭耳,必填
  s.homepage     = "http://EXAMPLE/MyLibrary"  

  #遵守的開(kāi)源協(xié)議串述,必填。注意GPL可能給公司帶來(lái)很大風(fēng)險(xiǎn)寞肖,不要輕易使用
  s.license      = "MIT"  

  #pod庫(kù)作者纲酗,必填
  s.author             = { "wangbingwf" => "wangbingwf@163.com" }  

  #平臺(tái)版本信息,這里表示支持iOS新蟆,7.0及以上系統(tǒng)
  s.platform     = :ios, "7.0"    

  #當(dāng)支持多平臺(tái)時(shí)耕姊,使用deployment_target替代platform
  #s.osx.deployment_target = '8.0'  

  #代碼路徑,這里雖然填寫(xiě)的是git倉(cāng)庫(kù)的路徑栅葡,但Podfile中使用path方式引入podspec時(shí)茉兰,并不會(huì)再?gòu)膅it上下載代碼,而是使用本地的代碼欣簇,所以就可以在這種方式下開(kāi)發(fā)lib庫(kù)规脸。
  #這里支持git坯约,svn,http等莫鸭。并且可以設(shè)置tag或version等信息
  s.source       = { :git => "https://git.coding.net/yourgit/MyLibrary.git", :tag => s.version.to_s} 

  # ———— Subspecs ————————————————————————————————————#
  # ———— MyLibraryCFiles ———————————————————————————————#
  #創(chuàng)建一個(gè)subspec
   s.subspec 'MyLibraryCFiles' do |subcfiles|

    #subspec包含的代碼文件闹丐,上面source是路徑,這里source_files是具體要包含哪些文件
    #其中**表示包含子目錄被因,*表示當(dāng)前目錄下的所有文件
    #下面表示當(dāng)前subspec包含MyLibrary/cfiles目錄及其子目錄中的所有.h和.c文件卿拴;以及MyLibrary/log目錄下的所有.h和.c文件
    subcfiles.source_files = ["MyLibrary/cfiles/**/*.{h,c}",
                              "MyLibrary/log/*.{h,c}"]

    #不包含的文件
    subcfiles.exclude_files = ["MyLibrary/jni/**/*",
                            "MyLibrary/profile/unit_test/*"]

    #加入到pod庫(kù)中,被一起編譯
    #這里通常使用私有第三方庫(kù)時(shí)梨与,需要依賴(lài)某個(gè)lib或framework時(shí)使用堕花。
    #添加如下選項(xiàng)后,會(huì)將.a添加到工程中粥鞋,并且添加LIBRARY_SEARCH_PATHS路徑
    #但是需要注意的是缘挽,如果使用pod package對(duì)該pod庫(kù)進(jìn)行打包,這個(gè).a并不會(huì)打進(jìn)去呻粹。
    #比如說(shuō)使用pod package對(duì)MyLibrary打包成MyLibrary.a壕曼,inner.a并不會(huì)被編譯進(jìn)MyLibrary.a。
    #此時(shí)等浊,如果如果對(duì)外提供MyLibrary.a腮郊,inner.a也同樣需要提供出去
    subcfiles.vendored_libraries = "MyLibrary/lib/ios/inner.a"

    #pod工程的配置
    #對(duì)于HEADER_SEARCH_PATHS,對(duì)將設(shè)置的字符串直接拷貝到xcode中筹燕,不會(huì)像上面source_files這樣使用相對(duì)路徑轧飞。
    #所以,我在這里先獲取當(dāng)前路徑庄萎,再設(shè)置進(jìn)去踪少。最后加**表示recursive塘安,即循環(huán)查找子目錄的意思
    $dir = File.dirname(__FILE__)
    $dir = $dir + "/MyLibrary/cfiles/**"  #$dir:/Users/wangbing/TempCode/MyLibrary/cfiles/**
    subcfiles.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => $dir}

    #demo工程的配置糠涛,上面是對(duì)pod工程的設(shè)置,當(dāng)需要對(duì)demo工程設(shè)置時(shí)兼犯,使用user_target_xcconfig忍捡,這里就不做介紹了

    #相對(duì)于public_headers,這些文件不會(huì)被公開(kāi)給Demo
    subcfiles.private_header_files = "MyLibrary/cfiles/**/*.h"
    #保護(hù)目錄結(jié)構(gòu)不變切黔,如果不設(shè)置砸脊,所有頭文件都將被放到同一個(gè)目錄下
    subcfiles.header_mappings_dir = "MyLibrary/cfiles/**"
    end

# ———— MyLibraryMain ———————————————————————————————#
  #創(chuàng)建一個(gè)subspec
  s.subspec 'MyLibraryMain' do |submain|

    #引入代碼文件
    submain.source_files = "MyLibrary/main/**/*.{h,m}"

    #設(shè)置公開(kāi)頭文件
    submain.public_header_files = "MyLibrary/main/public.h"

    #設(shè)置資源文件
    submain.resource  = "MyLibrary/resources/configFiles.bundle"

    #設(shè)置MyLibraryMain模塊依賴(lài)的系統(tǒng)庫(kù),注意纬霞,這里加的是系統(tǒng)庫(kù)
    submain.frameworks = "SystemConfiguration"

    #設(shè)置依賴(lài)凌埂,這里可以依賴(lài)當(dāng)前spec中的subspec,也可以依賴(lài)github上公開(kāi)的開(kāi)源庫(kù)诗芜,如'AFNetworking'瞳抓。
    submain.dependency "MyLibrary/MyLibraryCFiles"
    end
end
  • podspec坑

  • 坑——HEADER_SEARCH_PATHS
    在我實(shí)際項(xiàng)目使用過(guò)程中埃疫,C文件的存在給我編寫(xiě)spec帶來(lái)了很大問(wèn)題。
    故事是這樣的孩哑,我們項(xiàng)目中要引用另一個(gè)團(tuán)隊(duì)編寫(xiě)的.a庫(kù)栓霜,暫且稱(chēng)為inner.a。這個(gè)庫(kù)是C寫(xiě)的横蜒,同時(shí)胳蛮,頭文件中存在多層嵌套。
    這要求在使用該靜態(tài)庫(kù)時(shí)丛晌,要在HEADER_SEARCH_PATHS中添加頭文件的路徑仅炊。
    于是我一開(kāi)始在podspec中是這么寫(xiě)的
subcfiles.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" =>"MyLibrary/cfiles/**"}

于是,編譯出錯(cuò)了茵乱,找不到頭文件茂洒,因?yàn)檫@個(gè)設(shè)置在xcode中是這樣的:

HEADER_SEARCH_PATHS

Shit!為什么不像上面似的,給加相對(duì)路徑呢瓶竭,畢竟是路徑的設(shè)置嘛督勺。但是也可以解決的,解決方案有三:

  1. 如果知道Demo工程和lib庫(kù)之間的路徑關(guān)系斤贰,可以通過(guò)${PODS_ROOT}/../../MyLibrary/cfiles/**來(lái)解決智哀。
  2. 通過(guò)設(shè)置絕對(duì)路徑來(lái)解決:
    podspec中使用ruby腳本,獲取當(dāng)前路徑荧恍,而podspeclib庫(kù)的位置一般不會(huì)變瓷叫,所以最終使用了這種方式來(lái)設(shè)置HEADER_SEARCH_PATHS
$dir = File.dirname(__FILE__)
$dir = $dir + "/MyLibrary/cfiles/**"  #$dir:/Users/wangbing/TempCode/MyLibrary/cfiles/**
subcfiles.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => $dir}
  1. 利用CocoaPods總會(huì)添加的兩個(gè)默認(rèn)路徑送巡,設(shè)置header_mappings_dir保護(hù)目錄結(jié)構(gòu)不發(fā)生變化摹菠。
#設(shè)置cfiles及子目錄結(jié)構(gòu)保持不變
subcfiles.header_mappings_dir = "MyLibrary/cfiles/**"

#將這些文件設(shè)置為private_file或public_file
subcfiles.private_header_files = "MyLibrary/cfiles/**/*.h"

#因?yàn)槲业腃頭文件有嵌套,需要查找子目錄骗爆,所以需要將non-recursive改為recursive
subcfiles.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "${PODS_ROOT}/Headers/Private/**"}

通過(guò)方法3同樣使用了${PODS_ROOT}次氨,與方法1有什么區(qū)別呢?區(qū)別就是摘投,如果按照方法3煮寡,可以忽略Demo工程與lib庫(kù)的路徑關(guān)系。因?yàn)樵趫?zhí)行pod install后犀呼,系統(tǒng)會(huì)在Pods工程目錄下生成PrivatePublic目錄幸撕,就不用考慮原來(lái)cfiles的路徑了,如下圖外臂。

cfiles目錄

五坐儿、CocoaPods打包靜態(tài)庫(kù)

如果你開(kāi)發(fā)的SDK并不想開(kāi)源,那么在通過(guò)CocoaPods管理并開(kāi)發(fā)之后,還可以通過(guò)CocoaPods進(jìn)行打包貌矿。生成framework.a累铅。打包命令是pod package

pod package

像上面的例子中站叼,我的打包命令為:pod package MyLibrary.podspec --force --no-mangle --embedded --subspecs= MyLibraryMain娃兽。然后將生成的framework和inner.a共同交給使用者使用即可。

這里需要注意

  1. 打包命令會(huì)根據(jù)podspec文件下載代碼到一個(gè)臨時(shí)文件中進(jìn)行打包尽楔,并不是使用的本地文件铃彰,所以記得要提交并打tag膘魄。
  2. 上面的HEADER_SEARCH_PATHS問(wèn)題瑞妇,使用方法1和方法2同樣會(huì)導(dǎo)致pod package失敗始腾。因?yàn)槟悴恢?code>cfiles的路徑,無(wú)法添加到HEADER_SEARCH_PATHS呕寝。但卻可以使用方法3!
  3. podspec文件中使用vendor標(biāo)識(shí)的frameworklibraries勋眯,并不會(huì)真正編譯到最終的framework中。這真的很讓我受傷下梢,我查了好久客蹋。。孽江。好久讶坯。。岗屏。好久辆琅。。这刷。也正因?yàn)檫@個(gè)問(wèn)題婉烟,我決定放棄pod package方式。準(zhǔn)備嘗試自己寫(xiě)個(gè)腳本進(jìn)行打包暇屋,還在準(zhǔn)備中似袁。。率碾。

六叔营、總結(jié)

研究CocoaPods的初衷是為了組件化開(kāi)發(fā)屋彪,目前算是有了一點(diǎn)初步的認(rèn)識(shí)所宰。
我們把不同的功能模塊放在不同的文件夾中,通過(guò)podspec進(jìn)行配置畜挥,通過(guò)podfile進(jìn)行引用仔粥,通過(guò)pod package進(jìn)行打包。一切是很方便的。
不過(guò)在我的實(shí)際應(yīng)用中躯泰,目前在打包和public_headers方面還有一些問(wèn)題谭羔,I'm working on it!

最后,大家有疑惑的可以留言麦向,寫(xiě)的有問(wèn)題的歡迎糾正瘟裸!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市诵竭,隨后出現(xiàn)的幾起案子话告,更是在濱河造成了極大的恐慌,老刑警劉巖卵慰,帶你破解...
    沈念sama閱讀 216,470評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件沙郭,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡裳朋,警方通過(guò)查閱死者的電腦和手機(jī)病线,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)鲤嫡,“玉大人送挑,你說(shuō)我怎么就攤上這事∨郏” “怎么了让虐?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,577評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)罢荡。 經(jīng)常有香客問(wèn)我赡突,道長(zhǎng),這世上最難降的妖魔是什么区赵? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,176評(píng)論 1 292
  • 正文 為了忘掉前任惭缰,我火速辦了婚禮,結(jié)果婚禮上笼才,老公的妹妹穿的比我還像新娘漱受。我一直安慰自己,他們只是感情好骡送,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布昂羡。 她就那樣靜靜地躺著,像睡著了一般摔踱。 火紅的嫁衣襯著肌膚如雪虐先。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,155評(píng)論 1 299
  • 那天派敷,我揣著相機(jī)與錄音蛹批,去河邊找鬼撰洗。 笑死,一個(gè)胖子當(dāng)著我的面吹牛腐芍,可吹牛的內(nèi)容都是我干的差导。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼猪勇,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼设褐!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起泣刹,我...
    開(kāi)封第一講書(shū)人閱讀 38,903評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤络断,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后项玛,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體貌笨,經(jīng)...
    沈念sama閱讀 45,319評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評(píng)論 2 332
  • 正文 我和宋清朗相戀三年襟沮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了锥惋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,703評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡开伏,死狀恐怖膀跌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情固灵,我是刑警寧澤捅伤,帶...
    沈念sama閱讀 35,417評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站巫玻,受9級(jí)特大地震影響丛忆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜仍秤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評(píng)論 3 325
  • 文/蒙蒙 一熄诡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧诗力,春花似錦凰浮、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,664評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至瓣窄,卻和暖如春笛厦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背康栈。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,818評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工递递, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人啥么。 一個(gè)月前我還...
    沈念sama閱讀 47,711評(píng)論 2 368
  • 正文 我出身青樓登舞,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親悬荣。 傳聞我的和親對(duì)象是個(gè)殘疾皇子菠秒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評(píng)論 2 353

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