iOS模塊化的探索

iOS原生模塊化的探索

大概是去年秋天開始御蒲,隨著滬江學(xué)習(xí)的App越來(lái)越大纵顾,我做了很多模塊化的嘗試敬鬓,最近要把滬學(xué)的一些輕量化學(xué)習(xí)的組件拆分并移植到CCtalk串慰,所以把從去年的嘗試寫出來(lái)偏塞。

我嘗試過(guò)幾種模塊化的方式,可能在不同場(chǎng)景下使用不同的方式邦鲫,帶來(lái)的效果都不太一樣灸叼。

先說(shuō)幾個(gè)具體的例子

練習(xí)

exercise

練習(xí)是第一個(gè)模塊化的業(yè)務(wù),起因如下:

  • 上一版的練習(xí)基于H5制作庆捺,網(wǎng)校和滬學(xué)共用一套古今,模塊化能方便兩條產(chǎn)品線接入使用
  • 練習(xí)沒(méi)有課程的一些功能比如點(diǎn)贊
  • Swift2.0時(shí)代早期Xcode經(jīng)常crash,OC和Swift混編會(huì)有一些問(wèn)題滔以,單獨(dú)開發(fā)可以減少Xcode崩潰率??
  • 滬學(xué)主項(xiàng)目已經(jīng)很大了捉腥,在這樣的工程下搞開發(fā),開發(fā)體驗(yàn)太差你画,效率較低

因?yàn)槭堑谝粋€(gè)獨(dú)立的模塊抵碟,考慮了以下問(wèn)題

  1. 是否使用SnapKit,TZStackView坏匪,RxSwift這類第三方庫(kù)
    多引用一個(gè)庫(kù)拟逮,意味著這個(gè)模塊的依賴會(huì)復(fù)雜,從交互稿來(lái)看引入TZStackView是必要的剥槐,RxSwift和SnapKit對(duì)項(xiàng)目有模塊侵入性太強(qiáng)唱歧,直接丟棄宪摧。
  2. 開發(fā)完成之后與主項(xiàng)目的集成是不是有坑(事實(shí)證明坑很大)
    剛開始也認(rèn)為依賴很少坑應(yīng)該比較小粒竖,集成的時(shí)候確實(shí)有大坑,會(huì)面會(huì)講碰到了比較坑的問(wèn)題几于。
  3. 隊(duì)友是否接受這樣開發(fā)蕊苗?
    不接受,按這個(gè)方案做出來(lái)了沿彭,最后并沒(méi)有使用模塊的集成進(jìn)去朽砰。等后期添加完口語(yǔ)題的的時(shí)候依賴就很復(fù)雜了,拆成單獨(dú)的模塊的難度指數(shù)增長(zhǎng)。

實(shí)現(xiàn)模塊的時(shí)候瞧柔,核心的問(wèn)題是如何和主工程進(jìn)行業(yè)務(wù)和數(shù)據(jù)的交互漆弄?先說(shuō)明一個(gè)概念,我們的練習(xí)題的集合是一個(gè)課程造锅,而題目和課程并不是一一對(duì)應(yīng)的撼唾,題目是可以組合的,A課程和B課程都是有可能有相同的題目哥蔚。
所以在結(jié)構(gòu)上大致的想法如圖

Module.002

分成課程和內(nèi)容

課程可以 收藏倒谷,分享,點(diǎn)贊糙箍,打分渤愁,評(píng)價(jià)
內(nèi)容可以閱讀,聽寫深夯,做(練習(xí))抖格,看(視頻)

做題這個(gè)模塊,我劃分的時(shí)候只應(yīng)該包含內(nèi)容部分咕晋,而課程部分屬于業(yè)務(wù)邏輯他挎,不同的App在計(jì)分的業(yè)務(wù)和出題的邏輯是不一樣的。

在這里我定義了一些接口捡需,讓業(yè)務(wù)方的Model實(shí)現(xiàn)這些接口办桨,這樣就有了做題的數(shù)據(jù)源。模塊與業(yè)務(wù)邏輯使用接口來(lái)完成數(shù)據(jù)的轉(zhuǎn)換站辉,當(dāng)子模塊有數(shù)據(jù)返回給業(yè)務(wù)方的時(shí)呢撞,有模塊內(nèi)部拋出一個(gè)對(duì)業(yè)務(wù)方公開的Model。這樣能保證內(nèi)容與業(yè)務(wù)是完全獨(dú)立的饰剥。還有一些小問(wèn)題殊霞,比如一些課程需要的邏輯,做題的流程汰蓉,使用一些通知來(lái)發(fā)出一些事件绷蹲,業(yè)務(wù)邏輯根據(jù)通知來(lái)處理事件。

/// 模塊的接口
/// 選擇題類型
public protocol ExerciseQuestionBody {
    var itemID: Int { get }
    var type: QuestionBodyType { get }
    var content: String { get }
    var imageURL: String { get }
    var audioURL: String { get }
}

///主工程Model
struct Question: ExerciseQuestionBody {
    let itemID: Int
    let type: QuestionBodyType
    let content: String
    let imageURL: String
    let audioURL: String
}

/// 模塊的Model
public struct SpeechAnswer: ExerciseUserSpeech {
    public let score: Float
    public let isCorrect: Bool
}
    
Module.001

上面的圖顾孽,是這種某塊拆分的簡(jiǎn)單依賴關(guān)系祝钢,業(yè)務(wù)方依賴模塊。

總結(jié)

優(yōu)點(diǎn)

  • 可以復(fù)用
  • 方便測(cè)試
  • 開發(fā)過(guò)程愉悅

缺點(diǎn)

  • 在做模塊時(shí)需要考慮的比較完整
  • 集成到業(yè)務(wù)方需要做一些相應(yīng)的對(duì)接

在和App集成的時(shí)候遇到一個(gè)很大坑若厚,因?yàn)槲覀兊膒ods引用了靜態(tài)庫(kù)拦英,!framework就不能使用了,練習(xí)模塊是Swift開發(fā)同時(shí)有一個(gè)音頻庫(kù)的依賴测秸,cocoapods引用音頻播放庫(kù)屬于靜態(tài)庫(kù)疤估,不能被Swift的framework鏈接...
在做了很多嘗試之后使用了比較trick的技巧灾常,把音頻庫(kù)使用做為一個(gè)公共framework,讓pods的Target去搜尋Carthage下是否有這個(gè)Framework铃拇。

修改podSpec钞瀑,讓cocapods的target去查找framework

 s.vendored_frameworks = 'Carthage/Build/iOS/HSAudiomanager.framework'
 s.xcconfig = { 'FRAMEWORK_SEARCH_PATHS' => '$(PROJECT_DIR)/../Carthage/Build/iOS/' }

發(fā)現(xiàn)頁(yè)

discove

當(dāng)練習(xí)沒(méi)有機(jī)會(huì)集成到主項(xiàng)目的時(shí)候,第二個(gè)機(jī)會(huì)來(lái)了慷荔,新版本的發(fā)現(xiàn)頁(yè)仔戈,引用強(qiáng)運(yùn)營(yíng)需求的發(fā)現(xiàn)頁(yè)的設(shè)計(jì)完全脫離了課程的體系,所以完全可以做為一個(gè)單獨(dú)的子模塊去實(shí)現(xiàn)拧廊。

  • 脫離主項(xiàng)目單獨(dú)可以演示
  • 可以給公司其他產(chǎn)品使用
  • 頁(yè)面元素組件化
  • 方便測(cè)試(為什么又提到測(cè)試)

我又有了這些問(wèn)題监徘。

  1. 資源文件問(wèn)題
    子模塊里有自己的Loading,提供給調(diào)用方接口吧碾,去實(shí)現(xiàn)相應(yīng)的樣式凰盔。
  2. 發(fā)現(xiàn)頁(yè)支持上拉加載更多,刷新倦春,這類通用的邏輯是主項(xiàng)目中存在的户敬,是否存在兩套代碼
    存在,因?yàn)槿绻鰹橐粋€(gè)完整的框架睁本,并且這幾個(gè)邏輯屬于必須的業(yè)務(wù)尿庐。
  3. 業(yè)務(wù)方使用發(fā)現(xiàn)頁(yè)這個(gè)框架,如何更方便的定制呢堰,如果有我們寫好的組件是否共享給別人
    我最初的想法就是抄瑟,把發(fā)現(xiàn)頁(yè)的模版單獨(dú)做為業(yè)務(wù)邏輯模塊,業(yè)務(wù)邏輯擁有自己的模版和數(shù)據(jù)適配器枉疼,根據(jù)自己的業(yè)務(wù)定制樣式皮假。在最近的其他產(chǎn)品線使用中,這個(gè)做法是驗(yàn)證可行的骂维。
Module.003

這個(gè)是發(fā)現(xiàn)頁(yè)目前的的結(jié)構(gòu)

因?yàn)橛辛酥暗木毩?xí)碰到的坑惹资,發(fā)現(xiàn)頁(yè)集成時(shí)可以說(shuō)輕車熟路,碰到比較大的坑就是和OC交互的時(shí)候產(chǎn)生了問(wèn)題 Framework 里不能寫bridge橋接航闺,而模版里有一些公共組件時(shí)Objective-C代碼實(shí)現(xiàn)的褪测,在重寫不劃算。所以O(shè)C的代碼做為一個(gè)單獨(dú)的Framework潦刃,在Swift框架只使用 Framwork依賴的方式解決侮措。

Slide 和 泛聽

slide
extensiveListen

Slide 是一個(gè)輕量級(jí)別的PPT,泛聽是音頻播放頁(yè)面
這兩個(gè)模塊并沒(méi)有完全被抽離福铅,因?yàn)橛心K之間的耦合萝毛,Slide的PPT內(nèi)容 和 泛聽在音頻介紹使用了同一個(gè)富文本渲染組件MediaView.

Module.004

那么就成了拆成兩個(gè)模塊 SlideKit 和 ListenKit 兩個(gè)模塊 同時(shí)引用一個(gè)MediaView組件模塊

查詞模塊

查詞屬于一個(gè)比較老的代碼,ListenKit 模塊的拆分的時(shí)候發(fā)現(xiàn)了一些問(wèn)題滑黔,有一些不必要的業(yè)務(wù)依賴笆包,比如網(wǎng)絡(luò)請(qǐng)求是寫在內(nèi)部的,添加的的依賴庫(kù)實(shí)際上只使用了一個(gè)依賴庫(kù)的一個(gè)函數(shù)略荡。

因?yàn)闃I(yè)務(wù)邏輯已經(jīng)成熟庵佣,并且不會(huì)改動(dòng),我做了另一種模塊化嘗試汛兜,使用了依賴注入的方式巴粪,把項(xiàng)目中需要網(wǎng)絡(luò)請(qǐng)求要求外部去實(shí)現(xiàn)。在內(nèi)部有查詞發(fā)音粥谬,發(fā)音的請(qǐng)求不需要通過(guò)驗(yàn)證肛根,所以直接使用最基本URLSession實(shí)現(xiàn)。這樣依賴注入的接口只有查詞請(qǐng)求漏策,和查詞的Model派哲,Model需要注入時(shí)原因是,因?yàn)榭赡懿樵~來(lái)源會(huì)變掺喻,使用統(tǒng)一的借口芭届,只需要適配不同的來(lái)源就可以了。

Module.005

AudioManager

播放器組件感耙,這是一個(gè)服務(wù)模塊褂乍,屬于比較底層服務(wù)。
對(duì)于播放器最早的設(shè)想即硼,給播放器URI就播放逃片。所以早起播放器,只需要URL就可以了只酥。
當(dāng)后期的時(shí)候有了播放列表题诵,就擴(kuò)展支持了播放列表的借口。
播放列表需要包含如果信息层皱,就提供一組播放列表的接口性锭,讓業(yè)務(wù)model去實(shí)現(xiàn)。

Module.006

模塊化探索

上面的幾個(gè)例子叫胖,是我在去年模塊化做的嘗試中的一部分草冈。
目前我們有三種模塊的話的方式

  1. 完全業(yè)務(wù)獨(dú)立,這個(gè)模塊開箱即用瓮增,只需要對(duì)項(xiàng)目的Router配置一下怎棱,就可以自動(dòng)打開。因?yàn)檫@種組件的擴(kuò)展性很低绷跑,所以我并沒(méi)有去嘗試拳恋。大概如下圖的結(jié)構(gòu),其實(shí)等于每個(gè)App里包含了另一個(gè)App砸捏。


    Module.007
  2. 第二種方式類似查詞模塊谬运,提供一組依賴注入的方式隙赁,由App實(shí)現(xiàn),模塊使用時(shí)調(diào)用App的Provieder梆暖,具有定制性伞访,不過(guò)接口會(huì)很多。


    Module.008
  3. 第三種方式轰驳,模塊化和組件分層厚掷,業(yè)務(wù)邏輯應(yīng)當(dāng)是由Component組合成的,Bussiness作為單獨(dú)的一層级解。主App中只包含少量的公工業(yè)務(wù)邏輯冒黑。

Module.009

最后

當(dāng)然還是有第四種方式的,組件化React-Native

待續(xù)...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末勤哗,一起剝皮案震驚了整個(gè)濱河市抡爹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌俺陋,老刑警劉巖豁延,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異腊状,居然都是意外死亡诱咏,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門缴挖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)袋狞,“玉大人,你說(shuō)我怎么就攤上這事映屋」堆欤” “怎么了?”我有些...
    開封第一講書人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵棚点,是天一觀的道長(zhǎng)早处。 經(jīng)常有香客問(wèn)我,道長(zhǎng)瘫析,這世上最難降的妖魔是什么砌梆? 我笑而不...
    開封第一講書人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮贬循,結(jié)果婚禮上咸包,老公的妹妹穿的比我還像新娘。我一直安慰自己杖虾,他們只是感情好烂瘫,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著奇适,像睡著了一般坟比。 火紅的嫁衣襯著肌膚如雪芦鳍。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,598評(píng)論 1 305
  • 那天温算,我揣著相機(jī)與錄音怜校,去河邊找鬼间影。 笑死注竿,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的魂贬。 我是一名探鬼主播巩割,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼付燥!你這毒婦竟也來(lái)了宣谈?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤键科,失蹤者是張志新(化名)和其女友劉穎闻丑,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體勋颖,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡嗦嗡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了饭玲。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片侥祭。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖茄厘,靈堂內(nèi)的尸體忽然破棺而出矮冬,到底是詐尸還是另有隱情,我是刑警寧澤次哈,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布胎署,位于F島的核電站,受9級(jí)特大地震影響窑滞,放射性物質(zhì)發(fā)生泄漏琼牧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一葛假、第九天 我趴在偏房一處隱蔽的房頂上張望障陶。 院中可真熱鬧,春花似錦聊训、人聲如沸抱究。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)鼓寺。三九已至勋拟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間妈候,已是汗流浹背敢靡。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留苦银,地道東北人啸胧。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像幔虏,于是被迫代替她去往敵國(guó)和親纺念。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,147評(píng)論 25 707
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理想括,服務(wù)發(fā)現(xiàn)陷谱,斷路器,智...
    卡卡羅2017閱讀 134,657評(píng)論 18 139
  • 離我們家兩個(gè)胡同的東邊起第二家的那位老人去世了瑟蜈。 早上烟逊,我還沒(méi)起床,就聽見媽在說(shuō)她的花被凍死了和老人不在了铺根。 花我...
    東子金帛閱讀 370評(píng)論 0 1
  • 2號(hào)的我擅長(zhǎng)與別人溝通宪躯,喜歡聊天,講話夷都,是很好的配合與協(xié)調(diào)者^(guò)^ 可是長(zhǎng)期的配合會(huì)失去自我眷唉,沒(méi)有主見;在選擇那方面...
    Sky星紫閱讀 2,026評(píng)論 0 0
  • 日子一天天的過(guò)著 每個(gè)人都在一天天的變化 生理上 心理上 精神上 這種變化 是向積極的方面還是走下坡路呢 高三的時(shí)...
    123女孩閱讀 370評(píng)論 0 1