欢迎使用 Swift Protobuf!
Apple 的 Swift 编程语言与 Google 的 Protocol Buffer(“protobuf”)序列化技术完美互补。它们都强调高性能和程序员安全性。
本项目提供命令行程序,用于向 Google 的 protoc
添加 Swift 代码生成功能,并提供使用生成的代码所需的运行时库。在使用 protoc 插件从您的 .proto 文件生成 Swift 代码后,您需要将此库添加到您的项目中。
与替代序列化系统相比,SwiftProtobuf 具有许多优势
.proto
schema 文件中定义数据结构,可以清晰地记录您的通信约定。.serializedBytes()
方法返回一个字节包,其中包含数据的紧凑二进制形式。您可以使用 init(contiguousBytes:)
初始化器反序列化数据。.jsonUTF8Bytes()
方法返回数据的 JSON 格式,可以使用 init(jsonUTF8Bytes:)
初始化器进行解析。Set<>
或 Dictionary<>
中。最重要的是,您可以采用相同的 .proto
文件并生成 Java、C++、Python 或 Objective-C 代码,以供其他平台使用。 这些语言生成的代码将使用与 SwiftProtobuf 完全相同的序列化和反序列化约定,从而可以轻松地以二进制或 JSON 形式交换序列化数据,而无需您付出额外的努力。
更多信息可在相关文档中找到
protoc
程序添加 Swift 支持的 protoc-gen-swift
插件如果您以前使用过 Protocol Buffers,则添加 Swift 支持非常简单:您只需构建 protoc-gen-swift
程序并将其复制到您的 PATH 中即可。 protoc
程序会自动找到并使用它,从而允许您为 proto 文件构建 Swift 源代码。 当然,您还需要按照下面的说明将 SwiftProtobuf 运行时库添加到您的项目中。
要将 Swift 与 Protocol Buffers 一起使用,您需要
Swift 5.8 或更高版本的编译器(或者,如果使用 Xcode 构建,则需要 Xcode 14.3 或更高版本,这是 App Store 的要求)。 Swift protobuf 项目正在针对 Swift.org 提供的最新发布版本的 Swift 进行开发和测试
Google 的 protoc 编译器。 Swift protoc 插件正在针对最新的 protobuf 源代码进行积极开发和测试。 SwiftProtobuf 测试需要支持 swift_prefix
选项(在 protoc 3.2.0 中引入)的 protoc 版本。 它可能适用于早期版本的 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 版本或较旧的系统版本,您可能还需要将 --static-swift-stdlib
与 swift build
一起使用。
如果您更喜欢使用 Homebrew
brew install swift-protobuf
这将安装 protoc
编译器和 Swift 代码生成器插件。
要为您的 .proto 文件生成 Swift 输出,您可以像往常一样运行 protoc
命令,使用 --swift_out=<directory>
选项
protoc --swift_out=. my.proto
protoc
程序将自动在您的 PATH
中查找 protoc-gen-swift
并使用它。
每个 .proto
输入文件都将被转换为输出目录中相应的 .pb.swift
文件。
有关构建和使用 protoc-gen-swift
的更多信息,请参见详细的插件文档。
要使用生成的代码,您需要在项目中包含 SwiftProtobuf
库模块。 具体方法取决于您构建项目的方式。 请注意,在所有情况下,我们都强烈建议您使用与您用于生成代码的 protoc-gen-swift
版本对应的 SwiftProtobuf 库版本。
将 .pb.swift
文件复制到您的项目后,您需要将 SwiftProtobuf 库添加到您的项目中以支持生成的代码。 如果您使用的是 Swift Package Manager,请将依赖项添加到您的 Package.swift
文件中,并将 SwiftProtobuf
库导入到所需的目标中。 调整这里的 "1.27.0"
以匹配您用于构建上述插件的 [tag_name]
dependencies: [
.package(url: "https://github.com/apple/swift-protobuf.git", from: "1.27.0"),
],
targets: [
.target(
name: "MyTarget",
dependencies: [.product(name: "SwiftProtobuf", package: "swift-protobuf")]
),
]
如果您使用的是 Xcode,那么您应该
.pb.swift
源文件直接添加到您的项目如果您使用的是 CocoaPods,请将其添加到您的 Podfile
中,调整 :tag
以匹配您用于构建上述插件的 [tag_name]
pod 'SwiftProtobuf', '~> 1.0'
并运行 pod install
。
注意:需要 CocoaPods 1.7 或更高版本。
安装代码生成器,使用它从您的 .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: you can choose to serialize into
// any type conforming to `SwiftProtobufContiguousBytes`. For example:
// Resolve the `SwiftProtobufContiguousBytes` return value to `Data`
let binaryData: Data = try info.serializedBytes()
// Resolve the `SwiftProtobufContiguousBytes` return value to `[UInt8]`
let binaryDataAsBytes: [UInt8] = try info.serializedBytes()
// Note that while the `serializedBytes()` spelling is generally preferred,
// you may also use `serializedData()` to get the bytes as an instance of
// `Data` where required.
// This means that the following two statements are equivalent:
// let binaryData: Data = try info.serializedBytes()
// let binaryData: Data = try info.serializedData()
// Deserialize a received Data object from `binaryData`
let decodedInfo = try BookInfo(serializedData: binaryData)
// Deserialize a received [UInt8] object from `binaryDataAsBytes`
let decodedInfo = try BookInfo(serializedBytes: binaryDataAsBytes)
// Serialize to JSON format as a Data object, or as any other type conforming to
// SwiftProtobufContiguousBytes. For example:
let jsonData: Data = try info.jsonUTF8Data()
let jsonBytes: [UInt8] = try info.jsonUTF8Bytes()
// Deserialize from JSON format from `jsonBytes`
let receivedFromJSON = try BookInfo(jsonUTF8Bytes: jsonBytes)
您可以在详细的 API 文档中找到更多信息。
如果您遇到问题,请向我们发送详细的报告。 至少,请包括
swift --version
)protoc --version
git log -1
获取最新的提交 ID)