所有文章已搬遷到個(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)用乍桂。
點(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}}
然后點(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)值。
可以看到命令行的輸出如下:
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)目:
結(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