protobuf3.0之後已經很好用了,swift版也有,但網上教程很多已經很老了,不適用了,所以寫個新的
總的過程是3步:
1.編譯安裝.proto格式轉換器; 2.引入相應版本的protobuf(多用CocoaPods); 3.命令列轉換成OC或swift檔案並拖入專案中;
第一步alexeyxo大神(方法二)用了Homebrew全自動安裝,最方便,蘋果(方法三)和谷歌(方法一)的需要手動輸入命令,蘋果還要手動放到/usr/local/bin/目錄下,較為複雜,不過目前蘋果正在快速更新,估計以後就更好用了
方法一:安裝編譯google官方的OC, protobuf3.0以後
參考文章http://blog.csdn.net/mtc1256/article/details/52180929
- 編譯和安裝 直接在github.com/google/prot… 找到已經編譯好的objectivec版本下載就行了.
下載好之後開始安裝
cd protobuf-3.0.0
./configure
make -j8
sudo make install
複製程式碼
驗證是否安裝成功
$ which protoc
/usr/local/bin/protoc
複製程式碼
- 用pod引入專案中
pod 'Protobuf', '~> 3.2.0'
複製程式碼
- 寫一個測試指令碼生成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進入Person.proto所在的資料夾下,執行命令
protoc --objc_out=. Person.proto
複製程式碼
然後在gen資料夾下就會生成Person.pbobjc.h和Person.pbobjc.m檔案。 protobuf為了效能考慮,建立的都是mrc檔案,因此在build phrases ->Compile sources中給拖入的檔案新增 -fno-objc-arc的標誌
- 簡單使用
//建立,直直接賦值
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版本後已經提供了OC版,所以只有swift版還在更新 地址裡面也有操作步驟說明https://github.com/alexeyxo
推薦使用Homebrew自動安裝+pod引用的方式
- 安裝編譯 利用Homebrew自動安裝(建議使用)
1.ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
2.brew install protobuf-swift
複製程式碼
或手動編譯
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
複製程式碼
- 編譯安裝後引入專案中 手動新增 ./src/ProtocolBuffers/ProtocolBuffers.xcodeproj 到自己的專案 也可以使用pod方式(建議使用)
use_frameworks!
pod 'ProtocolBuffers-Swift'
複製程式碼
- 輸出到當前目錄 cd到Person.proto目錄,執行下列,得到Person.proto.swift檔案,拖入專案中即可
protoc Person.proto --swift_out="./"
複製程式碼
- 簡單使用
//建立:用builder賦值,得到的是Person.Builder類,不是模型
let myPersonBuilder = Person.Builder()
myPersonBuilder.name = "coderXu"
myPersonBuilder.level = 100
myPersonBuilder.icon = "123.png"
//轉成data,需要用到build()來得到真正的模型person例項
guard let myPerson = try? myPersonBuilder.build() else { return }
let data = myPerson.data()
//從data轉回來
let myPerson2 = try? Person.parseFrom(data: data)
print(myPerson2.name)
print(myPerson2.level)
print(myPerson2.icon)
複製程式碼
方法三:使用蘋果官方提供的swift版
參考https://github.com/apple/swift-protobuf
需要注意:如果已經使用了方法二的第三方swift版,需要執行brew uninstall protobuf-swift解除安裝掉
否則會和蘋果官方的swift轉換工具衝突,因為兩個都叫protoc-gen-swift,但是轉換出來的格式不一樣,蘋果官方得到的叫Person.pb.swift,而第三方的叫Person.proto.swift,而且會報錯import ProtocolBuffers找不到no such module ProtocolBuffers
- 編譯和安裝 先下載,進入,列出tag,切換到對應分支,然後build
$ git clone https://github.com/apple/swift-protobuf.git
$ cd swift-protobuf
$ git tag -l
$ git checkout tags/[tag_name]
$ swift build
複製程式碼
然後進入.build/debug資料夾下,找到protoc-gen-swift,這是一個可執行檔案,複製一份放到系統的PATH環境目錄下,在mac也就是磁碟/usr/local/bin下面 其中protoc是方法一谷歌生成OC版轉換器
需要注意:如果已經使用了方法二的第三方swift版,需要先執行brew uninstall protobuf-swift解除安裝掉 否則會和蘋果官方的swift轉換工具衝突,因為兩個都叫protoc-gen-swift,但是轉換出來的格式不一樣,蘋果官方得到的叫Person.pb.swift,而第三方的叫Person.proto.swift,而且會報錯import ProtocolBuffers找不到no such module ProtocolBuffers
- 引入專案 推薦用pod,pod install
pod 'SwiftProtobuf'
複製程式碼
- 轉換輸出 cd到Person.proto目錄,執行下列系統會自動PATH環境目錄下的protoc-gen-swift轉換,得到Person.pb.swift檔案,拖入專案中即可
protoc --swift_out=. Person.proto
複製程式碼
- 簡單使用
//直接初始化一個Person例項
var myPerson = Person()
//賦值
myPerson.name = "sss"
myPerson.level = 4
myPerson.icon = "444.jpg"
print(myPerson)
//預設情況下,要求必須有值時(required),如果賦值不完整時,這一步會報錯
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)
//要求必須有值時(required),賦值不完整時也可以通過引數partial: true來強制轉換出來
guard let data2 = try? myPerson.serializedData(partial: true) else {print("error")
return}
print("========serializedData=\(data2)")
//同理,data2中的資料不完整也可以通過引數partial: true來強制轉換出來
guard let myPerson3 = try? person(serializedData: data2, partial: true) else {
print("error")
return
}
print(myPerson3)
複製程式碼
//json格式字串初始化,可以將字典序列化為Data後再轉換為String得到
let jsonString = "{\"name\":\"xu\",\"icon\":\"321.jpg\",\"level\":2}"
//Person(jsonString: jsonString)
//Person(textFormatString: textString)
//建立:得到模型
guard var myPerson = try? Person(jsonString: jsonString) else {
print("error")
return
}
//修改
myPerson.icon = "li.png"
print(myPerson)
//得到Protocol Buffer二進位制序列化的data,一般用來傳輸
guard let data = try? myPerson.serializedData() else {
print("error")
return}
print("=========\(data)")
//從Protocol Buffer二進位制序列化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轉換的data,一般用來內部使用
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:
//學生模型
message student{
required string name = 1; //姓名
required int32 age = 2; //年齡
optional string addr = 3;
}
//班級模型,包含班級名和學生
message class{
required string name = 1; //班級名稱
repeated student member = 2; //班級成員
}
複製程式碼
初始化時的textFormat格式應為
name: "Communication 2004"
member {
name: "flyan338"
age: 26
addr: "china"
}
member {
name: "likeliu"
age: 25
addr: "china"
}
member {
name: "gaoy"
age: 24
addr: "American"
}
複製程式碼
這份配置表明:一個叫做 "Communication 2004"的班級,有3個student,你可以直接用protobuf來load出來