iOS引入google ProtocolBuffer(protobuf3)

protobuf3.0之后已經(jīng)很好用了,swift版也有,但網(wǎng)上教程很多已經(jīng)很老了,不適用了,所以寫個(gè)新的

總的過程是3步:
1.編譯安裝.proto格式轉(zhuǎn)換器;
2.引入相應(yīng)版本的protobuf(多用CocoaPods);
3.命令行轉(zhuǎn)換成OC或swift文件并拖入項(xiàng)目中;

第一步alexeyxo大神(方法二)用了Homebrew全自動(dòng)安裝,最方便,蘋果(方法三)和谷歌(方法一)的需要手動(dòng)輸入命令,蘋果還要手動(dòng)放到/usr/local/bin/目錄下,較為復(fù)雜,不過目前蘋果正在快速更新,估計(jì)以后就更好用了

方法一:安裝編譯google官方的OC, protobuf3.0以后

參考文章http://blog.csdn.net/mtc1256/article/details/52180929

下載好之后開始安裝

cd protobuf-3.0.0
./configure
make -j8
sudo make install

驗(yàn)證是否安裝成功

$ which protoc
/usr/local/bin/protoc
  • 用pod引入項(xiàng)目中
pod 'Protobuf', '~> 3.2.0'
  • 寫一個(gè)測試腳本生成proto代碼

Person.proto

syntax = "proto3";
package com.xxx;
option swift_prefix = "TCC";//swift類前綴,適用于方法三
option objc_class_prefix = "TCC";//OC類前綴,適用于方法一
message Person{
 string name = 1;
 int32 level = 2;
 string icon = 3;
}

或者proto2語法

syntax = "proto2";

message Person {
    required string name = 1;
    required int32 level = 2;
    required string icon = 3;
}

代碼直接生成.h和.m
舉例:cd進(jìn)入Person.proto所在的文件夾下,執(zhí)行命令

protoc  --objc_out=. Person.proto

然后在gen文件夾下就會(huì)生成Person.pbobjc.h和Person.pbobjc.m文件谴餐。
protobuf為了性能考慮,創(chuàng)建的都是mrc文件,因此在build phrases ->Compile
sources中給拖入的文件添加 -fno-objc-arc的標(biāo)志

  • 簡單使用
//創(chuàng)建,直直接賦值
Person *myPerson = [Person alloc] init];
myPerson.name = @"xu";
myPerson.level = 4;
myPerson.icon = @"123.jpg";
//得到data
NSData *data = myPerson.data;
NSLog(@"%@",data);
//從data得到模型
NSError *error = nil;
Person *myPerson2 = [Person parseFromData:data error:&error];
NSLog(@"%@",myPerson2.description);

方法二:使用別人編譯好的,包括OC,swift

參考http://www.cnblogs.com/akforsure/p/5190187.html
github上有大神提供了編譯好的OC和swift版protobuf.由于目前谷歌官方在3.0版本后已經(jīng)提供了OC版,所以只有swift版還在更新
地址里面也有操作步驟說明https://github.com/alexeyxo

推薦使用Homebrew自動(dòng)安裝+pod引用的方式

  • 安裝編譯
    利用Homebrew自動(dòng)安裝(建議使用)
1.ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
2.brew install protobuf-swift

或手動(dòng)編譯

1.ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

2.brew install automake

3.brew install libtool

4.brew install protobuf

5.git clone git@github.com:alexeyxo/protobuf-swift.git

6../scripts/build.sh
  • 編譯安裝后引入項(xiàng)目中
    手動(dòng)添加 ./src/ProtocolBuffers/ProtocolBuffers.xcodeproj 到自己的項(xiàng)目
    也可以使用pod方式(建議使用)
use_frameworks!
pod 'ProtocolBuffers-Swift'
  • 輸出到當(dāng)前目錄
    cd到Person.proto目錄,運(yùn)行下列,得到Person.proto.swift文件,拖入項(xiàng)目中即可
protoc  Person.proto --swift_out="./"
  • 簡單使用
//創(chuàng)建:用builder賦值,得到的是Person.Builder類,不是模型
let myPersonBuilder = Person.Builder()
myPersonBuilder.name = "coderXu"
myPersonBuilder.level = 100
myPersonBuilder.icon = "123.png"
        
//轉(zhuǎn)成data,需要用到build()來得到真正的模型person實(shí)例
guard let myPerson = try? myPersonBuilder.build() else { return }
let data = myPerson.data()

//從data轉(zhuǎn)回來
let myPerson2 = try? Person.parseFrom(data: data)
print(myPerson2.name)
print(myPerson2.level)
print(myPerson2.icon)

方法三:使用蘋果官方提供的swift版

參考https://github.com/apple/swift-protobuf

需要注意:如果已經(jīng)使用了方法二的第三方swift版,需要執(zhí)行brew uninstall protobuf-swift卸載掉
否則會(huì)和蘋果官方的swift轉(zhuǎn)換工具沖突,因?yàn)閮蓚€(gè)都叫protoc-gen-swift,但是轉(zhuǎn)換出來的格式不一樣,蘋果官方得到的叫Person.pb.swift,而第三方的叫Person.proto.swift,而且會(huì)報(bào)錯(cuò)import ProtocolBuffers找不到no such module ProtocolBuffers

  • 編譯和安裝
    先下載,進(jìn)入,列出tag,切換到對(duì)應(yīng)分支,然后build
$ git clone https://github.com/apple/swift-protobuf.git
$ cd swift-protobuf
$ git tag -l
$ git checkout tags/[tag_name]
$ swift build

然后進(jìn)入.build/debug文件夾下,找到protoc-gen-swift,這是一個(gè)可執(zhí)行文件,復(fù)制一份放到系統(tǒng)的PATH環(huán)境目錄下,在mac也就是磁盤/usr/local/bin下面
其中protoc是方法一谷歌生成OC版轉(zhuǎn)換器


WX20170515-230043@2x.png

需要注意:如果已經(jīng)使用了方法二的第三方swift版,需要先執(zhí)行brew uninstall protobuf-swift卸載掉
否則會(huì)和蘋果官方的swift轉(zhuǎn)換工具沖突,因?yàn)閮蓚€(gè)都叫protoc-gen-swift,但是轉(zhuǎn)換出來的格式不一樣,蘋果官方得到的叫Person.pb.swift,而第三方的叫Person.proto.swift,而且會(huì)報(bào)錯(cuò)import ProtocolBuffers找不到no such module ProtocolBuffers

  • 引入項(xiàng)目
    推薦用pod,pod install
pod 'SwiftProtobuf'
  • 轉(zhuǎn)換輸出
    cd到Person.proto目錄,運(yùn)行下列系統(tǒng)會(huì)自動(dòng)PATH環(huán)境目錄下的protoc-gen-swift轉(zhuǎn)換,得到Person.pb.swift文件,拖入項(xiàng)目中即可
protoc --swift_out=.  Person.proto
  • 簡單使用
//直接初始化一個(gè)Person實(shí)例
var myPerson = Person()
//賦值
myPerson.name = "sss"
myPerson.level = 4
myPerson.icon = "444.jpg"
print(myPerson)
//默認(rèn)情況下,要求必須有值時(shí)(required),如果賦值不完整時(shí),這一步會(huì)報(bào)錯(cuò)
guard let data = try? myPerson.serializedData() else {print("error")  return}
print("========serializedData=\(data)")
        
guard let myPerson2 = try? Person(serializedData: data) else {
     print("error")
     return
}
print(myPerson2)
//要求必須有值時(shí)(required),賦值不完整時(shí)也可以通過參數(shù)partial: true來強(qiáng)制轉(zhuǎn)換出來
guard let data2 = try? myPerson.serializedData(partial: true) else {print("error")
     return}
print("========serializedData=\(data2)")
//同理,data2中的數(shù)據(jù)不完整也可以通過參數(shù)partial: true來強(qiáng)制轉(zhuǎn)換出來
guard let myPerson3 = try? person(serializedData: data2, partial: true) else {
     print("error")
     return
}
print(myPerson3)
//json格式字符串初始化,可以將字典序列化為Data后再轉(zhuǎn)換為String得到
let jsonString = "{\"name\":\"xu\",\"icon\":\"321.jpg\",\"level\":2}"
//Person(jsonString: jsonString)
//Person(textFormatString: textString)
//創(chuàng)建:得到模型
guard var myPerson = try? Person(jsonString: jsonString) else {
     print("error")
    return
}
//修改
myPerson.icon = "li.png"
print(myPerson)

//得到Protocol Buffer二進(jìn)制序列化的data,一般用來傳輸
guard let data = try? myPerson.serializedData() else {
    print("error")
    return}
print("=========\(data)")
//從Protocol Buffer二進(jìn)制序列化data 得到模型
guard let myPerson2 = try? Person(serializedData: data) else {
    print("error")
    return
}
print(myPerson2)
//textFormatString格式示例,中間用\n或空格分隔
let textString = "name:\"xu\" icon:\"321.jpg\" level:2"
//得到myPerson模型
guard var myPerson = try? Person(textFormatString: textString) else {
       print("error")
       return
}
//修改模型
myPerson.icon = "li.png"
print(myPerson)

//得到UTF-8 JSON序列化的data,這樣沒用到protobuf,是用iOS的JSON serialization轉(zhuǎn)換的data,一般用來內(nèi)部使用
guard let data2 = try? myPerson.jsonUTF8Data() else {print("error")
    return}
print("========jsonUTF8Data=\(data2)")
//從UTF-8 JSON序列化的data 得到模型
guard let myPerson3 = try? Person(jsonUTF8Data: data2) else {
     print("error")
    return
}
print(myPerson3)

最后,protobuf的textFormat格式舉例:
文件定義test.proto:

//學(xué)生模型
message student{  
    required string name = 1;   //姓名  
    required int32  age = 2;    //年齡  
    optional string addr = 3;  
}  
  
//班級(jí)模型,包含班級(jí)名和學(xué)生  
message class{  
    required string name = 1;   //班級(jí)名稱  
    repeated student member = 2;    //班級(jí)成員 
}

初始化時(shí)的textFormat格式應(yīng)為

name: "Communication 2004"  
member {  
  name: "flyan338"  
  age: 26  
  addr: "china"  
}  
member {  
  name: "likeliu"  
  age: 25  
  addr: "china"  
}  
member {  
  name: "gaoy"  
  age: 24  
  addr: "American"  
}  

這份配置表明:一個(gè)叫做 "Communication 2004"的班級(jí)偶摔,有3個(gè)student昭躺,你可以直接用protobuf來load出來

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末近弟,一起剝皮案震驚了整個(gè)濱河市壳鹤,隨后出現(xiàn)的幾起案子京髓,更是在濱河造成了極大的恐慌盟劫,老刑警劉巖夜牡,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異侣签,居然都是意外死亡塘装,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門硝岗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來氢哮,“玉大人袋毙,你說我怎么就攤上這事型檀。” “怎么了听盖?”我有些...
    開封第一講書人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵胀溺,是天一觀的道長。 經(jīng)常有香客問我皆看,道長仓坞,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任腰吟,我火速辦了婚禮无埃,結(jié)果婚禮上徙瓶,老公的妹妹穿的比我還像新娘。我一直安慰自己嫉称,他們只是感情好侦镇,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著织阅,像睡著了一般壳繁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上荔棉,一...
    開封第一講書人閱讀 51,208評(píng)論 1 299
  • 那天闹炉,我揣著相機(jī)與錄音,去河邊找鬼润樱。 笑死渣触,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的壹若。 我是一名探鬼主播昵观,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼舌稀!你這毒婦竟也來了啊犬?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤壁查,失蹤者是張志新(化名)和其女友劉穎觉至,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體睡腿,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡语御,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了席怪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片应闯。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖挂捻,靈堂內(nèi)的尸體忽然破棺而出碉纺,到底是詐尸還是另有隱情,我是刑警寧澤刻撒,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布骨田,位于F島的核電站,受9級(jí)特大地震影響声怔,放射性物質(zhì)發(fā)生泄漏态贤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一醋火、第九天 我趴在偏房一處隱蔽的房頂上張望悠汽。 院中可真熱鬧箱吕,春花似錦、人聲如沸柿冲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽姻采。三九已至雅采,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間慨亲,已是汗流浹背婚瓜。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留刑棵,地道東北人巴刻。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓,卻偏偏與公主長得像蛉签,于是被迫代替她去往敵國和親胡陪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354