jiaModuleDemo項目是為了解決關(guān)于項目中如何進行模塊化開發(fā)而編寫的實例盐数,包含如何進行路由式械筛、本地模塊間交互的實現(xiàn)杭隙;目前還是在頁面層級進行抽離放妈,對于項目中各個模塊共有的基礎(chǔ)功能也進行提取骂倘,可以結(jié)合私有Pods進行管理眼滤;
項目中存在的問題
問題一:頁面耦合嚴重
上面這張圖中左邊體現(xiàn)了目前項目中存在的問題,對于頁面之間相互耦合历涝,而頁面之間的傳參也各不相同诅需,由于不同的開發(fā)人員或者簡便方式等原因漾唉,傳參的類型都有差異,包含如實體堰塌、簡單基本類型等赵刑,先前項目對于路由方式也不支持,導致要實現(xiàn)收到消息推送進行不同的頁面跳轉(zhuǎn)存在硬編碼情況场刑,對于功能擴展存在相當大的問題般此;而右邊則是模塊化后頁面之間的交互方式;頁面之間也不存在耦合關(guān)系牵现,都只跟JiaMediator這個中介者相依賴铐懊;而傳參都統(tǒng)一成以字典的形式;雖然可能犧牲一些方便跟隨意瞎疼,卻可以解耦模塊化科乎;并且加入對路由方式的處理;約定好相關(guān)的協(xié)議進行交互贼急;用這種路由方式代替那些第三方的路由插件則是因為它的靈活性茅茂,最主要還是省去了第三方路由插件在啟動時要注冊路由的問題;
問題二:相同模塊重復開發(fā)
當公司里面有多個項目同時進行太抓,并且有可能是多個人分別不同項目時空闲,就會存在如上圖出現(xiàn)的情況,其實每個APP中都是有很多共同的模塊走敌,當然有可能你會把相同功能模塊代碼復制一份在新項目中碴倾,但這其實并不是最好的方式,在后期不斷迭代過程中掉丽,不同的人會往里面增加很多帶有個人色彩的代碼影斑;這樣就像相同的模塊項目后期對于多個項目統(tǒng)一管理也是災難性,有可能會失控机打,哪怕項目轉(zhuǎn)移別人接手也會無形中浪費很多時間,增加維護成本片迅,所以實例中更注重對于一些相同模塊進行提取残邀,求同存異;而模塊化結(jié)合私有Pods進行管理柑蛇,對于常用功能的封裝芥挣,只要開放出一些簡單開關(guān)配置方式,就可以實現(xiàn)一個功能耻台,比如日志記錄空免、網(wǎng)絡(luò)請求模塊、網(wǎng)絡(luò)狀態(tài)變化提示等盆耽;
模塊化解決方案
頁面交互解耦
實現(xiàn)調(diào)用代碼:
NSDictionary *curParams=@{kDesignerModuleActionsDictionaryKeyName:@"wujunyang",kDesignerModuleActionsDictionaryKeyID:@"1001",kDesignerModuleActionsDictionaryKeyImage:@"designerImage"};
switch (indexPath.row) {
case 0:
{
UIViewController *viewController=[[JiaMediator sharedInstance]JiaMediator_Designer_viewControllerForDetail:curParams];
[self presentViewController:viewController animated:YES completion:nil];
break;
}
case 1:
{
UIViewController *viewController=[[JiaMediator sharedInstance]JiaMediator_Designer_viewControllerForDetail:curParams];
[self.navigationController pushViewController:viewController animated:YES];
break;
}
case 2:
{
NSString *curRoue=@"jiaScheme://Designer/nativeFetchDetailViewController?name=wujunyang&ID=1001&image=designerImage";
UIViewController *viewController=[[JiaMediator sharedInstance]performActionWithUrl:[NSURL URLWithString:curRoue] completion:^(NSDictionary *info) {
}];
[self.navigationController pushViewController:viewController animated:YES];
break;
}
default:
break;
}
上面針對本地模塊調(diào)用及路由方式調(diào)用的跳轉(zhuǎn)
1:JiaMediator起到一個中介的作用蹋砚,所有的模塊間響應交互都是通過它進行扼菠,每個模塊都會對它進行擴展分類(例如:JiaMediator+模塊A),分類主要是為了用于本地間調(diào)用而又不想用路由的方式坝咐,若要用路由的方式則要注意關(guān)于路由約束準確編寫循榆,它將會直接影響到能否正確響應到目標;
2:JiaMediator是每個模塊都要用到的內(nèi)容墨坚,可以把它放在公共的模塊中秧饮,因為關(guān)于各個模塊的JiaMediator由每個模塊自個負責,開放給要調(diào)用的模塊使用泽篮;
3:為了解耦對于頁面間的傳參都采用字典形式盗尸,項目中所有的頁面都繼承于一個基頁面jiaBaseViewController,里面已經(jīng)有對初始化對于字典參數(shù)的接收并賦值帽撑,每個模塊的子頁面只要調(diào)用parameterDictionary屬性泼各,就可以獲取關(guān)于參數(shù)的內(nèi)容;同樣jiaBaseViewController也是每個模塊都要使用油狂,所以也被提取在公共里面历恐,其還包括一些導欄條的封裝及關(guān)于網(wǎng)絡(luò)狀態(tài)變化的提示等;
//頁面接收參數(shù)
@property(nonatomic,strong)NSDictionary *parameterDictionary;
//初始化參數(shù)
- (id)initWithRouterParams:(NSDictionary *)params;
- (id)initWithRouterParams:(NSDictionary *)params {
self = [super init];
if (self) {
_parameterDictionary=params;
NSLog(@"當前參數(shù):%@",params);
}
return self;
}
4:當響應某一個模塊目標后专筷,將會把相應的viewController進行返回弱贼,而對于具體如何操作則是在獲得當前控制器自行處理,比如是跳轉(zhuǎn)還是彈出展現(xiàn)磷蛹;
5:為了減少對于字典參數(shù)key拼寫錯誤問題吮旅,每個模塊都有一個對應key值的常量配置文件,已經(jīng)把對應的key值都定義成的常量味咳,方便調(diào)用庇勃;
#ifndef HeaderDesignerConfig_h
#define HeaderDesignerConfig_h
//鍵值
static NSString * const kDesignerModuleActionsDictionaryKeyName=@"name";
static NSString * const kDesignerModuleActionsDictionaryKeyID=@"ID";
static NSString * const kDesignerModuleActionsDictionaryKeyImage=@"image";
#endif /* HeaderDesignerConfig_h */
NSDictionary *curParams=@{kDesignerModuleActionsDictionaryKeyName:@"wujunyang",kDesignerModuleActionsDictionaryKeyID:@"1
JiaCore(基礎(chǔ)功能封裝)
JiaCore是整個APP最基礎(chǔ)模塊,所有的模塊化都要依賴槽驶,主要包含一些全局的功能模塊责嚷,比如JiaBaseViewController、JiaAppDelegate等掂铐;目前已經(jīng)把一些默認的功能進行集成在里面罕拂,包含網(wǎng)絡(luò)狀態(tài)變化判斷及提示、日志記錄功能等全陨;并把一些相關(guān)配置的內(nèi)容用JiaCoreConfigManager這個管理類進行統(tǒng)一設(shè)置爆班,比如是否打開日志記錄功能;JiaCoreConfigManager類則是開放給具體APP設(shè)置全局的相關(guān)配置辱姨;下面就以其中一個日志記錄功能進行講解:
//JiaCore基礎(chǔ)模塊相關(guān)配置
JiaCoreConfigManager *jiaCoreConfig=[JiaCoreConfigManager sharedInstance];
jiaCoreConfig.recordlogger=YES;
然后具體APP的PrefixHeader.pch引入命名空間并進行設(shè)置記錄日志的等級:
#import "JiaCocoaLumberjack.h"
//DDLog等級
static const int ddLogLevel = DDLogLevelVerbose;
這樣就完成的一個APP對于日志記錄模塊的引入柿菩,JiaCore已經(jīng)幫你完成的關(guān)于日志記錄的相關(guān)配置,并且錯誤內(nèi)容以一種可讀性較好的格式記錄到file文件中雨涛,而且這些file文件生成規(guī)則也都定義好了枢舶,當然如何時你要是在Xcode控制臺顯示不同等級色彩懦胞,只要安裝XcodeColors插件并簡單進行設(shè)置就可以了,對于不同等級不同色彩都已經(jīng)在JiaCore配置完成祟辟;
在JiaCore里面也默認集成了熱更新的功能医瘫,只要傳入簡單的對象數(shù)組就會啟動熱更新;其中JiaPathchModel已經(jīng)是定義好的模型旧困,在APP中把接口請求轉(zhuǎn)化成模型數(shù)組醇份,其中patchId是唯一值名稱、md5則是JS文件的MD5值吼具、url是JS的下載路徑僚纷、ver則是對哪個版本起作用;因為一般我們在外面的APP都是多版本共存拗盒,熱更新也要進行版本區(qū)分怖竭,只下載與本版本相對應的熱更新JS文件加載;而MD5值則是為了增加安全性陡蝇,避免JS文件被別人進行修改而影響APP的運行痊臭,在JiaCore會對下載后的JS文件進行MD5計算并比較;對于沒有在jSPatchMutableArray以前的JS文件會被刪除登夫;
//熱更新內(nèi)容
JiaPathchModel *sample=[[JiaPathchModel alloc]init];
sample.patchId = @"patchId_sample1";
sample.md5 = @"2cf1c6f6c5632dc21224bf42c698706b";
sample.url = @"http://test.qshmall.net:9090/demo1.js";
sample.ver = @"1";
JiaPathchModel *sample1=[[JiaPathchModel alloc]init];
sample1.patchId = @"patchId_sample2";
sample1.md5 = @"e8a4eaeadce5a4598fb9a868e09c75fd";
sample1.url = @"http://test.qshmall.net:9090/demo2.js";
sample1.ver = @"1";
//JiaCore基礎(chǔ)模塊相關(guān)配置
JiaCoreConfigManager *jiaCoreConfig=[JiaCoreConfigManager sharedInstance];
jiaCoreConfig.jSPatchMutableArray=[@[sample,sample1] mutableCopy];
JiaNetWork(網(wǎng)絡(luò)交互封裝)
對于網(wǎng)絡(luò)請求模塊則采用YTKNetwork广匙,底層還是以AFNetworking進行網(wǎng)絡(luò)通信交互,定義一個繼承于YTKBaseRequest的JiaBaseRequest恼策,針對JiaBaseRequest則是為了后期各個APP可以對它進行分類擴展鸦致,對于一些超時、請求頭部等進行統(tǒng)一個性化設(shè)置涣楷,畢竟這些是每個APP都不相同分唾;而針對模塊中關(guān)于請求網(wǎng)絡(luò)的前綴設(shè)置,則在每個模塊中都有一個單例的配置類狮斗,此配置類是為了針對該模塊對不同APP變化而定義绽乔;相應的配置內(nèi)容開放給APP,由具體APP來定義碳褒,例如現(xiàn)在項目中的JiaBaseRequest+App.h類迄汛,里面有簡單設(shè)置超時跟頭部;當然記得把這個分類引入到APP中骤视,比如AppPrefixHeader這個APP的全局頭部;
#import "JiaBaseRequest+App.h"
@implementation JiaBaseRequest (App)
- (NSTimeInterval)requestTimeoutInterval {
return 15;
}
//公共頭部設(shè)置
- (NSDictionary *)requestHeaderFieldValueDictionary
{
NSDictionary *headerDictionary=@{@"platform":@"ios"};
return headerDictionary;
}
@end
網(wǎng)絡(luò)層整體實現(xiàn)如下:
JiaGT模塊(個推封裝)
消息推送對于一個APP是相當重要性鹃觉,一般是采用第三方的SDK進行集成专酗,其實大部分的SDK處理代碼都是差不多,在這實例中對差異化的內(nèi)容進行提取盗扇,實例中將以個推進行模塊化祷肯,因為消息推送的大部分代碼都集中在AppDelegate中沉填,造成的一大堆雜亂代碼,當然也有一部分人對AppDelegate進行擴展分類進行移除代碼佑笋,實例中將采用另外一種解決方案進行抽取翼闹,可以達到完全解耦,在具體的APP里面將不會再出現(xiàn)個推SDK相關(guān)內(nèi)容猎荠,只要簡單進行配置跟處理消息就可以,下面只是簡單的列出部分代碼关摇,其它封裝代碼見源代碼;
//設(shè)置個推模塊的配置
jiaGTConfigManager *gtConfig=[jiaGTConfigManager sharedInstance];
gtConfig.jiaGTAppId=@"0uuwznWonIANoK07JeRWgAs";
gtConfig.jiaGTAppKey=@"26LeO4stbrA7TeyMUJdXlx3";
gtConfig.jiaGTAppSecret=@"2282vl0IwZd9KL3ZpDyoUL7";
#pragma mark 消息推送相關(guān)處理
/**
*? @author wujunyang, 16-07-07 16:07:25
*
*? @brief? 處理個推消息
*
*? @param NotificationMessage
*/
-(void)gtNotification:(NSDictionary *)NotificationMessage
{
NSLog(@"%@",NotificationMessage[@"payload"]);
NSLog(@"-----接收到個推通知------");
}
/**
*? @author wujunyang, 16-07-07 16:07:40
*
*? @brief? 處理遠程蘋果通知
*
*? @param RemoteNotificationMessage
*/
-(void)receiveRemoteNotification:(NSDictionary *)RemoteNotificationMessage
{
NSLog(@"%@",RemoteNotificationMessage[@"message"]);
NSLog(@"-----接收到蘋果通知------");
}
/**
*? @author wujunyang, 16-09-21 14:09:33
*
*? @brief 獲得注冊成功時的deviceToken 可以在里面做一些綁定操作
*
*? @param deviceToken
*/
-(void)receiveDeviceToken:(NSString *)deviceToken
{
NSLog(@"-----當前deviceToken:%@------",deviceToken);
}
上面能夠?qū)€推進行完全的解耦不得不提一個第三方的插件XAspect碾阁,如果想對它進行了解可以在github進行查找输虱;它的主要作用如下圖,可以用它進行其它第三方SDK的抽離
JiaAnalytics模塊(友盟統(tǒng)計封裝)
JiaAnalytics模塊是在友盟統(tǒng)計SDK跟Aspect相結(jié)合基礎(chǔ)上完成脂凶,對于頁面的進出統(tǒng)計采用Aop切面方式進行宪睹,把原本應該在每個頁面生命周期的統(tǒng)計代碼移除,App運用只要簡單配置友盟相對應的信息蚕钦,也可以設(shè)置要統(tǒng)計頁面的過濾條件亭病,目前已經(jīng)有三種如要統(tǒng)計的開頭頁面的前綴字符串數(shù)組、要統(tǒng)計的頁面名稱字符串數(shù)組冠桃、不統(tǒng)計的頁面名稱字符串數(shù)組命贴;可以結(jié)合使用,達到精確統(tǒng)計頁面的目的食听;而且把統(tǒng)計的代碼放在異步線程進行胸蛛,不會影響主線程的響應;
JiaShare模塊(友盟分享及第三方登錄封裝)
JiaShare模塊運用友盟分享最新版的SDK進行封裝樱报,并把一些其它不是很常用的去除葬项,目前只支持新浪、微信聊天迹蛤、微信朋友圈民珍、QQ聊天頁面、qq空間盗飒、騰訊微博嚷量;分享包括純文本、圖文逆趣、URL蝶溶、視頻地址、音樂地址,并在里面已經(jīng)運用JavaScriptCore.framework封裝好關(guān)于H5頁面調(diào)用分享并傳參的功能抖所;可以直接在UIWebView里面進行調(diào)用梨州;本模塊只是對功能進行封裝田轧,對于友盟在info.plist的配置還是要自行手動,如不明白可以直接到友盟分享官網(wǎng)查看每窖,項目到也有配置好一份可以直接參考岛请;JiaPlatformHelper類里面有一個判斷當前手機是否有安裝相應平臺軟件的方法警绩,可以用它進行隱藏相應的操作功能肩祥,避免上架時審核不過混狠;下面的代碼是在項目的AppDelegate里面進行配置.
//友盟分享
JiaShareConfigManager *jiaShareConfig=[JiaShareConfigManager sharedInstance];
jiaShareConfig.shareAppKey=@"57e3f1cbe0f55a42080011ec";
jiaShareConfig.shareLogEnabled=YES;
//設(shè)置平臺
[jiaShareConfig setPlaform:JiaSocialPlatConfigType_Tencent appKey:@"100424468" appSecret:@"c7394704798a158208a74ab60104f0ba" redirectURL:@"http://www.umeng.com/social"];
[jiaShareConfig setPlaform:JiaSocialPlatConfigType_Wechat appKey:@"wxdc1e388c3822c80b" appSecret:@"3baf1193c85774b3fd9d18447d76cab0" redirectURL:@"http://www.umeng.com/social"];
[jiaShareConfig setPlaform:JiaSocialPlatConfigType_Sina appKey:@"3921700954" appSecret:@"04b48b094faeb16683c32669824ebdad" redirectURL:@"http://sns.whalecloud.com/sina2/callback"];
然后就可以進行分享将饺,在ViewController里面進行調(diào)用,JiaSocialPlatformType是分享平臺的枚舉刮吧,shareUrlDataWithPlatform為URL分享方式杀捻,其它可以直接見源代碼JiaShareHelper類
[JiaShareHelper shareUrlDataWithPlatform:JiaSocialPlatformType_WechatSession withShareUrl:@"http://www.sina.com.cn" withTitle:@"新浪" withDescr:@"新浪網(wǎng)頁" withThumImage:@"http://dev.umeng.com/images/tab2_1.png" withCompletion:^(id result, NSError *error) {
if(error)
{
NSLog(@"分享出錯了");
}
}];
如果有加載H5頁面致讥,而且也要進行分享的功能就可以使用JiaWebShareHelper,因為使用到的是JavaScriptCore垢袱,所以只能用在UIWebView中港柜,如果你要是使用WKWebView可以自個再進行封閉,下面是加載H5頁面中的webViewDidFinishLoad代碼;
- (void)webViewDidFinishLoad:(UIWebView *)webView {
self.jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
// 通過模型調(diào)用方法授舟,這種方式更好些释树。
JiaWebShareHelper *shareHelper? = [[JiaWebShareHelper alloc] init];
self.jsContext[@"jia"] = shareHelper;
shareHelper.jsContext = self.jsContext;
shareHelper.webView = self.webView;
self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
context.exception = exceptionValue;
NSLog(@"異常信息:%@", exceptionValue);
};
}
H5中就可以很方便直接進行:
下面簡單介紹關(guān)于第三方登錄跟獲取用戶信息的功能奢啥,其功能代碼放在JiaPlatformHelper里面桩盲,已經(jīng)對授權(quán)成功及獲取用戶信息都有回去調(diào)相應的參數(shù)回來:
if(![JiaPlatformHelper installPlatAppWithType:JiaSocialPlatformType_QQ])
{
[weakSelf showResult:@"沒有安裝QQ軟件,將此功能隱藏"];
return;
}
[JiaPlatformHelper authWithPlatform:JiaSocialPlatformType_QQ withCompletion:^(NSString *uid, NSString *openid,NSString *accessToken, NSError *error) {
if (error) {
NSLog(@"出錯了");
return;
}
NSString *result=[NSString stringWithFormat:@"獲得到的值為:uid:%@--token:%@--openid:%@",uid,accessToken,openid];
[weakSelf showResult:result];
}];
獲取用戶信息的代碼如下:
[JiaPlatformHelper getUserInfoWithPlatform:JiaSocialPlatformType_QQ withCompletion:^(NSString *name, NSString *iconUrl, NSString *gender, NSError *error) {
if (error) {
NSLog(@"出錯了");
return;
}
NSString *result=[NSString stringWithFormat:@"獲得到的值為:name:%@--性別:%@",name,gender];
[weakSelf showResult:result];
}];
關(guān)于取消授權(quán)也有相應的方法:
[JiaPlatformHelper cancelAuthWithPlatform:JiaSocialPlatformType_QQ withCompletion:^(id result, NSError *error) {
if (error) {
NSLog(@"出錯了");
return;
}
NSString *ressult=@"取消成功";
[weakSelf showResult:ressult];
}];
模塊化結(jié)合私有Pods方案
上面實例中只是把相關(guān)模塊化的提取都在一個工程進行體現(xiàn)捞蛋,最后還是要落實結(jié)合Pods進行管理柬姚,把每個模塊分開管理量承,不同的APP可以簡單通過Pods指令就可以達到引入模塊的效果,對于一些相同模塊可以在不同的APP重復引用拿穴,減小重復開發(fā)成本贞言;
在本項目中已經(jīng)引入的Pod來管理目前開發(fā)的幾個模塊阀蒂,并導入在我目前的Github的一個庫里Spec進行統(tǒng)一管理,首先要引入Pod來管理則要增加jiaModule.podspec文件酗失;
Pod::Spec.new do |s|
s.name? ? ? ? = "jiaModule"
s.version? ? ? = "0.0.6"
s.summary? ? ? = "iOS模塊化功能的引用"
s.homepage? ? = "https://github.com/wujunyang/jiaModuleDemo"
s.license? ? ? = { :type => "MIT", :file => "FILE_LICENSE" }
s.author? ? ? ? ? ? = { "wujunyang" => "wujunyang@126.com" }
s.platform? ? = :ios, "7.0"
s.source? ? ? = { :git => "https://github.com/wujunyang/jiaModuleDemo.git", :tag => "0.0.6" }
s.requires_arc = true
s.subspec 'JiaCore' do |jiaCore|
jiaCore.source_files = 'jiaModuleDemo/BaseModule/JiaCore/**/*.{h,m}'
jiaCore.dependency 'XAspect'
jiaCore.dependency 'YYCache'
jiaCore.dependency 'JSPatch'
jiaCore.dependency 'RealReachability'
jiaCore.dependency 'FLEX', '~> 2.0'
jiaCore.dependency 'CocoaLumberjack', '~> 2.0.0-rc'
jiaCore.dependency 'AFNetworking', '~>2.6.0'
end
s.subspec 'JiaGT' do |jiaGT|
jiaGT.source_files = 'jiaModuleDemo/BaseModule/JiaGT/**/*'
jiaGT.dependency 'jiaModule/JiaCore'
jiaGT.dependency 'XAspect'
jiaGT.dependency 'GTSDK', '~> 1.5.0'
end
s.subspec 'JiaAnalytics' do |jiaAnalytics|
jiaAnalytics.source_files = 'jiaModuleDemo/BaseModule/JiaAnalytics/**/*'
jiaAnalytics.dependency 'jiaModule/JiaCore'
jiaAnalytics.dependency 'XAspect'
jiaAnalytics.dependency 'Aspects'
jiaAnalytics.dependency 'UMengAnalytics-NO-IDFA', '~> 4.1.1'
end
s.frameworks = 'UIKit'
# s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" }
# s.dependency "JSONKit", "~> 1.4"
end
上面的文件會把不同的模塊進行分離规肴,可以一起引入也可以單獨引入某一個模塊删壮;pod會自動把相應的依賴都引入,下面是全部引入關(guān)于jiaModule模塊
source 'https://github.com/CocoaPods/Specs.git'
source 'https://github.com/wujunyang/WjySpecs.git'
platform :ios, "7.0"
pod 'jiaModule'
假如要引入只是其中一個模塊:
source 'https://github.com/CocoaPods/Specs.git'
source 'https://github.com/wujunyang/WjySpecs.git'
platform :ios, "7.0"
pod 'jiaModule/JiaCore’
pod 'jiaModule/JiaGT’
下面簡單介紹兩條關(guān)于驗證跟提交jiaModule.podspec的指令兑牡,都要打開終端進入項目根目錄均函,也就是jiaModule.podspec所在的目錄,然后進行執(zhí)行洛勉;
#驗證是否正確(后面還有一個git的私有地址)
pod lib lint jiaModule.podspec --allow-warnings --use-libraries --sources=
#提交到庫? (specs就是你們的私有庫名如迟,見下面repo add指令時的名字,后面還有一個git的私有地址)
pod repo push specs jiaModule.podspec --allow-warnings --use-libraries --sources=https://github.com/CocoaPods/Specs.git,https://github.com/wujunyang/WjySpecs.git
注意:如果提交到庫時報下面的問題牛哺,說明還沒有把私有倉庫集下載到本地:
[!] Unable to find the `specs` repo. If it has not yet been cloned, add it via `pod repo add`.
可以直接執(zhí)行指令(specs名字可以自行定義,跟上面提交時對應該上就行):
pod repo add specs https://github.com/wujunyang/WjySpecs.git
會在路徑:/Users/自個電腦用戶名/.cocoapods/repos(被隱藏引润,要用指令進行顯示出來) 下有一個文件夾specs 另外還有一個是Pod官網(wǎng)的文件夾淳附;
最后還要登錄Git賬號跟密碼奴曙,就可以成功提交了
Username for 'https://github.com': wujunyang@126.com
Password for 'https://wujunyang@126.com@github.com':
To https://github.com/wujunyang/WjySpecs.git
80ca876..d4f7446? master -> master
重點:此為分享的東西:文章作者為:wujunyang
1:分享的鏈接網(wǎng)址:http://www.cocoachina.com/ios/20161103/17932.html
2:分享的demo鏈接網(wǎng)址:https://github.com/SmartFire/jiaModuleDemo/