本文的文档规范部分的内容参考自: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 排版