基于 Cookiecutter 打造 iOS 項(xiàng)目模版

所有文章已搬遷到個(gè)人站點(diǎn):me.harley-xk.studio,歡迎訪(fǎng)問(wèn)留言

前言

每次新創(chuàng)建一個(gè)項(xiàng)目,我們總是要做這些事情:創(chuàng)建項(xiàng)目漂彤、初始化 pod鸯匹、安裝 pod坊饶、配置工程、寫(xiě)(或者引入)一些框架性的代碼殴蓬。當(dāng)項(xiàng)目寫(xiě)的多了匿级,會(huì)發(fā)現(xiàn)這里面基本上是大量的重復(fù)勞動(dòng),每次要做的事情幾乎是一樣的染厅,但是又不可避免痘绎。特別是當(dāng)有時(shí)候想寫(xiě)一些玩具性質(zhì)的小項(xiàng)目時(shí),創(chuàng)建項(xiàng)目所使用的勞動(dòng)量相比就更加明顯了肖粮。

其實(shí)可以看出來(lái)孤页,以上這些工作其實(shí)都屬于模版性質(zhì)的,如果我們能夠先編輯好一個(gè)項(xiàng)目模版涩馆,然后每次都基于這個(gè)模版創(chuàng)建新項(xiàng)目的話(huà)就好了行施。其實(shí) Xcode 本身就提供了模版功能允坚,多年前我也曾基于 Xcode 的模版功能做過(guò)一些簡(jiǎn)單的文件模版和項(xiàng)目模版。但是 Xcode 模版配置比較繁瑣蛾号,并且官方的文檔基本找不到(也可能是我沒(méi)認(rèn)真找)稠项。

那么有沒(méi)有什么別的好辦法呢?這就引出這次要說(shuō)的主角了:Cookiecutter

簡(jiǎn)介

Cookiecutter 是一個(gè)用 Python 開(kāi)發(fā)的項(xiàng)目模版工具鲜结,在 Github 上可以找到它的源碼展运,這個(gè)項(xiàng)目目前已經(jīng)有將近一萬(wàn)個(gè) star 了。

Cookiecutter 并不是一個(gè) iOS 專(zhuān)用的工具轻腺,它的支持相當(dāng)廣泛乐疆,基本上所有主流的項(xiàng)目方案都可以使用它來(lái)建立模版,這源于它十分簡(jiǎn)單粗暴的實(shí)現(xiàn)原理:先創(chuàng)建一個(gè)項(xiàng)目框架作為模版贬养,將項(xiàng)目名稱(chēng)等一系列參數(shù)以關(guān)鍵字的方式在配置文件中指定好挤土,然后新建項(xiàng)目時(shí)根據(jù)配置好的模版參數(shù),替換模版中所有目錄和子目錄的名稱(chēng)误算,以及所有文本中匹配到的關(guān)鍵字仰美。當(dāng)然了,Cookiecutter 還有很多高級(jí)用法儿礼,可以去查詢(xún)它的文檔咖杂。

這篇文章只是拋磚引玉,介紹一下我基于 Cookiecutter 創(chuàng)建一個(gè)簡(jiǎn)單的 App 模版的過(guò)程蚊夫。

安裝

首先需要安裝 Cookiecutter诉字,針對(duì)不同的平臺(tái)和環(huán)境,Cookiecutter 提供了相當(dāng)多的安裝方式知纷。不過(guò) iOS 開(kāi)發(fā)者基本都在 macOS 環(huán)境下工作壤圃,所以其他的就略過(guò)了。

mac 下官方推薦使用 Homebrew 來(lái)安裝:

brew install Cookiecutter

整個(gè)安裝過(guò)程都是自動(dòng)的琅轧,非常簡(jiǎn)單伍绳。

創(chuàng)建模版

新建項(xiàng)目

首先我們需要?jiǎng)?chuàng)建一個(gè)模版:打開(kāi) Xcode,新建一個(gè)單頁(yè)應(yīng)用乍桂。


新建單頁(yè)應(yīng)用

點(diǎn)擊 'next', 然后將對(duì)應(yīng)屬性設(shè)置為 template 關(guān)鍵字冲杀,如下圖所示:

  • Product Name: {{cookiecutter.product_name}}
  • Organization Name: {{cookiecutter.organization_name}}
  • Organization Identifier: {{cookiecutter.organization_identifier}}
創(chuàng)建項(xiàng)目

然后點(diǎn)擊 next 創(chuàng)建項(xiàng)目,項(xiàng)目創(chuàng)建完畢后睹酌,打開(kāi) info.plist权谁,將 Bundle identifier 指定為 com.{{cookiecutter.organization_identifier}}.{{cookiecutter.product_name}} 否則 Xcode 默認(rèn)會(huì)將 {} 替換為 -,導(dǎo)致后續(xù)創(chuàng)建項(xiàng)目時(shí)替換失敗憋沿。

配置文件

接下來(lái)闯传,在與剛創(chuàng)建完畢的項(xiàng)目根目錄同級(jí),也就是 {{cookiecutter.product_name}} 文件夾所在的目錄,創(chuàng)建一個(gè) cookiecutter.json 文件甥绿,內(nèi)容如下:

{
    "product_name": "Hello",
    "organization_name": "Someone Co.,Ltd.",
    "organization_identifier": "someone"
}

JSON 中的 key 就是我們剛才創(chuàng)建項(xiàng)目時(shí)填寫(xiě)的那幾個(gè)用雙括號(hào)包含起來(lái)的名稱(chēng)字币,并且去掉 cookiecutter 前綴,key 對(duì)應(yīng)的值表示默認(rèn)值共缕。使用 Cookiecutter 從模版創(chuàng)建項(xiàng)目時(shí)洗出,它會(huì)詢(xún)問(wèn)配置文件中的這幾個(gè) key,讓我們給它指定名稱(chēng)图谷,如果不指定翩活,則使用配置文件中的默認(rèn)值。

另外便贵,需要哪些 key菠镇,以及 key 的名稱(chēng)是不固定的,你可以根據(jù)自己的需要自己定義任意數(shù)量的 key承璃,只要保證在模版項(xiàng)目中使用相同的名稱(chēng)利耍,并且需要帶上 cookiecutter 前綴

至此盔粹,一個(gè)最簡(jiǎn)單的項(xiàng)目模版就創(chuàng)建完了隘梨,你也可以根據(jù)自己的需要給這個(gè)項(xiàng)目添加一些額外的代碼,新建項(xiàng)目時(shí)所有額外添加的內(nèi)容都將原樣保留舷嗡。

鉤子

上面創(chuàng)建的項(xiàng)目非常簡(jiǎn)單轴猎,但是我們實(shí)際開(kāi)發(fā)中一般都需要使用 Cocoapods 來(lái)管理第三方依賴(lài),并且有些庫(kù)幾乎是所有項(xiàng)目都需要用到的进萄,比如 Alamofire捻脖、SnapKit 等等。那么能不能通過(guò)模版一并完成 pods 的配置和安裝呢中鼠?

這就可以用上 Cookiecutter 的鉤子功能了郎仆,鉤子通俗一點(diǎn)講也叫回調(diào),可以在某些特性情況下觸發(fā)一些事件兜蠕,執(zhí)行一些操作等。

Cookiecutter 的鉤子配置非常簡(jiǎn)單抛寝,只需要在配置文件同級(jí)目錄下新建一個(gè) hooks 目錄熊杨,然后將寫(xiě)好的腳本放在該目錄中,Cookiecutter 會(huì)自動(dòng)調(diào)用盗舰。

目前 Cookiecutter 支持兩個(gè)事件晶府,即創(chuàng)建項(xiàng)目之前和創(chuàng)建項(xiàng)目完成之后,會(huì)分別調(diào)用對(duì)應(yīng)的腳本文件钻趋,目前支持 shell 腳本和 python 腳本川陆。在安裝前調(diào)用的腳本需要命名為 pre_gen_project.sh 或者 pre_gen_project.py;同樣的蛮位,在安裝之后調(diào)用的腳本需要命名為 post_gen_project.sh 或者 post_gen_project.py较沪,取決于腳本使用的語(yǔ)言鳞绕。

自動(dòng)安裝 pods

首先需要在項(xiàng)目目錄下,即 {{cookiecutter.product_name}}/ 目錄下創(chuàng)建 Podfile 文件尸曼,并配置好常用的依賴(lài)庫(kù):

target '{{cookiecutter.product_name}}' do

  use_frameworks!

  # Pods for {{cookiecutter.product_name}}

  # Networking
  pod 'Alamofire'
  # ImageCache
  pod 'Kingfisher'
  # AutoLayout
  pod 'SnapKit'

end

好了们何,不要執(zhí)行 pod install,因?yàn)檫@只是個(gè)模版控轿,可能實(shí)際創(chuàng)建項(xiàng)目時(shí)這些庫(kù)已經(jīng)更新了冤竹,所以需要在創(chuàng)建項(xiàng)目時(shí)才安裝依賴(lài)。

接下來(lái)打開(kāi) post_gen_project.sh, 寫(xiě)上 pod 安裝相關(guān)的命令:

#!/bin/bash
GREEN='\033[0;32m'
echo -e "${GREEN}Project successfuly generated!"
echo -e "${GREEN}Installing Pods..."
pod install
echo -e "${GREEN}Pods Install Finished"

其實(shí)只需要寫(xiě)一句 pod install 就夠了茬射,不過(guò)為了創(chuàng)建項(xiàng)目時(shí)命令行的輸出內(nèi)容能夠更加友好鹦蠕,我添加了一些額外的狀態(tài)輸出的內(nèi)容,你也可以在其中添加一些其他需要處理的事務(wù)在抛。

這時(shí)候我們的項(xiàng)目框架才算基本完成钟病。此時(shí),我們的項(xiàng)目模版目錄應(yīng)該是類(lèi)似下面這樣:

ios_template/
├── {{cookiecutter.product_name}}/
│   ├── {{cookiecutter.product_name}}.xcodeproj
│   ├── Podfile
│   └── ...
├── hooks
│   ├── pre_gen_project.sh
│   └── post_gen_project.sh
└── cookiecutter.json

使用

分發(fā)模版

模版做完了霜定,放到哪里呢档悠?本地目錄也是可以的,Cookiecutter 支持從任何可以訪(fǎng)問(wèn)的路徑加載項(xiàng)目模版望浩,不過(guò)為了方便使用和團(tuán)隊(duì)共享辖所,最好是將模版推送到 git 倉(cāng)庫(kù)中,這樣也方便后期修改以及多人維護(hù)等磨德。

另外缘回,如果你的模版項(xiàng)目非常大,也可以打包成 zip 上傳典挑,Cookiecutter 支持從 zip 包創(chuàng)建項(xiàng)目酥宴,創(chuàng)建時(shí)會(huì)自動(dòng)解壓。

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

創(chuàng)建項(xiàng)目也非常簡(jiǎn)單您觉,確保 Cookiecutter 已經(jīng)正確安裝后拙寡,只需要 cd 到你準(zhǔn)備創(chuàng)建項(xiàng)目的目錄,然后執(zhí)行以下命令就好了:

cookiecutter https://github.com/Harley-xk/iOS_Template_Comet.git

后面的路徑可以是本地路徑也可以是遠(yuǎn)程路徑琳水,可以是 git肆糕,也可以是 zip。Cookiecutter 還支持很多其他的倉(cāng)庫(kù)形式在孝,詳細(xì)可以查看它的文檔诚啃。

命令執(zhí)行后就開(kāi)始創(chuàng)建項(xiàng)目了,Cookiecutter 會(huì)對(duì)你在配置文件中設(shè)置的每一個(gè)關(guān)鍵字進(jìn)行詢(xún)問(wèn)私沮,你可以輸入新項(xiàng)目需要使用的值始赎,或者也可以直接回車(chē)后使用默認(rèn)值。

可以看到命令行的輸出如下:

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

Cookiecutter 會(huì)在用戶(hù)目錄下緩存所有安裝過(guò)的項(xiàng)目模版,下次安裝時(shí)會(huì)詢(xún)問(wèn)你是否需要更新模版:

You've downloaded /Users/Harley-xk/.cookiecutters/iOS_Template_Comet before. Is it okay to delete and re-download it?

輸入 yes造垛,它會(huì)自動(dòng)更新模版后創(chuàng)建項(xiàng)目魔招。

另外可以看到在創(chuàng)建項(xiàng)目之后 pod install 指令也自動(dòng)執(zhí)行了,我們?cè)?Podfile 里面指定的三個(gè)依賴(lài)庫(kù)都已經(jīng)成功安裝了筋搏∑桶伲可以進(jìn)入 MyApp 目錄下面,打開(kāi) MyApp.xcworkspace 查看創(chuàng)建完畢的項(xiàng)目:

創(chuàng)建完畢的項(xiàng)目

結(jié)束語(yǔ)

其實(shí)可以發(fā)現(xiàn) Cookiecutter 的原理和使用都非常簡(jiǎn)單”计辏現(xiàn)在項(xiàng)目越做越龐大俄周,架構(gòu)也越來(lái)越復(fù)雜,雖然我們可以通過(guò)組件化的方式最大化的重用代碼髓迎,減少工作量峦朗,但是依然需要寫(xiě)大量的膠水代碼來(lái)整合各個(gè)組件,做大量的項(xiàng)目配置排龄、項(xiàng)目初始化的工作波势,通過(guò)使用 Cookiecutter,可以進(jìn)一步節(jié)省大量的工作橄维。

ps. 我在 Github 上創(chuàng)建了我自己的 iOS 項(xiàng)目模版尺铣,你如果不想自己寫(xiě),也可以使用我的模版:https://github.com/Harley-xk/iOS_Template_Comet.git

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末争舞,一起剝皮案震驚了整個(gè)濱河市凛忿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌竞川,老刑警劉巖店溢,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異委乌,居然都是意外死亡床牧,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)遭贸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)戈咳,“玉大人,你說(shuō)我怎么就攤上這事壕吹≈埽” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵算利,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我泳姐,道長(zhǎng)效拭,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮缎患,結(jié)果婚禮上慕的,老公的妹妹穿的比我還像新娘。我一直安慰自己挤渔,他們只是感情好肮街,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著判导,像睡著了一般嫉父。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上眼刃,一...
    開(kāi)封第一講書(shū)人閱讀 51,370評(píng)論 1 302
  • 那天绕辖,我揣著相機(jī)與錄音,去河邊找鬼擂红。 笑死仪际,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的昵骤。 我是一名探鬼主播树碱,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼变秦!你這毒婦竟也來(lái)了成榜?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤伴栓,失蹤者是張志新(化名)和其女友劉穎伦连,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體钳垮,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡惑淳,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了饺窿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片歧焦。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖肚医,靈堂內(nèi)的尸體忽然破棺而出绢馍,到底是詐尸還是另有隱情,我是刑警寧澤肠套,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布舰涌,位于F島的核電站,受9級(jí)特大地震影響你稚,放射性物質(zhì)發(fā)生泄漏瓷耙。R本人自食惡果不足惜朱躺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望搁痛。 院中可真熱鬧长搀,春花似錦、人聲如沸鸡典。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)彻况。三九已至谁尸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間疗垛,已是汗流浹背症汹。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留贷腕,地道東北人背镇。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像泽裳,于是被迫代替她去往敵國(guó)和親瞒斩。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354