iOS組件化(上篇)- 拆分基礎(chǔ)組件

修改說(shuō)明:有朋友反映Xcode9編譯RAC4.x失敗,無(wú)法設(shè)置Use Legacy Swift Language Version 的問(wèn)題】既螅現(xiàn)在將RAC版本改成了2.5(OC版本)庆聘。感謝朋友們的反饋铜犬。git clone 之后執(zhí)行pod install即可匣掸。不用再設(shè)置UseLegacySwiftLanguage Version霸琴。

? ? ? 組件化在業(yè)界已經(jīng)炒的水深火熱播聪,關(guān)于組件化的好處和組件化的方案網(wǎng)上已經(jīng)有大篇的文章了朽基。(Casa的這篇文章對(duì)幾種方案的利弊講述的很不錯(cuò))筆者就不在贅述了。筆者通過(guò)拆分一個(gè)現(xiàn)有的demo來(lái)簡(jiǎn)單聊一下項(xiàng)目實(shí)施組件化的過(guò)程(將分為上篇离陶、中篇稼虎、下三篇)。

iOS組件化(上篇)- 拆分基礎(chǔ)組件

iOS組件化(中篇)-拆分業(yè)務(wù)組件

iOS組件化(下篇)-加載XIB招刨、圖片資源



## 一霎俩、Demo簡(jiǎn)要說(shuō)明


demo可以從github下載(下載之后執(zhí)行pod install ), 因?yàn)橹坝肦AC+MVVM寫(xiě)項(xiàng)目,這里用了RAC4.x沉眶。pod install之后需要修改一下ReactiveCocoaResult的UseLegacySwiftLanguage Version 為YES打却。按照下面的方式解決即可:

修改Result
修改ReactiveCocoa

設(shè)置好之后編譯運(yùn)行就ok了。(接口不太穩(wěn)定谎倔,第一次運(yùn)行可能沒(méi)數(shù)據(jù)柳击,再運(yùn)行一次就ok了)

demo采用了“去model化”的設(shè)計(jì),關(guān)于“去model化”的優(yōu)勢(shì)《去model化和數(shù)據(jù)對(duì)象》講述的很清楚片习。

以下內(nèi)容摘自《iOS應(yīng)用架構(gòu)談 網(wǎng)絡(luò)層設(shè)計(jì)方案》


交付什么樣的數(shù)據(jù)給業(yè)務(wù)層捌肴?

我見(jiàn)過(guò)非常多的App的網(wǎng)絡(luò)層在拿到JSON數(shù)據(jù)之后槽地,會(huì)將數(shù)據(jù)轉(zhuǎn)變成對(duì)應(yīng)的對(duì)象原型阻逮。注意牢硅,我這里指的不是NSDictionary萝映,而是類(lèi)似Item這樣的對(duì)象。這種做法是能夠提高后續(xù)操作代碼的可讀性的殴穴。在比較直覺(jué)的思路里面,是需要這部分轉(zhuǎn)化過(guò)程的,但這部分轉(zhuǎn)化過(guò)程的成本是很大的卦碾,主要成本在于:

數(shù)組內(nèi)容的轉(zhuǎn)化成本較高:數(shù)組里面每項(xiàng)都要轉(zhuǎn)化成Item對(duì)象,如果Item對(duì)象中還有類(lèi)似數(shù)組起宽,就很頭疼洲胖。轉(zhuǎn)化之后的數(shù)據(jù)在大部分情況是不能直接被展示的,為了能夠被展示坯沪,還需要第二次轉(zhuǎn)化绿映。只有在API返回的數(shù)據(jù)高度標(biāo)準(zhǔn)化時(shí),這些對(duì)象原型(Item)的可復(fù)用程度才高,否則容易出現(xiàn)類(lèi)型爆炸叉弦,提高維護(hù)成本丐一。

調(diào)試時(shí)通過(guò)對(duì)象原型查看數(shù)據(jù)內(nèi)容不如直接通過(guò)NSDictionary/NSArray直觀(guān)。

同一API的數(shù)據(jù)被不同View展示時(shí)淹冰,難以控制數(shù)據(jù)轉(zhuǎn)化的代碼库车,它們有可能會(huì)散落在任何需要的地方。

其實(shí)我們的理想情況是希望API的數(shù)據(jù)下發(fā)之后就能夠直接被View所展示樱拴。首先要說(shuō)的是柠衍,這種情況非常少。另外晶乔,這種做法使得View和API聯(lián)系緊密珍坊,也是我們不希望發(fā)生的。

在設(shè)計(jì)安居客的網(wǎng)絡(luò)層數(shù)據(jù)交付這部分時(shí)正罢,我添加了reformer(名字而已阵漏,叫什么都好)這個(gè)對(duì)象用于封裝數(shù)據(jù)轉(zhuǎn)化的邏輯,這個(gè)對(duì)象是一個(gè)獨(dú)立對(duì)象腺怯,事實(shí)上袱饭,它是作為Adaptor模式存在的。我們可以這么理解:想象一下我們洗澡時(shí)候使用的蓮蓬頭呛占,水管里出來(lái)的水是API下發(fā)的原始數(shù)據(jù)虑乖。reformer就是蓮蓬頭上的不同水流擋板,需要什么模式晾虑,就撥到什么模式疹味。


以下內(nèi)容摘自《iOS應(yīng)用架構(gòu)談 組件化方案》


組件化方案中的去model設(shè)計(jì)

組件間調(diào)用時(shí),是需要針對(duì)參數(shù)做去model化的帜篇。如果組件間調(diào)用不對(duì)參數(shù)做去model化的設(shè)計(jì)糙捺,就會(huì)導(dǎo)致業(yè)務(wù)形式上被組件化了,實(shí)質(zhì)上依然沒(méi)有被獨(dú)立笙隙。

假設(shè)模塊A和模塊B之間采用model化的方案去調(diào)用洪灯,那么調(diào)用方法時(shí)傳遞的參數(shù)就會(huì)是一個(gè)對(duì)象。

如果對(duì)象不是一個(gè)面向接口的通用對(duì)象竟痰,那么mediator的參數(shù)處理就會(huì)非常復(fù)雜签钩,因?yàn)橐獏^(qū)分不同的對(duì)象類(lèi)型。如果mediator不處理參數(shù)坏快,直接將對(duì)象以范型的方式轉(zhuǎn)交給模塊B铅檩,那么模塊B必然要包含對(duì)象類(lèi)型的聲明。假設(shè)對(duì)象聲明放在模塊A莽鸿,那么B和A之間的組件化只是個(gè)形式主義昧旨。如果對(duì)象類(lèi)型聲明放在mediator拾给,那么對(duì)于B而言,就不得不依賴(lài)mediator兔沃。但是蒋得,大家可以從上面的架構(gòu)圖中看到,對(duì)于響應(yīng)請(qǐng)求的模塊而言粘拾,依賴(lài)mediator并不是必要條件窄锅,因此這種依賴(lài)是完全不需要的,這種依賴(lài)的存在對(duì)于架構(gòu)整體而言缰雇,是一種污染入偷。

如果參數(shù)是一個(gè)面向接口的對(duì)象,那么mediator對(duì)于這種參數(shù)的處理其實(shí)就沒(méi)必要了械哟,更多的是直接轉(zhuǎn)給響應(yīng)方的模塊疏之。而且接口的定義就不可能放在發(fā)起方的模塊中了,只能放在mediator中暇咆。響應(yīng)方如果要完成響應(yīng)锋爪,就也必須要依賴(lài)mediator,然而前面我已經(jīng)說(shuō)過(guò)爸业,響應(yīng)方對(duì)于mediator的依賴(lài)是不必要的其骄,因此參數(shù)其實(shí)也并不適合以面向接口的對(duì)象的方式去傳遞。

因此扯旷,使用對(duì)象化的參數(shù)無(wú)論是否面向接口拯爽,帶來(lái)的結(jié)果就是業(yè)務(wù)模塊形式上是被組件化了,但實(shí)質(zhì)上依然沒(méi)有被獨(dú)立钧忽。

在這種跨模塊場(chǎng)景中毯炮,參數(shù)最好還是以“去model化”的方式去傳遞,在iOS的開(kāi)發(fā)中耸黑,就是以字典的方式去傳遞桃煎。這樣就能夠做到只有調(diào)用方依賴(lài)mediator,而響應(yīng)方不需要依賴(lài)mediator大刊。然而在去model化的實(shí)踐中为迈,由于這種方式自由度太大,我們至少需要保證調(diào)用方生成的參數(shù)能夠被響應(yīng)方理解缺菌,然而在組件化場(chǎng)景中曲尸,限制去model化方案的自由度的手段,相比于網(wǎng)絡(luò)層和持久層更加容易得多男翰。

因?yàn)榻M件化天然具備了限制手段:參數(shù)不對(duì)就無(wú)法調(diào)用!無(wú)法調(diào)用時(shí)直接debug就能很快找到原因纽乱。


本文中demo的大致結(jié)構(gòu)如下:

項(xiàng)目初始結(jié)構(gòu)

將一個(gè)項(xiàng)目組件化拆分掉蛾绎,一般會(huì)拆分一些基礎(chǔ)組件、一些功能組件和業(yè)務(wù)組件。將拆分好的組件放到遠(yuǎn)程倉(cāng)庫(kù)租冠,統(tǒng)一通過(guò)Cocoapods進(jìn)行管理鹏倘。



## 二、 幾個(gè)基本概念


當(dāng)然顽爹,要實(shí)現(xiàn)這個(gè)管理的過(guò)程纤泵,有一些概念還是必須知道的。

概念圖

如上圖所示: 遠(yuǎn)程索引庫(kù)镜粤、本地索引庫(kù)捏题、遠(yuǎn)程代碼庫(kù)、本地代碼庫(kù)肉渴。筆者通過(guò)拆分demo 中的一個(gè)category的基礎(chǔ)組件說(shuō)明上面的四個(gè)概念公荧。



## 三、實(shí)踐


第一步:基礎(chǔ)組件Category

一同规、遠(yuǎn)程索引庫(kù)

什么是遠(yuǎn)程索引庫(kù)循狰?

? ? ? ? 每創(chuàng)建一個(gè)組件都會(huì)帶有一個(gè) xxx.podspec 的索引文件。專(zhuān)門(mén)用來(lái)存放這些索引文件的庫(kù)就叫做索引庫(kù)券勺。我們需要將這些索引文件上傳到遠(yuǎn)程索引庫(kù)才能保證其他的同事能夠拿來(lái)用绪钥。

創(chuàng)建遠(yuǎn)程索引庫(kù)( 注:這里是在github上創(chuàng)建了一個(gè)public的organization名字叫FFComponent)筆者這里創(chuàng)建的public的,自己公司的項(xiàng)目創(chuàng)建private的私有索引庫(kù)即可关炼,私有索引的步驟和pubic的操作方式一樣

FFSpecs索引庫(kù)

遠(yuǎn)程索引庫(kù)已經(jīng)創(chuàng)建成功程腹,可以看到遠(yuǎn)程索引庫(kù)的地址

索引庫(kù)地址

二、 本地索引庫(kù) (本地索引庫(kù)就是用來(lái)存放本地索引文件的庫(kù))

1. 打開(kāi)終端 pod repo 查看一下當(dāng)前有哪些本地索引庫(kù)(如果你之前沒(méi)有創(chuàng)建過(guò)盗扒,應(yīng)該只有一個(gè)master)

pod repo查看本地索引庫(kù)

2. 通過(guò)pod repo add <本地索引庫(kù)的名字>? <遠(yuǎn)程索引庫(kù)的地址> 跪楞,創(chuàng)建本地索引庫(kù)并和遠(yuǎn)程索引庫(kù)做關(guān)聯(lián)(注:本地索引庫(kù)的名字建議和遠(yuǎn)程索引庫(kù)起的名字一樣)

命令

3. 通過(guò)下面的方式可以查看本地索引庫(kù)的物理地址

物理地址

三、遠(yuǎn)程代碼庫(kù) (代碼實(shí)際存放的遠(yuǎn)程倉(cāng)庫(kù))

創(chuàng)建遠(yuǎn)程代碼倉(cāng)庫(kù)(和創(chuàng)建遠(yuǎn)程索引庫(kù)的方式一樣)侣灶,創(chuàng)建一個(gè)FFCategoryKit的遠(yuǎn)程代碼庫(kù)甸祭,用來(lái)存放FFCategory組件的代碼。同樣獲取到FFCategoryKit組件的遠(yuǎn)程代碼庫(kù)地址褥影。

FFCategory組件
遠(yuǎn)程代碼庫(kù)地址

四池户、本地代碼庫(kù)

創(chuàng)建FFCategoryKit組件本地代碼庫(kù)

1. pod lib create <組件名>? 創(chuàng)建本地代碼組件模版庫(kù)(根據(jù)自身需求對(duì)下面的提示信息做選擇就好)

2. 編譯swift版本錯(cuò)誤解決,修改一下ReactiveCocoa和Result的UseLegacySwiftLanguage Version 為YES凡怎。

UseLegacySwiftLanguageVersion 為YES

3 .編譯運(yùn)行通過(guò)看下效果校焦。接著把FlowerField_Component 里的Others路徑下的文件夾拖入到組件FFCategoryKit的classes路徑下。

4. 接著cd到Example下進(jìn)行pod install (把剛才拖入到classes里的文件夾pod進(jìn)來(lái))

5. 編譯組件看是否報(bào)錯(cuò)统倒,編譯通過(guò)后需要修改podspecs索引文件寨典,一般需要修改下面幾個(gè)問(wèn)題。

a. 修改版本號(hào)

b. 修改項(xiàng)目的簡(jiǎn)單概述和詳細(xì)描述

c. 修改homepage和source地址

d. 添加依賴(lài)庫(kù)

修改前的狀態(tài)如下圖所示:

修改前的狀態(tài)

修改對(duì)應(yīng)的地方即可

修改后如下:

podspec修改后

6. 編譯運(yùn)行通過(guò)后房匆,提交組件到遠(yuǎn)程代碼庫(kù)并打tag.


-? git add .

- git commit -m “xxx"

- git remote add origin 遠(yuǎn)程代碼倉(cāng)庫(kù)地址

- git push origin master

- git tag 版本號(hào) (注:這里的版本號(hào)必須和podspec里寫(xiě)的版本號(hào)一致)

- git push --tags


7.? 接下來(lái)可以驗(yàn)證podspec索引文件是否正確

首先耸成,通過(guò)pod lib lint FFCategoryKit.podspec --verbose --allow-warnings 驗(yàn)證本地索引文件是否正確

也可以略過(guò)本地驗(yàn)證

直接通過(guò)pod spec lint --verbose --allow-warnings 命令驗(yàn)證podspec索引文件(既驗(yàn)證本地同時(shí)驗(yàn)證遠(yuǎn)程的podspec)

這個(gè)命令是驗(yàn)證遠(yuǎn)程podspec是否正確报亩,就是驗(yàn)證提交到代碼倉(cāng)庫(kù)里的podspec是否正確

--verbose 是為了打印更加詳細(xì)的信息方便查看

有時(shí)會(huì)遇到這樣的錯(cuò)誤

驗(yàn)證時(shí)發(fā)現(xiàn)`source_files`匹配不到文件

此時(shí),去遠(yuǎn)程代碼庫(kù)看看對(duì)應(yīng)的Classes是否為空


圖片發(fā)自簡(jiǎn)書(shū)App



錯(cuò)誤說(shuō)明:如果遇到下面的錯(cuò)誤井氢,就按照提示在終端輸入`echo "2.3" > .swift-version`弦追,然后在繼續(xù)驗(yàn)證,驗(yàn)證通過(guò)后再通過(guò) pod repo push 提交到遠(yuǎn)程索引倉(cāng)庫(kù)花竞,如果沒(méi)有遇到該問(wèn)題自動(dòng)略過(guò).

錯(cuò)誤

8. 驗(yàn)證通過(guò)后劲件,pod repo push <本地索引庫(kù)> <索引文件名> - -verbose - -allow-warnings 提交索引文件到遠(yuǎn)程索引庫(kù)。

本地也可以查看已成功

9. 接下來(lái)回到FlowerField_Component工程修改podfile文件,把FFCategoryKit組件pod進(jìn)來(lái)(:需要在Podfile中指定組件遠(yuǎn)程索引庫(kù)地址约急,如果不指定默認(rèn)會(huì)從master的索引庫(kù)查找就會(huì)報(bào)找不到組件)

Podfile文件修改如下 :

執(zhí)行pod install零远,按照上面同樣的方式修改一下ReactiveCocoa和Result的UseLegacySwiftLanguage Version 成YES

同樣在項(xiàng)目查看已經(jīng)pod進(jìn)來(lái)了。

10. 編譯運(yùn)行如下


第二步:基礎(chǔ)組件APIs

? ? ? ? 對(duì)項(xiàng)目FlowerField_Component中Others下的APIs實(shí)施組件化烤宙,因?yàn)锳PIs組件中會(huì)依賴(lài)AFN框架遍烦,所以這里會(huì)說(shuō)明一下。按照和FFCategoryKit組件同樣的方式來(lái)創(chuàng)建APIs組件對(duì)應(yīng)的遠(yuǎn)程代碼庫(kù)躺枕,本地代碼模版庫(kù)服猪,索引庫(kù)就不用創(chuàng)建了。

1. FFAPIs組件遠(yuǎn)程代碼庫(kù)和本地代碼模版庫(kù)

FFAPIs組件遠(yuǎn)程代碼庫(kù)
本地代碼模版庫(kù)

2. 同樣將APIs文件夾拖入到FFAPIsKit下的classes下面拐云。因?yàn)锳PIs中的NetworkHelper類(lèi)依賴(lài)AFN框架罢猪,所以需要修改podspec索引文件,修改如下:

3. 回到Example進(jìn)行pod install, 編譯運(yùn)行通過(guò)后進(jìn)行提交組件到遠(yuǎn)程代碼庫(kù)叉瘩。按照同樣的方式打好tag膳帕,驗(yàn)證podspec并提交索引文件。然后在本地索引庫(kù)查看發(fā)現(xiàn)FFAPIsKit組件已經(jīng)完成了薇缅。

4. 最后危彩,同樣回到FlowerField_Component修改Podfile后pod install。修改ReactiveCocoa和Result的UseLegacySwiftLanguage Version 為YES后編譯運(yùn)行泳桦。

5. 采用同樣的方式對(duì)configs汤徽、reformerKeys、tools灸撰、mainView進(jìn)行組件化谒府,創(chuàng)建組件FFConfigsKit、FFReformerKeysKit浮毯、FFToolsKit完疫、FFMainViewKit。

說(shuō)明:FFToolsKit 依賴(lài)MBProgressHUD庫(kù)债蓝; 別忘記在對(duì)應(yīng)的podspec索引文件中添加依賴(lài)庫(kù)壳鹤。

6. 基礎(chǔ)組件化結(jié)束之后,F(xiàn)lowerField_Component中Podfile如下:

FlowerField_Component的Podfile

首先感謝您能堅(jiān)持聽(tīng)我啰嗦到這里饰迹。到這里上篇就結(jié)束了器虾。后兩篇將陸續(xù)更新出來(lái)讯嫂。項(xiàng)目組件化過(guò)程中一定也會(huì)遇到各樣的問(wèn)題。歡迎大家留言交流互相學(xué)習(xí)兆沙。我的郵箱 jiajung@aliyun.com? 也歡迎大家Emial交流。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末莉掂,一起剝皮案震驚了整個(gè)濱河市葛圃,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌憎妙,老刑警劉巖库正,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異厘唾,居然都是意外死亡褥符,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)抚垃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)喷楣,“玉大人,你說(shuō)我怎么就攤上這事鹤树∠澈福” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵罕伯,是天一觀(guān)的道長(zhǎng)曲伊。 經(jīng)常有香客問(wèn)我,道長(zhǎng)追他,這世上最難降的妖魔是什么坟募? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮邑狸,結(jié)果婚禮上懈糯,老公的妹妹穿的比我還像新娘。我一直安慰自己推溃,他們只是感情好昂利,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著铁坎,像睡著了一般蜂奸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上硬萍,一...
    開(kāi)封第一講書(shū)人閱讀 51,692評(píng)論 1 305
  • 那天扩所,我揣著相機(jī)與錄音,去河邊找鬼朴乖。 笑死祖屏,一個(gè)胖子當(dāng)著我的面吹牛助赞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播袁勺,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼雹食,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了期丰?” 一聲冷哼從身側(cè)響起群叶,我...
    開(kāi)封第一講書(shū)人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎钝荡,沒(méi)想到半個(gè)月后街立,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡埠通,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年赎离,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片端辱。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡梁剔,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出掠手,到底是詐尸還是另有隱情憾朴,我是刑警寧澤,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布喷鸽,位于F島的核電站众雷,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏做祝。R本人自食惡果不足惜砾省,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望混槐。 院中可真熱鬧编兄,春花似錦、人聲如沸声登。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)悯嗓。三九已至件舵,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間脯厨,已是汗流浹背铅祸。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人临梗。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓涡扼,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親盟庞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子吃沪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

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