iOS組件化-資源管理

在組件化前期的工作中顷级,我們會面臨如何管理圖片柜裸、音視頻等資源的問題。我們需要關(guān)注的問題是如何將相應(yīng)的資源和組件一起打包本鸣,并保證能夠在組件內(nèi)和組件間的正常使用。以下內(nèi)容均針對于使用CocoaPods方式組件化對資源文件管理的討論硅蹦。

文件管理方式:

1. 集中式管理

將所有的資源文件做成一個組件荣德,其它相應(yīng)的組件依賴該資源組件,通過組件暴露的相關(guān)接口獲取對應(yīng)的資源童芹。

2. 分散式管理

將資源文件進(jìn)行清晰分類涮瞻,對應(yīng)的資源文件嵌入至對應(yīng)的組件中,如有共用文件假褪,抽取公共資源組件將公共資源放入該組件中署咽,或者將公共資源直接放至主工程中。

集中式管理與分散式管理優(yōu)缺點(diǎn)對比:
總結(jié)建議:

集中式管理可方便維護(hù)生音,可對項(xiàng)目文件進(jìn)行統(tǒng)一管理艇抠,此外還可降低文件冗余的概率,可用于較大久锥、耦合嚴(yán)重的項(xiàng)目家淤。倘若是新項(xiàng)目或者組件對主工程依賴性不強(qiáng)的組件,可采用分散式管理瑟由,將組件的相關(guān)資源與組件綁定絮重。

resources和resource_bundles

resouresresource_bundlesCocoaPods兩種資源文件引用的方式。

1. resource/resources

resourceresources兩個屬性功能相同歹苦,不同的是resources可以批量指定文件資源青伤,resource只能指定單個文件資源。

1.1 語法
spec.resource = 'Resources/HockeySDK.bundle'
spec.resources = ['Images/*.png', 'Sounds/*']
1.2 官方描述 Podspec語法官方介紹

resources將指定的資源復(fù)制到目標(biāo)bundle殴瘦,我們強(qiáng)烈建議開發(fā)者使用 resource bundles去構(gòu)建靜態(tài)資源庫狠角。使用resources屬性僅僅是將指定的文件資源復(fù)制到目標(biāo)bundle,如此Xcode不會對相關(guān)資源進(jìn)行優(yōu)化操作蚪腋。

看完官方描述丰歌,我們第一直覺就會放棄使用這種方式了。雖然如此屉凯,但是我們還是去看看如果使用這種方式具體會產(chǎn)生哪些影響立帖。

1.3 resource探究

使用pod lib create SCResource_Resources命令創(chuàng)建項(xiàng)目。打開Example中的項(xiàng)目悠砚,并刪除SCResource_Resources.podspec中無用的代碼晓勇。如下圖所示。

1.3.1 resource不嵌入xcassets文件

選中ReplaceMe.m文件,右鍵Show in Finder,調(diào)至上一級文件夾绑咱,看到ClassesAssets文件夾绰筛。我們把ReplaceMe.m刪除,并刪除SCResource_Resources.podspec中的s.source_files,因?yàn)槲覀冊谫Y源組件中暫時不用編輯代碼描融。然后把事先準(zhǔn)備好的圖片資源放入Assets文件夾下,并設(shè)置resource屬性别智。最終如下圖所示。

終端pod install后稼稿,便可以看到圖片資源已經(jīng)被加到Resources文件夾下薄榛。

查看資源文件在包中的位置

真機(jī)運(yùn)行,選擇Products文件夾下的SCResource_Resources_Example.app右鍵Show in Finder,選中SCResource_Resources_Example右鍵让歼,選擇顯示包內(nèi)容敞恋,就可以看到我們添加的Images文件夾。查看并記錄文件夾的大小谋右。發(fā)現(xiàn)和事先我們準(zhǔn)備的文件夾大小相同,均為21.5M硬猫。

資源文件獲取

一般情況下,我們在項(xiàng)目中獲取圖片都是通過使用imageNamed:方法去獲取改执。那么現(xiàn)在我們把圖片資源放在組件中啸蜜,通過這樣的方式也能夠獲取嗎?
我們在Example項(xiàng)目中的SCViewController.mviewDidLoad方法中鍵入如下代碼:


前面我們查看過Images最終在APP中的路徑辈挂,并且容易找到goodluck_smile圖片的路徑是Images/好運(yùn)墻/goodluck_smile衬横。運(yùn)行項(xiàng)目,發(fā)現(xiàn)我們拿到的image對象是nil终蒂。

很糟糕蜂林,我們沒有獲取到對應(yīng)的圖片。查看注釋可以知道imageNamed:是從main bundle中獲取文件資源拇泣,那么如果我們把圖片放在主工程中的Images.xcassets文件中噪叙,這里的文件在最終的包中的路徑是什么呢?帶著這樣的疑問霉翔,我們簡單地把一張圖片(goodluck_smile)放入Images.xcassets中睁蕾,真機(jī)運(yùn)行后,通過上述查看資源文件在包中的位置的操作方法進(jìn)行查看债朵。

可以看到多出了Assets.car文件子眶,由此可以知道,Images.xcassets中的圖片資源葱弟,最終會被打包成Assets.car文件壹店,也從側(cè)面可以說明Assets.car文件所在的目錄就是main bundle的路徑,那么為什么組件中的圖片沒有被正常獲取呢芝加?難道是因?yàn)槲覀兟窂絾栴}?
前面我們已經(jīng)說過goodluck_smile圖片是在Images/好運(yùn)墻/ 下,那么我么手動拼接試試藏杖。為了排除其它影響将塑,我們刪除掉前面在Images.xcassets中的圖片文件,并運(yùn)行蝌麸。

這時候点寥,我們正確獲取到了我們想要的圖片。現(xiàn)在我們可以通過代碼來獲取到組件中的圖片了来吩,需要注意的點(diǎn)是需要傳入圖片的相對路徑敢辩,那么在xib中又如何呢?
我們再Main.storyboard中添加一個UIImageView,并直接設(shè)置goodluck_smile圖片,瞬間就心情大好弟疆,因?yàn)榱ⅠR就看到Main.storyboard顯示了對應(yīng)的圖片戚长。

真機(jī)運(yùn)行,看看會不會有什么問題怠苔。
運(yùn)行后發(fā)現(xiàn)同廉,我們設(shè)置的圖片沒有正常顯示,那么也是因?yàn)槲覀円顚懴鄬β窂降脑騿岣趟荆课覀內(nèi)ピ囋嚒?/p>

這時候迫肖,發(fā)現(xiàn)Main.storyboard沒有正常顯示圖片,但是真機(jī)運(yùn)行后攒驰,圖片顯示正常蟆湖。

總結(jié):

使用resource/resources直接存放文件資源時,無論是通過代碼獲取圖片玻粪,還是在xib中設(shè)置圖片帐姻,都需要填寫完整的相對路徑。當(dāng)然如果你想直接通過設(shè)置圖片名稱的方式獲取圖片奶段,那么你必須將圖片直接暴露在resources文件下饥瓷,不能新建文件對相關(guān)資源做整理。

1.3.2 resource嵌入xcassets文件

在沒有組件化時痹籍,我們一般把圖片資源都放在Images.xcassets文件內(nèi)管理呢铆,其為我們提供了許多優(yōu)化點(diǎn)和一些方便的功能,所以我們可能也希望在組件中也利用這些優(yōu)化和功能蹲缠。那么在resource中如何通過xcassets來管理圖片呢棺克?其實(shí)很簡單,只需在組件的Assets文件夾下創(chuàng)建Asset Catalog文件线定,再將圖片資源拖入即可娜谊。

這里需要注意的是:在創(chuàng)建Asset Catalog文件后,其目錄可能不在組件的Assets文件下斤讥,需要手動將其拖入至文件下纱皆。

pod install后,對項(xiàng)目進(jìn)行編譯,如果出現(xiàn)如下錯誤派草,則選擇File -> Workspace Settings -> Build SystemNew Build System(Default)改為Legacy Build System即可搀缠。

使用上文提到的查看資源文件在包中的位置的方式查看文件資源,前面我們也提及到近迁,xcassets文件最后打包進(jìn)APP是會轉(zhuǎn)成Assets.car文件的艺普,我們找到該文件,并查看該文件的大小鉴竭。

文件大小變成了69.1M歧譬,是原先21.5M的好幾倍,這會大大增大包的大小搏存。

資源文件獲取

在查看資源文件路徑后瑰步,我們發(fā)現(xiàn),其路徑和在主工程中的Images.xcassets在包中的路徑相同祭埂,那么可以推測面氓,正常使用相關(guān)方法應(yīng)該可以獲取到資源文件。

同樣在ViewDidLoad方法中鍵入一下代碼蛆橡,看能否正確獲取圖片資源舌界。斷點(diǎn)運(yùn)行后,發(fā)現(xiàn)可正常獲取泰演。

使用xib方式也一樣呻拌,這里就不再截圖,大家可以自己嘗試睦焕。

總結(jié):

resource嵌入xcassets文件時藐握,資源文件會被copymain bundle中,可以正常獲取資源文件垃喊,但是會造成APP大小變大猾普,因此不建議使用。

2. resource_bundle/resource_bundles

resource/resources類似本谜,resource_bundle/resource_bundles功能相同初家,區(qū)別在與指定一個和多個。

2.1 語法
spec.ios.resource_bundle = { 'MapBox' => 'MapView/Map/Resources/*.png' }
spec.resource_bundles = {
    'MapBox' => ['MapView/Map/Resources/*.png'],
    'MapBoxOtherResources' => ['MapView/Map/OtherResources/*.png']
}
2.2 官方描述 Podspec語法官方介紹

重點(diǎn)翻譯:強(qiáng)烈建議使用該方式為Pod構(gòu)建靜態(tài)庫,文件資源通過鍵值匹配資源乌助,bundle的名稱應(yīng)該包含Pod的名稱來降低名稱沖突的可能性溜在。

2.3 resource_bundle探究

下面同樣通過是否嵌入xcassets文件來分析這兩種情況的優(yōu)劣。

2.3.1 resource_bundle不嵌入xcassets文件

不嵌入xcassets文件時他托,和resource一樣掖肋,直接將文件資源拖入至Assets文件夾下,具體參考上文resource不嵌入xcasset文件中的內(nèi)容赏参。然后修改podspec文件制定文件資源的方式志笼,如下圖所示沿盅。

pod install,真機(jī)運(yùn)行籽腕,查看資源文件在包中的位置,可以看到一個SCResource_Resources.bundle的文件嗡呼。查看該文件的大小為21.1M纸俭,比原文件略小皇耗。

再選擇SCResource_Resources.bundle右鍵顯示包內(nèi)容,可看到我們放進(jìn)去的Images圖片文件夾揍很。

資源文件獲取

前面在resource的章節(jié)中郎楼,我們已經(jīng)知道需要通過拼接資源的相對路徑才能獲取相應(yīng)的資源,所以我們這里也嘗試看看會發(fā)生什么窒悔。

ViewDidLoad方法中鍵入下面代碼:

UIImage *image = [UIImage imageNamed:@"SCResource_Resources.bundle/Images/好運(yùn)墻/goodluck_smile"];

斷點(diǎn)查看是否能正常獲取圖片資源呜袁。

xib中同樣這樣拼接,真機(jī)運(yùn)行简珠,看能否正常顯示圖片阶界。

運(yùn)行后,我們可以如預(yù)期一樣獲取資源文件聋庵。

總結(jié):

resource_bundle不嵌入xcasset文件膘融,需拼接文件的相對路徑才能正確獲取圖片資源。

2.3.2 resource_bundle嵌入xcassets文件

嵌入xcassets文件時祭玉,也和resource一樣氧映,創(chuàng)建xcassets文件,拖入文件資源脱货,并拖入至Assets文件夾下岛都,具體參考上文resource嵌入xcasset文件中的內(nèi)容。

pod install并真機(jī)運(yùn)行,查看資源文件在包中的位置,我們同樣可以看到SCResource_Resources.bundle文件振峻,查看文件大小臼疫,可以看到只有16.8M,比前面所有情況都要小扣孟。

再選擇SCResource_Resources.bundle右鍵顯示包內(nèi)容烫堤,可看到我們放進(jìn)去的Assets.car文件。與前文的情況一致哈打。

資源文件獲取

resource的章節(jié)中塔逃,如果嵌套xcassets文件,我們可以直接通過圖片名稱來獲取文件資源料仗,那么這里是不是類似呢湾盗,我們來試試。

viewDidLoad方法中鍵入下面代碼:

UIImage *image = [UIImage imageNamed:@"goodluck_smile"];

運(yùn)行立轧,查看image對象是否存在格粪。

很遺憾躏吊,結(jié)果為nil。那么我們拼接路徑呢帐萎?同樣在viewDidLoad方法中鍵入下面代碼:

UIImage *image = [UIImage imageNamed:@"SCResource_Resources.bundle/goodluck_smile"];

運(yùn)行比伏,查看image對象是否存在。

同樣的結(jié)果疆导,還是nil赁项。

使用這種方式,我們需要換一個方法去獲取指定資源澈段,我們需要調(diào)用UIImageimageNamed:inBundle: compatibleWithTraitCollection:方法悠菜。指定bundle和圖片的名稱即可。

NSString *bundleName = @"SCResource_Resources";
NSString *imageBundlePath = [[NSBundle mainBundle] pathForResource:bundleName ofType:@"bundle"];
NSBundle *imageBundle = [NSBundle bundleWithPath:imageBundlePath];

UIImage *image = [UIImage imageNamed:@"goodluck_smile" inBundle:imageBundle compatibleWithTraitCollection:nil];

運(yùn)行败富,查看image對象是否存在

運(yùn)行結(jié)果如預(yù)期悔醋,可獲取對應(yīng)文件資源。

xib中如何設(shè)置呢?可以添加分類暴露bundleNameimageName使用IBInspectable修飾兽叮,調(diào)用imageNamed:inBundle: compatibleWithTraitCollection:方法芬骄。

總結(jié):

resource_bundle嵌入xcasset文件,包文件大小相對于其它情況較小鹦聪,但獲取文件資源時账阻,需要封裝方法調(diào)用UIImageimageNamed:inBundle: compatibleWithTraitCollection:方法。

總結(jié)

使用CocoaPods方式組件化椎麦,對文件資源進(jìn)行管理宰僧,建議使用resource_bundle/resource_bundles嵌入xcassets文件的方式。這樣一來可以使用xcassets的一些特性和優(yōu)化观挎,也能夠在一定程度上減小包的體積琴儿。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市嘁捷,隨后出現(xiàn)的幾起案子造成,更是在濱河造成了極大的恐慌,老刑警劉巖雄嚣,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晒屎,死亡現(xiàn)場離奇詭異,居然都是意外死亡缓升,警方通過查閱死者的電腦和手機(jī)鼓鲁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來港谊,“玉大人骇吭,你說我怎么就攤上這事∑缢拢” “怎么了燥狰?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵棘脐,是天一觀的道長。 經(jīng)常有香客問我龙致,道長蛀缝,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任目代,我火速辦了婚禮屈梁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘像啼。我一直安慰自己俘闯,他們只是感情好潭苞,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布忽冻。 她就那樣靜靜地躺著,像睡著了一般此疹。 火紅的嫁衣襯著肌膚如雪僧诚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天蝗碎,我揣著相機(jī)與錄音湖笨,去河邊找鬼。 笑死蹦骑,一個胖子當(dāng)著我的面吹牛慈省,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播眠菇,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼边败,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了捎废?” 一聲冷哼從身側(cè)響起笑窜,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎登疗,沒想到半個月后排截,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡辐益,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年断傲,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片智政。...
    茶點(diǎn)故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡认罩,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出女仰,到底是詐尸還是另有隱情猜年,我是刑警寧澤抡锈,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布,位于F島的核電站乔外,受9級特大地震影響床三,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜杨幼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一撇簿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧差购,春花似錦四瘫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽外里。三九已至糟趾,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間址芯,已是汗流浹背彰居。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工诚纸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人陈惰。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓畦徘,卻偏偏與公主長得像,于是被迫代替她去往敵國和親抬闯。 傳聞我的和親對象是個殘疾皇子井辆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評論 2 351

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