Protocol Buffer(簡稱Protobuf或PB)是由Google推出的一種數據交換格式. 與傳統的XML和JSON不一樣的是,它是一種二進制格式,免去了文本格式轉換的各類困擾,而且轉換效率也是很是快,因爲它的跨平臺、跨編程語言的特色,讓它愈來愈普及,尤爲是網絡數據交換方面日趨成爲一種主流.html
對於json和xml最終在網絡傳輸時都是以字符串轉二進制的進行傳輸的,使用的是utf8編碼格式,而PB在編碼與解碼上進行了改進,使數據包更小,因此我以爲能夠把他當作一種壓縮格式.這裏有一篇關於原理的博文,感興趣你們能夠去看一看 Protocol Buffer 序列化原理大揭祕 - 爲何Protocol Buffer性能這麼好?ios
咱們須要安裝PB的編譯器,將咱們用PB語法格式建立的對象轉化爲OC或Swift的對象,原來PB只支持Python,Java,C++,如今新的版本支持OC,Swift須要咱們額外配置一下,期待之後的更新吧.這是github的連接git
解壓縮後,cd到其目錄下執行下面的終端命令進行安裝github
$ ./autogen.sh
$ ./configure
$ make
$ make check
$ sudo install
複製代碼
安裝結束後,執行 protoc --version ,如有顯示版本號,則代表安裝成功.如果要試用Swift則須要編程
$ brew install protobuf-swift
$ git clone https://github.com/alexeyxo/protobuf-swift.git
//cd到clone後的目錄
$ ./scripts/build.sh
複製代碼
接下來就是建立proto文件,將其翻譯爲OC或Swift,因此先了解proto的語法json
接下來我只介紹些經常使用語法,這裏有介紹語法比較詳細的博文 這是一份頗有誠意的Protocol Buffer語法詳解 Protobuf3 語法指南 swift
//表示使用的是PB3的語法
syntax = "proto3";
//message表明着一個數據結構,也就至關於一個類, 類名Person
message Person {
string name = 1;
int32 age = 2;
repeated int32 friends = 3;
//這裏就至關於類中的屬性,string表示類型爲字符串,name表示屬性名,數字1則是用來標識Person中的屬性,在編解碼時用到,使用從1遞增便可,這樣效率高些
}
複製代碼
接下來是關於PB的數據結構類型,由於要控制數據編碼後大小,因此類型比較多數組
對應到iOS的OC和Swift中,上面就包含了所需的基本數據類型了,一個message,其實就能夠看作一個字典.至於數組就比較特別了,而是要在基本的數據結構前 加上可複用的修飾符 repeated 就如上面的friends同樣.bash
OC網絡
進入proto文件目錄 執行下面的命令
$ protoc --objc_out=./ ./test.proto
複製代碼
Swift
進入proto文件目錄 執行下面的命令
$ mbp$ protoc --swift_out=./ ./test.proto
複製代碼
這樣就獲得了,翻譯後所需的類文件了,接下來就要到項目中集成了
##項目集成 在項目中使用PB須要使用第三方庫,可使用CocoaPod集成
OC:
pod "Protobuf"
Swift:
pod 'ProtocolBuffers-Swift'
複製代碼
對於OC版本,拖進項目後要再作一些額外處理,生成的是MRC環境下的代碼,須要設置一下, 其次再編譯後會報一些錯誤,據我所知的處理方案是將其註釋掉(我瞭解到的是該方法在C99後失效了,至於爲什麼這裏還有,我也很無奈ㄟ( ▔, ▔ )ㄏ,到Github上反應了).這樣就可使用了. 而後就是PB的序列化與反序列化
OC
Person* p = [Person new];
p.name = @"南小鳥";
p.age = 18;
p.friendsArray = [GPBInt32Array array]; //這是裏面的數組,其餘方法能夠點進去看
[p.friendsArray addValue:10];
NSString* jsonStr = @"{\"name\":\"南小鳥\",\"age\":18,\"friendsArray\":[10]}";
NSData* data = [p data]; //序列化
NSData* strData = [jsonStr dataUsingEncoding:(NSUTF8StringEncoding)];
NSLog(@"PB --> %ld JSON --> %ld",data.length,strData.length);
//反序列化
Person* res = [[Person alloc] initWithData:data error:nil];
NSLog(@"%@,%ld,%@",res.name,res.age,res.friendsArray);
複製代碼
運行結果:
PB --> 16 JSON --> 49
南小鳥,18,<GPBInt32Array 0x600000059200> { 10 }
複製代碼
Swift
//建立新的對象,經過Builder來進行建立,賦值.
let p = Person.Builder()
p.name = "南小鳥"
p.age = 18
p.friends = [10]
//getMessage能夠獲得該對象,而後將其序列化
let data = p.getMessage().data()
//將其反序列化,可能出錯,須要try
let res = try! Person.parseFrom(data: data)
複製代碼
最後說一說PB的優缺點
優勢
1,數據壓縮效果好,序列化反序列速度快
2,跨平臺,生成一次proto文件,多端使用
複製代碼
缺點
1,可讀性行差(在代碼中)
2,最增長App包體積(生成的類自己就代碼不少,並且須要使用第三方庫)
3,用的人少(在項目交接時,還須要學習這方面的知識)
複製代碼
綜上:我的以爲該方案適用於大量頻繁的數據交流業務中,如IM 如有不許確的地方,歡迎你們指正