本文作者:丁同舟,來自金蝶隨手記技術團隊。
1、前言
本文接上篇《金蝶隨手記團隊分享:還在用JSON? Protobuf讓數據傳輸更省更快(原理篇)》,以iOS端的Objective-C代碼為例,向您演示如何使用Protobuf。
學習交流:
- 即時通訊開發交流群:320837163[推薦]
- 移動端IM開發入門文章:《新手入門一篇就夠:從零開發移動端IM》
(本文同步發布于:http://www.52im.net/thread-1515-1-1.html)
2、系列文章
本文是系列文章中的第2篇,總目錄如下:
《金蝶隨手記團隊分享:還在用JSON? Protobuf讓數據傳輸更省更快(原理篇)》
《金蝶隨手記團隊分享:還在用JSON? Protobuf讓數據傳輸更省更快(實戰篇)》(本文)
另外,如果您還打算系統地了解IM的開發知識,可以閱讀《新手入門一篇就夠:從零開發移動端IM》。
3、參考資料
《Protobuf通信協議詳解:代碼演示、詳細原理介紹等》
《一個基于Protocol Buffer的Java代碼演示》
《如何選擇即時通訊應用的數據傳輸格式》
《強列建議將Protobuf作為你的即時通訊應用數據傳輸格式》
《全方位評測:Protobuf性能到底有沒有比JSON快5倍?》
《移動端IM開發需要面對的技術問題(含通信協議選擇)》
《簡述移動端IM開發的那些坑:架構設計、通信協議和客戶端》
《理論聯系實際:一套典型的IM通信協議設計詳解》
《詳解如何在NodeJS中使用Google的Protobuf》
>> 更多同類文章 ……
4、基本介紹
Protocol buffers為 Google 提出的一種跨平臺、多語言支持且開源的序列化數據格式。相對于類似的 XML 和 JSON,Protocol buffers 更為小巧、快速和簡單。其語法目前分為proto2和proto3兩種格式。
目前 Google 官方的 Protobuf最新 release 版本為3.5.1,以下都是基于此版本的環境搭建。
關于 Protocol Buffer 的使用可以查閱官方文檔:https://developers.google.com/protocol-buffers/docs/overview。
5、準備工作
5.1 環境要求
Objective-C 2.0 Runtime (32bit & 64bit iOS, 64bit OS X)
Xcode 7.0+
注意:
Protobuf 出于性能考慮沒有使用 ARC,但在 ARC 下是可以使用的。
5.2 安裝
下載 Protobuf 代碼包(https://github.com/google/protobuf/releases),這里選擇 protobuf-objectivec-3.5.1.tar.gz。
5.3 解壓代碼包
編譯 Protobuf,這里可能需要安裝部分工具:
$ brew install autoconf
$ brew install automake
$ brew install libtool
運行下面腳本進行編譯:
$ ./autogen.sh
$ ./configure
$ make
$ makeinstall
檢查protobuf是否安裝成功:
$ protoc --version
如果成功打印版本號則安裝成功:
libprotoc 3.5.1
6、在 iOS 中使用 Protobuf
6.1 創建.proto文件
這里使用官方文檔上的一份示例數據結構創建Person.proto:
syntax = "proto3";
message Person {
string name = 1;
int32 id = 2;
string email = 3;
enumPhoneType {
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=./
6.2 引入 Protobuf 運行時資源
Google 官方的文檔提供了兩種引入方式,但使用第一種的時候編譯不能通過,所以這里選擇了第二種:
復制protobuf目錄下的:objectivec/*.h, objectivec/google/protobuf/*.pbobjc.h, objectivec/google/protobuf/*.pbobjc.m, 以及除去objectivec/GPBProtocolBuffers.m后的objectivec/*.m。
這里直接用命令行操作,首先進入protobuf下objectivec的目錄:
$ cdprotobuf-3.5.1/objectivec
然后復制符合規則的文件到指定的工程目錄下:
$mkdir~/ProtobufDemo/ProtocolBuffers~/ProtobufDemo/ProtocolBuffers/google~/ProtobufDemo/ProtocolBuffers/google/protobuf
$ cp*.h *.m ~/ProtobufDemo/ProtocolBuffers
$ cpgoogle/protobuf/*.pbobjc.h google/protobuf/*.pbobjc.m ~/ProtobufDemo/ProtocolBuffers/google/protobuf
注意:
上面的命令并沒有排除 GPBProtocolBuffers.m 文件,引入時需要手動排除。
現在把ProtocolBuffers目錄下所有文件以及上面編譯出來的Person.pbobjc.h和Person.pbobjc.m都引入到工程中。
現在工程目錄結構大概是長這樣:
需要注意,由于protobuf沒有使用 ARC,因此需要為所有.m文件加上-fno-objc-arc來關閉 ARC:
注意:
需要注意工程中的 Header Search Paths 要增加 $(PROJECT_DIR)/ProtocolBuffers(具體的路徑視情況而定)
6.3 直接引入 ProtocolBuffers 工程
如果覺得手動引入文件的方式過于復雜,可以直接引入ProtocolBuffers工程作為依賴項:
1)進入解壓后的protobuf目錄下,復制objective目錄下的所有文件到ProtobufDemo/ProtocolBuffers目錄下;
2)在ProtobufDemo工程中引入ProtocolBuffers_iOS工程:
3)在Build Phases中加入依賴關系并鏈接庫:
4)引入Person.pbobjc.h和Person.pbobjc.m文件并為.m加上-fno-objc-arc;
5)修改工程配置中部分路徑為 $(PROJECT_DIR)/ProtocolBuffers。
6.4 運行測試
首先引入頭文件:
#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:
: {
name: "person1"
id: 1
email: "123@qq.com"
}
Data: <0a077065 72736f6e 3110011a 0a313233 4071712e 636f6d>
Data Length: 23
Decoded: : {
name: "person1"
id: 1
email: "123@qq.com"
}
Coffee time!
(本文同步發布于:http://www.52im.net/thread-1515-1-1.html)