關(guān)于 iOS 批量打包的總結(jié)

關(guān)于 iOS 自動(dòng)化打包的一點(diǎn)看法

如果你曾經(jīng)試過做多 target 的項(xiàng)目,到了測(cè)試人員要測(cè)試包的時(shí)候,你就會(huì)明白什么叫“生不如死”。雖然 Xcode 打包很方便,但是當(dāng)你機(jī)械重復(fù)打 N 次包的時(shí)候,就會(huì)覺得這純粹是浪費(fèi)時(shí)間的工作。所以這時(shí)候自動(dòng)化打包就顯得尤為重要(其實(shí)就算只有一個(gè) target,就算使用 Xcode 打包很方便,也應(yīng)該構(gòu)建自動(dòng)化打包,因?yàn)槟憧梢怨?jié)省大量時(shí)間)。

構(gòu)建自動(dòng)化打包腳本

xcodebuild

使用 xcodebuild -h 來看看 xcodebuild 到底是干啥的

Usage: xcodebuild [-project <projectname>] [[-target <targetname>]...|-alltargets] [-configuration <configurationname>] [-arch <architecture>]... [-sdk [<sdkname>|<sdkpath>]] [-showBuildSettings] [<buildsetting>=<value>]... [<buildaction>]...
       xcodebuild [-project <projectname>] -scheme <schemeName> [-destination <destinationspecifier>]... [-configuration <configurationname>] [-arch <architecture>]... [-sdk [<sdkname>|<sdkpath>]] [-showBuildSettings] [<buildsetting>=<value>]... [<buildaction>]...
       xcodebuild -workspace <workspacename> -scheme <schemeName> [-destination <destinationspecifier>]... [-configuration <configurationname>] [-arch <architecture>]... [-sdk [<sdkname>|<sdkpath>]] [-showBuildSettings] [<buildsetting>=<value>]... [<buildaction>]...
       xcodebuild -version [-sdk [<sdkfullpath>|<sdkname>] [<infoitem>] ]
       xcodebuild -list [[-project <projectname>]|[-workspace <workspacename>]] [-json]
       xcodebuild -showsdks
       xcodebuild -exportArchive -archivePath <xcarchivepath> -exportPath <destinationpath> -exportOptionsPlist <plistpath>
       xcodebuild -exportLocalizations -localizationPath <path> -project <projectname> [-exportLanguage <targetlanguage>...]
       xcodebuild -importLocalizations -localizationPath <path> -project <projectname>

這里我只截取了 usage 部分,option 部分太多沒有截取。

這里介紹幾條畢竟常用的命令

1. xcodebuild -list ...

xcodebuild -list [[-project <projectname>]|[-workspace <workspacename>]] [-json]

usage: 輸出 project 中的 targets 和 configurations,或者 workspace 中 schemes。
-project-workspace 是輸出指定內(nèi)容,不輸入默認(rèn)輸出當(dāng)前目錄下。-json 是以 json 格式輸出。

example:

$ xcodebuild -list
Information about project "XX":
    Targets:
        XX
        XXTests

    Build Configurations:
        Debug
        Release

    If no build configuration is specified and -scheme is not passed then "Release" is used.

    Schemes:
        XX

2. xcodebuild -project ...

xcodebuild [-project <projectname>] [[-target <targetname>]...|-alltargets] [-configuration <configurationname>] [-arch <architecture>]... [-sdk [<sdkname>|<sdkpath>]] [-showBuildSettings] [<buildsetting>=<value>]... [<buildaction>]...

usage:

-project: 指定 project 名字,默認(rèn)首個(gè) project。

-target: 指定對(duì)應(yīng)的 target ,默認(rèn)首個(gè) target。

-configuration: 選擇Debug 或 Release,默認(rèn) Release,當(dāng)然如果你有自定義的配置的,就應(yīng)該選你配置的,上面 -list 中有輸出。

-showBuildSettings: 顯示工程的配置。

<buildsetting>=<value>: 修改工程的配置文件。

buildaction ... : 如下,默認(rèn)為 build

          Specify a build action (or actions) to perform on the target.
          Available build actions are:

          build       Build the target in the build root (SYMROOT).  This is
                      the default build action.

          installsrc  Copy the source of the project to the source root
                      (SRCROOT).

          install     Build the target and install it into the target's
                      installation directory in the distribution root
                      (DSTROOT).

          clean       Remove build products and intermediate files from the
                      build root (SYMROOT).

example:

  • $ xcodebuild -project 你的項(xiàng)目名字.xcodeproj -target 你的 target 名字 -configuration release

這行命令表示編譯 xx.xcodeproj 的 xx target。在 terminal 中會(huì)看到編譯過程,如果成功最后會(huì)輸出 ** BUILD SUCCEEDED **。最后會(huì)在當(dāng)前目錄下生成 build/Release-iphoneos/xx.app

  • $ xcodebuild -project 你的項(xiàng)目名字.xcodeproj -target 你的 target 名字 -configuration release -showBuildSettings

這行命令使用 -showBuildSettings 是不會(huì) build 項(xiàng)目的,只是輸出工程的配置。這里輸出的的內(nèi)容有(內(nèi)容過多,只截取部分)

Build settings for action build and target XX:
    ACTION = build
    AD_HOC_CODE_SIGNING_ALLOWED = NO
    ALTERNATE_GROUP = staff
    ALTERNATE_MODE = u+w,go-w,a+rX
    ALTERNATE_OWNER = TsuiYuenHong
    ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO
    ALWAYS_SEARCH_USER_PATHS = NO
    ALWAYS_USE_SEPARATE_HEADERMAPS = NO
    APPLE_INTERNAL_DEVELOPER_DIR = /AppleInternal/Developer
    APPLE_INTERNAL_DIR = /AppleInternal
    APPLE_INTERNAL_DOCUMENTATION_DIR = /AppleInternal/Documentation
    APPLE_INTERNAL_LIBRARY_DIR = /AppleInternal/Library
    APPLE_INTERNAL_TOOLS = /AppleInternal/Developer/Tools
    APPLICATION_EXTENSION_API_ONLY = NO
    APPLY_RULES_IN_COPY_FILES = NO
    ARCHS = armv7 arm64
    ...

如果要修改配置文件,就直接最命令最后加上你要修改的內(nèi)容。
例如在這行命令最后加上指定證書

  • $ xcodebuild -project 你的項(xiàng)目名字.xcodeproj -target 你的 target 名字 -configuration release PROVISIONING_PROFILE="你證書的id"

其中的字段是上面 -showBuildSettings 顯示的字段,也可以看官網(wǎng)介紹

3. xcodebuild -workspace ...

xcodebuild -workspace <workspacename> -scheme <schemeName> [-destination <destinationspecifier>]... [-configuration <configurationname>] [-arch <architecture>]... [-sdk [<sdkname>|<sdkpath>]] [-showBuildSettings] [<buildsetting>=<value>]... [<buildaction>]...

除了 workspace 和 scheme 之外其余選項(xiàng)都和上條命令相同。

-workspace: 指定 workspace 名字,默認(rèn)首個(gè) workspace

-scheme: 指定對(duì)應(yīng)的 scheme ,默認(rèn)首個(gè) scheme

4 . xcodebuild -exportArchive ...

這里順便介紹一下 archive 命令,因?yàn)樵谙旅媸褂?PackageApplication 會(huì)出一個(gè)警告說推薦使用 -exportArchive。所以我們就來嘗試一下使用 archive 來生成 app。

首先使用一下命令來生成 .xcarchive 文件
xcodebuild archive -workspace xx.xcworkspace -scheme xx -archivePath xx.xcarchive
可以看出添加上 archive 命令和最后加入 -archivePath 生成archivePath的路徑即可。
然后該路徑下會(huì)生成一個(gè) xx.archivePath,里面包括三個(gè)文件,xx.app.dsym文件(可用于bugly等監(jiān)控bug的平臺(tái)),info.plist(保存打包的一些信息),還有我們的 xx.app 文件。

其次使用 -exportArchive 生成 ipa 包

xcodebuild -exportArchive -archivePath xx.xcarchive -exportPath xx -exportFormat ipa

-archivePath: xx.archivePath 的路徑

-exportPath: 輸出路徑

-exportFormat: 生成類型,這里選擇我們需要的 ipa

這樣就利用我們的 xcodebuild 命令來生成 ipa 包

xcrun

這里也使用 xcrun 來生成 ipa 包即可

xcrun -sdk iphoneos PackageApplication build/Release-iphoneos/xx.app -o ~/Desktop/xx.ipa

但是,在 macos10.12 和 Xcode8 的環(huán)境下會(huì)出現(xiàn)一個(gè)警告

warning: PackageApplication is deprecated, use xcodebuild -exportArchive instead.

說明 PackageApplication 已經(jīng)被棄用了。

不過其實(shí)這一步可以幾乎等價(jià)于將 xx.app 放入一個(gè) payload 的文件夾下然后壓縮文件夾為 xx.ipa,當(dāng)然這樣做缺失一些信息,不過并不影響程序的運(yùn)行。

初步小結(jié)

綜上,我們有兩種方法來生成我們需要的 ipa 包。

  1. 使用 xcodebuild 命令來編譯我們的項(xiàng)目生成 app,然后再用 xcrun 將 app 轉(zhuǎn) ipa。
  2. 使用 xcodebuild archive 命令來直接生成我們需要的 ipa。

雖然現(xiàn)在網(wǎng)上幾乎都是使用 xcodebuild + xcrun 來來生成 ipa 包,不過既然官方說 PackageApplication is deprecated,那還是推薦使用第二種方法,一步到位。

自動(dòng)化打包正式開始

這里從我工作室的一個(gè)項(xiàng)目切入,這個(gè)項(xiàng)目需要最終生成 18 個(gè) ipa 包,但是他們幾乎是共用一套代碼的,不同的地方在于bundleName/bundleDisplayName/bundleid 等,以及一些資源文件的不同,例如 icon 等。所以可想而知如果選擇手動(dòng)打包的痛苦,并且當(dāng)你打包到一半發(fā)現(xiàn)某個(gè)地方錯(cuò)了要重新打包 ......

這里說一下自動(dòng)化打包1.0解決思路:

  1. 使用命令 defaults write 來修改項(xiàng)目中的 plist 文件,來達(dá)到修改 bundleName/bundleDisplayName/bundleid... 的目的。
  2. 使用命令 cp 來替換資源文件。
  3. 使用 xcodebuild -workspace .. 編譯出 app 包。
  4. 使用 xcrun ... 生成 ipa 。

這是我最開始想到的思路,最終運(yùn)行時(shí)間大概為每個(gè)包2.5m(時(shí)間主要浪費(fèi)在編譯),然后一套下來也要半個(gè)多小時(shí)。雖然比起手動(dòng)打快了不少,但還是太慢了。畢竟自動(dòng)化的目的不僅僅是自動(dòng),還要速度。

既然問題出在編譯上,那我的思路就往編譯一次多次使用這個(gè)方向上面思考。然后想到了既然只是資源文件和plist的不同,沒有涉及到代碼的更換(不過這個(gè)項(xiàng)目后期不同 app 會(huì)執(zhí)行不同一套代碼,不過也有解決辦法),這里就出現(xiàn)了自動(dòng)化打包2.0的版本。

  1. 使用 xcodebuild -workspace .. 編譯出 app 包。
  2. 使用命令 defaults write 來修改項(xiàng)目中的 plist 文件,來達(dá)到修改 bundleName/bundleDisplayName/bundleid... 的目的。
  3. 使用命令 cp 來替換資源文件。
  4. 重簽名 codesign -f -s "iPhone Distribution: xx co., LTD" --entitlements $Entitlements $ipaPath/Payload/YouXiaoYun.app
  5. 使用 xcrun ... 生成 ipa 。

和1.0大致相似,不過并不是每次生成 ipa 都需要編譯一次。而是編譯一次,然后直接修改 app 下內(nèi)容,不過這里會(huì)出現(xiàn)簽名錯(cuò)誤的問題,因?yàn)樵诰幾g的最后會(huì)用證書幫 app 簽名,如果你直接替換資源然后就生成 ipa 的話會(huì)導(dǎo)致 ipa 無法安裝。

那這時(shí)候神奇的重簽名技術(shù)就出來(重簽名用在正途上的真少見...hhhh,關(guān)于重簽名的文章 google 一下就會(huì)很多),使用 codesign 命令就可以幫修改過資源的 app 重簽名。
最終使用2.0的時(shí)間基本是在5-6分鐘左右。果然能機(jī)器完成的工作絕對(duì)不要手動(dòng)完成,從半天到30分鐘到最后的6分鐘,節(jié)省下來的時(shí)間可以讓你學(xué)習(xí)到更多。

上面說到如果不同 app 間會(huì)用到不同的代碼。例如 app A 里面的 title 叫 A 部門,app B 里面 title 又叫 B 部門,這樣就不會(huì)通過命令行直接修改到代碼,不過我想到的是維護(hù)一個(gè) plist 文件,plist 文件可以這樣設(shè)計(jì)的,每個(gè)不同 app 的 bundleName 都設(shè)置字典的鍵,然后字典下就可以是你自定義的內(nèi)容。然后每次啟動(dòng) app 就根據(jù) bundleName 來尋找對(duì)應(yīng)的字典,然后 title 就賦值為 plist 下 title 的值。如果不同代碼就根據(jù) code1 里面的值來 switch 不同的代碼。

appInfos.plist

最終代碼

以下是完整的腳本文件,部分信息需要自己替換。
以下腳本適用于一次打 N 個(gè)包,適用情況:

  1. 可以替換 bundle 信息
  2. 替換音頻圖片資源
  3. 可以執(zhí)行不同代碼
  4. 生成相應(yīng)的plist文件
  5. 上傳到蒲公英分發(fā)平臺(tái)

當(dāng)然也可以打一個(gè)包,適當(dāng)刪除某些代碼即可。

# 1.Configuration Info

# 項(xiàng)目路徑 需修改
projectDir="你的項(xiàng)目路徑"

# 打包生成路徑 需修改
ipaPath="ipa生成路徑"

# 圖標(biāo)路徑 需修改
iconPath="~/Desktop/icon"

# Provisioning Profile 需修改 查看本地配置文件
PROVISIONING_PROFILE="xxxxxxx-xxxx-4bfa-a696-0ec7391b24d8"

############# 重簽名需要文件
# 以下文件需放在 ipaPath 路徑下
Entitlements=$ipaPath/entitlements.plist
#############

# 版本號(hào)
bundleVersion="2.0.0"

# 選擇打包序號(hào) 多選則以空格隔開 如("1" "2" "3")
appPackNum=("1 2")

# 蒲公英分發(fā)參數(shù) 不分發(fā)可忽略 默認(rèn)不分發(fā) 下面的兩個(gè)KEY是默認(rèn)測(cè)試的網(wǎng)址對(duì)應(yīng)KEY
ISUPLOAD=0
USERKEY="xxx"
APIKEY="xxx"

# ---------------------------可選 如果需要替換 app 的 icon --------------------------------- #

# 配置App信息數(shù)組 格式:"AppName(和工程中appInfo.Plist對(duì)應(yīng))" "icon"
#Schemes:
#        1.app1 app1Icon
#        2.app2 app2Icon
#        3.app3 app3Icon

# --------------------------------------------------------------------------------------- #

# 打包個(gè)數(shù)
appPackNumLength=${#appPackNum[*]}

appInfos=(
          "app1" "app1Icon" "xxxx"
          "app2" "app2Icon" "xxxx"
          "app3" "app3Icon" "xxxx"
          )

appInfosLength=${#appInfos[*]}

# Scheme Name
schemeName="xx"

# Code Sign ID
CODE_SIGN_IDENTITY="xx co., LTD"

# 生成 APP 路徑
buildDir="build/Release-iphoneos"

# 開始時(shí)間
beginTime=`date +%s`

# 創(chuàng)建打包目錄
mkdir ${ipaPath}/AllPack

# 本地存放全部 IPA 的路徑
allIPAPackPath="${ipaPath}/allPack"

# 清除緩存
rm -rf $projectDir/$buildDir

# Build 生成 APP
xcodebuild -workspace ${projectDir}/xx.xcworkspace -scheme ${schemeName} -configuration Release clean -sdk iphoneos build CODE_SIGN_IDENTITY="${CODE_SIGN_IDENTITY}" PROVISIONING_PROFILE="${PROVISIONING_PROFILE}" SYMROOT="${projectDir}/build"
if [[ $? = 0 ]]; then
  echo "\033[31m 編譯成功\n \033[0m"
else
  echo "\033[31m 編譯失敗\n \033[0m"
fi

# 先創(chuàng)建 payload 文件夾
mkdir ~/Desktop/Payload
# 移動(dòng)編譯生成的 app 到桌面的 Payload 文件夾下
cp -Rf ${projectDir}/${buildDir}/${schemeName}.app $ipaPath/Payload

# 以下二選一
# 1.----全部打包----
#for (( i=0; i<appInfosLength; i+=3 )); do

# 2.----自定義打包----
for (( j=0; j<$appPackNumLength; j++)); do i=`expr ${appPackNum[$j]} - 1` i=`expr $i \* 3`

# App Bundle Name (CFBundleName)
appName=${appInfos[${i}]}

# App DisPlay Name
appDisplayName=${appInfos[${i}]}

# App Icon Name
appIconName=${appInfos[$i+1]}

# App Download Name
appDownloadName=${appInfos[$i+2]}

# 創(chuàng)建不同 app ipa 目錄
mkdir $allIPAPackPath/$appName
rm -rf $allIPAPackPath/$appName/*

echo "\033[31m appName:$appName appIconName:$appIconName appDownloadName:$appDownloadName\n \033[0m"

# 將對(duì)應(yīng)的 icon 復(fù)制到需要修改的 app 的目錄下
cp -Rf $iconPath/$appName/* $ipaPath/Payload/YouXiaoYun.app

if [[ $? = 0 ]]; then
 echo "\033[31m 修改 icon 成功\033[0m"
else
 echo "\033[31m 修改 icon 失敗\033[0m"
fi

# 修改 Plist
defaults write $ipaPath/Payload/xx.app/info.plist "CFBundleName" $appName
defaults write $ipaPath/Payload/xx.app/info.plist "CFBundleDisplayName" $appDisplayName

if [[ $? = 0 ]]; then
  echo "\033[31m 修改 Plist 成功\033[0m"
else
  echo "\033[31m 修改 Plist 失敗\033[0m"
fi

# 重簽名
codesign -f -s "xx co., LTD" --entitlements $Entitlements $ipaPath/Payload/xx.app
if [[ $? = 0 ]]; then
echo "\033[31m 簽名成功\n \033[0m"
else
echo "\033[31m 簽名失敗\n \033[0m"
fi

# 生成 ipa
xcrun -sdk iphoneos -v PackageApplication $ipaPath/Payload/.app -o ${ipaPath}/$appDownloadName.ipa

if [[ $? = 0 ]]; then
  echo "\033[31m \n 生成 IPA 成功 \n\n\n\n\n\033[0m"
else
  echo "\033[31m \n 生成 IPA 失敗 \n\n\n\n\n\033[0m"
fi

# 創(chuàng)建 Plist
plist_path=$allIPAPackPath/$appName/$appDownloadName.plist

cat << EOF > $plist_path
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>items</key>
    <array>
        <dict>
            <key>assets</key>
            <array>
                <dict>
                    <key>kind</key>
                    <string>software-package</string>
                    <key>url</key>
                    <string>https://xxxxxxxxxxxx/$appDownloadName.ipa</string>
                </dict>
                <dict>
                    <key>kind</key>
                    <string>display-image</string>
                    <key>url</key>
                    <string>https://xxxxxxxxxxxx/${appIconName}.png</string>
                </dict>
                <dict>
                    <key>kind</key>
                    <string>full-size-image</string>
                    <key>url</key>
                    <string>https://xxxxxxxxxxxx/${appIconName}.png</string>
                </dict>
            </array>
            <key>metadata</key>
            <dict>
                <key>bundle-identifier</key>
                <string>你的bundid</string>
                <key>bundle-version</key>
                <string>$bundleVersion</string>
                <key>kind</key>
                <string>software</string>
                <key>title</key>
                <string>$appDownloadName</string>
            </dict>
        </dict>
    </array>
</dict>
</plist>
EOF

# 移動(dòng)
mv ${ipaPath}/$appDownloadName.ipa ${allIPAPackPath}/$appName

# 6.上傳蒲公英分發(fā)平臺(tái)

if [[ $ISUPLOAD = 1 ]]; then
  echo "正在上傳蒲公英..."
  curl -F "file=@$allIPAPackPath/$appName/$appDownloadName.ipa" -F "uKey=$USERKEY" -F "_api_key=$APIKEY" http://www.pgyer.com/apiv1/app/upload

fi

done

# 清除無關(guān)文件
rm -rf $ipaPath/Payload

# 結(jié)束時(shí)間
endTime=`date +%s`
echo -e "打包時(shí)間$[ endTime - beginTime ]秒"

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,837評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,196評(píng)論 3 414
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,688評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,654評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,456評(píng)論 6 406
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,955評(píng)論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,044評(píng)論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,195評(píng)論 0 287
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,725評(píng)論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,608評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,802評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,318評(píng)論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,048評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,422評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,673評(píng)論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,424評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,762評(píng)論 2 372

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