我的iOS工程結(jié)構(gòu)(總結(jié)和工程實踐)

好的架構(gòu)不是設(shè)計出來的,而是進化而來的!本文是一位學(xué)習iOS開發(fā)者根據(jù)多年的經(jīng)驗總結(jié)了iOS工程結(jié)構(gòu),穩(wěn)重總結(jié)了在開發(fā)iOS項目中工程實踐,非常實用,推薦過來,一起來看看吧,希望對大家有所幫助
寫在前面
從2011年底開始學(xué)習iOS開發(fā),到現(xiàn)在也已經(jīng)快3年了,雖然中途沒有一直進行iOS的開發(fā)(總是在Android和iOS間切換),但始終沒有離開,而我現(xiàn)在的工作也一樣,在iOS和Android間來回游走,正如我博客的slogan一樣,“In Android&iOS”。其實對我來說,兩個平臺沒有絕對的好壞,我都喜歡、我都熱愛。有人會說,同樣的產(chǎn)品在不同平臺做兩次不會覺得厭煩嗎?這個問題我會給出肯定的回答,不會!因為如果你真的喜歡你所做的產(chǎn)品,做多少次都不會覺得煩,每一次的復(fù)盤都是一次改進的過程,很多創(chuàng)新都是在重復(fù)的工作中產(chǎn)生的。在技術(shù)層面,同一套思想用不同的技術(shù)來實現(xiàn),本身就是一個加強對不同平臺技術(shù)鞏固和理解的過程,技術(shù)本來就是來承載和表現(xiàn)業(yè)務(wù)的,在實現(xiàn)業(yè)務(wù)的過程中加強對業(yè)務(wù)的理解、實現(xiàn)對業(yè)務(wù)的創(chuàng)新,這或許也就是堆代碼和寫程序的區(qū)別吧!^_^
我的iOS工程結(jié)構(gòu)
接下來,我就簡單介紹下我做iOS項目時使用的工程結(jié)構(gòu)。首先要說的是,這只是我的工程結(jié)構(gòu),并不是規(guī)范,或許它存在很多問題和不規(guī)范的地方,我只是把它分享出來,給大家提供一個參考,也希望收到大家的一些反饋來幫助我改進!
項目結(jié)構(gòu)
下圖是我做iOS項目的一個常用工程結(jié)構(gòu),整體模式還是按照MVC的結(jié)構(gòu),只是在每一層做了一些細分處理,下面就簡單介紹下。
iOS工程中沒有像Java那樣非常嚴格的分包機制,不過在iOS工程中我們也可以通過Group的方式在工程中實現(xiàn)邏輯分包,這樣更有利于我們組織和管理代碼,使工程結(jié)構(gòu)更清晰和易于理解。在我的工程結(jié)構(gòu)中,主要有如下group:
Application:這個group中放的是AppDelegate和一些系統(tǒng)常量及系統(tǒng)配置文件;
Base:一些基本父類,包括父ViewController和一些公用頂層自定義父類,其他模塊的類一般都繼承自這里的一些類;
Controller:系統(tǒng)控制層,放置ViewController,均繼承于Group Base中的BaseViewController或BaseTableViewController;
View:系統(tǒng)中視圖層,由于我比較喜歡通過代碼實現(xiàn)界面,所以這里放的都是繼承于UIView的視圖,我將視圖從ViewController中分離出來全部放在這里,這樣能保持ViewController的精簡;
Model:系統(tǒng)中的實體,通過類來描述系統(tǒng)中的一些角色和業(yè)務(wù),同時包含對應(yīng)這些角色和業(yè)務(wù)的處理邏輯;
Handler:系統(tǒng)業(yè)務(wù)邏輯層,負責處理系統(tǒng)復(fù)雜業(yè)務(wù)邏輯,上層調(diào)用者是ViewController;
Storage:簡單數(shù)據(jù)存儲,主要是一些鍵值對存儲及系統(tǒng)外部文件的存取,包括對NSUserDefault和plist存取的封裝;
Network:網(wǎng)絡(luò)處理層(RTHttpClient),封裝了基于AFNetworking的網(wǎng)絡(luò)處理層,通過block實現(xiàn)處理結(jié)果的回調(diào),上層調(diào)用者是Handler層;
Database:數(shù)據(jù)層,封裝基于FMDB的sqlite數(shù)據(jù)庫存取和管理(RTDatabaseHelper),對外提供基于Model層對象的調(diào)用接口,封裝對數(shù)據(jù)的存儲過程。
Utils:系統(tǒng)工具類(AppUtils),主要放置一些系統(tǒng)常用工具類;
Categories:類別,對現(xiàn)有系統(tǒng)類和自定義類的擴展;
Resource:資源庫,包括圖片,plist文件等;
以上是對我的工程結(jié)構(gòu)中各個group的介紹,通過以下登錄模塊的系統(tǒng)類圖,可以比較直觀的看到這種工程結(jié)構(gòu)的全貌。
整體來看分為三大塊,黃色區(qū)域的模型和業(yè)務(wù)邏輯層(M),藍色區(qū)域的視圖層(V),紅色區(qū)域的視圖控制器層(C),其中,黃色區(qū)域?qū)崿F(xiàn)了對業(yè)務(wù)邏輯和數(shù)據(jù)處理的封裝,對應(yīng)他們的上層ViewController,可以實現(xiàn)非常簡單的接口調(diào)用,將業(yè)務(wù)復(fù)雜性從ViewController中抽離出來,通過模塊化的方式,保證ViewController的可讀性和可維護性。
保持ViewController簡單
往往大家都會抱怨iOS中ViewController寫著寫著就會越來越臃腫,那時因為隨著業(yè)務(wù)的復(fù)雜,功能的增多,所有的邏輯都包含在ViewController中,還包括一些諸如UITableViewDatasource的代理方法,使得ViewController臃腫不堪,可維護性極低,耦合性也很高,為了使ViewController能更簡單,便于維護和后續(xù)的開發(fā),給ViewController瘦身就顯得尤為必要,我的做法主要有三個方面。
1、View視圖與ViewController分離
如果你用Storyboard或者xib這是當然的,我比較喜歡手寫代碼,所以不在ViewController里面嵌入過多的View層代碼是保證ViewController簡單的方法之一,那么,可以將View部分的代碼單獨封裝到一個繼承自UIView的子類當中,然后通過自定義Delegate實現(xiàn)View與ViewController的通信。
2、業(yè)務(wù)邏輯與ViewController分離
將網(wǎng)絡(luò)請求處理和復(fù)雜的業(yè)務(wù)邏輯以及數(shù)據(jù)的存取工作單獨放到Handler層,對ViewController只暴露簡單的調(diào)用接口和通過block或delegate實現(xiàn)的回調(diào),這樣不僅能使我們的工程模塊化,也能大大降低ViewController的復(fù)雜性,就不會出現(xiàn)既包括網(wǎng)絡(luò)處理又包括數(shù)據(jù)處理的冗長的ViewController代碼了。Handler通過block或delegate將處理完的結(jié)果回調(diào)給ViewController,ViewController再將結(jié)果與View視圖層相關(guān)聯(lián)處理,這樣就真正起到了MVC的作用,整體原則就是,讓ViewController只關(guān)系和負責處理與它相關(guān)的事。
在BaseHandler.h中可以定義一些簡單的業(yè)務(wù)處理規(guī)則:
- #import <Foundation/Foundation.h>
- /** * Handler處理完成后調(diào)用的Block
- */ typedef void (^CompleteBlock)();
- /**
- * Handler處理成功時調(diào)用的Block */
- typedef void (^SuccessBlock)(id obj);
- /** * Handler處理失敗時調(diào)用的Block
- */ typedef void (^FailedBlock)(id obj);
- @interface BaseHandler : NSObject
- /**
- * 獲取請求URL *
- * @param path * @return 拼裝好的URL
- */ + (NSString *)requestUrlWithPath:(NSString *)path;
- @end
在LoginHandler中就可以定義對LoginViewController暴露的調(diào)用接口,在LoginHandler中封裝負責的網(wǎng)絡(luò)處理和業(yè)務(wù)處理邏輯,對LoginViewcontroller來說,只需要調(diào)用這個方法并傳入對應(yīng)的UserEntity實體對象和處理成功和失敗狀態(tài)下的回調(diào)block就可以了。
- #import "BaseHandler.h" #import "UserEntity.h"
- @interface LoginHandler : BaseHandler
- /**
- * 用戶登錄業(yè)務(wù)邏輯處理 *
- * @param user * @param success
- * @param failed */
- - (void)executeLoginTaskWithUser:(UserEntity *)user success:(SuccessBlock)success failed:(FailedBlock)failed;
- @end
3、Datasource或Delegate與ViewController分離
在iOS開發(fā)中經(jīng)常用到的UITableView包含了一系列的代理方法,這些方法往往也是使得ViewController變長變復(fù)雜的元兇之一,那么,將這些Datasource或Delegate分離出來也是行之有效的方法之一,例如,通過自定義Datasource類(實現(xiàn)UITableViewDatasource協(xié)議)來將跟UITableView相關(guān)的數(shù)據(jù)源處理代理方法都集中到一個特定的類當中,ViewController只需要設(shè)置這個自定義數(shù)據(jù)源類給UITableView,然后其他的就都可以交給自定義數(shù)據(jù)源類去處理了。
我參考了Lighter View Controllers上的介紹改進了一個BaseTableViewProtocol,基本上常用的一些場景是可以使用的,不過這個還得不斷優(yōu)化以適應(yīng)更多的場景,具體的代碼我放在Github上了,感興趣的同學(xué)可以去看看,使用方法可以參考上面鏈接中的介紹,基本類似,我的改進主要是支持對多section的適用。
BaseTableViewProtocol.h
BaseTableViewProtocol.m
寫在最后
以上是我在開發(fā)iOS項目中的一些總結(jié)和工程實踐,其中肯定還是存在很多問題的,我也在不斷尋求改進的方法,也歡迎各路高手給我提出意見和建議。關(guān)于這個工程結(jié)構(gòu)的一個簡單事例我放在我的Github上了,感興趣的同學(xué)可以去看看RTLibrary-ios。
相關(guān)文章
WebStorm如何調(diào)試Vue項目? webstorm配置vue開發(fā)環(huán)境指南
WebStorm 支持多種調(diào)試工具,包括瀏覽器的開發(fā)者工具,但本文主要講解的是使用 WebStorm 自帶的調(diào)試功能2025-04-15VSCode和webstorm怎么設(shè)置綠色護眼背景? 綠豆沙背景色的設(shè)置方法
護眼色一定程度能保護眼睛,緩解疲勞,VSCode和webstorm這兩款常用的軟件怎么設(shè)置護眼色呢?詳細請看下文介紹2025-04-15- WebStorm本身已經(jīng)足夠強大,但一些優(yōu)秀的插件能錦上添花,顯著提升開發(fā)效率,詳細請看下文介紹2025-04-15
如何安裝配置WebStorm? WebStorm安裝與使用全方位指南
WebStorm軟件在前端和后端開發(fā)領(lǐng)域都備受青睞,很多朋友不知道該怎么下載安裝,下面我們就來看看詳細的安裝配置教程2025-04-15Webstorm怎么配置? Webstorm入門之軟件配置教程
WebStorm是一款功能強大的集成開發(fā)環(huán)境(IDE),支持各種前端開發(fā)技術(shù),今天我們就來看看Webstorm的配置教程2025-04-15Webstorm怎么設(shè)置字體大小/背景顏色/背景圖片?
WebStorm 允許您自定義界面顏色,以創(chuàng)建更個性化和美觀的工作空間,今天我們就來看看Webstorm改變字體大小、背景顏色、設(shè)置背景圖片的方法2025-04-15- VScode上安裝PlatformIO插件能成功安裝,嘗試卸載VScode并刪除插件,這些錯誤仍然存在,下面我們就來看看這個問題的解決辦法2025-04-03
提升代碼搜索效率! VSCode里DeepSeek插件安裝與配置指南
今天我們將向大家介紹如何在Visual Studio Code中安裝并配置 DeepSeek 插件,幫助你更高效地進行代碼搜索2025-04-07- VSCode是一款免費且開源的代碼編輯器,因其強大的功能和良好的用戶體驗而廣受歡迎,本文將詳細介紹 VSCode 的基本使用方法,并通過插圖幫助你更好地理解2025-04-03
- 今天我們來聊聊如何安裝和配置VS Code,讓它成為你編程路上的得力助手,這個過程其實很簡單,只要跟著我的步驟走,你絕對能搞定2025-04-03