本文的文檔規範部分的內容參考自:NSHipster 的 Swift Documentation 做者 & Nate Cookhtml
曾經覺得好的代碼是能夠自我解釋不須要註釋的,後來發現不是這樣的。就算是我的項目,代碼註釋的重要性也是毋庸置疑。畢竟人的記憶只有七秒!git
一個開發者是從其餘語言轉到 Cocoa 開發,大都會被它冗長的代碼所 😺 到,Objective-C 的冗長使得其代碼就是有效的自我說明。有如 stringByAppendingPathExtension:
以及參數的顯式類型,這樣的方法通常不會給人留下太多的想象空間。不過 Swift 就有所不一樣了。github
但即便是自我說明的代碼也能夠經過說明文檔加以改進,並且只需少許的努力就能夠給別人產生顯著的好處。objective-c
每個現代編程語言都有註釋:由一個特殊的字符序列標記的非可執行的天然語言,如 //
,/**/
,#
和 --
。使用特殊格式註釋的文檔,提供了代碼的輔助解釋和上下文,能夠用編譯工具提取和解析。編程
從 00 年代早期,Headerdoc 就一直做爲蘋果首選的文檔標準。從 Perl 腳本解析勉強的 Javadoc 註釋做爲出發點,Headerdoc 最終成爲了蘋果在線文檔及 Xcode 中的開發者文檔的後臺引擎。json
隨着 WWDC 2014 的發佈,開發者文檔被翻修並從新設計,包含了 Swift 和 Objective-C 的支持。swift
相似 Javadoc, appledoc 可以從
.h
文件生成 HTML 和 Xcode 兼容的.docset
文檔。xcode
主要用於 C++,但通常在 iOS / OS X 的開發者社區不很受待見。ruby
支持 Objective-C 和 Swift,經過對 Clang 和 SourceKit 的 hook 方式獲取代碼 AST 樹來精準獲取註釋。markdown
就像許多蘋果開發者生態系統同樣,Swift 改變了一切。 本着 「與時俱進,與新共存」 的精神,Xcode 7 將Headerdoc 換成了粉絲最喜歡的 Markdown,尤爲是 Swift 風格的 Markdown。
Xcode 中生成 document 模版的快捷鍵爲 option(alt) + cmd + /
下面爲最基本的 Cocoa 註釋。
Objective-C 風格的註釋:
/// Let's say something /// /// @param bar I'm paramter /// @return I'm return value - (id)fooBar:(NSString *)bar; 複製代碼
Swift 風格的代碼註釋:
/// /// Let's say something /// /// - Parameter bar: I'm paramter /// - Returns: I'm return value func foo(bar: String) -> AnyObject { ... } 複製代碼
文檔註釋經過使用 /** ... */
的多行註釋或 ///...
的單行註釋來進行區分。在註釋塊裏面的內容支持標準的 Markdown 語法,規則以下:
-
、+
、 *
、 •
1,2,3,…
後跟一個點符 1.
或右括號 1)
或兩側括號括起來 (1)
#
做爲前綴,內容的分割線使用 ---
/** Hello, documentation [土土Edmond木](https://looseyi.github.io/) # Lists You can apply *italic*, **bold**, or `code` inline styles. --- # Unordered Lists - Lists are great, - but perhaps don't nest; - Sub-list formatting... - ...isn't the best. --- ## Ordered Lists 1. Ordered lists, too, 2. for things that are sorted; 3. Arabic numerals 4. are the only kind supported. */ 複製代碼
預覽效果
文檔註釋的開頭部分將成爲 「摘要「 Summary
,餘下的其餘內容將一塊兒納入 「討論」 Discussion
。
若是文檔註釋以段落之外的任何內容開頭,則其全部內容都將放入討論中。
Xcode能夠識別一些特殊字段,並使它們與符號描述分開。 當將 Parameter,Return 和 Throws 置爲項目符號項後帶上冒號 :
時,它們會在快捷提示和幫助文檔中與 討論
分段。
- Parameter <param name>:
開始並帶上參數的描述Returns:
開始並帶上返回值的描述Throws:
並配上可能拋出的異常描述,因爲 Swift 不會對超出錯誤一致性的拋出錯誤進行類型檢查,所以正確記錄錯誤尤其重要。本文咱們基本以 Swift 代碼做爲示例。若是代碼是 Objective-C,格式稍微有一些區別。
以返回值的關鍵字爲例。在 Swift 中,咱們編寫 -return :
,但在 Objective-C 中,您將編寫 @return
。 有關更多詳細信息,請參見 Apple 的 HeaderDoc 用戶指南。
/** Creates a personalized greeting for a recipient. - Parameter recipient: The person being greeted. - Throws: `MyError.invalidRecipient` if `recipient` is "Derek" (he knows what he did). - Returns: A new string saying hello to `recipient`. */ func greeting(to recipient: String) throws -> String { guard recipient != "Derek" else { throw MyError.invalidRecipient } return "Greetings, \(recipient)!" } 複製代碼
若是你的方法有多個參數的話,能夠經過 Parameters:
字段加上無序列表符來註釋:
/// Returns the magnitude of a vector in three dimensions /// from the given components. /// /// - Parameters: /// - x: The *x* component of the vector. /// - y: The *y* component of the vector. /// - z: The *z* component of the vector. func magnitude3D(x: Double, y: Double, z: Double) -> Double { return sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2)) } 複製代碼
除了上面的經常使用字段,Swift 風格的 Markdown 還定義了其餘幾個字段:
類型 | |
---|---|
Algorithm/Safety Information | Precondition Postcondition Requires Invariant Complexity Important Warning |
Metadata | Author Authors Copyright Date SeeAlso Since Version |
General Notes & Exhortations | Attention Bug Experiment Note Remark ToDo |
能夠按如下方式鬆散地組織它們,每一個字段在快速幫助中均顯示爲粗體標題,後跟一段文本:
- 字段名: 字段描述的內容從下一行開始
文檔註釋也支持嵌入 Code 來演示功能的正確用法或實現細節。插入代碼能夠經過添加三個反引號 ```
:
/** The area of the `Shape` instance. Computation depends on the shape of the instance. For a triangle, `area` is equivalent to: ``` let height = triangle.calculateHeight() let area = triangle.base * height / 2 ``` */ var area: CGFloat { get } 複製代碼
或者三個反波浪號 ~~~
:
/** The perimeter of the `Shape` instance. Computation depends on the shape of the instance, and is equivalent to: ~~~ // Circles: let perimeter = circle.radius * 2 * Float.pi // Other shapes: let perimeter = shape.sides.map { $0.length } .reduce(0, +) ~~~ */ var perimeter: CGFloat { get } 複製代碼
在 Objective-C 中,咱們經過預處理器指令 #pragma mark 將功能劃分爲有意義的,易於導航的部分。 在 Swift中,能夠經過註釋 // MARK:
實現相同的功能。以及咱們經常使用的其餘 tag:
// MARK:
// TODO:
// FIXME:
// NOTE:
爲了展現這些新標籤的實際做用,下面介紹瞭如何擴展 Bicycle 類以採用 CustomStringConvertible 協議並實現 description屬性。
// MARK: - CustomStringConvertible extension Bicycle: CustomStringConvertible { public var description: String { var descriptors: [String] = [] ... // FIXME: Use a distance formatter descriptors.append("...") // TODO: Allow bikes to be named? return descriptors.joined(separator: ", ") } } 複製代碼
/// 🚲 A two-wheeled, human-powered mode of transportation. class Bicycle { /// Frame and construction style. enum Style { /// A style for streets or trails. case road /// A style for long journeys. case touring /// A style for casual trips around town. case cruiser /// A style for general-purpose transportation. case hybrid } /// The style of the bicycle. let style: Style /// The size of the frame, in centimeters. let frameSize: Int /// The number of trips traveled by the bicycle. private(set) var numberOfTrips: Int /// The total distance traveled by the bicycle, in meters. private(set) var distanceTraveled: Double /** Take a bike out for a spin. Calling this method increments the `numberOfTrips` and increases `distanceTraveled` by the value of `meters`. - Parameter meters: The distance to travel in meters. - Precondition: `meters` must be greater than 0. */ func travel(distance meters: Double) { precondition(meters > 0) distanceTraveled += meters numberOfTrips += 1 } } 複製代碼
完整的 🚴♀️ 文檔,戳這裏。
接下來咱們一塊兒來實踐一下,如何使用 Jazzy 來生成項目的 API 文檔。
首先,Jazzy 支持對 Swift 和 Objective-C 的 Xcode project 項目生成文檔,對於 SwiftPM 也是近期剛支持的。咱們會逐步進階,從一個獨立的 Swift 和 ObjC 項目,再到混編項目,最後是基於 CocoaPods 來生成私有庫文檔。
Jazzy 默認是解析 Swift 代碼註釋來生成文檔。咱們先嚐試爲 Alamofire 生成 HTML 文檔。
首先須要安裝 Jazzy,Jazzy 是一個 Gem 依賴庫,更多瞭解 Gem 請看 《版本管理工具及 Ruby 工具鏈環境》。
[sudo] gem install jazzy
複製代碼
不過因爲 Alamofire 在項目的 Gemfile 中已經添加了 Jazzy 的依賴,因此咱們這裏使用 bundle install
來安裝。最後經過 -o Docs
將文檔輸出到項目的根目錄,完整命令以下:
$ git clone https://github.com/Alamofire/Alamofire $ cd Alamofire $ bundle install $ bundle exec jazzy -o Docs 複製代碼
生成文檔的效果:
Jazzy 默認會讀取項目中的 README.md
、README.markdown
、README.mdown
、README
文檔內容做爲 index page 的內容。
對於 Swift module 項目,Jazzy 在生成文檔時會自動尋找項目根目錄下的 project,而後執行 xcodebuild
或 swift build
來生成 Clang AST,再經過 SourceKit 來生成註釋文檔。
對於支持 SwiftPM 的項目,咱們也能夠經過指定 --wift-build-tool
來生成文檔:
$ bundle exec jazzy \ -o Docs \ --module Alamofire \ --swift-build-tool spm \ --build-tool-arguments -Xswiftc,-swift-version,-Xswiftc,5 複製代碼
Objective-C 項目文檔的生成須要多幾個參數,這裏咱們以 AFNetworking 爲例。
clone 代碼到本地後須要修改 AFNetworking 目錄下的 Gemfile 添加 Jazzy 依賴:
source "https://rubygems.org" gem "fastlane" gem "cocoapods" gem "jazzy" gem "xcode-install" 複製代碼
接着安裝 jazzy 生成 docs 文檔:
$ bundle install $ bundle exec jazzy \ -o Docs \ --objc \ --umbrella-header AFNetworking/AFNetworking.h \ --framework-root AFNetworking 複製代碼
Umbrella header
路徑Jazzy 對於混編項目的支持目前還不是很友好。想要生成混編代碼註釋的文檔,咱們須要事先生成 json
格式的中間產物,再傳遞給 Jazzy 來生成完整的文檔。這裏須要用到工具 sourcekitten。
先看基於混編項目生成文檔的方式:
# 輸出 SourceKitter 的 Swift 文檔數據到 json sourcekitten doc -- -workspace MyProject.xcworkspace -scheme MyScheme > swiftDoc.json # 輸出 SourceKitter 的 Objective-C 文檔數據到 json sourcekitten doc --objc $(pwd)/MyProject/MyProject.h \ -- -x objective-c -isysroot $(xcrun --show-sdk-path --sdk iphonesimulator) \ -I $(pwd) -fmodules > objcDoc.json # 合併 swift 和 Objective-C json 並輸出文檔 jazzy --sourcekitten-sourcefile swiftDoc.json,objcDoc.json 複製代碼
固然 Jazzy 還有其餘不少使用參數這裏就不一一介紹了,你們感興趣的能夠查看官方文檔或者使用 jazzy --help <command>
。
這裏羅列了四個問題用來考察你是否已經掌握了這篇文章,若是沒有建議你加入**收藏 **再次閱讀:
Objective-C 和 Swift 代碼註釋的區別?
對包含多個參數的方法註釋與單個參數對方法有什麼區別?
代碼註釋都支持哪些 Markdown 格式?
Jazzy 支持幾種模式的文檔生成?
本文使用 mdnice 排版