ProtoBuf簡介
Protocol Buffer的簡稱。Google旗下的一款平臺無關,語言無關,可擴展的序列化結構數(shù)據(jù)格式,適合用于數(shù)據(jù)存儲,作為不同應用、語言之間相互通信的數(shù)據(jù)交換格式,序列化后的數(shù)據(jù)為二進制數(shù)據(jù)(pb格式的數(shù)據(jù)),類比XML、JSON。本文記錄的是ProtoBuf在iOS平臺oc語言的使用,ProtoBuf3.0.0以上才官方支持Objective-C,低于3.0.0的請忽略或使用第三方轉換工具,并且基于性能原因沒有使用ARC,但可以被ARC代碼調用。
Objective-C的protobuf庫,下載地址為
https://github.com/google/protobuf/releases
使用流程:
轉換:使用轉換的二進制工具protoc,將XXX.proto文件轉成Objective C文件,即XXX.h和XXX.m文件。
集成:在iOS項目中加入protobuf庫以及上述生成的OC文件
集體步驟:
1.生成protoc
如果沒有裝autoconf automake libtool需要先裝這幾個,這里使用brew來安裝,在shell執(zhí)行 brew install autoconf automake libtool即可,如果沒有brew請自行先安裝brew。 cd進入已下載的protobuf庫文件下,執(zhí)行以下命令:
./autogen.sh
./configure
make
make check
sudo make install
再執(zhí)行 :
./objectivec/DevTools/full_mac_build.sh
執(zhí)行完后會看到src目錄下生成了protoc二進制文件
注意:cd進入已下載的protobuf庫文件路徑不要用空格,libtool無法識別路徑中的空格,make會失敗。本人踩過的坑,浪費時間。
2.使用protoc轉換
創(chuàng)建proto文件,比如Student.proto
syntax = "proto3";
message Student
{
required int32 age = 1;
required string name = 2;
optional string address = 3;
}
在src目錄(protoc所在目錄)執(zhí)行
protoc --proto_path=... --objc_out=... XXX.proto
其中proto_path是創(chuàng)建的proto文件所在目錄,objc_out為Objective-C文件輸出路徑,XXX.proto是創(chuàng)建的proto文件,可以一次轉換多個proto文件,加在XXX.proto后面即可。
如:protoc --proto_path=/Users/admin/Desktop/src --objc_out=/Users/admin/Desktop/dist Student.proto
3.集成
將生成的Ojective-C文件(上面例子的Student.pbobjc.h和Student.pbobjc.m)放到項目中,如果項目使用了ARC,要將.m(例子的Student.pbobjc.m)的Complier Flags設為-fno-objc-arc。(protobuf基于性能原因沒有使用ARC)
加入protobuf庫,有兩種方式
第一種是使用CocoaPods集成。
使用CocoaPods集成,有一個現(xiàn)成的pod可以使用–Protobuf,可以pod search Protobuf搜索查看詳情,pod內容為
platform :ios, '7.1'
pod 'Protobuf', '~> 3.1.0'
需要注意的是 platform :ios, ‘7.1’
7.1及以上才能導入這個庫,這種方式優(yōu)點是操作簡單,缺點是platform :ios, ‘7.1’ 要7.1或以上
第二種是把相關文件拖入項目中。
拖入相關文件到項目中,將objectivec文件夾下的所有的.h文件和.m文件(除了GPBProtocolBuffers.m)(GPB開頭的那些文件)以及整個google文件夾add到項目中,如果項目中使用了ARC需要將以上所有.m文件的的Complier Flags設為-fno-objc-arc。這種方法的優(yōu)點是靈活性強,沒有7.1的束縛。缺點是操作麻煩點,如果用了ARC的話還要手動添加-fno-objc-arc(使用CocoaPods集成會自動添加)
簡單使用,示例代碼:
- (void)viewDidLoad {
[super viewDidLoad];
Student *student = [[Student alloc] init];
student.age = 18;
student.name = @"XiaoMing";
student.address = @"Beijing";
NSData *data = [student data];
NSLog(@"序列化:%@",data);
Student *s = [Student parseFromData:data error:nil];
NSLog(@"反序列化:%@",s);
}