簡介:php
protobuf 即 google protocol buffer 是一種數據封裝格式協議;java
好比其餘常常用的xml,json等格式;protobuf的優點是效率高,一樣的一份數據使用protobuf存儲的時候更小,更加方便;python
官網:linux
https://developers.google.com/protocol-buffers/git
https://github.com/google/protobufgithub
在iOS上的使用json
目前最新的版本須要xcode7.0+,以及不支持ARCxcode
1. 從github上面下載所有代碼ruby
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 sh full_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 for imports. May be specified multiple times; directories will be searched in order. If not given, the current working directory is used. --version Show version info and exit. -h, --help Show this text and exit. --encode=MESSAGE_TYPE Read a text-format message of the given type from standard input and write it in binary to standard output. The message type must be defined in PROTO_FILES or their imports. --decode=MESSAGE_TYPE Read a binary message of the given type from standard input and write it in text format to standard output. The message type must be defined in PROTO_FILES or their imports. --decode_raw Read an arbitrary protocol message from standard input and write the raw tag/value pairs in text format to standard output. No PROTO_FILES should be given when using this flag. -oFILE, Writes a FileDescriptorSet (a protocol buffer, --descriptor_set_out=FILE defined in descriptor.proto) containing all of the input files to FILE. --include_imports When using --descriptor_set_out, also include all dependencies of the input files in the set, so that the set is self-contained. --include_source_info When using --descriptor_set_out, do not strip SourceCodeInfo from the FileDescriptorProto. This results in vastly larger descriptors that include information about the original location of each decl in the source file as well as surrounding comments. --dependency_out=FILE Write a dependency output file in the format expected by make. This writes the transitive set of input file paths to FILE --error_format=FORMAT Set the format in which 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 defined in the given proto files. Groups share the same field number space with the parent message. Extension ranges are counted as occupied fields numbers. --plugin=EXECUTABLE Specifies a plugin executable to use. Normally, protoc searches the PATH for plugins, but you may specify additional executables not in the path using this flag. Additionally, EXECUTABLE may be of the form NAME=PATH, in which case the given plugin name is mapped to the given executable even if the 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.
生成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:0 error:nil]; NSLog(@"JSON: %@",pj); NSLog(@"%lu", jsd.length); //xml NSString *xml = @"<name>jobs</name><age>86</age><address>Beijing</address>"; 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
protobuf靜態類庫方式 demo https://github.com/cocoajin/TDDDemo/tree/master/PGBlibT
參考:
https://github.com/google/protobuf
http://www.ibm.com/developerworks/cn/linux/l-cn-gpb/
https://my.oschina.net/kgdugyiy/blog/538333