iOS中關於模組化開發解決方案(純乾貨)_IOS

來源:互聯網
上載者:User

關於iOS模組化開發解決方案網上也有一些介紹,但真正落實在在具體的執行個體卻很少看到,計劃編寫系統文章來介紹關於我對模組化解決方案的理解,裡面會有包含到一些關於解耦、路由、封裝、私人Pod管理等內容;並編寫的一個執行個體項目放在git進行開源[jiaModuleDemo],裡面現在已經放著一些封裝的功能模組;會不斷的進行更新,假如你感興趣可以Star一下,項目也不斷的更新完善最佳化;如果你有更好的方案或者說好的建議可以lssues,我會在短時間進行更新並修改相應的問題;

一:項目中存在的問題

1:當公司裡面有多重專案同時進行,並且有可能是多個人分別不同項目時,就會存在如上圖出現的情況,其實每個APP中都是有很多共同的模組,當然有可能你會把相同功能模組代碼複製一份在新項目中,但這其實並不是最好的方式,在後期不斷迭代過程中,不同的人會往裡面增加很多帶有個人色彩的代碼;這樣就像相同的模組項目後期對於多重專案統一管理也是災難性,有可能會失控,哪怕項目轉移別人接手也會無形中浪費很多時間,增加維護成本,所以執行個體中更注重對於一些相同模組進行提取,求同存異;而模組化結合私人Pods進行管理,對於常用功能的封裝,只要開放出一些簡單開關配置方式,就可以實現一個功能,比如日誌記錄、網路請求模組、網路狀態變化提示等;

2:對於頁面之間相互耦合,而頁面之間的傳參也各不相同,由於不同的開發人員或者簡便方式等原因,傳參的類型都有差異,包含如實體、簡單基本類型等,先前項目對於路由方式也不支援,導致要實現收到訊息推送進行不同的頁面跳轉存在寫入程式碼情況,對於功能擴充存在相當大的問題;而右邊則是模組化後頁面之間的互動方式;頁面之間也不存在耦合關係,都只跟JiaMediator這個中介者相依賴;而傳參都統一成以字典的形式;雖然可能犧牲一些方便跟隨意,卻可以解耦模組化;並且加入對路由方式的處理;約定好相關的協議進行互動;用這種路由方式代替那些第三方的路由外掛程式則是因為它的靈活性,最主要還是省去了第三方路由外掛程式在啟動時要註冊路由的問題;

二:解決方案實現之模組化

1:JiaCore(基礎功能封裝)

JiaCore是整個APP最基礎模組,所有的模組化都要依賴,主要包含一些全域的功能模組,比如JiaBaseViewController、JiaAppDelegate等;目前已經把一些預設的功能進行整合在裡面,包含網路狀態變化判斷及提示、日誌記錄功能等;並把一些相關配置的內容用JiaCoreConfigManager這個管理類進行統一設定,比如是否開啟日誌記錄功能;JiaCoreConfigManager類則是開放給具體APP設定全域的相關配置;下面就以其中一個日誌記錄功能進行講解:

//JiaCore基礎模組相關配置JiaCoreConfigManager *jiaCoreConfig=[JiaCoreConfigManager sharedInstance];jiaCoreConfig.recordlogger=YES;然後具體APP的PrefixHeader.pch引入命名空間並進行設定記錄日誌的等級:#import "JiaCocoaLumberjack.h"//DDLog等級static const int ddLogLevel = DDLogLevelVerbose;

這樣就完成的一個APP對於日誌記錄模組的引入,JiaCore已經幫你完成的關於日誌記錄的相關配置,並且錯誤內容以一種可讀性較好的格式記錄到file檔案中,而且這些file檔案建置規則也都定義好了,當然如何時你要是在Xcode控制台顯示不同等級色彩,只要安裝XcodeColors外掛程式並簡單進行設定就可以了,對於不同等級不同色彩都已經在JiaCore配置完成;

2:JSPatch熱更新功能

在JiaCore裡面也預設整合了熱更新的功能,只要傳入簡單的對象數組就會啟動熱更新;其中JiaPathchModel已經是定義好的模型,在APP中把介面請求轉化成模型數組,其中patchId是唯一值名稱、md5則是JS檔案的MD5值、url是JS的下載路徑、ver則是對哪個版本起作用;因為一般我們在外面的APP都是多版本共存,熱更新也要進行版本區分,只下載與本版本相對應的熱更新JS檔案載入;而MD5值則是為了增加安全性,避免JS檔案被別人進行修改而影響APP的運行,在JiaCore會對下載後的JS檔案進行MD5計算並比較;對於沒有在jSPatchMutableArray以前的JS檔案會被刪除;

//熱更新內容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基礎模組相關配置JiaCoreConfigManager *jiaCoreConfig=[JiaCoreConfigManager sharedInstance];jiaCoreConfig.jSPatchMutableArray=[@[sample,sample1] mutableCopy];

3:JiaGT模組(個推封裝)

訊息推送對於一個APP是相當重要性,一般是採用第三方的SDK進行整合,其實大部分的SDK處理代碼都是差不多,在這執行個體中對差異化的內容進行提取,執行個體中將以個推進行模組化,因為訊息推送的大部分代碼都集中在AppDelegate中,造成的一大堆雜亂代碼,當然也有一部分人對AppDelegate進行擴充分類進行移除代碼,執行個體中將採用另外一種解決方案進行抽取,可以達到完全解耦,在具體的APP裡面將不會再出現個推SDK相關內容,只要簡單進行配置跟處理訊息就可以,下面只是簡單的列出部分代碼,其它封裝代碼見原始碼;

//設定個推模組的配置jiaGTConfigManager *gtConfig=[jiaGTConfigManager sharedInstance];gtConfig.jiaGTAppId=@"0uuwznWonIANoK07JeRWgAs";gtConfig.jiaGTAppKey=@"26LeO4stbrA7TeyMUJdXlx3";gtConfig.jiaGTAppSecret=@"2282vl0IwZd9KL3ZpDyoUL7";#pragma mark 訊息推送相關處理/*** @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 <#deviceToken description#>*/-(void)receiveDeviceToken:(NSString *)deviceToken{NSLog(@"-----當前deviceToken:%@------",deviceToken);}

4:JiaAnalytics模組(友盟統計封裝)

JiaAnalytics模組是在友盟統計SDK跟Aspect相結合基礎上完成,對於頁面的進出統計採用Aop切面方式進行,把原本應該在每個頁面生命週期的統計代碼移除,App運用只要簡單配置友盟相對應的資訊,也可以設定要統計頁面的過濾條件,目前已經有三種如要統計的開頭頁面的前置詞字元串數組、要統計的頁面名稱字串數組、不統計的頁面名稱字串數組;可以結合使用,達到精確統計頁面的目的;而且把統計的代碼放在非同步線程進行,不會影響主線程的響應;

__weak typeof(self) ws = self;dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{[UIViewController aspect_hookSelector:@selector(viewWillAppear:) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> info, BOOL animated){UIViewController *controller = [info instance];BOOL filterResult=[ws fileterWithControllerName:NSStringFromClass([controller class])];if (filterResult) {[ws beginLogPageView:[controller class]];}} error:NULL];[UIViewController aspect_hookSelector:@selector(viewWillDisappear:) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> info, BOOL animated){UIViewController *controller = [info instance];BOOL filterResult=[ws fileterWithControllerName:NSStringFromClass([controller class])];if (filterResult) {[ws endLogPageView:[controller class]];}} error:NULL];});

三:解決方案實現之頁面解耦

JiaMediator起到一個中介的作用,所有的模組間響應互動都是通過它進行,每個模組都會對它進行擴充分類(例如:JiaMediator+模組A),分類主要是為了用於本地間調用而又不想用路由的方式,若要用路由的方式則要注意關於路由約束準確編寫,它將會直接影響到能否正確響應到目標;執行個體中也有關於使用通知的方式進行回調參數的回傳問題;

執行個體代碼如下:

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;}case 3:{NSDictionary *userParaDictionary=@{kUserModuleActionsDictionaryKeyID:@"1"};UIViewController *viewController=[[JiaMediator sharedInstance] JiaMediator_User_viewControllerForDetail:userParaDictionary];[self.navigationController pushViewController:viewController animated:YES];break;}default:break;}

四:模組化結合私人Pods方案

執行個體中只是把相關模組化的提取都在一個工程進行體現,最後還是要落實結合Pods進行管理,把每個模組分開管理,不同的APP可以簡單通過Pods指令就可以達到引入模組的效果,對於一些相同模組可以在不同的APP重複引用,減小重複開發成本;

以上所述是小編給大家介紹的iOS中關於模組化開發解決方案(純乾貨),希望對大家有所協助,如果大家有任何疑問請給我留言,小編會及時回複大家的。在此也非常感謝大家對雲棲社區網站的支援!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.