前言
前幾篇博客描述了手動創建組件的方法,到新公司發現這種方式不適合小公司快捷方便的需求,所以轉而向cocoapods
為我們提供的pod lib
命令來創建組件,這樣對于沒接觸過組件化的新人比較友好,另外也確實少了很多自己需要配置的各種東西。
準備
- 組件創建需要
cocoapods
- 如果想上傳到倉庫還需要有
git
- 如果環境都沒搭建可以看下之前本序列的文章都有介紹
創建
1、創建組件命令,你可以CD
到特定文件夾下執行命令,創建名為名為Demo的組件為例
# 開始執行以下命令后會去github克隆模板代碼沒翻墻可能會比較慢
pod lib create Demo
#創建過程中的選項可參考下面,有特殊也可以自己決定
What platform do you want to use?? [ iOS / macOS ] 平臺我們選擇iOS
> iOS
What language do you want to use?? [ Swift / ObjC ] 語言我選擇oc
> ObjC
Would you like to include a demo application with your library? [ Yes / No ] 是否創建demo工程
> Yes
Which testing frameworks will you use? [ Specta / Kiwi / None ] 是否添加測試支持
> None
Would you like to do view based testing? [ Yes / No ] 是否添加測試的view
> No
What is your class prefix? 類名使用的前綴
> GG
當前命令執行完之后,它會幫我們執行pod install
命令并自動打開里面的Example
工程,我們先看下創建后文件夾目錄:
image.png
- Demo文件夾是我們實際的組件目錄,后面創建的圖片及文件和源代碼都在這里
- Demo文件夾下有兩個文件夾,一個
Classes
是存放代碼的地方在xcode創建的時候記得把代碼的目錄選擇放這里,一個是Assets
存放不限于圖片的其他資源文件一般我們放圖片可以創建一個系統的.xcassets
圖片管理器很方便存取 - Demo.podspec是組件的描述,不懂可以看下之前的基本概念都是一樣的
- Example 是我們調試使用的工程,跟我們平時使用的項目差不多,只是它在
Example/Podfile
中幫我們加入了當前組件的本地依賴方便我們調試
pod 'Demo', :path => '../'
- .git是git相關的你可以刪掉它后續自己創建
- .travis.yml是有關自動化相關的也可以先忽略或者直接刪除
在xcode中的工程目錄:
image.png
- 紅色部分是調試工程的目錄先不管他
- 綠色部分就是我們在調試的時候組件代碼具體呈現的地方,
Demo
就是我們組件的名稱有多個的話就是多個這樣的文件夾,Demo/Pod
中的放的是組件的描述和README.md文件和實際的目錄是同步的
2、創建好之后最好到項目根目錄下打開.gitgnore
忽略文件中添加下列兩行,忽略我們在測試的工程添加的依賴也上傳到git上
Example/Pods
Example/Podfile.lock
3、如果有自己的私有庫,在Example/Podfile
中替換以下添加私有源,沒有的可以忽略這步
source 'git@xxxx/Specs.git'
4、上傳到倉庫,刪掉項目根目錄下的git
文件夾,使用以下命令將文件提交至git,嫌麻煩也可以直接使用Sourcetree
來上傳
#當組件的根目錄下
cd Demo
git init
#關聯內網git倉庫
git remote add origin git@xxxt/Demo.git
#提交源碼
git add .
git commit -m "Initial commit"
git push -u origin master
5、創建源代碼文件應注意選擇路徑,還有對應的target選擇
image.png
6、圖片的讀取問題
- 我們可以在xcode中選擇
Asset Catalog
來創建一個自己的圖片管理器,名字最好用組件名稱來命令好區分,一般存放在組件的Assets
目錄下
image.png
- 存放圖片的時候和我們一般項目中存儲的沒什么區別
- 如果需要發布組件需要在
podsepc
中添加以下描述,以我的示例工程為例
s.resource_bundles = {
'Demo' => ['Demo/Assets/Demo.xcassets']
}
- 代碼獲取圖片我寫了個工具類,就是獲取
bundle
之后再獲取里面的圖片,使用方法也在里面了,使用這種方法Podfile
需要去掉里面默認添加的use_frameworks!
,后續swift再作兼容
//
// ResourceManager.h
// AssetsKit
//
// Created by GuoMS on 2019/2/18.
//
#import <Foundation/Foundation.h>
/* 使用方法,新建一個文件,頭文件寫入以下宏定義
#import "ResourceManager.h"
//自定義特定的名稱
#undef XXXBundle
#define XXXBundle [ResourceManager resourceBundleForClass:[self class] podName:@"組件名稱"]
#undef BXXXImage
#define BXXXImage(name) [ResourceManager imageName:name inBundle:XXXBundle]
*/
@interface BQSResourceManager : NSObject
/**
獲取組件的bundle并緩存
@param aClass 當前調用的類,用于定位bundle位置
@param name 組件的名字
@return bundle
*/
+ (NSBundle *)resourceBundleForClass:(Class)aClass
podName:(NSString *)name;
/**
制定bundle獲取圖片
@param name 圖片名字
@param bundle bundle實例
@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, @"組件名稱不能為空");
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, @"圖片名稱不能為空");
if (name.length <= 0 || !bundle) {
return [UIImage new];
}
UIImage * image = [UIImage imageNamed:name
inBundle:bundle
compatibleWithTraitCollection:nil];
return image;
}
@end
最后添加了新的頭文件之后有時候在Example
工程中導入會提示找不到頭文件,可以重新執行pod install
就可以找到了
如果你有遇到什么問題歡迎在評論中回復,我看到的都會回