自定义podspec, cocoapods助力组件化

这一阵子搞模块化开发,碰到了好多问题,刚腾出时间总结、分享一下。

为什么最后敲定选用cocoapods来进行模块化开发呢

因为我不会用linux 命令去改xcode的buildSettings,当然,如果有会的留言或者私信告诉我,不胜感激……报酬是你出花生我出酒,聚在一起喝两口 PS:本人不敢喝酒哈~

最好的学习cocoapods当然是到官网了 https://cocoapods.org/。 从安装到使用都比较全面,当然在安装或者使用过程中,如果有问题,那就谷歌百度,各种谷歌百度各种的有解决方法。本文通过podspec文件的编写,讲述如何使用cocoapods实现模块化开发。

一说到要自己创建pod管理,一谷歌百度就是

pod trunk push NAME.podspec

很多都纠结在

cd ~/code/Pods/NAME
pod lib lint

这里不用纠结了,为啥呢?因为你在做项目呢,你肯定不能公开你的东西,项目都是存放在自己git服务器上了。当然以后肯定要 pod trunk push 上去的,因为开源一直都是我力赞的……

创建过程详见官网Making a CocoaPod

这里我们根据资源的存放位置分为三种:

  • public server (比如gitHub,谁都能看到)
  • private server (自己的git服务器了,自己和管理员能看见)
  • local (存在本地磁盘的一个角落里,自己偷着看)

通过podspec我们来分析具体的实现,首先到我们对应的模块文件夹下创建一个podspec,名字呢,我建议跟你的模块名字一样,你要不一样倒也无妨反正。看看我们这个模块的文件夹目录结构,podspec按照这个结构去写的,当然怎么写那都无所谓啊,看个人喜好,下面的目录结构只是用来举栗子的,下面我举个栗子:

ZuiyeModule 有这么个模块,结构如下

模块结构.jpg

各种各样的文件是吧,尽可能的全乎,在命令行里先进到ZuiyeModule这个目录下,创建一个podspec

pod spec create ZuiyeModule

该文件夹下就创建了一个这样的podspec文件

zmspec.png

我们打开看一下

open ZuiyeModule.podspec 

内如如下

#
#  Be sure to run `pod spec lint ZuiyeModule.podspec' to ensure this is a
#  valid spec and to remove all comments including this before submitting the spec.
#
#  To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html
#  To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/
#

Pod::Spec.new do |s|

  # ―――  Spec Metadata  ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  These will help people to find your library, and whilst it
  #  can feel like a chore to fill in it's definitely to your advantage. The
  #  summary should be tweet-length, and the description more in depth.
  #

  s.name         = "ZuiyeModule"
  s.version      = "0.0.1"
  s.summary      = "A short description of ZuiyeModule."

  # This description is used to generate tags and improve search results.
  #   * Think: What does it do? Why did you write it? What is the focus?
  #   * Try to keep it short, snappy and to the point.
  #   * Write the description between the DESC delimiters below.
  #   * Finally, don't worry about the indent, CocoaPods strips it!
  s.description  = <<-DESC
                   DESC

  s.homepage     = "http://EXAMPLE/ZuiyeModule"
  # s.screenshots  = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif"


  # ―――  Spec License  ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  Licensing your code is important. See http://choosealicense.com for more info.
  #  CocoaPods will detect a license file if there is a named LICENSE*
  #  Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'.
  #

  s.license      = "MIT (example)"
  # s.license      = { :type => "MIT", :file => "FILE_LICENSE" }


  # ――― Author Metadata  ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  Specify the authors of the library, with email addresses. Email addresses
  #  of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also
  #  accepts just a name if you'd rather not provide an email address.
  #
  #  Specify a social_media_url where others can refer to, for example a twitter
  #  profile URL.
  #

  s.author             = { "yuhailong" => "714387953@qq.com" }
  # Or just: s.author    = "yuhailong"
  # s.authors            = { "yuhailong" => "714387953@qq.com" }
  # s.social_media_url   = "http://twitter.com/yuhailong"

  # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  If this Pod runs only on iOS or OS X, then specify the platform and
  #  the deployment target. You can optionally include the target after the platform.
  #

  # s.platform     = :ios
  # s.platform     = :ios, "5.0"

  #  When using multiple platforms
  # s.ios.deployment_target = "5.0"
  # s.osx.deployment_target = "10.7"
  # s.watchos.deployment_target = "2.0"
  # s.tvos.deployment_target = "9.0"


  # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  Specify the location from where the source should be retrieved.
  #  Supports git, hg, bzr, svn and HTTP.
  #

  s.source       = { :git => "http://EXAMPLE/ZuiyeModule.git", :tag => "#{s.version}" }


  # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  CocoaPods is smart about how it includes source code. For source files
  #  giving a folder will include any swift, h, m, mm, c & cpp files.
  #  For header files it will include any header in the folder.
  #  Not including the public_header_files will make all headers public.
  #

  s.source_files  = "Classes", "Classes/**/*.{h,m}"
  s.exclude_files = "Classes/Exclude"

  # s.public_header_files = "Classes/**/*.h"


  # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  A list of resources included with the Pod. These are copied into the
  #  target bundle with a build phase script. Anything else will be cleaned.
  #  You can preserve files from being cleaned, please don't preserve
  #  non-essential files like tests, examples and documentation.
  #

  # s.resource  = "icon.png"
  # s.resources = "Resources/*.png"

  # s.preserve_paths = "FilesToSave", "MoreFilesToSave"


  # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  Link your library with frameworks, or libraries. Libraries do not include
  #  the lib prefix of their name.
  #

  # s.framework  = "SomeFramework"
  # s.frameworks = "SomeFramework", "AnotherFramework"

  # s.library   = "iconv"
  # s.libraries = "iconv", "xml2"


  # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  If your library depends on compiler flags you can set them in the xcconfig hash
  #  where they will only apply to your library. If you depend on other Podspecs
  #  you can include multiple dependencies to ensure it works.

  # s.requires_arc = true

  # s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" }
  # s.dependency "JSONKit", "~> 1.4"

end


我们看一下都需要配置哪些参数,没加#注释的都是必要的字段


s.name         = "ZuiyeModule"
s.version      = "0.0.1"
s.summary      = "A short description of ZuiyeModule."

name、version、summary这个比较直观哈


  s.description  = <<-DESC
                   DESC

描述,在DESC中间写,比如

 s.description  = <<-DESC
          这个是我测试的,这个模块主要实现自定义功能
                   DESC

s.homepage     = "http://EXAMPLE/ZuiyeModule"

主页么,没要求,随便写,但也别太随便了,最好是当前模块在git的主页(如果你是本地的pod类库,那这个也没有用)


 s.license      = "MIT (example)"

如果你在gitHub上创建项目这个是必选的

license.png
 s.license      = "MIT"

s.author             = { "yuhailong" => "714387953@qq.com" }

作者: 嘴爷


 # s.platform     = :ios, "8.0"

平台:IOS 最低版本:8.0


# deployment_target或者s.platform不开启,那在使用的时候会有arc问题(后续podspec文件中设置只支持arc)
 # 比如__weak不能使用
 
 #  When using multiple platforms
 # s.ios.deployment_target = "5.0"
 # s.osx.deployment_target = "10.7"
 # s.watchos.deployment_target = "2.0"
 # s.tvos.deployment_target = "9.0"
 

部署版本

deployment_target或者s.platform不开启,那在使用的时候会有arc问题(后续podspec文件中设置只支持arc) 比如__weak不能使用,
设置了 s.platform 后,这个可以不用管


s.source       = { :git => "http://EXAMPLE/ZuiyeModule.git", :tag => "#{s.version}" }

资源的git 地址,四种写法,喜欢哪种随意

# source的写法可以参照下面的写法
#pod 'VenderName', :git => 'https://github.com/zuiye/ZuiyeSDK.git', :tag => '0.7.0'
#pod 'VenderName', :git => 'https://github.com/zuiye/ZuiyeSDK.git', :branch => 'develop'
#pod 'VenderName', :git => 'https://github.com/zuiye/ZuiyeSDK.git', :commit => '082f8319af'
# 当引用本地的时候这个参数就没有用了
  s.source       = { :git => "local" }

s.source_files  = "Classes", "Classes/**/*.{h,m}"

代码文件,Classes 文件夹,/**/表示文件夹下的所有文件和文件夹, *.{h,m,mm} 表匹配该文件夹下的所有.h .m .mm文件,多个文件路径用逗号分开

# 所有需要引用的文件都要添加进来 /**/表示所有文件夹 *.{文件后缀}代表所有符合后缀名的文件
  s.source_files  = "Classes", "Classes/**/*.{h,m,mm}", "Resources/**/*.{h,m,mm}"

# s.resource  = "icon.png"
  # s.resources = "Resources/*.png"

资源文件,我理解的是除了代码之外的所有文件.asset .a .framework. .xib .storyboard等等

# png,xib,bundle 等必须当资源文件去添加  framework,a 不能引用,否则打包之后体积将包含该整个a文件
  s.resource  = 'Resources/**/*.{png,xib,bundle,xcassets}'
  # s.resources = "Resources/*.png"

当然我们在写代码的时候也不方便去吧xib跟关联的类分开,所以我们可以把资源文件跟类文件放一起,把 Resources 文件夹换成 Classes 文件夹就好了

s.resource  = 'Classes/**/*.{png,xib,bundle,xcassets}'


# s.preserve_paths = "FilesToSave", "MoreFilesToSave"

framework要加preserve_paths 预加载路径

# framework要加preserve_paths 预加载路径
  s.preserve_paths = "Resources/**/*.{framework,a}"

# s.framework  = "SomeFramework"
# s.frameworks = "SomeFramework", "AnotherFramework"

# s.library   = "iconv"
# s.libraries = "iconv", "xml2"

以上要注意多个framework或者library用逗号分开就行,这个是系统的,如果是三方的framework 或者 library呢

# ――― Linking 相关参数说明―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #

  # s.libraries  表示这个pod依赖的 苹果官方的库,也就是类似libstdc++.a ,libsqlite.a 等等的a文件;
  # s.vendored_libraries 就表示用户自己的a文件,比如新浪微博SDK的libWeiboSDK.a, 微信libWeChatSDK.a;
  # s.frameworks 表示pod依赖的 苹果的framework, 比如 UIKit,SystemConfiguration等等
  # s.vendored_frameworks, 表示pod依赖的自己的framework,比如QQSDK的TencentOpenAPI.framework,JSPatch热更新JSPatchPlatform.framework;
  # .a 或者 libz.tbd 后缀不要,名字里lib开头的三个字母不要,libz.tbd 应写成 'z'

# ――― Linking 相关参数说明 ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #

针对本模块的写法示例

 # s.library   = 'z'
  s.libraries =  'iconv','sqlite3','stdc++','z'

  s.vendored_libraries  = 'Resources/lib/**/*.{a}'
  s.vendored_frameworks = 'Resources/Framework/**/*.{framework}'

# s.requires_arc = true

ARC


#s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SRCROOT)/usr/include/libxml2" }
#s.xcconfig = { 'LIBRARY_SEARCH_PATHS' => '"$(PODS_ROOT)/xxx/xxx"' }
#s.xcconfig = { "FRAMEWORK_SEARCH_PATHS" => "Resources/Framework" }

这个配制想必大家在没用pod的时候,引入三方的时候,多多少少都要改点


# s.dependency "JSONKit", "~> 1.4"

依赖,可以依赖本地写法就好比podFile中的写法,多个依赖,那就多写几行

s.dependency "JSONKit", "~> 1.4"
s.dependency 'BaseModel', :path => 'BaseProject/BaseModel'

因为有依赖了,所以AFNetworking、SDWebImage什么的可以不用写的podFile里了

podFile中的写法

# ―――  PodFile 中的写法可以如下 ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
#组件通信  如果提交到spec仓库,并审核通过
#pod 'CTMediator', '~> 0.0.3'

# 以下所有的spec文件都没有提交到spec仓库
#首页   代码在git上
#pod 'EHomePage', :git =>  'https://github.com/yhl714387953/EHomePage.git'

#首页使用本地代码   git上有相关的代码  这里用的绝对路径,不建议,可仿如下用相对路径
#pod 'EHomePage', :podspec => '~/Desktop/EHomePage/EHomePage.podspec'

#首页使用本地代码  代码只在本地了,文件路径可以直接简写成PodFile所在文件夹之后的路径
#pod 'BaseModel', :path => 'BaseProject/BaseModel'
# ―――  PodFile 中的写法可以如上 ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #

我们podspec写完了,执行下

pod update --no-repo-update
addNewModule.png

我们看看项目里的结构

在Pods中的显示.png

如果文件夹里少了个某个文件夹,是因为那个文件夹里没有东西。

新添加的 ZuiyeModelDevelopment Pods 文件夹下了,如果你觉得写的麻烦,那就按我的文件目录放置,podspec 文件内容都复制过去然后改个s.name 就行了

s.name         = "自己的模块名字"

现成的大鱼在下面了(podspec 内容)

# ―――  PodFile 中的写法可以如下 ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
#组件通信  如果提交到spec仓库,并审核通过
#pod 'CTMediator', '~> 0.0.3'

# 以下所有的spec文件都没有提交到spec仓库
#首页   代码在git上
#pod 'EHomePage', :git =>  'https://github.com/yhl714387953/EHomePage.git'

#首页使用本地代码   git上有相关的代码  这里用的绝对路径,不建议,可仿如下用相对路径
#pod 'EHomePage', :podspec => '~/Desktop/EHomePage/EHomePage.podspec'

#首页使用本地代码  代码只在本地了,文件路径可以直接简写成PodFile所在文件夹之后的路径
#pod 'BaseModel', :path => 'BaseProject/BaseModel'
# ―――  PodFile 中的写法可以如上 ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #


#
#  Be sure to run `pod spec lint JSPatchModule.podspec' to ensure this is a
#  valid spec and to remove all comments including this before submitting the spec.
#
#  To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html
#  To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/
#

Pod::Spec.new do |s|

  # ―――  Spec Metadata  ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  These will help people to find your library, and whilst it
  #  can feel like a chore to fill in it's definitely to your advantage. The
  #  summary should be tweet-length, and the description more in depth.
  #

  s.name         = "ZuiyeModule"
  s.version      = "1.0.0"
  s.summary      = "测试资源文件,png、 xib、 bundle、 a、 framework"

  # This description is used to generate tags and improve search results.
  #   * Think: What does it do? Why did you write it? What is the focus?
  #   * Try to keep it short, snappy and to the point.
  #   * Write the description between the DESC delimiters below.
  #   * Finally, don't worry about the indent, CocoaPods strips it!
  s.description  = <<-DESC
                      测试资源文件
                   DESC

  s.homepage     = "www.zuiye.com"
  # s.screenshots  = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif"


  # ―――  Spec License  ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  Licensing your code is important. See http://choosealicense.com for more info.
  #  CocoaPods will detect a license file if there is a named LICENSE*
  #  Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'.
  #

  s.license      = "MIT"
  # s.license      = { :type => "MIT", :file => "FILE_LICENSE" }


  # ――― Author Metadata  ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  Specify the authors of the library, with email addresses. Email addresses
  #  of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also
  #  accepts just a name if you'd rather not provide an email address.
  #
  #  Specify a social_media_url where others can refer to, for example a twitter
  #  profile URL.
  #

  s.author             = { "yuhailong" => "714387953@qq.com" }
  # Or just: s.author    = "yuhailong"
  # s.authors            = { "yuhailong" => "714387953@qq.com" }
  # s.social_media_url   = "http://twitter.com/yuhailong"

  # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  If this Pod runs only on iOS or OS X, then specify the platform and
  #  the deployment target. You can optionally include the target after the platform.
  #

  s.platform     = :ios
  s.platform     = :ios, "8.0"

  #  When using multiple platforms
  # s.ios.deployment_target = "5.0"
  # s.osx.deployment_target = "10.7"
  # s.watchos.deployment_target = "2.0"
  # s.tvos.deployment_target = "9.0"


  # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  Specify the location from where the source should be retrieved.
  #  Supports git, hg, bzr, svn and HTTP.
  #

# source的写法可以参照下面的写法
#pod 'VenderName', :git => 'https://github.com/zuiye/ZuiyeSDK.git', :tag => '0.7.0'
#pod 'VenderName', :git => 'https://github.com/zuiye/ZuiyeSDK.git', :branch => 'develop'
#pod 'VenderName', :git => 'https://github.com/zuiye/ZuiyeSDK.git', :commit => '082f8319af'
# 当引用本地的时候这个参数就没有用了
  s.source       = { :git => "local" }


  # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  CocoaPods is smart about how it includes source code. For source files
  #  giving a folder will include any swift, h, m, mm, c & cpp files.
  #  For header files it will include any header in the folder.
  #  Not including the public_header_files will make all headers public.
  #
  # 所有需要引用的文件都要添加进来 /**/表示所有文件夹 *.{文件后缀}代表所有符合后缀名的文件
  s.source_files  = "Classes", "Classes/**/*.{h,m,mm}", "Resources/**/*.{h,m,mm}"
  #s.exclude_files = "Classes/Exclude"

  # s.public_header_files = "Classes/**/*.h"


  # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  A list of resources included with the Pod. These are copied into the
  #  target bundle with a build phase script. Anything else will be cleaned.
  #  You can preserve files from being cleaned, please don't preserve
  #  non-essential files like tests, examples and documentation.
  #

  # s.resource  ="Classes/View/JSTableView.xib"
  #s.resource  = ['Classes/**/*.png','Classes/View/*.xib']

  # png,xib,bundle 等必须当资源文件去添加  framework,a 不能引用,否则打包之后体积将包含该整个a文件
  s.resource  = 'Resources/**/*.{png,xib,bundle,xcassets}'
  # s.resources = "Resources/*.png"

# framework 要加preserve_paths 预加载路径
  s.preserve_paths = "Resources/**/*.{framework,a}"


  # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  Link your library with frameworks, or libraries. Libraries do not include
  #  the lib prefix of their name.
  #

  #s.framework  = 'JavaScriptCore'
  s.frameworks = 'SystemConfiguration','CoreGraphics','CoreTelephony','Security','CoreLocation','JavaScriptCore'
  
  # s.library   = 'z'
  s.libraries =  'iconv','sqlite3','stdc++','z'

  s.vendored_libraries  = 'Resources/lib/**/*.{a}'
  s.vendored_frameworks = 'Resources/Framework/**/*.{framework}'

  # ――― Linking 相关参数说明―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #

  # s.libraries  表示这个pod依赖的 苹果官方的库,也就是类似libstdc++.a ,libsqlite.a 等等的a文件;
  # s.vendored_libraries 就表示用户自己的a文件,比如新浪微博SDK的libWeiboSDK.a ;
  # s.frameworks 表示pod依赖的 苹果的framework, 比如 UIKit,SystemConfiguration等等
  # s.vendored_frameworks, 表示pod依赖的自己的framework,比如QQSDK的TencentOpenAPI.framework;
  # .a 或者 libz.tbd 后缀不要,名字里lib开头的三个字母不要,libz.tbd 应写成 'z'

  # ――― Linking 相关参数说明 ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #


  # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  If your library depends on compiler flags you can set them in the xcconfig hash
  #  where they will only apply to your library. If you depend on other Podspecs
  #  you can include multiple dependencies to ensure it works.

  s.requires_arc = true

  #s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SRCROOT)/usr/include/libxml2" }
  #s.xcconfig = { 'LIBRARY_SEARCH_PATHS' => '"$(PODS_ROOT)/xxx/xxx"' }
  #s.xcconfig = { "FRAMEWORK_SEARCH_PATHS" => "Resources/Framework" }
  # s.dependency "JSONKit", "~> 1.4"

end


感谢您阅读完毕,如有疑问,欢迎添加QQ:714387953(蜗牛上高速)。
github:https://github.com/yhl714387953/SpecModule
如果有错误,欢迎指正,一起切磋,共同进步
如果喜欢可以Follow、Star、Fork,都是给我最大的鼓励

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,417评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,921评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,850评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,945评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,069评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,188评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,239评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,994评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,409评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,735评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,898评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,578评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,205评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,916评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,156评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,722评论 2 363
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,781评论 2 351

推荐阅读更多精彩内容