Swift Protobuf
欢迎使用 Swift Protobuf!
Apple 的 Swift 编程语言 是 Google 的 Protocol Buffer(protobuf)序列化技术的完美补充。它们都强调高性能和程序员安全性。
该项目提供了一个命令行程序,可以将 Swift 代码生成添加到 Google 的 protoc
中,以及一个必要的运行时库,用于使用生成的代码。在使用 protoc 插件从您的 .proto 文件生成 Swift 代码后,您需要将此库添加到项目中。
SwiftProtobuf 的特点
SwiftProtobuf 比其他序列化系统提供了许多优势
- 安全性:protobuf 代码生成系统避免了与手写序列化代码常见的手误。
- 正确性:SwiftProtobuf 通过了自己的全面测试套件和 Google 的全面符合性测试。
- 基于模式:在单独的
.proto
模式文件中定义您的数据结构可以清楚地描述您的通信惯例。 - 符合语言风格:SwiftProtobuf 充分利用了 Swift 语言。特别是,所有生成的类型都提供了完整的 Swift 副本写入值语义。
- 高效二进制序列化:`
.serializedData()
` 方法返回一个具有您数据紧凑二进制形式的Data
。您可以使用 `init(serializedData:)` 初始化器来反序列化数据。 - 标准的JSON序列化:
.jsonUTF8Data()
方法返回数据的JSON格式,可以使用init(jsonUTF8Data:)
初始化器进行解析。 - 可哈希、可比较:生成的结构体可以放入
Set<>
或Dictionary<>
中。 - 高性能:二进制和JSON序列化器已经进行了大量优化。
- 可扩展:您可以向任何生成的类型添加自己的Swift扩展。
最好的是,您可以使用相同的.proto
文件生成Java、C++、Python或Objective-C,以在其他平台上使用。这些语言的生成代码将使用与SwiftProtobuf完全相同的序列化和反序列化约定,使得在您不额外努力的情况下,方便地交换二进制或JSON格式的序列化数据。
文档
更多详细信息可在相关文档中找到
- Google的protobuf文档提供了关于协议缓冲区、protoc编译器和如何使用C++、Java以及其他语言与协议缓冲区相关的一般信息。
- PLUGIN.md记录了添加Swift支持的
protoc-gen-swift
插件 - API.md记录了如何使用生成的代码。这是使用SwiftProtobuf项目的必备阅读。
- cocoadocs.org有生成的API文档
- INTERNALS.md记录了生成的代码和库的内部结构。如果需要对SwiftProtobuf本身进行操作的人员,则需要这个。
- STYLE_GUIDELINES.md记录了我们在代码库中采用的风格指南,如果您有兴趣做出贡献的话。
开始
如果您之前使用过Protocol Buffers,则添加Swift支持很简单:只需要构建protoc-gen-swift
程序并将其复制到您的PATH中。protoc
程序会自动找到并使用它,允许您为proto文件构建Swift源代码。当然,您还需要按照以下说明将SwiftProtobuf运行时库添加到项目中。
系统需求
要使用 Swift 与 Protocol buffers,您需要
-
Swift 4.2 或更高版本的编译器(Xcode 10.0 或更高版本)。支持 Swift Package Manager;或使用包含的 Xcode 项目。Swift protobuf 项目正在针对最新版本的 Swift 进行开发和测试,该版本可在 Swift.org 获取。
-
Google 的 protoc 编译器。Swift protoc 插件正在积极开发和针对最新的 protobuf 源进行测试。SwiftProtobuf 测试需要支持
swift_prefix
选项的 protoc 版本(自 protoc 3.2.0 以来引入)。它可能适用于更早的 protoc 版本。您可以从 Google 的 github 存储库 获取最新版本。
构建和安装代码生成插件
要将 .proto
文件转换为 Swift,您需要 Google 的 protoc 编译器以及 SwiftProtobuf 代码生成插件。
在支持的 Swift 平台上构建插件应该是简单的。
$ git clone https://github.com/apple/swift-protobuf.git
$ cd swift-protobuf
选择您要使用的 SwiftProtobuf 的发布版本。您可以使用以下命令获取版本列表:
$ git tag -l
选择您将使用的版本后,设置您的本地状态以匹配,并构建 protoc 插件
$ git checkout tags/[tag_name]
$ swift build -c release
这将在 .build/release
目录中创建一个名为 protoc-gen-swift
的二进制文件。
要安装,只需将此可执行文件复制到您的 PATH
环境变量所在的目录。
注意:Swift 运行时现在包含在 macOS 中。如果您正在使用旧版本的 Xcode 或较旧的系统版本,您可能需要使用 swift build
与 --static-swift-stdlib
。
通过 Homebrew 等其他方式安装
如果您想使用 Homebrew
$ brew install swift-protobuf
这将为您安装 protoc
编译器和 Swift 代码生成插件。
将.proto文件转换为Swift
要为您的.proto文件生成Swift输出,您需要像往常一样运行protoc
命令,使用--swift_out=<目录>
选项
$ protoc --swift_out=. my.proto
protoc
程序将自动在您的PATH
中查找protoc-gen-swift
并使用它。
每个.proto
输入文件都将转换为输出目录中相应的.pb.swift
文件。
有关构建和使用protoc-gen-swift
的更多信息,请参阅详细插件文档。
将SwiftProtobuf库添加到您的项目中...
要使用生成的代码,您需要在项目中包含SwiftProtobuf
库模块。您如何做到这一点将取决于您的项目构建方式。请注意,在所有情况下,我们强烈建议您使用与用于生成代码的protoc-gen-swift
版本相对应的SwiftProtobuf
库版本。
swift build
...使用将.pb.swift
文件复制到您的项目中后,您需要将SwiftProtobuf库添加到您的项目中以支持生成的代码。如果您使用的是Swift包管理器,请在Package.swift
文件中添加依赖关系,并将SwiftProtobuf
库导入到所需的目标中。将"1.6.0"
此处调整为与上面构建插件时使用的[tag_name]
相匹配
dependencies: [
.package(name: "SwiftProtobuf", url: "https://github.com/apple/swift-protobuf.git", from: "1.6.0"),
],
targets: [
.target(name: "MyTarget", dependencies: ["SwiftProtobuf"]),
]
在Xcode中使用
如果你使用Xcode,则应该
- 将生成自您的protos的源文件
.pb.swift
直接添加到项目中 - 将此包中的Xcode项目中的适当目标
SwiftProtobuf_<平台>
添加到您的项目中。
在CocoaPods中使用
如果你使用CocoaPods,请在Podfile
中添加以下内容,并根据你在构建插件时使用的[tag_name]
调整`:tag`
pod 'SwiftProtobuf', '~> 1.0'
然后运行pod install
。
注意:需要CocoaPods 1.7或更高版本。
在Carthage中使用
如果你使用Carthage,请在Cartfile
中添加以下内容,但请调整标签以匹配你在构建插件时使用的[tag_name]
github "apple/swift-protobuf" ~> 1.0
运行carthage update
并将SwiftProtobuf.framework
拖入Xcode项目。
快速开始
一旦安装了代码生成器,使用它从您的.proto
文件生成了Swift代码,并将SwiftProtobuf库添加到项目中后,您就可以像使用任何其他Swift结构体一样使用生成的类型。
例如,您可能从以下非常简单的proto文件开始
syntax = "proto3";
message BookInfo {
int64 id = 1;
string title = 2;
string author = 3;
}
然后使用以下方式生成Swift代码:
$ protoc --swift_out=. DataModel.proto
生成的代码将为每个proto字段公开一个Swift属性,同时还包括一系列的序列化和反序列化功能。
// Create a BookInfo object and populate it:
var info = BookInfo()
info.id = 1734
info.title = "Really Interesting Book"
info.author = "Jane Smith"
// As above, but generating a read-only value:
let info2 = BookInfo.with {
$0.id = 1735
$0.title = "Even More Interesting"
$0.author = "Jane Q. Smith"
}
// Serialize to binary protobuf format:
let binaryData: Data = try info.serializedData()
// Deserialize a received Data object from `binaryData`
let decodedInfo = try BookInfo(serializedData: binaryData)
// Serialize to JSON format as a Data object
let jsonData: Data = try info.jsonUTF8Data()
// Deserialize from JSON format from `jsonData`
let receivedFromJSON = try BookInfo(jsonUTF8Data: jsonData)
更多详细信息可以在API文档中找到。
报告任何问题
如果在运行过程中遇到问题,请向我们发送详细的报告。至少请包括以下信息:
- 具体的操作系统和版本(例如,“macOS 10.12.1”或“Ubuntu 16.10”)
- 已安装的Swift版本(从
swift --version
获取) - 正在使用的protoc编译器的版本(从
protoc --version
获取) - 此源代码的具体版本(可以使用
git log -1
获取最新提交ID) - 可能进行的任何本地更改