前言
前幾篇博客描述了手動(dòng)創(chuàng)建組件的方法蹦漠,到新公司發(fā)現(xiàn)這種方式不適合小公司快捷方便的需求檩咱,所以轉(zhuǎn)而向cocoapods
為我們提供的pod lib
命令來(lái)創(chuàng)建組件辛润,這樣對(duì)于沒(méi)接觸過(guò)組件化的新人比較友好,另外也確實(shí)少了很多自己需要配置的各種東西解幼。
準(zhǔn)備
- 組件創(chuàng)建需要
cocoapods
- 如果想上傳到倉(cāng)庫(kù)還需要有
git
- 如果環(huán)境都沒(méi)搭建可以看下之前本序列的文章都有介紹
創(chuàng)建
1放仗、創(chuàng)建組件命令污桦,你可以CD
到特定文件夾下執(zhí)行命令,創(chuàng)建名為名為Demo的組件為例
# 開(kāi)始執(zhí)行以下命令后會(huì)去github克隆模板代碼沒(méi)翻墻可能會(huì)比較慢
pod lib create Demo
#創(chuàng)建過(guò)程中的選項(xiàng)可參考下面,有特殊也可以自己決定
What platform do you want to use?? [ iOS / macOS ] 平臺(tái)我們選擇iOS
> iOS
What language do you want to use?? [ Swift / ObjC ] 語(yǔ)言我選擇oc
> ObjC
Would you like to include a demo application with your library? [ Yes / No ] 是否創(chuàng)建demo工程
> Yes
Which testing frameworks will you use? [ Specta / Kiwi / None ] 是否添加測(cè)試支持
> None
Would you like to do view based testing? [ Yes / No ] 是否添加測(cè)試的view
> No
What is your class prefix? 類(lèi)名使用的前綴
> GG
當(dāng)前命令執(zhí)行完之后匙监,它會(huì)幫我們執(zhí)行pod install
命令并自動(dòng)打開(kāi)里面的Example
工程凡橱,我們先看下創(chuàng)建后文件夾目錄:
- Demo文件夾是我們實(shí)際的組件目錄,后面創(chuàng)建的圖片及文件和源代碼都在這里
- Demo文件夾下有兩個(gè)文件夾亭姥,一個(gè)
Classes
是存放代碼的地方在xcode創(chuàng)建的時(shí)候記得把代碼的目錄選擇放這里稼钩,一個(gè)是Assets
存放不限于圖片的其他資源文件一般我們放圖片可以創(chuàng)建一個(gè)系統(tǒng)的.xcassets
圖片管理器很方便存取 - Demo.podspec是組件的描述,不懂可以看下之前的基本概念都是一樣的
- Example 是我們調(diào)試使用的工程达罗,跟我們平時(shí)使用的項(xiàng)目差不多坝撑,只是它在
Example/Podfile
中幫我們加入了當(dāng)前組件的本地依賴(lài)方便我們調(diào)試
pod 'Demo', :path => '../'
- .git是git相關(guān)的你可以刪掉它后續(xù)自己創(chuàng)建
- .travis.yml是有關(guān)自動(dòng)化相關(guān)的也可以先忽略或者直接刪除
在xcode中的工程目錄:
- 紅色部分是調(diào)試工程的目錄先不管他
- 綠色部分就是我們?cè)谡{(diào)試的時(shí)候組件代碼具體呈現(xiàn)的地方静秆,
Demo
就是我們組件的名稱(chēng)有多個(gè)的話就是多個(gè)這樣的文件夾,Demo/Pod
中的放的是組件的描述和README.md文件和實(shí)際的目錄是同步的
2巡李、創(chuàng)建好之后最好到項(xiàng)目根目錄下打開(kāi).gitgnore
忽略文件中添加下列兩行抚笔,忽略我們?cè)跍y(cè)試的工程添加的依賴(lài)也上傳到git上
Example/Pods
Example/Podfile.lock
3、如果有自己的私有庫(kù)侨拦,在Example/Podfile
中替換以下添加私有源殊橙,沒(méi)有的可以忽略這步
source 'git@xxxx/Specs.git'
4、上傳到倉(cāng)庫(kù)狱从,刪掉項(xiàng)目根目錄下的git
文件夾膨蛮,使用以下命令將文件提交至git,嫌麻煩也可以直接使用Sourcetree
來(lái)上傳
#當(dāng)組件的根目錄下
cd Demo
git init
#關(guān)聯(lián)內(nèi)網(wǎng)git倉(cāng)庫(kù)
git remote add origin git@xxxt/Demo.git
#提交源碼
git add .
git commit -m "Initial commit"
git push -u origin master
5季研、創(chuàng)建源代碼文件應(yīng)注意選擇路徑敞葛,還有對(duì)應(yīng)的target選擇
6、圖片的讀取問(wèn)題
- 我們可以在xcode中選擇
Asset Catalog
來(lái)創(chuàng)建一個(gè)自己的圖片管理器与涡,名字最好用組件名稱(chēng)來(lái)命令好區(qū)分惹谐,一般存放在組件的Assets
目錄下
- 存放圖片的時(shí)候和我們一般項(xiàng)目中存儲(chǔ)的沒(méi)什么區(qū)別
- 如果需要發(fā)布組件需要在
podsepc
中添加以下描述,以我的示例工程為例
s.resource_bundles = {
'Demo' => ['Demo/Assets/Demo.xcassets']
}
- 代碼獲取圖片我寫(xiě)了個(gè)工具類(lèi)驼卖,就是獲取
bundle
之后再獲取里面的圖片,使用方法也在里面了氨肌,使用這種方法Podfile
需要去掉里面默認(rèn)添加的use_frameworks!
,后續(xù)swift再作兼容
//
// ResourceManager.h
// AssetsKit
//
// Created by GuoMS on 2019/2/18.
//
#import <Foundation/Foundation.h>
/* 使用方法款慨,新建一個(gè)文件,頭文件寫(xiě)入以下宏定義
#import "ResourceManager.h"
//自定義特定的名稱(chēng)
#undef XXXBundle
#define XXXBundle [ResourceManager resourceBundleForClass:[self class] podName:@"組件名稱(chēng)"]
#undef BXXXImage
#define BXXXImage(name) [ResourceManager imageName:name inBundle:XXXBundle]
*/
@interface BQSResourceManager : NSObject
/**
獲取組件的bundle并緩存
@param aClass 當(dāng)前調(diào)用的類(lèi)谬莹,用于定位bundle位置
@param name 組件的名字
@return bundle
*/
+ (NSBundle *)resourceBundleForClass:(Class)aClass
podName:(NSString *)name;
/**
制定bundle獲取圖片
@param name 圖片名字
@param bundle bundle實(shí)例
@return 圖片檩奠、為空返回nil
*/
+ (UIImage *)imageName:(NSString *)name
inBundle:(NSBundle *)bundle;
@end
//
// ResourceManager.m
// AssetsKit
//
// Created by GuoMS on 2019/2/18.
//
#import "ResourceManager.h"
@interface BQSResourceManager()
@property (strong, nonatomic) NSMutableDictionary *bundleDic;
@end
@implementation ResourceManager
+ (instancetype)sharedInstance {
static BQSResourceManager *manager;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manager = [[self alloc]init];
manager.bundleDic = [NSMutableDictionary dictionary];
});
return manager;
}
+ (NSBundle *)resourceBundleForClass:(Class)aClass podName:(NSString *)name {
NSAssert(aClass, @"class 不能為空");
NSAssert(name.length > 0, @"組件名稱(chēng)不能為空");
if (name.length <= 0 || !aClass) {
return nil;
}
//獲取bundle
NSBundle *cacheBundle = [[BQSResourceManager sharedInstance].bundleDic objectForKey:name];
if (cacheBundle) {
return cacheBundle;
}
NSBundle *bundle = [NSBundle bundleForClass:aClass];
if (bundle) {
NSString *resourceBundlePath = [bundle pathForResource:name ofType:@"bundle"];
if (resourceBundlePath && [[NSFileManager defaultManager] fileExistsAtPath:resourceBundlePath]) {
bundle = [NSBundle bundleWithPath:resourceBundlePath];
}
[[BQSResourceManager sharedInstance].bundleDic setObject:bundle forKey:name];
return bundle;
}
return nil;
}
+ (UIImage *)imageName:(NSString *)name
inBundle:(NSBundle *)bundle {
NSAssert(bundle, @"bundle 不能為空");
NSAssert(name.length > 0, @"圖片名稱(chēng)不能為空");
if (name.length <= 0 || !bundle) {
return [UIImage new];
}
UIImage * image = [UIImage imageNamed:name
inBundle:bundle
compatibleWithTraitCollection:nil];
return image;
}
@end
最后添加了新的頭文件之后有時(shí)候在Example
工程中導(dǎo)入會(huì)提示找不到頭文件,可以重新執(zhí)行pod install
就可以找到了
如果你有遇到什么問(wèn)題歡迎在評(píng)論中回復(fù)附帽,我看到的都會(huì)回