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
- 编译和安装
直接在https://github.com/google/protobuf/releases 找到已经编译好的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出来