使用
protocolbuffer(以下简称PB)是google 的一种数据交换的格式,它独立于语言,独立于平台。google 提供了多种语言的实现:java、c++、go 和 python,每一种实现都包含了相应语言的编译器以及库文件。由于它是一种二进制的格式,比使用 xml 进行数据交换快许多。可以把它用于分布式应用之间的数据通信或者异构环境下的数据交换。作为一种效率和兼容性都很优秀的二进制数据传输格式,可以用于诸如网络传输、配置文件、数据存储等诸多领域(以上是复制的百度…一般都是用在网络通讯时序列化反序列化用的)。
1.首先你得知道要用到brew 查看是干什么的
打开终端 万一你已经安了呢 输入:
brew -v
结果如果是这个 那就是没安 (如下结果)
-bash: brew: command not found
显示上边的not found ,则在终端输入这个,来安装HomeBrew
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
终端会往下走。。。 (省略)
最终在看看版本就有了吧
brew -v
Homebrew 2.0.1
2.该安装所需的东西了 一个个的安就好
brew install automake
brew install libtool
brew install protobuf
3.去GitHub上查找相关资源并下载,点击查看:Google/protobuf 的GitHub地址
4.安装完成测试一下把Protocol Buffers 转成oc可用的文件
先找个.proto文件 下载的文件夹中(即在3步骤中链接下载)有这个一个文件 就用它了把他转成oc可用的文件。如下图:
在桌面上建一个文件夹就叫protoBuf, 把这.proto文件拷贝进去
在终端cd到项目文件夹 接着终端输入下面这行 ./是你本身文件的名字 out=后面是你输出文件路径
protoc ./addressbook.proto --objc_out=./
命令操作,如图1:
可以看到生成的oc .h 和.m文件了,如图2:
5.到现在应该是安装和基本准备工作完了,来使用一下吧 使用cocoapods 导入 你也可以搜一下版本 安一个3.0以上的版本就好(3.0才正式支持oc)
# Google Protobuf
pod 'ProtocolBuffers', '~> 1.9.11'
pod 'Protobuf', '~> 3.6.1'
注意:这两个框架一个是协议,一个是路径配置文件;缺一不可。
6.新建个测试项目吧 把刚才生成的.m和.h拖入项目中,如图:
编译会报错,因为不支持ARC环境 官方说明 需把关闭.m文件的ARC 加上这个:-fno-objc-arc
官方解释截图如下:
在项目的target中做一下修改,如图:
在重新编译就OK了。
查看项目的文件:.proto 文件(注释在代码里边哈)
// See README.txt for information and build instructions.
//
// Note: START and END tags are used in comments to define sections used in
// tutorials. They are not part of the syntax for Protocol Buffers.
//
// To get an in-depth walkthrough of this file and the related examples, see:
// https://developers.google.com/protocol-buffers/docs/tutorials
// [START declaration]
syntax = "proto3";//(文件的第一行指定了你正在使用proto3语法:如果你没有指定这个,编译器会使用proto2。这个指定语法行必须是文件的非空非注释的第一个行。具体语法自行百度哈)
package tutorial;//(自定义包名)
import "google/protobuf/timestamp.proto";
// [END declaration]
// [START java_declaration]
//(java 可忽略)
option java_package = "com.example.tutorial";
option java_outer_classname = "AddressBookProtos";
// [END java_declaration]
// [START csharp_declaration]
//(C# 可忽略)
option csharp_namespace = "Google.Protobuf.Examples.AddressBook";
// [END csharp_declaration]
// [START messages]
message Person {
string name = 1;
int32 id = 2; // Unique ID number for this person.
string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
string number = 1;
PhoneType type = 2;
}
repeated PhoneNumber phones = 4;
//(repeated:在一个格式良好的消息中,这种字段可以重复任意多次(包括0次)。重复的值的顺序会被保留。在proto3中,repeated的标量域默认情况虾使用packed。)
google.protobuf.Timestamp last_updated = 5;
}
//[test objc]
message ExterBook{
string exterDetial = 1;
string exterNote = 2;
string exterTest = 3;
}
// Our address book file is just one of these.
message AddressBook {
repeated Person people = 1;
ExterBook exterBook = 2;
}
// [END messages]
生成的 .pbobje.h 文件(.h和.m文件是自动生成的,主要详细看.proto文件)
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: addressbook.proto
// This CPP symbol can be defined to use imports that match up to the framework
// imports needed when using CocoaPods.
#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS)
#define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0
#endif
#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
#import <Protobuf/GPBProtocolBuffers.h>
#else
#import "GPBProtocolBuffers.h"
#endif
#if GOOGLE_PROTOBUF_OBJC_VERSION < 30002
#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources.
#endif
#if 30002 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION
#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources.
#endif
// @@protoc_insertion_point(imports)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
CF_EXTERN_C_BEGIN
@class ExterBook;
@class GPBTimestamp;
@class Person;
@class Person_PhoneNumber;
NS_ASSUME_NONNULL_BEGIN
#pragma mark - Enum Person_PhoneType
typedef GPB_ENUM(Person_PhoneType) {
/**
* Value used if any message's field encounters a value that is not defined
* by this enum. The message will also have C functions to get/set the rawValue
* of the field.
**/
Person_PhoneType_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,
Person_PhoneType_Mobile = 0,
Person_PhoneType_Home = 1,
Person_PhoneType_Work = 2,
};
GPBEnumDescriptor *Person_PhoneType_EnumDescriptor(void);
/**
* Checks to see if the given value is defined by the enum or was not known at
* the time this source was generated.
**/
BOOL Person_PhoneType_IsValidValue(int32_t value);
#pragma mark - AddressbookRoot
/**
* Exposes the extension registry for this file.
*
* The base class provides:
* @code
* + (GPBExtensionRegistry *)extensionRegistry;
* @endcode
* which is a @c GPBExtensionRegistry that includes all the extensions defined by
* this file and all files that it depends on.
**/
@interface AddressbookRoot : GPBRootObject
@end
#pragma mark - Person
typedef GPB_ENUM(Person_FieldNumber) {
Person_FieldNumber_Name = 1,
Person_FieldNumber_Id_p = 2,
Person_FieldNumber_Email = 3,
Person_FieldNumber_PhonesArray = 4,
Person_FieldNumber_LastUpdated = 5,
};
/**
* [START messages]
**/
@interface Person : GPBMessage
@property(nonatomic, readwrite, copy, null_resettable) NSString *name;
/** Unique ID number for this person. */
@property(nonatomic, readwrite) int32_t id_p;
@property(nonatomic, readwrite, copy, null_resettable) NSString *email;
@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<Person_PhoneNumber*> *phonesArray;
/** The number of items in @c phonesArray without causing the array to be created. */
@property(nonatomic, readonly) NSUInteger phonesArray_Count;
@property(nonatomic, readwrite, strong, null_resettable) GPBTimestamp *lastUpdated;
/** Test to see if @c lastUpdated has been set. */
@property(nonatomic, readwrite) BOOL hasLastUpdated;
@end
#pragma mark - Person_PhoneNumber
typedef GPB_ENUM(Person_PhoneNumber_FieldNumber) {
Person_PhoneNumber_FieldNumber_Number = 1,
Person_PhoneNumber_FieldNumber_Type = 2,
};
@interface Person_PhoneNumber : GPBMessage
@property(nonatomic, readwrite, copy, null_resettable) NSString *number;
@property(nonatomic, readwrite) Person_PhoneType type;
@end
/**
* Fetches the raw value of a @c Person_PhoneNumber's @c type property, even
* if the value was not defined by the enum at the time the code was generated.
**/
int32_t Person_PhoneNumber_Type_RawValue(Person_PhoneNumber *message);
/**
* Sets the raw value of an @c Person_PhoneNumber's @c type property, allowing
* it to be set to a value that was not defined by the enum at the time the code
* was generated.
**/
void SetPerson_PhoneNumber_Type_RawValue(Person_PhoneNumber *message, int32_t value);
#pragma mark - ExterBook
typedef GPB_ENUM(ExterBook_FieldNumber) {
ExterBook_FieldNumber_ExterDetial = 1,
ExterBook_FieldNumber_ExterNote = 2,
ExterBook_FieldNumber_ExterTest = 3,
};
/**
* [test objc]
**/
@interface ExterBook : GPBMessage
@property(nonatomic, readwrite, copy, null_resettable) NSString *exterDetial;
@property(nonatomic, readwrite, copy, null_resettable) NSString *exterNote;
@property(nonatomic, readwrite, copy, null_resettable) NSString *exterTest;
@end
#pragma mark - AddressBook
typedef GPB_ENUM(AddressBook_FieldNumber) {
AddressBook_FieldNumber_PeopleArray = 1,
AddressBook_FieldNumber_ExterBook = 2,
};
/**
* Our address book file is just one of these.
**/
@interface AddressBook : GPBMessage
@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<Person*> *peopleArray;
/** The number of items in @c peopleArray without causing the array to be created. */
@property(nonatomic, readonly) NSUInteger peopleArray_Count;
@property(nonatomic, readwrite, strong, null_resettable) ExterBook *exterBook;
/** Test to see if @c exterBook has been set. */
@property(nonatomic, readwrite) BOOL hasExterBook;
@end
NS_ASSUME_NONNULL_END
CF_EXTERN_C_END
#pragma clang diagnostic pop
// @@protoc_insertion_point(global_scope)
项目运行:
/// Google protobuf
#import "Addressbook.pbobjc.h"
-(void)googleProtobufTest
{
AddressBook *addressBook = [AddressBook message];
Person *person = [Person message];
person.name = @"张三";
person.email = @"zhangsan123@163.com";
person.id_p = 1001;
NSLog(@"Google protobuf测试:***Person=:%@\n----:id:%d",person,person.id_p);
[addressBook.peopleArray addObject:person];
ExterBook *eBook = [ExterBook message];
eBook.exterNote = @"通讯录备注";
eBook.exterDetial = @"汉中门160号";
eBook.exterTest = @"备注测试";
addressBook.exterBook = eBook;
NSLog(@"Google protobuf测试:***AddressBook=:%@",addressBook);
//序列化
NSData *data = [addressBook data];
AddressBook *book = [AddressBook parseFromData:data error:nil];
NSLog(@"book:%@\n备注信息:exterDetial:%@",book,book.exterBook.exterDetial);
}
打印结果:如图: