組件化開發(fā)之-一步一步實(shí)現(xiàn)iOS組件化開發(fā)架構(gòu)(一)

原創(chuàng) 2017-05-25

關(guān)鍵點(diǎn):

  • 組件化框架以及所需技能
  • 驗(yàn)證項(xiàng)目
    • 創(chuàng)建私有Repo
    • 創(chuàng)建工程
    • 創(chuàng)建組件Pod
    • 配置Jenkins-Pipeline
    • 通過fastlane 創(chuàng)建lanes

由于最近在公司要求做關(guān)于組件化開發(fā)的事库倘,索性就將自己如何實(shí)現(xiàn)一步一步的記錄下來蠢壹,這里介紹如何來實(shí)現(xiàn)的缀旁,將會分為幾個階段介紹,現(xiàn)目前介紹第一階段:驗(yàn)證(即驗(yàn)證所需技能细办、Android客戶端和我們實(shí)現(xiàn)的技術(shù)不同時如何找出較優(yōu)方案、如何與后端管理系統(tǒng)配合砌左,后端需要提供哪些能力)住闯,如果有不合理的地方望指點(diǎn)我的郵箱

關(guān)于為什么我們在開發(fā)移動端的時候需要使用到組件化開發(fā)呢拂酣?這里有一些我自己通過別人介紹以及自己在驗(yàn)證組件化開發(fā)時的體會組件化開發(fā)之-我們有什么必要使用組件化開發(fā)秋冰?

我們后臺采用微服務(wù)架構(gòu),有能力為第三方開發(fā)者提供更多的服務(wù)婶熬,但是有時候?yàn)榱诉m應(yīng)業(yè)務(wù)需求的快速變化剑勾,以及部分客戶(如電信埃撵、移動)特殊需求(不能用我們平臺提供的服務(wù)時、不能將數(shù)據(jù)提交至第三方管理平臺等)虽另,這時候別人在開發(fā)自己的后臺時暂刘,也要求我們前端架構(gòu)也能夠考慮到了可擴(kuò)展開發(fā),也就是說要求我們的架構(gòu)需要能夠滿足 插件化開發(fā)(為第三方提供SDK)捂刺,那么為了實(shí)現(xiàn)這些需求我們需要做哪些呢谣拣?

組件化框架以及所需技能

首先簡單介紹一下我們iOS組件化的架構(gòu),如下圖族展,整個架構(gòu)會分為三個階段實(shí)現(xiàn):

  • 實(shí)現(xiàn)基礎(chǔ)及業(yè)務(wù)模塊組件化開發(fā)
  • 封裝Framework及規(guī)范SDK接口文檔
  • 團(tuán)隊(duì)內(nèi)首先使用SDK完成插件化開發(fā)
  • [組件]: 目前我們包含了業(yè)務(wù)組件以及基礎(chǔ)組件森缠。業(yè)務(wù)組件涉及到你所需要完成的某個需求,這里是根據(jù)公司業(yè)務(wù)需求進(jìn)行開發(fā)仪缸;常用的網(wǎng)絡(luò)贵涵,數(shù)據(jù)存儲等我們把它們劃歸到基礎(chǔ)組件中來,但是請你記住一點(diǎn)腹殿,也是很重要的一點(diǎn):基礎(chǔ)組件的開發(fā)應(yīng)該是建立在業(yè)務(wù)需求的基礎(chǔ)之上独悴,任何獨(dú)立開發(fā)出來的基礎(chǔ)組件對于業(yè)務(wù)需求來說并不會起到任何幫助作用,應(yīng)該由業(yè)務(wù)需求指導(dǎo)基礎(chǔ)組件的開發(fā)锣尉,任何獨(dú)立出來的基礎(chǔ)組件應(yīng)該是建立在你需要做的某個功能上,如上圖中提到的網(wǎng)絡(luò)請求决采、藍(lán)牙BLE自沧、MQTT等基礎(chǔ)組件。
  • [私有/公有倉庫]: 團(tuán)隊(duì)協(xié)作開發(fā)時树瞭,我們應(yīng)該也可能是必須使用到的是版本控制工具拇厢。你應(yīng)該從上圖中看到,我們使用到了CocoaPods晒喷,我推薦你使用Git孝偎,當(dāng)然使用SVN也沒有什么問題,但是如果你覺得你寫的公有基礎(chǔ)組件可以為大多數(shù)業(yè)務(wù)需求提供服務(wù)能力凉敲,想通過開源來為大家所使用衣盾,并且也從中找出不足,那么用Git是一個比較好的選擇爷抓。如果你以前使用的是SVN這個版本控制工具势决,而且是經(jīng)常使用命令的方式來使用,相信你可以很快過渡到Git并且熟練使用蓝撇,這里我的另一篇Git基礎(chǔ)果复,就應(yīng)該能夠滿足你創(chuàng)建Pod了。
  • [Pod]:相信你在開發(fā)iOS中也或多或少用過第三方依賴渤昌,也應(yīng)該聽說和使用過CocoaPods虽抄,在我們的組件化架構(gòu)中我們需要使用到該項(xiàng)技能更多一點(diǎn)的東西:組件化開發(fā)之-Cocoapods使用及創(chuàng)建發(fā)布自己的Pod以及組件化開發(fā)之-pod創(chuàng)建規(guī)范走搁,我們需要能夠創(chuàng)建自己的公有Pod 以及私有Pod,使用過Pod之后你會發(fā)現(xiàn)這個第三方依賴管理工具也同樣非常適合用來進(jìn)行組件化以及插件化管理迈窟。
  • [Web后臺管理]:上面架構(gòu)圖的Web管理后臺其實(shí)可以不存在私植,但是為什么這里需要考慮進(jìn)組件開發(fā)框架中呢?我相信你們?nèi)绻翘峁┪⒎?wù)后臺菠隆,那么你肯定遇到過很多需要定制化業(yè)務(wù)需求兵琳,或者你在出售你自己業(yè)務(wù)的時候需要分別為不同用戶定制不同的App,而不是把你所開發(fā)的所有業(yè)務(wù)組件一起打包送你給你的客戶骇径,這個時候你就需要用到后臺管理來根據(jù)不同用戶躯肌,不同權(quán)限,不同選擇構(gòu)建你的移動應(yīng)用破衔。Web后臺管理這里僅僅為移動端提供權(quán)限清女、用戶自定義業(yè)務(wù)、后期用戶開發(fā)的自定義業(yè)務(wù)Pod管理晰筛、自動生成配置文件以及后續(xù)觸發(fā)自動打包功能嫡丙。
  • [Jenkins]:是持續(xù)集成的一個很好引擎,那么我們?yōu)槭裁丛谲浖_發(fā)中實(shí)現(xiàn)持續(xù)集成呢读第?就我現(xiàn)目前了解到發(fā)現(xiàn)曙博,如果我們是團(tuán)隊(duì)開發(fā)來完成某一下工作,那么我們就存在多次提交代碼怜瞒,提交之后需要快速的驗(yàn)證修改父泳,我們不能每次提交一個就自己去為App打一次包交由測試團(tuán)隊(duì)來測試吧。而且有時候我們一個需求開發(fā)完成我們遇到特殊情況需要快速上線呢吴汪?Agile教給了我們做出來的東西需要是MVP(這里不是你王者榮耀游戲中的那個最屌的隊(duì)友惠窄,也不是美國職業(yè)籃球聯(lián)賽最有價值球員獎,而是最小可運(yùn)行版本)漾橙,其中有一個步驟需要我們使用工具來實(shí)現(xiàn)杆融,這時候我們就用到了Jenkins,我的另一片文章寫了關(guān)于如何使用:組件化開發(fā)之-基于Jenkins搭建iOS持續(xù)集成開發(fā)環(huán)境霜运。
  • [SDK/Framework]:要實(shí)現(xiàn)插件化開發(fā)以及平臺管理脾歇,那么你肯定得為第三方開發(fā)者提供一個可快速實(shí)現(xiàn)的框架以及規(guī)范吧,上圖中提到的開發(fā)業(yè)務(wù)組件/基礎(chǔ)組件就是我們?yōu)榈谌介_發(fā)公司提供的一些可以快速使用的Framework和能夠快速接入平臺的SDK觉渴,以及一些開發(fā)規(guī)范介劫,只要按照這個開發(fā)規(guī)范來進(jìn)行,那么你的需求就可以在原有的基礎(chǔ)之上實(shí)現(xiàn)特殊需求的業(yè)務(wù)案淋,并且快速集成發(fā)布你的版本座韵。
  • [第三方開發(fā)]:你只需要按照上述提到的開發(fā)規(guī)范進(jìn)行開即可,開發(fā)完成后的業(yè)務(wù)組件有兩種方式快速接入到平臺:一種是你可以將你的業(yè)務(wù)組件直接上傳或者打包成Framework,并且通過Pod方式提交到我們鎖提供的私有Pod倉庫誉碴,同時在我們的后臺按照規(guī)范提交你的組件模塊宦棺;另一種方式是可能你不喜歡讓別人看到你的代碼(即使是你的合作者),那么你可以提交到你自己的私有倉庫并且創(chuàng)建好你的Private Pod黔帕,告訴平臺你的倉庫地址即可代咸。至于剩下的事情就交于平臺處理吧,你將會比你完全構(gòu)建一個App花費(fèi)更少的時間成黄。

要實(shí)現(xiàn)插件化是需要建立在組件化的基礎(chǔ)之上的呐芥,這一階段我們只講述關(guān)于組件化開發(fā)相關(guān)的框架及技術(shù),在組件化成型并穩(wěn)定的情況再來考慮插件化開發(fā)奋岁。以下是我們實(shí)現(xiàn)整個框架的腦圖(現(xiàn)階段我們只做圖中右半部分):

驗(yàn)證項(xiàng)目

上述章節(jié)已經(jīng)提到了我們需要做的事以及需要了解的技術(shù)思瘟,以及我們?nèi)绾畏蛛A段實(shí)現(xiàn),這里就不廢話了闻伶,直接開始創(chuàng)建一個驗(yàn)證項(xiàng)目滨攻。

創(chuàng)建私有Repo

現(xiàn)在我們添加自己私有倉庫就算成功了蓝翰, 接下來就是需要來創(chuàng)建自己的工程光绕。

創(chuàng)建工程

由于這里是驗(yàn)證工程,我們就將工程命名為VerifyProject吧畜份,同樣也需要在Github上創(chuàng)建工程的倉庫(因?yàn)槲覀兒笃谛枰ㄟ^Jenkins自動下載代碼進(jìn)行配置并構(gòu)建)

  • 創(chuàng)建項(xiàng)目Repository

  • 將Repository拉取下來并且通過XCode創(chuàng)建工程VerifyProject

  • 創(chuàng)建配置文件Config以及Config.swift
    ???其實(shí)我們可以在后續(xù)通過Jenkins-Pipeline 腳本動態(tài)創(chuàng)建這兩個文件的诞帐,但是這里為什么需要首先創(chuàng)建呢?一個原因是:整項(xiàng)目是由哪些組件構(gòu)建而成是動態(tài)的爆雹,我們需要根據(jù)Web管理后臺的配置來修改配置文件景埃、我們主模塊的顯示以及修改Podfile。還有一個更重要的原因是:我們知道如果你在項(xiàng)目中動態(tài)添加任何文件顶别,XCode是無法將其打包到你的項(xiàng)目中的,因?yàn)槟悴]有指定它這些新創(chuàng)建的文件是需要編譯的拒啰,當(dāng)然也有大神提出了解決方案的使用代碼為 Xcode 工程添加文件驯绎,略微有點(diǎn)麻煩,我們這里是驗(yàn)證工程谋旦,就先跑起來再說剩失,在后階段慢慢完善。
    創(chuàng)建完成后册着,你的項(xiàng)目看起來應(yīng)該是這樣的:

  • 初始化你的Podfile拴孤,這個時候請你記住不需要在Podfile添加任何依賴


    現(xiàn)在你的工程創(chuàng)建也已經(jīng)完成了,現(xiàn)在提交到Github倉庫甲捏,它看起來應(yīng)該是:

創(chuàng)建組件Pod

接下來就是創(chuàng)建你的組件Pod了演熟,在創(chuàng)建組件Pod的時候我建議參考組件化開發(fā)之-pod創(chuàng)建規(guī)范(這僅僅是一個簡單的規(guī)范,適合小項(xiàng)目) 。這里我們創(chuàng)建5個組件模塊稱之為:VerifyA芒粹、VerifyB兄纺、VerifyC、VerifyD化漆、VerifyE估脆,創(chuàng)建方式是相同的,我以VerifyA為例座云。

  • 在Github上創(chuàng)建Repository
  • 創(chuàng)建Example疙赠,假設(shè)我們采用的是MVVM開發(fā)模式,創(chuàng)建好之后在UIViewcontroller中添加簡單代碼即可朦拖,最后看起來應(yīng)該是:
  • 創(chuàng)建.podspec圃阳,并且創(chuàng)建Pod/Classes目錄,將Example的View贞谓、ViewModel限佩、Model拷貝至Classes目錄
$ pod spec create Verify+A

最后你的目錄結(jié)構(gòu)看起來應(yīng)該是:

  • 修改.podspec


  • 本地驗(yàn)證.podspec是否正確

$ pod lib lint
  • 提交到Github,并遠(yuǎn)程驗(yàn)證裸弦,按照下列步驟需要首先提交Git祟同,然后添加Tag
$ git add .
$ git commit -m "添加Pod"
$ git push

# 添加Tag
$ git tag 0.0.1  # 這里需要與你.podspec中 s.version相同
$ git push --tags

# 驗(yàn)證
$ pod spec lint 

-> Verify+A (0.0.1)

Analyzed 1 podspec.

Verify+A.podspec passed validation.

  • 添加Pod到你私有的Repo中
$ pod repo push Verify Verify+A.podspec  

Validating spec
 -> Verify+A (0.0.1)

Updating the `Verify' repo

Already up-to-date.

Adding the spec to the `Verify' repo

 - [No change] Verify+A (0.0.1)

Pushing the `Verify' repo

Username for 'https://github.com': wangcccong@foxmail.com
Password for 'https://wangcccong@foxmail.com@github.com':
To https://github.com/ApterKingRepo/Specs.git
   ea61c37..3df4c78  master -> master
  • 試試搜索你的Pod
$ pod search Verify+A 

-> Verify+A (0.0.1)
  業(yè)務(wù)組件A
  pod 'Verify+A', '~> 0.0.1'
   - Homepage: https://github.com/ApterKingRepo/Verify-A
   - Source:   https://github.com/ApterKingRepo/Verify-A.git
   - Versions: 0.0.1 [Verify repo]
  • 現(xiàn)在你可以使用了瞧剖,請記住在你的Podfile中添加你Private Pod 源
source 'https://github.com/CocoaPods/Specs'
source 'https://github.com/ApterKingRepo/Specs.git'  
platform :ios, "9.0"  
target "XXX" do  
  pod 'Verify+A', '~>0.0.1'  
end
  • 按照上述方法創(chuàng)建你的其他組件运嗜,最后創(chuàng)建成功之后,在你的Specs中斑鸦,看到的應(yīng)該是這樣

配置Jenkins-Pipeline

在使用Jenkins之前你需要去了解fastlane如何使用窖贤。我的另一篇文章有一個簡單介紹:組件化開發(fā)之-基于Jenkins搭建iOS持續(xù)集成開發(fā)環(huán)境砖顷,但是更多更詳細(xì)功能還請你移步fastlane docs

  • New Item 創(chuàng)建一個Pipeline


  • 配置Pipeline General


  • 配置Pipeline Triggers
    ???我們選擇帶參數(shù)的遠(yuǎn)程觸發(fā)赃梧,從下圖的提示中我們可以看到滤蝠,你只需要訪問JENKINS_URL/job/iOS/job/Verify/build?token=TOKEN_NAME 既可以觸發(fā)了,如果你帶有參數(shù)再添加即可...?token=token&module=A,B,D

  • 配置Pipeline


    由于在配置Pipeline script時授嘀,我們需要依賴于fastlane物咳,我們這里就先說一說在Pipeline中需要的幾個Stage (這里只以簡單的介紹,其他更多單元測試蹄皱、功能測試等览闰,在后面階段再來詳細(xì)介紹),注意從Jenkins2.5以后Pipeline腳本支持兩種方式巷折,新的一種方式是創(chuàng)建一個Jenkinsfile压鉴,然后再來寫你的腳本,最好的方式是參考官方文檔Pipeline Syntax锻拘,已經(jīng)很詳細(xì)介紹了油吭,在這里我就不細(xì)說了。

# 偽代碼
pipeline {
    enviroment {
      環(huán)境變量
    }
    parameters {
      參數(shù)配置
    }
    stages('配置項(xiàng)目') {
       stage('拉取原始項(xiàng)目')
      stage('寫入配置文件')
      stage('配置Podfile')
      stage('引入模塊')
      stage('構(gòu)建項(xiàng)目')
      stage('部署到蒲公英')
    }
    post {
      failure { 
        hook_failure   #通知管理后臺,構(gòu)建失敗上鞠,重新構(gòu)建
      }
      success {
        hook_success  # 通知管理后臺际邻,構(gòu)建成功,用戶可以直接去下載
      }
    }
}

通過fastlane 創(chuàng)建lanes

  • 創(chuàng)建你的fastlane
    這里需要你進(jìn)入我們之前創(chuàng)建的VerifyProject項(xiàng)目中芍阎,然后初始化fastlane
$ cd VerifyProject
$ fastlane init

如果是第一次使用fastlane init世曾,你需要按照提示信息輸入你的Apple ID 以及密碼,后面的事情就交給fastlane創(chuàng)建就可以了谴咸。但是有時候你會發(fā)現(xiàn)如果你已經(jīng)使用過了fastlane init之后轮听,并且這時候如果你的Apple ID的密碼改變了,該怎么辦呢岭佳? fastlane tool chains 提供了一個工具credentials_manager血巍, 這時候你只需要刪除保存的密碼:

$ fastlane fastlane-credentials remove --username xxx@xxx.com
password has been deleted.

現(xiàn)在你可以直接執(zhí)行你的fastlane init 了,如果你想要在執(zhí)行時不需要輸入密碼珊随,你可以:

 $ fastlane fastlane-credentials add --username xxx@xxx.com
Password: *********
Credential xxx@xxx.com:********* added to keychain.

成功之后你會看到如下信息

+----------------+-----------------------------+
|          Summary for produce 2.35.0          |
+----------------+-----------------------------+
| app_name       | VerifyProject               |
| app_identifier | com.ApterKing.VerifyProject |
| username       | xxxxxx@xxx.com              |
| sku            | 1495690xx                   |
| platform       | ios                         |
| language       | English                     |
| skip_itc       | false                       |
| skip_devcenter | false                       |
| team_id        | FJAP4H992E                  |
+----------------+-----------------------------+
  • 創(chuàng)建你的Gemfile述寡,你需要用到fastlane哪些工具集,如我現(xiàn)在的如下:
source 'https://gems.ruby-china.org/'

gem 'fastlane', '2.35.0'
gem 'gym'
gem 'xcov'
gem 'cocoapods', '1.2.1'
gem 'xcpretty'
gem 'dotenv'

  • 創(chuàng)建一些環(huán)境配置App.env
# 項(xiàng)目相關(guān)
FL_PROJECT_PATH = "./VerifyProject.xcodeproj"
FL_WORKSPACE_PATH = "./VerifyProject.xcworkspace"
FL_SCHEME = "VerifyProject"

# 輸出目錄
FL_OUTPUT_ROOT_DIRECTORY = "./fastlane_build"

# 蒲公英
FL_PGYER_USER_KEY = "6fe2235f85a756314753774cee5fb164"
FL_PGYER_API_KEY = "43ce06e684f029fe3ec64a436c2a5c15"
  • 修改Fastfile叶洞,創(chuàng)建lanes鲫凶,我主要有:
    ???在創(chuàng)建lane config_generate、config_pod這幾個模塊中我們需要用到shell腳本衩辟,你可以從這里去了解一下基礎(chǔ)的shell腳本寫法:Shell 教程
// 進(jìn)入到fastlane目錄下
$ bundle exec fastlane lanes
--------- ios---------
----- fastlane ios config_generate
生成配置文件
Usage: bundle exec fastlane ios config_generate param:[數(shù)據(jù)/URL等]

----- fastlane ios config_pod
配置Podfile
Usage: bundle exec fastlane ios config_pod

----- fastlane ios build
構(gòu)建項(xiàng)目
Usage: bundle exec fastlane ios build config:[Debug/Release]

----- fastlane ios deploy
部署到蒲公英
Usage: bundle exec fastlane ios deploy config:[Debug/Release]
  • 準(zhǔn)備工作已經(jīng)做好螟炫,還記得我們前面提到的Pipeline script是使用偽代碼表示的嗎?現(xiàn)在我們需要來完善它艺晴,以下是我寫的:
pipeline {
  agent any   // 你也可以使用 agent {label 'mac_for_iOS'}

  environment {
    BASH_PROFILE = '~/.bashrc'
  }

  stages {
    stage('拉取項(xiàng)目') {
      steps {
        git 'https://github.com/ApterKingRepo/VerifyProject.git'
      }
    }

    stage('生成配置文件') {
      steps {
        dir('./VerifyProject/fastlane') {
          sh "bundle exec fastlane ios config_generate param:'${params.module}'"
        }
      }
    }

    stage('配置Podfile') {
      steps {
        dir('./VerifyProject/fastlane') {
          sh 'bundle exec fastlane ios config_pod'
        }
      }
    }

    stage('構(gòu)建項(xiàng)目') {
      steps {
        dir('./VerifyProject/fastlane') {
          sh 'bundle exec fastlane ios build config:Debug'
        }
      }
    }

    stage('部署項(xiàng)目') {
      steps {
        dir('./VerifyProject/fastlane') {
          sh 'bundle exec fastlane ios deploy config:Debug'
        }
      }
    }
  }

  post {
    failure {
      echo '構(gòu)建失敗,你可以調(diào)用遠(yuǎn)程通知昼钻,或者發(fā)送一個Email'
    }

    success {
      echo '構(gòu)建成功,你可以調(diào)用遠(yuǎn)程通知,或者發(fā)送一個Email'
    }
  }
}
  • 最后你需要來觸發(fā)你的Pipeline了封寞,由于我們現(xiàn)在是測試然评,沒有與Web端鏈接,但是也能夠模擬遠(yuǎn)程傳遞參數(shù)觸發(fā):

  • 最后你想到的應(yīng)該是Build就ok 了對吧狈究?那么你應(yīng)該是想錯了沾瓦,你會看到的是:



    各種錯誤,也不要擔(dān)心谦炒,慢慢修改即可,最后你總會看到構(gòu)建成功风喇,我將這個整個的構(gòu)建過程發(fā)布到了Github上了宁改, 你可以從:

  • Verify 私有Repo

  • VerifyProject 源碼

  • 業(yè)務(wù)組件A

  • 業(yè)務(wù)組件B
    ...

你可以講代碼下載來自己照著做一遍,應(yīng)該就會比較熟悉整個流程魂莫,這里面的代碼還沒有考慮到如何進(jìn)行業(yè)務(wù)組件間的調(diào)用还蹲,我將在下一階段來介紹
** 這里也有一點(diǎn)公有Pod代碼,你也可以來看看:**

最后你會發(fā)現(xiàn):最快熟悉的方式應(yīng)該是自己做一遍,你會發(fā)現(xiàn)里面有很多坑谜喊,踩多了你也就會了潭兽。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市斗遏,隨后出現(xiàn)的幾起案子山卦,更是在濱河造成了極大的恐慌,老刑警劉巖诵次,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件账蓉,死亡現(xiàn)場離奇詭異,居然都是意外死亡逾一,警方通過查閱死者的電腦和手機(jī)铸本,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來遵堵,“玉大人箱玷,你說我怎么就攤上這事∧八蓿” “怎么了锡足?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長限番。 經(jīng)常有香客問我舱污,道長,這世上最難降的妖魔是什么弥虐? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任扩灯,我火速辦了婚禮,結(jié)果婚禮上霜瘪,老公的妹妹穿的比我還像新娘珠插。我一直安慰自己,他們只是感情好颖对,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布捻撑。 她就那樣靜靜地躺著,像睡著了一般缤底。 火紅的嫁衣襯著肌膚如雪顾患。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天个唧,我揣著相機(jī)與錄音江解,去河邊找鬼。 笑死徙歼,一個胖子當(dāng)著我的面吹牛犁河,可吹牛的內(nèi)容都是我干的鳖枕。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼桨螺,長吁一口氣:“原來是場噩夢啊……” “哼宾符!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起灭翔,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤魏烫,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后缠局,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體则奥,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年狭园,在試婚紗的時候發(fā)現(xiàn)自己被綠了读处。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡唱矛,死狀恐怖罚舱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情绎谦,我是刑警寧澤管闷,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站窃肠,受9級特大地震影響包个,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜冤留,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一碧囊、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧纤怒,春花似錦糯而、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至烘豹,卻和暖如春瓜贾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背携悯。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工阐虚, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蚌卤。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓实束,卻偏偏與公主長得像,于是被迫代替她去往敵國和親逊彭。 傳聞我的和親對象是個殘疾皇子咸灿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評論 2 354

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