简介:
protobuf 即 google protocol buffer 是一种数据封装格式协议;
比如其他经常用的xml,json等格式;protobuf的优势是效率高,同样的一份数据使用protobuf存储的时候更小,更加方便;
官网:
https://developers.google.com/protocol-buffers/
https://github.com/google/protobuf
在iOS上的使用
目前最新的版本需要xcode7.0+,以及不支持ARC
1. 从github上面下载全部代码
2. 在mac上编译protobuf 可能还需要 autoconf,libtool,automake,
请先在mac上安装这三个依赖库;使用brew安装就行
brew install autoconf
brew install libtool
brew install automake
automake的安装可能会连接到被墙的网站,这时从网上找一份谷歌host即可;
3. 解压下载的 protobuf-master, 并打开终端入/protobuf-master/objectivec/DevTools/ 目录
执行 sudo shfull_mac_build.sh
等待编译完成,如果遇到错误可能是上面3个依赖或是别的依赖没有安装,排查一下就好
4. 安装完成之后,即会在protobuf-master/src/ 目录下生成 protoc 可执行程序
以后我们需要用该生成把 .proto文件生成对应平台的代码;
5. 如下安装protobuf定义的proto3语法生成一份测试用的数据格式,Person.proto文件
syntax = "proto3";
message Person {string name = 1;
int32 age= 2;string address = 3;
}
6. 使用 protoc 将 .proto文件 生成对应平台的代码;这里生成oc的代码
如下protoc命令的帮助
Parse PROTO_FILES and generate output based on the options given:-IPATH, --proto_path=PATH Specify the directory in which to search forimports. May be specified multiple times;
directories will be searchedinorder. If not
given, the current working directoryisused.--version Show version info and exit.-h, --help Show thistext and exit.--encode=MESSAGE_TYPE Read a text-format message of the given type
from standard input and write itinbinary
to standard output. The message type must
be definedinPROTO_FILES or their imports.--decode=MESSAGE_TYPE Read a binary message of the given type from
standard input and write itintext format
to standard output. The message type must
be definedinPROTO_FILES or their imports.--decode_raw Read an arbitrary protocol message from
standard input and write the raw tag/value
pairsintext format to standard output. No
PROTO_FILES should be given whenusing thisflag.-oFILE, Writes a FileDescriptorSet (a protocol buffer,--descriptor_set_out=FILE defined indescriptor.proto) containing all of
the input files to FILE.--include_imports When using --descriptor_set_out, also include
all dependencies of the input filesintheset, so that the set is self-contained.--include_source_info When using --descriptor_set_out, donot strip
SourceCodeInfo from the FileDescriptorProto.
This resultsinvastly larger descriptors that
include information about the original
location of each declin the source file aswellassurrounding comments.--dependency_out=FILE Write a dependency output file inthe format
expected by make. This writes the transitivesetof input file paths to FILE--error_format=FORMAT Set the format inwhich to print errors.
FORMAT may be‘gcc‘ (the default) or ‘msvs‘(Microsoft Visual Studio format).--print_free_field_numbers Print the free field numbers of the messages
definedinthe given proto files. Groups share
the same field number space with the parent
message. Extension ranges are countedasoccupied fields numbers.--plugin=EXECUTABLE Specifies a plugin executable to use.
Normally, protoc searches the PATHforplugins, but you may specify additional
executables notin the path using thisflag.
Additionally, EXECUTABLE may be of the form
NAME=PATH, in which casethe given plugin nameis mapped to the given executable even ifthe executable‘s own name differs.
--cpp_out=OUT_DIR Generate C++header and source.--csharp_out=OUT_DIR Generate C# source file.--java_out=OUT_DIR Generate Java source file.--javanano_out=OUT_DIR Generate Java Nano source file.--js_out=OUT_DIR Generate JavaScript source.--objc_out=OUT_DIR Generate Objective C header and source.--php_out=OUT_DIR Generate PHP source file.--python_out=OUT_DIR Generate Python source file.--ruby_out=OUT_DIR Generate Ruby source file.
View Code
生成OC代码格式命令
D/protoc --proto_path=A --objc_out=B C/Person.proto
D: 表示 protoc 可执行程序的目录
A:表示处理proto文件需要的目录,和生成目录一样就行
B:表示生成代码的文件,oc会成生.h和.m 这里就是指生成文件需要放的目录
C:表示需要的.proto文件,即protoc会根据此文件里面定义的格式生成相应平台代码文件
生成之后的oc,.h 和 .m 就可以放到xcode工程里面使用了,不支持ARC,ARC的工程对此.m添加 -fno-objc-arc
7. 这里使用xcode7.3创建了DEMO工程,GPBDemo,并设置工程为 mrc
把第6步生成的Person.pbobjc.h,Person.pbobjc.m 导入工程
把 protobuf-master/objectivec/ 目录下面所有的 .h 和.m 手动导入工程,把该目录下的google文件也会部导入工程
在工程设置 header search path 添加 $(PROJECT_DIR)/GBPDemo , 不然导入上面的google文件夹之后编译会出头文件连接错误;
把GPBProtocolBuffers.m 从工程里面删除掉(这里是官网说的https://github.com/google/protobuf/tree/master/objectivec)
导入之后的工程结构如下
以上配置完成之后,编译就正常通过了
8. 测试使用protobuf
在工程ViewController.m 里面导入
#import "GPBProtocolBuffers.h"
#import "Person.pbobjc.h"
如下代码
Person *pe =[[Person alloc]init];
pe.name= @"jobs";
pe.age= 86;
pe.address= @"Beijing";//以下是效率对比//protocbufer
NSLog(@"protocbufer: %@",pe);
NSLog(@"%lu",[pe data].length);//json
NSDictionary *pj = @{@"name":@"jobs",@"age":@86,@"address":@"Beijing"};
NSData*jsd = [NSJSONSerialization dataWithJSONObject:pj options:0error:nil];
NSLog(@"JSON: %@",pj);
NSLog(@"%lu", jsd.length);//xml
NSString *xml = @"jobs86
Beijing";NSData*xmlData =[xml dataUsingEncoding:NSUTF8StringEncoding];
NSLog(@"XML: %@",xml);
NSLog(@"%lu",xmlData.length);
[pe release];
执行结果:
从上可以看出:
同样的数据:
protubuf:占17个字节
json: 44个字节
xml:56个字节
以上就是效率上的测试使用
9. 总结
数据按照protobuf封装可以通过网络传给后台,后台同样使用protobuf处理;
会非常的方便的高效;后台定义一份proto数据格式,然后生成其他平台的代码,集成调用非常的方便,也偏于维护和扩展;
更新关于protobuf的数据格式,组合语法可以参考官方文档说明
10:上述的 iOS 示例工程
https://github.com/cocoajin/TDDDemo/tree/master/GBPDemo
参考:
https://github.com/google/protobuf
http://www.ibm.com/developerworks/cn/linux/l-cn-gpb/
https://my.oschina.net/kgdugyiy/blog/538333
原文:http://www.cnblogs.com/cocoajin/p/6100841.html