原标题:还在用JSON? Google Protocol Buffers 更快更小
背景
由于随手记客户端与服务端交互的过程中,对部分数据的传输大小和效率有较高的要求,普通的数据格式如 JSON 或者 XML 已经不能满足,因此决定采用 Google 推出的 Protocol Buffers 以达到数据高效传输。
介绍
Protocol buffers 为 Google 提出的一种跨平台、多语言支持且开源的序列化数据格式。相对于类似的 XML 和 JSON,Protocol buffers 更为小巧、快速和简单。其语法目前分为proto2
和proto3
两种格式。
目前 Google 官方的 Protobuf 最新 release 版本为3.5.1,以下都是基于此版本的环境搭建。
关于 Protocol Buffer 的使用可以查阅官方文档
准备工作
环境要求
Objective-C 2.0 Runtime (32bit & 64bit iOS, 64bit OS X)
Xcode 7.0+
Note
Protobuf 出于性能考虑没有使用 ARC,但在 ARC 下是可以使用的
安装
下载 Protobuf 代码包,这里选择
protobuf-objectivec-3.5.1.tar.gz
解压代码包
编译 Protobuf,这里可能需要安装部分工具:
$ brew install autoconf $ brew install automake $ brew install libtool
运行下面脚本进行编译
$ ./autogen.sh $ ./configure $ make $ make install
检查
protobuf
是否安装成功
$ protoc --version
如果成功打印版本号则安装成功
libprotoc 3.5.1
在 iOS 中使用 Protobuf
创建.proto文件
这里使用官方文档上的一份示例数据结构创建Person.proto
syntax = "proto3"; message Person { string name = 1; int32 id = 2; string email = 3; enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2; } message PhoneNumber { string number = 1; PhoneType type = 2; } repeated PhoneNumber phone = 4; }
使用命令行编译Person.proto
为objective-c
的文件,编译出来的文件为Person.pbobjc.h
和Person.pbobjc.m
protoc Person.proto --objc_out=./
引入 Protobuf 运行时资源
Google 官方的文档提供了两种引入方式,但使用第一种的时候编译不能通过,所以这里选择了第二种:
复制protobuf
目录下的objectivec/*.h
, objectivec/google/protobuf/*.pbobjc.h
, objectivec/google/protobuf/*.pbobjc.m
, 以及除去objectivec/GPBProtocolBuffers.m
后的objectivec/*.m
这里直接用命令行操作,首先进入protobuf
下objectivec
的目录:
$ cd protobuf-3.5.1/objectivec
然后复制符合规则的文件到指定的工程目录下:
$ mkdir ~/ProtobufDemo/ProtocolBuffers ~/ProtobufDemo/ProtocolBuffers/google ~/ProtobufDemo/ProtocolBuffers/google/protobuf $ cp *.h *.m ~/ProtobufDemo/ProtocolBuffers $ cp google/protobuf/*.pbobjc.h google/protobuf/*.pbobjc.m ~/ProtobufDemo/ProtocolBuffers/google/protobuf
Note
上面的命令并没有排除 GPBProtocolBuffers.m 文件,引入时需要手动排除
现在把ProtocolBuffers
目录下所有文件以及上面编译出来的Person.pbobjc.h
和Person.pbobjc.m
都引入到工程中
现在工程目录结构大概是长这样
需要注意,由于protobuf
没有使用 ARC,因此需要为所有.m
文件加上-fno-objc-arc
来关闭 ARC
Note
需要注意工程中的 Header Search Paths 要增加
$(PROJECT_DIR)/ProtocolBuffers
(具体的路径视情况而定)
直接引入 ProtocolBuffers 工程
如果觉得手动引入文件的方式过于复杂,可以直接引入ProtocolBuffers
工程作为依赖项
进入解压后的
protobuf
目录下,复制objective
目录下的所有文件到ProtobufDemo/ProtocolBuffers
目录下在
ProtobufDemo
工程中引入ProtocolBuffers_iOS
工程在
Build Phases
中加入依赖关系并链接库引入
Person.pbobjc.h
和Person.pbobjc.m
文件并为.m
加上-fno-objc-arc
修改工程配置中部分路径为
$(PROJECT_DIR)/ProtocolBuffers
测试
首先引入头文件
#import "Person.pbobjc.h"
生成Person
对象并进行编码和解码
Person *p = [[Person alloc] init]; p.id_p = 1; p.name = @"person1"; p.email = @"123@qq.com"; //encode NSData *data = [p data]; NSLog(@"Protocol Buffers:\n%@\nData: %@\nData Length: %lu", p, data, data.length); //decode Person *newP = [[Person alloc] initWithData:data error:nil]; NSLog(@"Decoded: %@", newP);
运行程序,打印日志如下:
Protocol Buffers: <Person 0x60c0000da2b0>: { name: "person1" id: 1 email: "123@qq.com" } Data: <0a077065 72736f6e 3110011a 0a313233 4071712e 636f6d> Data Length: 23 Decoded: <Person 0x6040000d9c90>: { name: "person1" id: 1 email: "123@qq.com" }
Coffee time!
作者:随手记技术团队
链接:https://juejin.im/post/5ab9ec4a6fb9a028c14a7a91
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
共同学习,写下你的评论
评论加载中...
作者其他优质文章