苹果在github的SwiftProtobuf地址:https://github.com/apple/swift-protobuf
懒得看的直接去按照苹果的文档操作即可(不过可能有坑,见下文)
这篇文章的目的,是想简略的说一下Protobuf
是什么,以及接入为什么要做一些额外的事情。
一、背景摘要
Protobuf
是谷歌搞的一种数据格式,按照官方的说法,和编程语言无关,和计算平台无关,就像XML和JSON一样,它就是一种数据格式而已。
但网络传输中的数据是二进制的,要为上层开发者所用就得对应的语言支持解析了,而在iOS这边,谷歌官方只实现了OC的解析,并没有支持Swift的解析。。。。。。
but,苹果官方亲自出马实现了一个解析库(链接文首),现在都已经要2023了,谁还用OC啊!(主要作者现在的项目都是Swift为主😁),所以我们忽略掉OC直接上Swift,如果项目里OC实在是真的换不掉或者不值得换,那就真诚的建议把数据解析层用Swift实现,搞个适配器给OC调用即可。
二、插件安装
我们上面说的解析,其实严格来讲并不准确,因为Protobuf的工作原理是先通过它的语法定义好一个后缀为.proto的文件,这个文件里面确定了用哪个版本的协议,有什么数据,具体的数据结构以及每个字段是什么类型。然后将这个文件编译生成对应开发语言的数据模型类,在实际的开发中,我们只需要把生成的模型类拖到工程中,收到后端给的Protobuf二进制数据后,调用SwiftProtobuf提供的序列化API即可。
所以,我们需要安装一个把.proto文件转为Swift文件的插件,苹果在github的项目README文件里介绍了两种安装方式,自己编译和Homebrew这里推荐Homebrew,因为它最省事:
// 打开终端执行以下命令即可:
brew install swift-protobuf
如果Homebrew没有安装或者装不上又没有时间折腾的话,就只能自己编译了。具体操作也很简单,一共五个指令都在README里面,这里就不抄录了,但有一点需要注意,编译的版本需要与最终iOS工程依赖的SwiftProtobuf版本一致。
编译完成之后,需要配置环境变量,protoc命令才能正常执行。
进入clone下来的swift-protobuf工程,把隐藏文件打开command + shift + .
,然后进入build/release,里面有一个protoc-gen-swift的可执行文件,把它copy到/usr/local/bin目录下(这里比较坑,部分电脑配置了也找不到protoc命令,暂不知原因,Homebrew安装快速便捷,这些步骤都可以省略)
三、Swift文件生成(保姆式教程)
//1、打开终端,创建一个文件夹
mkdir pbExample
//2、进入创建的文件夹
cd pbExample
//3、创建proto文件
touch pbExample.proto
//4、打开新建的proto文件,编辑内容
open pbExample.proto
//5、将以下内容copy进proto文件
// 聪明的同学已经知道这是什么了,对,它就是proto语法定义的一个数据结构,我们最终会用它来生成一个Swift的数据模型
// 去不了google的同学请自行baidu,资料很多
syntax = "proto3";
message BookInfo {
int64 id = 1;
string title = 2;
string author = 3;
}
//6、保存关闭,然后生成Swift文件
protoc --swift_out=. pbExample.proto
//7、如果执行后没有任何报错,说明已经成功了,执行 ls ,你会看到一个
//pbExample.pb.swift的文件,把它拖到我们自己的iOS工程里面就可以正常使用了
四、iOS工程接入SwiftProtobuf
支持CocoaPods和SPM接入,这里仅演示pod,SPM就不水字数了。
// CocoaPods 1.7 or newer is required.
pod 'SwiftProtobuf'
然后我们把之前生成的pbExample.pb.swift文件拉入我们自己的工程,就进入我们正常的开发环节。
贴一段官方的Example:
// 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(jsonUTF8Bytes: jsonData)
网友评论