Swift中協議緩衝區的實現。
協議緩衝區是一種以有效但可擴展的格式編碼結構化數據的方法。該項目基於Google的協議緩衝區的實現。有關更多信息,請參見Google Protobuf項目。
1。 WGEThttps wget https://github.com/google/protobuf/archive/v3.2.0.tar.gz
2。 tar tar xzf v3.2.0.tar.gz
3。 cd cd protobuf-3.2.0/
4 sudo apt-get install autoreconf automake libtool make
5 ./autogen.sh
6 ./configure CXXFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib
7 sudo make && sudo make install
8 cd .. && wget https://github.com/alexeyxo/protobuf-swift/archive/3.0.9.tar.gz && tar xzf 3.0.9.tar.gz && cd protobuf-swift-3.0.9
9 ./script/build.sh && swift build
1。 Ruby ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
2。 brew install protobuf-swift
1。 Ruby 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 git clone [email protected]:alexeyxo/protobuf-swift.git
6 ./scripts/build.sh
在您的項目中添加./src/ProtocolBuffers/ProtocolBuffers.xcodeproj 。
Podfile:
use_frameworks!
pod 'ProtocolBuffers-Swift'
卡特菲爾:
github "alexeyxo/protobuf-swift"
protoc person.proto --swift_out= " ./ " syntax = "proto2" ;
message Person {
required int32 id = 1 ;
required string name = 2 ;
optional string email = 3 ;
} let personBuilder = Person . Builder ( )
personBuilder . id = 123
personBuilder . name = " Bob "
personBuilder . email = " [email protected] "
let person = try ! personBuilder . build ( )
print ( person )
person . data ( ) //return NSData syntax = "proto2" ;
message Perfomance
{
required int32 ints = 1 ;
required int64 ints64 = 2 ;
required double doubles = 3 ;
required float floats = 4 ;
optional string str = 5 ;
optional bytes bytes = 6 ;
optional string description = 7 ;
} var originalBuilder = ProtoPerfomance . Builder ( )
originalBuilder . setInts ( Int32 ( 32 ) )
. setInts64 ( Int64 ( 64 ) )
. setDoubles ( Double ( 12.12 ) )
. setFloats ( Float ( 123.123 ) )
. setStr ( " string " )
let original = originalBuilder . build ( ) syntax = "proto2" ;
message Foo {
optional int32 val = 1 ;
// some other fields.
}
message Bar {
optional Foo foo = 1 ;
// some other fields.
}
message Baz {
optional Bar bar = 1 ;
// some other fields.
} var builder = baz . toBuilder ( )
builder . getBarBuilder ( ) . getFooBuilder ( ) . setVal ( 10 )
baz = builder . build ( ) syntax = "proto3" ;
message MapMessageValue
{
int32 valueInMapMessage = 1 ;
}
message MessageContainsMap
{
enum EnumMapValue
{
FirstValueEnum = 0 ;
SecondValueEnum = 1 ;
}
map < int32 , int32 > map_int32_int32 = 1 ;
map < int64 , int64 > map_int64_int64 = 2 ;
map < string , string > map_string_string = 3 ;
map < string , bytes > map_string_bytes = 4 ;
map < string , MapMessageValue > map_string_message = 5 ;
map < int32 , EnumMapValue > map_int32_enum = 6 ;
} final internal class MessageContainsMap : GeneratedMessage , GeneratedMessageProtocol , Hashable {
...
private ( set ) var mapInt32Int32 : Dictionary < Int32 , Int32 > = Dictionary < Int32 , Int32 > ( )
private ( set ) var mapInt64Int64 : Dictionary < Int64 , Int64 > = Dictionary < Int64 , Int64 > ( )
private ( set ) var mapStringString : Dictionary < String , String > = Dictionary < String , String > ( )
private ( set ) var mapStringBytes : Dictionary < String , NSData > = Dictionary < String , NSData > ( )
private ( set ) var mapInt32Enum : Dictionary < Int32 , MessageContainsMap . EnumMapValue > = Dictionary < Int32 , MessageContainsMap . EnumMapValue > ( )
...
} let personBuilder = Person . builder ( )
personBuilder . id = 123
personBuilder . name = " Bob "
personBuilder . email = " [email protected] "
let person = personBuilder . build ( )
let jsonData = person . toJSON ( ) //return NSData
let jsonDictionaryObject : Dictionary < String , AnyObject > = person . encode ( )
let personFromJson = Person . fromJSON ( jsonData ) //Person var person = Person . parseFromData ( bytes ) // from NSData syntax = "proto3" ;
message SubMessage {
string str = 1 ;
}
message SampleMessage {
oneof test_oneof {
string name = 4 ;
int32 id = 5 ;
SubMessage mes = 6 ;
}
} var sm = SampleMessage . Builder ( )
sm . name = " Alex "
sm . id = 123
println ( ss . build ( ) ) //-> id: 123 syntax = "proto3" ;
message SearchResponse {
message Result {
string url = 1 ;
string title = 2 ;
repeated string snippets = 3 ;
}
repeated Result result = 1 ;
} var builderResult = SearchResponse . Result . Builder ( )
builderResult . url = " http://protobuf.axo.io "
builderResult . title = " Protocol Bufers Apple Swift "
var searchRespons = SearchResponse . builder ( )
searchRespons . result += [ builderResult . build ( ) ]
println ( searchRespons . build ( ) ) syntax = "proto2" ;
package FooBar ;
message Perfomance
{
required int32 ints = 1 ;
required int64 ints64 = 2 ;
required double doubles = 3 ;
required float floats = 4 ;
optional string str = 5 ;
optional bytes bytes = 6 ;
optional string description = 7 ;
} public extension FooBar {
...
final public class Perfomance : GeneratedMessage , GeneratedMessageProtocol {
...
}
} import "google/protobuf/descriptor.proto" ;
package google.protobuf ;
enum AccessControl {
InternalEntities = 0 ;
PublicEntities = 1 ;
}
message SwiftFileOptions {
optional string class_prefix = 1 ;
optional AccessControl entities_access_control = 2 [ default = PublicEntities ];
optional bool compile_for_framework = 3 [ default = true ];
}
message SwiftMessageOptions {
optional bool generate_error_type = 1 [ default = false ];
}
message SwiftEnumOptions {
optional bool generate_error_type = 1 [ default = false ];
}
extend google.protobuf.FileOptions {
optional SwiftFileOptions swift_file_options = 5092014 ;
}
extend google.protobuf.MessageOptions {
optional SwiftMessageOptions swift_message_options = 5092014 ;
}
extend google.protobuf.EnumOptions {
optional SwiftEnumOptions swift_enum_options = 5092015 ;
}
option (.google.protobuf.swift_file_options).compile_for_framework = false;
option (.google.protobuf.swift_file_options).entities_access_control = PublicEntities;目前,Protobuf-Swift的編譯器正在支持自定義選項。
如果您使用自定義選項,則需要添加:
import 'google/protobuf/swift-descriptor.proto';在您的.proto文件中。
此選項需要使用前綴生成類名稱。
例子:
import 'google/protobuf/swift-descriptor.proto';
option (.google.protobuf.swift_file_options).class_prefix = "Proto";
message NameWithPrefix
{
optional string str = 1 ;
}生成的班級有一個名稱:
final internal class ProtoNameWithPrefix : GeneratedMessageoption (.google.protobuf.swift_file_options).entities_access_control = PublicEntities;默認情況下,所有生成的類標記為internal 。如果要標記為public ,則可以使用entities_access_control選項。
option (.google.protobuf.swift_file_options).entities_access_control = PublicEntities;
message MessageWithCustomOption
{
optional string str = 1 ;
}生成的班級和所有領域都被標記為public :
final public class MessageWithCustomOption : GeneratedMessageoption (.google.protobuf.swift_enum_options).generate_error_type = true;import 'google/protobuf/swift-descriptor.proto';
enum ServiceError {
option (.google.protobuf.swift_enum_options).generate_error_type = true;
BadRequest = 0 ;
InternalServerError = 1 ;
}
message UserProfile {
message Request {
required string userId = 1 ;
}
message Response {
optional UserProfile profile = 1 ;
optional ServiceError error = 2 ;
optional Exception exception = 3 ;
}
message Exception {
option (.google.protobuf.swift_message_options).generate_error_type = true;
required int32 errorCode = 1 ;
required string errorDescription = 2 ;
}
optional string firstName = 1 ;
optional string lastName = 2 ;
optional string avatarUrl = 3 ;
} public enum ServiceError : Error , RawRepresentable , CustomDebugStringConvertible , CustomStringConvertible {
public typealias RawValue = Int32
case badRequest
case internalServerError
public init ? ( rawValue : RawValue ) {
switch rawValue {
case 0 : self = . badRequest
case 1 : self = . internalServerError
default : return nil
}
}
public var rawValue : RawValue {
switch self {
case . badRequest : return 0
case . internalServerError : return 1
}
}
public func throwException ( ) throws {
throw self
}
public var debugDescription : String { return getDescription ( ) }
public var description : String { return getDescription ( ) }
private func getDescription ( ) -> String {
switch self {
case . badRequest : return " .badRequest "
case . internalServerError : return " .internalServerError "
}
}
} func generateException ( ) throws {
let user = UserProfile . Response . Builder ( )
user . error = . internalServerError
let data = try user . build ( ) . data ( )
let userError = try UserProfile . Response . parseFrom ( data : data )
if userError . hasError {
throw userError . error //userError.error.throwException()
}
}
do {
try generateException ( )
} catch let err as ServiceError where err == . internalServerError {
XCTAssertTrue ( true )
} catch {
XCTAssertTrue ( false )
}
func throwExceptionMessage ( ) throws {
let exception = UserProfile . Exception . Builder ( )
exception . errorCode = 403
exception . errorDescription = " Bad Request "
let exc = try exception . build ( )
let data = try UserProfile . Response . Builder ( ) . setException ( exc ) . build ( ) . data ( )
let userError = try UserProfile . Response . parseFrom ( data : data )
if userError . hasException {
throw userError . exception
}
}
do {
try throwExceptionMessage ( )
} catch let err as UserProfile . Exception {
print ( err )
XCTAssertTrue ( true )
} catch {
XCTAssertTrue ( false )
}
option (.google.protobuf.swift_file_options).compile_for_framework = false;此選項刪除生成的文件的字符串import ProtocolBuffers 。
添加了眾所周知的類型原型(Any.proto,empty.proto,timestamp.proto,lisation.proto等)。用戶可以像常規的原始文件一樣導入和使用這些原始人。將來的發行版(以實用程序助手功能的形式,或者將它們替換為生成的代碼中的語言特定類型)。
message Any {
// A URL/resource name whose content describes the type of the
// serialized message.
//
// For URLs which use the schema `http`, `https`, or no schema, the
// following restrictions and interpretations apply:
//
// * If no schema is provided, `https` is assumed.
// * The last segment of the URL's path must represent the fully
// qualified name of the type (as in `path/google.protobuf.Duration`).
// * An HTTP GET on the URL must yield a [google.protobuf.Type][google.protobuf.Type]
// value in binary format, or produce an error.
// * Applications are allowed to cache lookup results based on the
// URL, or have them precompiled into a binary to avoid any
// lookup. Therefore, binary compatibility needs to be preserved
// on changes to types. (Use versioned type names to manage
// breaking changes.)
//
// Schemas other than `http`, `https` (or the empty schema) might be
// used with implementation specific semantics.
//
// Types originating from the `google.*` package
// namespace should use `type.googleapis.com/full.type.name` (without
// schema and path). A type service will eventually become available which
// serves those URLs (projected Q2/15).
string type_url = 1 ;
// Must be valid serialized data of the above specified type.
bytes value = 2 ;
} Google . Protobuf . Any ( ) message Api {
// The fully qualified name of this api, including package name
// followed by the api's simple name.
string name = 1 ;
// The methods of this api, in unspecified order.
repeated Method methods = 2 ;
// Any metadata attached to the API.
repeated Option options = 3 ;
// A version string for this api. If specified, must have the form
// `major-version.minor-version`, as in `1.10`. If the minor version
// is omitted, it defaults to zero. If the entire version field is
// empty, the major version is derived from the package name, as
// outlined below. If the field is not empty, the version in the
// package name will be verified to be consistent with what is
// provided here.
//
// The versioning schema uses [semantic
// versioning](http://semver.org) where the major version number
// indicates a breaking change and the minor version an additive,
// non-breaking change. Both version numbers are signals to users
// what to expect from different versions, and should be carefully
// chosen based on the product plan.
//
// The major version is also reflected in the package name of the
// API, which must end in `v<major-version>`, as in
// `google.feature.v1`. For major versions 0 and 1, the suffix can
// be omitted. Zero major versions must only be used for
// experimental, none-GA apis.
//
// See also: [design doc](http://go/api-versioning).
//
//
string version = 4 ;
// Source context for the protocol buffer service represented by this
// message.
SourceContext source_context = 5 ;
}
// Method represents a method of an api.
message Method {
// The simple name of this method.
string name = 1 ;
// A URL of the input message type.
string request_type_url = 2 ;
// If true, the request is streamed.
bool request_streaming = 3 ;
// The URL of the output message type.
string response_type_url = 4 ;
// If true, the response is streamed.
bool response_streaming = 5 ;
// Any metadata attached to the method.
repeated Option options = 6 ;
} Google . Protobuf . Api ( ) message Duration {
// Signed seconds of the span of time. Must be from -315,576,000,000
// to +315,576,000,000 inclusive.
int64 seconds = 1 ;
// Signed fractions of a second at nanosecond resolution of the span
// of time. Durations less than one second are represented with a 0
// `seconds` field and a positive or negative `nanos` field. For durations
// of one second or more, a non-zero value for the `nanos` field must be
// of the same sign as the `seconds` field. Must be from -999,999,999
// to +999,999,999 inclusive.
int32 nanos = 2 ;
} Google . Protobuf . Duration ( ) message Empty {
} Google . Protobuf . Empty ( ) message FieldMask {
// The set of field mask paths.
repeated string paths = 1 ;
} Google . Protobuf . FieldMask ( ) message SourceContext {
// The path-qualified name of the .proto file that contained the associated
// protobuf element. For example: `"google/protobuf/source.proto"`.
string file_name = 1 ;
} Google . Protobuf . SourceContext ( ) message Struct {
// Map of dynamically typed values.
map < string , Value > fields = 1 ;
}
// `Value` represents a dynamically typed value which can be either
// null, a number, a string, a boolean, a recursive struct value, or a
// list of values. A producer of value is expected to set one of that
// variants, absence of any variant indicates an error.
message Value {
oneof kind {
// Represents a null value.
NullValue null_value = 1 ;
// Represents a double value.
double number_value = 2 ;
// Represents a string value.
string string_value = 3 ;
// Represents a boolean value.
bool bool_value = 4 ;
// Represents a structured value.
Struct struct_value = 5 ;
// Represents a repeated `Value`.
ListValue list_value = 6 ;
}
}
// `ListValue` is a wrapper around a repeated field of values.
message ListValue {
// Repeated field of dynamically typed values.
repeated Value values = 1 ;
}
// `NullValue` is a singleton enumeration to represent the null
// value for the `Value` type union.
enum NullValue {
// Null value.
NULL_VALUE = 0 ;
} Google . Protobuf . Struct ( ) message Timestamp {
// Represents seconds of UTC time since Unix epoch
// 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to
// 9999-12-31T23:59:59Z inclusive.
int64 seconds = 1 ;
// Non-negative fractions of a second at nanosecond resolution. Negative
// second values with fractions must still have non-negative nanos values
// that count forward in time. Must be from 0 to 999,999,999
// inclusive.
int32 nanos = 2 ;
} Google . Protobuf . Timestamp ( ) message Type {
// The fully qualified message name.
string name = 1 ;
// The list of fields.
repeated Field fields = 2 ;
// The list of oneof definitions.
// The list of oneofs declared in this Type
repeated string oneofs = 3 ;
// The proto options.
repeated Option options = 4 ;
// The source context.
SourceContext source_context = 5 ;
}
// Field represents a single field of a message type.
message Field {
// Kind represents a basic field type.
enum Kind {
// Field type unknown.
TYPE_UNKNOWN = 0 ;
// Field type double.
TYPE_DOUBLE = 1 ;
// Field type float.
TYPE_FLOAT = 2 ;
// Field type int64.
TYPE_INT64 = 3 ;
// Field type uint64.
TYPE_UINT64 = 4 ;
// Field type int32.
TYPE_INT32 = 5 ;
// Field type fixed64.
TYPE_FIXED64 = 6 ;
// Field type fixed32.
TYPE_FIXED32 = 7 ;
// Field type bool.
TYPE_BOOL = 8 ;
// Field type string.
TYPE_STRING = 9 ;
// Field type message.
TYPE_MESSAGE = 11 ;
// Field type bytes.
TYPE_BYTES = 12 ;
// Field type uint32.
TYPE_UINT32 = 13 ;
// Field type enum.
TYPE_ENUM = 14 ;
// Field type sfixed32.
TYPE_SFIXED32 = 15 ;
// Field type sfixed64.
TYPE_SFIXED64 = 16 ;
// Field type sint32.
TYPE_SINT32 = 17 ;
// Field type sint64.
TYPE_SINT64 = 18 ;
}
// Cardinality represents whether a field is optional, required, or
// repeated.
enum Cardinality {
// The field cardinality is unknown. Typically an error condition.
CARDINALITY_UNKNOWN = 0 ;
// For optional fields.
CARDINALITY_OPTIONAL = 1 ;
// For required fields. Not used for proto3.
CARDINALITY_REQUIRED = 2 ;
// For repeated fields.
CARDINALITY_REPEATED = 3 ;
}
// The field kind.
Kind kind = 1 ;
// The field cardinality, i.e. optional/required/repeated.
Cardinality cardinality = 2 ;
// The proto field number.
int32 number = 3 ;
// The field name.
string name = 4 ;
// The type URL (without the scheme) when the type is MESSAGE or ENUM,
// such as `type.googleapis.com/google.protobuf.Empty`.
string type_url = 6 ;
// Index in Type.oneofs. Starts at 1. Zero means no oneof mapping.
int32 oneof_index = 7 ;
// Whether to use alternative packed wire representation.
bool packed = 8 ;
// The proto options.
repeated Option options = 9 ;
}
// Enum type definition.
message Enum {
// Enum type name.
string name = 1 ;
// Enum value definitions.
repeated EnumValue enumvalue = 2 ;
// Proto options for the enum type.
repeated Option options = 3 ;
// The source context.
SourceContext source_context = 4 ;
}
// Enum value definition.
message EnumValue {
// Enum value name.
string name = 1 ;
// Enum value number.
int32 number = 2 ;
// Proto options for the enum value.
repeated Option options = 3 ;
}
// Proto option attached to messages/fields/enums etc.
message Option {
// Proto option name.
string name = 1 ;
// Proto option value.
Any value = 2 ;
} Google . Protobuf . Type ( )
... // Wrapper message for double.
message DoubleValue {
// The double value.
double value = 1 ;
}
// Wrapper message for float.
message FloatValue {
// The float value.
float value = 1 ;
}
// Wrapper message for int64.
message Int64Value {
// The int64 value.
int64 value = 1 ;
}
// Wrapper message for uint64.
message UInt64Value {
// The uint64 value.
uint64 value = 1 ;
}
// Wrapper message for int32.
message Int32Value {
// The int32 value.
int32 value = 1 ;
}
// Wrapper message for uint32.
message UInt32Value {
// The uint32 value.
uint32 value = 1 ;
}
// Wrapper message for bool.
message BoolValue {
// The bool value.
bool value = 1 ;
}
// Wrapper message for string.
message StringValue {
// The string value.
string value = 1 ;
}
// Wrapper message for bytes.
message BytesValue {
// The bytes value.
bytes value = 1 ;
} Google . Protobuf . StringValue ( )開發人員 - Alexey Khokhlov
Google協議緩衝區 - Cyrus Najmabadi,Sergey Martynov,Kenton Varda,Sanjay Ghemawat,Jeff Dean等