本文翻譯自 CFHipsterRef
轉(zhuǎn)載自:http://chaosky.me/2017/01/04/Xcode-Toolchain/
寫(xiě)在前面的話
雖然我們來(lái)自不同背景揪惦、有不同觀點(diǎn)储笑,經(jīng)歷不同炼列;雖然我們做事動(dòng)機(jī)不同,信念赤兴、偏見(jiàn)和意見(jiàn)使我們彼此分離妖滔,有一件事我們是在一起的:
不管好壞,我們都必須使用 Xcode桶良。
Xcode 不僅僅只是一個(gè)應(yīng)用程序铛楣,在 GUI 之下是一個(gè)應(yīng)用程序和命令行工具的結(jié)合,它們與開(kāi)發(fā)人員的工作流程一樣是編輯器的核心艺普。
Xcode Tools
xcode-select
每個(gè)人與 Xcode 的旅程從一個(gè)選擇開(kāi)始。xcode-select
提供了這個(gè)選擇鉴竭,盡管是一個(gè)永恒的問(wèn)題:『蛋糕或死亡歧譬?』
從 Mavericks 開(kāi)始,在 Mac 上的開(kāi)發(fā)者從執(zhí)行一條命令開(kāi)始:
$ xcode-select --install
將安裝命令行工具搏存,編譯 Objective-C 代碼必備的瑰步。
xcrun
xcrun
是 Xcode 基本的命令行工具。使用它可以調(diào)用其他工具璧眠。
$ xcrun xcodebuild
除運(yùn)行命令之外缩焦,xcrun
可以查找文件和顯示 SDK 的路徑:
$ xcrun --find clang
$ xcrun --sdk iphoneos --find pngcrush
$ xcrun --sdk macosx --show-sdk-path
因?yàn)?xcrun
的執(zhí)行是基于當(dāng)前的 Xcode 版本環(huán)境(通過(guò) xcode-select
設(shè)置)读虏,所以在系統(tǒng)中能存在多個(gè)版本的 Xcode 工具鏈?zhǔn)欠浅H菀椎摹?/p>
在腳本和其他外部工具中使用 xcrun
能確保在不同環(huán)境中保證一致性。比如袁滥,Xcode 附帶了代碼分發(fā)工具 Git盖桥。通過(guò)調(diào)用 $ xcrun git
而不是 $ git
,構(gòu)建系統(tǒng)可以保證運(yùn)行正確题翻。
xcodebuild
第二個(gè)最重要的 Xcode 工具是 xcodebuild
揩徊,顧名思義,構(gòu)建 Xcode project 和 workspace嵌赠。
不用傳遞任何構(gòu)建參數(shù)塑荒,xcodebuild
默認(rèn)為 Xcode.app 最近使用的 scheme 和 配置:
$ xcodebuild
然而,任何 scheme姜挺、targets齿税、配置、目標(biāo)設(shè)備炊豪、SDK和導(dǎo)出數(shù)據(jù)位置都可以配置:
$ xcodebuild -workspace NSHipster.xcworkspace -scheme "NSHipster"
有六個(gè)可以依次調(diào)用的構(gòu)建操作:
操作 | 描述 |
---|---|
build | 在構(gòu)建根路徑(SYMROOT)構(gòu)建target凌箕。默認(rèn)構(gòu)建操作。 |
analyze | 在構(gòu)建根路徑(SYMROOT)構(gòu)建和分析target或者scheme溜在。需要指定 scheme陌知。 |
archive | 在構(gòu)建根路徑(SYMROOT)打包 scheme。需要指定 scheme掖肋。 |
test | 在構(gòu)建根路徑(SYMROOT)測(cè)試 scheme仆葡。需要指定 scheme和可選指定目標(biāo)設(shè)備。 |
installsrc | 拷貝工程源到源根路徑(SRCROOT)志笼。 |
install | 構(gòu)建target沿盅、安裝到target在目標(biāo)設(shè)備根路徑(DSTROOT)的安裝目錄 |
clean | 從構(gòu)建根路徑(SYMROOT)移除構(gòu)建的產(chǎn)品和中間文件 |
genstrings
genstrings
工具從指定的C或者Objective-C源文件生成 .strings
文件。在不同的 locale
本地化應(yīng)用程序使用 .strings
文件纫溃。在蘋(píng)果的 Cocoa Core Competencies
中的 [Internationalization](https://developer.apple.com/library/mac/documentation/general/conceptual/devpedia-cocoacore/- Internationalization.html) 有相關(guān)的描述腰涧。
$ genstrings -a /path/to/source/files/*.m
每次在源文件中使用 NSLocalizedString
,genstrings
將會(huì)追加 key
和 comment
到目標(biāo)文件中紊浩。然后由開(kāi)發(fā)人員為每個(gè)目標(biāo) locale 創(chuàng)建文件的副本窖铡, 并將該文件翻譯。
fr.lproj/Localizable.strings
/* No comment provided by engineer. */
"Username"="nom d'utilisateur";
/* {User First Name}'s Profile */
"%@'s Profile"="profil de %1$@";
ibtool
正如 genstrings
作用于源代碼坊谁,而 ibtool
作用于 XIB
文件费彼。
$ ibtool --generate-strings-file Localizable.strings en.lpoj/Interface.xib
本地化是它的主要功能,ibtool
還擁有對(duì) Interface Builder
文檔有效的其他幾個(gè)功能口芍。
-
--convert
: 更改所有對(duì)類(lèi)名的引用 -
--upgrade
: 將文檔升級(jí)到最新版 -
--enable-auto-layout
:?jiǎn)⒂米詣?dòng)布局 -
--update-frames
:更新框架 -
--update-constraints
:更新約束
iprofiler
iprofiler
測(cè)量應(yīng)用程序的性能箍铲,而不啟動(dòng) Instruments.app
:
$ iprofiler -allocations -leaks -T 15s -o perf -a NSHipster
上面的命令將附加到 NSHipster 程序,運(yùn)行15秒鬓椭,分析內(nèi)存分配和泄露颠猴,然后將結(jié)果寫(xiě)入perf文件关划。之后輸出結(jié)果可以通過(guò) Instruments.app 讀取和顯示。
xed
這個(gè)命令可以簡(jiǎn)單地打開(kāi) Xcode翘瓮。
$ xed NSHipster.xcworkspace
通過(guò)傳遞 -w
參數(shù)贮折,xed
將等待直到所有打開(kāi)的窗口關(guān)閉。對(duì)于腳本化用戶交互非常有用春畔,例如提示用戶編輯文件并繼續(xù)一旦完成脱货。
agvtool
agvtool
用于讀取和寫(xiě)入 Xcode工程 Info.plist 中的版本號(hào)。
$ agvtool what-version
返回當(dāng)前版本
$ agvtool next-version
累加 CURRENT_PROJECT_VERSION
和 DYLIB_CURRENT_VERSION
律姨。傳遞 -all
選項(xiàng)將更新 Info.plist
中的 CFBundleVersion
振峻。
其他工具
除了上述的 Xcode 工具以外,還有一些其他用 xcrun
調(diào)用的程序:
編譯 & 匯編
- clang: 編譯 C择份、C++扣孟、Objective-C和 Objective-C 源文件。
- lldb: 調(diào)試C荣赶、C++凤价、Objective-C 和 Objective-C 程序
- nasm: 匯編文件
- ndisasm: 反匯編文件
- symbols: 顯示一個(gè)文件或者進(jìn)程的符號(hào)信息。
- strip: 刪除或修改符號(hào)表附加到匯編器和鏈接編輯器的輸出拔创。
- atos: 將數(shù)字內(nèi)存地址轉(zhuǎn)換為二進(jìn)制映像或進(jìn)程的符號(hào)利诺。
處理器
-
unifdef: 從代碼中移除條件宏
#ifdef
。 - ifnames: 在 C++ 文件中找出所有條件剩燥。
庫(kù)
- ld: 將目標(biāo)文件和庫(kù)合并成一個(gè)文件慢逾。
- otool: 顯示目標(biāo)文件或庫(kù)的指定部分。
- ar: 創(chuàng)建和維護(hù)庫(kù)文檔灭红。
-
libtool: 使用鏈接器
ld
創(chuàng)建庫(kù)侣滩。 - ranlib: 更新歸檔庫(kù)的目錄。
- mksdk: 創(chuàng)建和更新 SDK变擒。
- lorder: 列出目標(biāo)文件的依賴君珠。
腳本
- sdef: 腳本定義提取器
- sdp: 腳本定義處理器
- desdp: 腳本定義生成器
- amlint: 檢查 Automator 對(duì)問(wèn)題的操作
打包
- installer: 安裝 OS X 包。
- pkgutil: 讀取和操縱 OS X 包娇斑。
- lsbom: 列出 bom(Bill of Mterials)內(nèi)容策添。
文檔
- headerdoc: 處理頭文檔。
-
gatherheaderdoc: 編譯和鏈接
headerdoc
輸出毫缆。 -
headerdoc2html: 從
headerdoc
輸出生成 HTML舰攒。 -
hdxml2manxml: 從
headerdoc
XML 輸出翻譯成被xml2man
使用的文件。 -
xml2man: 將
Man Page Generation Language(MPGL)
XML文件轉(zhuǎn)換為手冊(cè)頁(yè)悔醋。
Core Data
-
momc: 編譯
Managed Object Model(.mom)
文件 -
mapc: 編譯
Core Data Mapping Model(.xcmappingmodel)
文件
第三方工具
appledoc
Cocoa 開(kāi)發(fā)人員認(rèn)為 Objective-C 的冗長(zhǎng)有助于自注釋代碼。在 longMethodNamesWithNamedParameters:
和 明確的參數(shù)類(lèi)型兽叮。Objective-C 方法不會(huì)留下太多的想象力芬骄。
但是即使自注釋代碼也可以通過(guò)文檔來(lái)改進(jìn)猾愿,只用少量的努力就能夠?qū)λ水a(chǎn)生顯著的益處。
在 Objective-C 中账阻,選擇的文檔工具是 appledoc
蒂秘。使用 javadoc
類(lèi)似的語(yǔ)法,appledoc
能夠從 .h文件生成 HTML 和 Xcode 兼容的 .docset 文檔淘太,看起來(lái)幾乎和蘋(píng)果官方文檔完全相同姻僧。
Objective-C 文檔由任何 @interface
或 @protocol
之前的 /** */
注釋塊(注意額外的初始星號(hào))以及任何方法或 @property
聲明指定。文檔還可能包含系統(tǒng)字段的標(biāo)簽蒲牧,如參數(shù)或返回值:
- @param [param] [Description]: 描述應(yīng)傳遞什么值或此參數(shù)
- @return [Description]: 描述方法的返回值
- @see [selector]: 提供 『參見(jiàn)』相關(guān)項(xiàng)目的參考
- @discussion [Discussion]: 提供額外的背景資料
- @warning [Description]: 調(diào)用異称埠兀或潛在的危險(xiǎn)行為
appledoc
可以通過(guò)以下命令安裝:
$ brew install appledoc
要生成文檔,需要在 Xcode 工程的根目錄下執(zhí)行 appledoc
命令冰抢,傳遞元數(shù)據(jù)比如工程名和公司名:
$ appledoc --project-name CFHipsterRef --project-company "NSHipster" --company-id com.nshipster --output ~/Documents .
從目標(biāo)目錄中找到的頭文件中生成并安裝一個(gè)Xcode .docset文件松嘶。
通過(guò)傳遞 --help
參數(shù)可以找到其他配置選項(xiàng)(包括HTML輸出):
$ appledoc --help
xctool
它可以直接替代 xcodebuild,也就是 Xcode.app 自己所依賴的底層工具挎扰。
我們自己作為蘋(píng)果硬件和軟件的消費(fèi)者翠订,都清楚設(shè)計(jì)的重要性怎么強(qiáng)調(diào)都不為過(guò)。在這個(gè)方面遵倦,xctool 做得非常漂亮尽超。構(gòu)建過(guò)程的每一步都經(jīng)過(guò)清晰的組織,使用 ANSI 彩色字符和一系列 Unicode 裝飾字符梧躺,使得表現(xiàn)的方式既容易理解又具有視覺(jué)吸引力似谁,同時(shí) xctool 的美麗不僅僅體現(xiàn)了表面:構(gòu)建過(guò)程同樣支持以其他工具可讀取的格式進(jìn)行輸出:
$ xctool -reporter plain:output.txt build
- pretty: (默認(rèn)) 一個(gè)文字化的輸出器,使用 ANSI 顏色和 unicode 符號(hào)來(lái)進(jìn)行美化輸出燥狰。
- plain: 類(lèi)似 pretty, 不過(guò)沒(méi)有顏色和 Unicode棘脐。
- phabricator: 把構(gòu)建/測(cè)試的結(jié)果輸出為 JSON 數(shù)組,它可以被 Phabricator 的代碼評(píng)審工具讀取龙致。
- junit: 把測(cè)試結(jié)果輸出成和 JUnit/xUnit 兼容的 XML 文件蛀缝。
- json-stream: 一個(gè)由構(gòu)建/測(cè)試事件組成的 JSON 字典流,每行一個(gè)(示例輸出)目代。
- json-compilation-database: 輸出構(gòu)建事件的 JSON Compilation Database 屈梁,它可以用于基于 Clang Tooling 的工具,例如 OCLint.
xctool 相對(duì)于 xcodebuild 另一個(gè)主要的進(jìn)步是榛了,xctool 可以和 Xcode.app 一樣執(zhí)行應(yīng)用測(cè)試(xcodebuild 不能區(qū)分項(xiàng)目 scheme 中哪些是測(cè)試使用的 target在讶,更不用說(shuō)在模擬器中執(zhí)行測(cè)試了)。
僅僅因?yàn)檫@一個(gè)原因霜大,xctool 就深刻地影響了 Objective-C 社區(qū)中新興的持續(xù)集成測(cè)試的規(guī)范构哺。
通過(guò)以下命令安裝 xctool
:
$ brew install xctool
OCLint
OCLint 是一個(gè)靜態(tài)代碼分析工具,可以檢查 Objective-C(也支持 C 和 C++)代碼中常見(jiàn)的問(wèn)題,例如空的 if/else/try/catch/finally 語(yǔ)句曙强,未使用的本地變量和參數(shù)残拐,大量復(fù)雜的沒(méi)有注釋的(NCSS),具有圈復(fù)雜度或者 NPath 復(fù)雜度的代碼碟嘴,冗余的代碼溪食,代碼“異味”,以及其他的不好的代碼實(shí)踐娜扇。
安裝 OCLint 最好的方式是通過(guò) Homebrew Cask:
$ brew cask install oclint
還記得 xctool
的 json-compilation-database
輸出選項(xiàng)嗎错沃?它的輸出可以直接 被 OCLint
讀取,供它進(jìn)行魔法一般的靜態(tài)分析雀瓢。
$ xctool -workspace NSHipster.xcworkspace -scheme "NSHipster" -reporter json-compilation-database build > compile_commands.json
$ oclint-json-compilation-database
xcpretty
xcpretty
類(lèi)似于 xctool
枢析,改進(jìn)了 xcodebuild
的構(gòu)建輸出,但是 xcpretty
不是嘗試替換 xcodebuild
致燥,而是擴(kuò)展并改進(jìn)它阔挠。
實(shí)際上基显,xcpretty 通過(guò)獲取 xcodebuild 的管道輸出而不是直接調(diào)用,充分體現(xiàn)了 Unix的可組合性理念:
$ xcodebuild [flags] | xcpretty -c
這種方法的一個(gè)主要好處是它真的很快——事實(shí)上,在某些情況下啡直,xcpretty 實(shí)際上比直接調(diào)用 xcodebuild 快一點(diǎn)畜号,因?yàn)樗?jié)省了打印到控制臺(tái)的時(shí)間帚呼。
與 xctool 的另一個(gè)共性是報(bào)告器功能质涛,其具有格式化輸出到JUnit風(fēng)格的XML、HTML或上述OCTool 兼容的 json編譯數(shù)據(jù)庫(kù)格式箱蝠。
xcpretty 通過(guò) RubyGems 安裝:
$ gem install xcpretty
Nomad
Nomad
是用于 iOS 和 OS X 開(kāi)發(fā)的世界級(jí)命令行實(shí)用程序的集合续捂。它自動(dòng)化常見(jiàn)的管理任務(wù),以便開(kāi)發(fā)人員可以專(zhuān)注于構(gòu)建和傳輸軟件宦搬。
每個(gè)工具可以單獨(dú)安裝牙瓢,也可以一起安裝:
$ gem install nomad-cli
Cupertino
應(yīng)用程序 Provisioning 流程普遍被蘋(píng)果開(kāi)發(fā)人員厭惡。
除了整個(gè)過(guò)程是一個(gè)從開(kāi)始到完成的噩夢(mèng)间校,許多操作需要通過(guò) Web 界面進(jìn)行交互矾克。不僅需要大量的額外點(diǎn)擊,但使得它非常不自動(dòng)化憔足。
Cupertino
提供一個(gè)命令行工具管理設(shè)備胁附、provisioning pro?le、app ID 和證書(shū)滓彰。
$ ios devices:list
+------------------------------+---------------------------------------+
|
Listing 2 devices. You can register 98 additional devices.
|
+---------------------------+------------------------------------------+
| Device Name
| Device Identifier
|
+---------------------------+------------------------------------------+
| Johnny Appleseed iPad
| 0123456789012345678901234567890123abcdef |
| Johnny Appleseed iPhone
| abcdef0123456789012345678901234567890123 |
+---------------------------+------------------------------------------+
$ ios devices:add "iPad 1"=abc123
$ ios devices:add "iPad 2"=def456 "iPad 3"=ghi789 ...
通過(guò)以下命令單獨(dú)安裝:
$ gem install cupertino
Shenzhen
Web 開(kāi)發(fā)人員在 iOS 上的對(duì)應(yīng)部分是能夠在幾秒鐘內(nèi)持續(xù)部署代碼控妻,而不是等待幾天 Capertino 批準(zhǔn)(有時(shí)拒絕!)更新揭绑。
幸運(yùn)的是弓候,一個(gè)圍繞著開(kāi)發(fā)和企業(yè)分發(fā)的新興產(chǎn)業(yè)已經(jīng)興起。第三方服務(wù)像 HockeyApp、DeployGate 和 TestFlight 提供給開(kāi)發(fā)者更容易的范式注冊(cè)測(cè)試用戶和發(fā)送最新構(gòu)建給QA菇存。
Shenzhen
是進(jìn)一步自動(dòng)化此過(guò)程的工具彰居,通過(guò)構(gòu)建 .ipa文件,然后發(fā)布到 FTP/SFTP服務(wù)器撰筷、S3 存儲(chǔ)或者其他任何上述第三方服務(wù)。
$ cd /path/to/iOS Project/
$ ipa build
$ ipa distribute:sftp --host HOST -u USER -p PASSWORD -P FTP_PATH
Houston
Houston
是一個(gè)簡(jiǎn)單的工具發(fā)送蘋(píng)果推送通知畦徘。傳遞憑據(jù)毕籽、構(gòu)造消息并將其發(fā)送到設(shè)備。
$ apn push "<token>" -c /path/to/apple_push_notification.pem -m "Hello from the command line!"
這個(gè)工具對(duì)測(cè)試遠(yuǎn)程推送非常有用——尤其是在新應(yīng)用中實(shí)現(xiàn)該功能井辆。
Venice
不管怎樣應(yīng)用內(nèi)購(gòu)買(mǎi)已經(jīng)成為app開(kāi)發(fā)者最有利的商業(yè)模式关筒。有了這么多,對(duì)某人的生活而言確保這些購(gòu)買(mǎi)的有效性是首要的杯缺。
Venice
是一個(gè)命令行程序蒸播,用于驗(yàn)證 Apple 應(yīng)用內(nèi)購(gòu)買(mǎi)收據(jù),并檢索與收據(jù)數(shù)據(jù)相關(guān)的信息萍肆。
$ iap verify /path/to/receipt
+-----------------------------+-------------------------------+
|
Receipt
|
+-----------------------------+-------------------------------+
| app_item_id
|
|
| bid
| com.foo.bar
|
| bvrs
| 20120427
|
| original_purchase_date
| Sun, 01 Jan 2013 12:00:00 GMT |
| original_transaction_id
| 1000000000000001
|
| product_id
| com.example.product
|
| purchase_date
| Sun, 01 Jan 2013 12:00:00 GMT |
| quantity
| 1
|
| transaction_id
| 1000000000000001
|
| version_external_identifier |
|
+-----------------------------+-------------------------------+
像 Houston
袍榆、Venice
有一個(gè)客戶端庫(kù)組件,允許它部署在 Rails或 Sinatra應(yīng)用程序上塘揣。驗(yàn)證服務(wù)器上的收據(jù)允許保留他們自己的過(guò)去購(gòu)買(mǎi)記錄包雀,這對(duì)于最新的指標(biāo)和歷史分析是有用的。因此亲铡,任何人關(guān)于IAP需要認(rèn)真對(duì)待是推薦的做法才写。
Dubai
Passbook 管理登機(jī)牌、電影票奖蔓、零售優(yōu)惠券和會(huì)員卡赞草。使用 PassKit API,開(kāi)發(fā)人員可以注冊(cè) Web 服務(wù)自動(dòng)更新 Passbook的內(nèi)容吆鹤,例如登機(jī)牌上的登機(jī)口更改或會(huì)員卡添加積分厨疙。
Dubai
可以很容易地從腳本或命令行生成 .pkpass 文件,允許快速迭代你的 pass 的設(shè)計(jì)和內(nèi)容檀头,或者在空中生成一次性的轰异。
$ pk generate Example.pass -T boarding-pass
一旦生成了通行證,它可以用 Dubai
創(chuàng)建本地 HTTP 服務(wù)暑始,允許通行證在 iOS 模擬器中實(shí)時(shí)預(yù)覽:
$ pk serve Example.pass -c /path/to/certificate.p12
$ open http://localhost:4567/pass.pkpass