简述

Protobuf是一种由谷歌开发的,通过proto协议约束的数据格式,详情请见官网

协议

syntax = "proto3";

package xxxx;
option objc_class_prefix = "xxx";

message SearchRequest {
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
}

上面是一个简易的protobuf协议,其中有两点需要注意⚠️:

  • 第一行一定是显示的声明proto对应的版本,如果没有显示声明,默认是“proto2”

  • 如果项目中,有多个pb协议,那么这些pb协议之间可能会有相同的定义,比如错误信息等。java等通过packge声明包名区分,但是package对Objective-C不生效,此时需要通过objc_class_prefix给生成类名带上前缀

优点

  • Protobuf数据格式的数据是以二进制方式传输的,数据量相对XML,JSON等数据格式会小很多倍,所以传输速度也会快很多
  • 接收到Protobuf数据格式的数据后,需要对其反序列化,生成对应的模型,反序列化的过程效率高于XML数据格式

生成编程语言代码

Protobuf支持生成多种编程语言代码,前提是装了protobuf的编译器

For C++, the compiler generates a .h and .cc file from each .proto, with a class for each message type described in your file.

For Java, the compiler generates a .java file with a class for each message type, as well as a special Builderclasses for creating message class instances.

Python is a little different – the Python compiler generates a module with a static descriptor of each message type in your .proto, which is then used with a metaclass to create the necessary Python data access class at runtime.

For Go, the compiler generates a .pb.go file with a type for each message type in your file.

For Ruby, the compiler generates a .rb file with a Ruby module containing your message types.

For Objective-C, the compiler generates a pbobjc.h and pbobjc.m file from each .proto, with a class for each message type described in your file.

For C#, the compiler generates a .cs file from each .proto, with a class for each message type described in your file.

For Dart, the compiler generates a .pb.dart file with a class for each message type in your file.

iOS开发中,通过以下命令,生成Objective-C的类(.h & .m)

protoc --proto_path=. --objc_out=. xxx.proto

执行完该命令就可以生成对应Objective-C的类,然后拖到我们的工程,即可使用

Charles抓包

但是在日常开发中,免不了要跟后台联调,如果是HTTP/HTTPS的协议接口,通常都是通过Charles抓包定位问题

如果不做任何处理,会发现Charles无法解析,因为Charles不知道pb定义的格式,此时需要把描述文件添加到Charles

生成描述文件

通过以下命令,生成对应的描述文件xxx.desc

protoc -oxxx.desc xxx.proto

其中 -o 后面紧接着输出文件xxx.desc,中间没有空格

添加描述文件

在Charles面板,我们右键对应的接口,然后选择 Viewer Mappings…,

首先选择Request type & Response type 为 Protocol Buffers

然后点击Open Descriptor Registry,把上一步生成的xxx.desc添加进来,如下图

Request & Response都配置完以后,效果如下图

  • Request type: Protocol Buffers
  • Message type:package+对应的request对象
  • Response type: Protocol Buffers
  • Message type:package+对应的response对象

截止,就完成了Charles抓包解析Protobuf数据格式了