Protocol Buffers - Google's data interchange format (grpc依赖)
https://developers.google.com/protocol-buffers/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
219 lines
9.2 KiB
219 lines
9.2 KiB
Protocol Buffers - Google's data interchange format |
|
=================================================== |
|
|
|
Copyright 2008 Google Inc. |
|
|
|
This directory contains the Objective C Protocol Buffers runtime library. |
|
|
|
Requirements |
|
------------ |
|
|
|
The Objective C implementation requires: |
|
|
|
- Objective C 2.0 Runtime (32bit & 64bit iOS, 64bit OS X). |
|
- Xcode 10.3 (or later). |
|
- The library code does *not* use ARC (for performance reasons), but it all can |
|
be called from ARC code. |
|
|
|
Installation |
|
------------ |
|
|
|
The distribution pulled from github includes the sources for both the |
|
compiler (protoc) and the runtime (this directory). After cloning the distribution |
|
and needed submodules ([see the src directory's README](../src/README.md)), |
|
to build the compiler and run the runtime tests, you can use: |
|
|
|
$ objectivec/DevTools/full_mac_build.sh |
|
|
|
This will generate the `src/protoc` binary. |
|
|
|
Building |
|
-------- |
|
|
|
There are two ways to include the Runtime sources in your project: |
|
|
|
Add `objectivec/*.h`, `objectivec/google/protobuf/*.pbobjc.h`, and |
|
`objectivec/GPBProtocolBuffers.m` to your project. |
|
|
|
*or* |
|
|
|
Add `objectivec/*.h`, `objectivec/google/protobuf/*.pbobjc.h`, |
|
`objectivec/google/protobuf/*.pbobjc.m`, and `objectivec/*.m` except for |
|
`objectivec/GPBProtocolBuffers.m` to your project. |
|
|
|
|
|
If the target is using ARC, remember to turn off ARC (`-fno-objc-arc`) for the |
|
`.m` files. |
|
|
|
The files generated by `protoc` for the `*.proto` files (`*.pbobjc.h` and |
|
`*.pbobjc.m`) are then also added to the target. |
|
|
|
Usage |
|
----- |
|
|
|
The objects generated for messages should work like any other Objective C |
|
object. They are mutable objects, but if you don't change them, they are safe |
|
to share between threads (similar to passing an NSMutableDictionary between |
|
threads/queues; as long as no one mutates it, things are fine). |
|
|
|
There are a few behaviors worth calling out: |
|
|
|
A property that is type NSString\* will never return nil. If the value is |
|
unset, it will return an empty string (@""). This is inpart to align things |
|
with the Protocol Buffers spec which says the default for strings is an empty |
|
string, but also so you can always safely pass them to isEqual:/compare:, etc. |
|
and have deterministic results. |
|
|
|
A property that is type NSData\* also won't return nil, it will return an empty |
|
data ([NSData data]). The reasoning is the same as for NSString not returning |
|
nil. |
|
|
|
A property that is another GPBMessage class also will not return nil. If the |
|
field wasn't already set, you will get a instance of the correct class. This |
|
instance will be a temporary instance unless you mutate it, at which point it |
|
will be attached to its parent object. We call this pattern *autocreators*. |
|
Similar to NSString and NSData properties it makes things a little safer when |
|
using them with isEqual:/etc.; but more importantly, this allows you to write |
|
code that uses Objective C's property dot notation to walk into nested objects |
|
and access and/or assign things without having to check that they are not nil |
|
and create them each step along the way. You can write this: |
|
|
|
``` |
|
- (void)updateRecord:(MyMessage *)msg { |
|
... |
|
// Note: You don't have to check subMessage and otherMessage for nil and |
|
// alloc/init/assign them back along the way. |
|
msg.subMessage.otherMessage.lastName = @"Smith"; |
|
... |
|
} |
|
``` |
|
|
|
If you want to check if a GPBMessage property is present, there is always as |
|
`has\[NAME\]` property to go with the main property to check if it is set. |
|
|
|
A property that is of an Array or Dictionary type also provides *autocreator* |
|
behavior and will never return nil. This provides all the same benefits you |
|
see for the message properties. Again, you can write: |
|
|
|
``` |
|
- (void)updateRecord:(MyMessage *)msg { |
|
... |
|
// Note: Just like above, you don't have to check subMessage and otherMessage |
|
// for nil and alloc/init/assign them back along the way. You also don't have |
|
// to create the siblingsArray, you can safely just append to it. |
|
[msg.subMessage.otherMessage.siblingsArray addObject:@"Pat"]; |
|
... |
|
} |
|
``` |
|
|
|
If you are inspecting a message you got from some other place (server, disk, |
|
etc), you may want to check if the Array or Dictionary has entries without |
|
causing it to be created for you. For this, there is always a `\[NAME\]_Count` |
|
property also provided that can return zero or the real count, but won't trigger |
|
the creation. |
|
|
|
For primitive type fields (ints, floats, bools, enum) in messages defined in a |
|
`.proto` file that use *proto2* syntax there are conceptual differences between |
|
having an *explicit* and *default* value. You can always get the value of the |
|
property. In the case that it hasn't been set you will get the default. In |
|
cases where you need to know whether it was set explicitly or you are just |
|
getting the default, you can use the `has\[NAME\]` property. If the value has |
|
been set, and you want to clear it, you can set the `has\[NAME\]` to `NO`. |
|
*proto3* syntax messages do away with this concept, thus the default values are |
|
never included when the message is encoded. |
|
|
|
The Objective C classes/enums can be used from Swift code. |
|
|
|
Objective C Generator Proto File Options |
|
---------------------------------------- |
|
|
|
**objc_class_prefix=\<prefix\>** (no default) |
|
|
|
This options allow you to provide a custom prefix for all the symbols generated |
|
from a proto file (classes (from message), enums, the Root for extension |
|
support). |
|
|
|
If not set, the generation option `use_package_as_prefix` (documented below) |
|
controls what is used instead. Since Objective C uses a global namespace for all |
|
of its classes, there can be collisions. `use_package_as_prefix=yes` should |
|
avoid collisions since proto package are used to scope/name things in other |
|
languages, but this option can be used to get shorter names instead. Convention |
|
is to base the explicit prefix on the proto package. |
|
|
|
Objective C Generator `protoc` Options |
|
-------------------------------------- |
|
|
|
When generating Objective C code, `protoc` supports a `--objc_opt` argument; the |
|
argument is comma-delimited name/value pairs (_key=value,key2=value2_). The |
|
_keys_ are used to change the behavior during generation. The currently |
|
supported keys are: |
|
|
|
* `generate_for_named_framework`: The `value` used for this key will be used |
|
when generating the `#import` statements in the generated code. Instead |
|
of being plain `#import "some/path/file.pbobjc.h"` lines, they will be |
|
framework based, i.e. - `#import <VALUE/file.pbobjc.h>`. |
|
|
|
_NOTE:_ If this is used with `named_framework_to_proto_path_mappings_path`, |
|
then this is effectively the _default_ to use for everything that wasn't |
|
mapped by the other. |
|
|
|
* `named_framework_to_proto_path_mappings_path`: The `value` used for this key |
|
is a path to a file containing the listing of framework names and proto |
|
files. The generator uses this to decide if another proto file referenced |
|
should use a framework style import vs. a user level import |
|
(`#import <FRAMEWORK/file.pbobjc.h>` vs `#import "dir/file.pbobjc.h"`). |
|
|
|
The format of the file is: |
|
* An entry is a line of `frameworkName: file.proto, dir/file2.proto`. |
|
* Comments start with `#`. |
|
* A comment can go on a line after an entry. |
|
(i.e. - `frameworkName: file.proto # comment`) |
|
|
|
Any number of files can be listed for a framework, just separate them with |
|
commas. |
|
|
|
There can be multiple lines listing the same frameworkName in case it has a |
|
lot of proto files included in it; and having multiple lines makes things |
|
easier to read. |
|
|
|
* `runtime_import_prefix`: The `value` used for this key to be used as a |
|
prefix on `#import`s of runtime provided headers in the generated files. |
|
When integrating ObjC protos into a build system, this can be used to avoid |
|
having to add the runtime directory to the header search path since the |
|
generate `#import` will be more complete. |
|
|
|
* `use_package_as_prefix` and `proto_package_prefix_exceptions_path`: The |
|
`value` for `use_package_as_prefix` can be `yes` or `no`, and indicates |
|
if a prefix should be derived from the proto package for all the symbols |
|
for files that don't have the `objc_class_prefix` file option (mentioned |
|
above). This helps ensure the symbols are more unique and means there is |
|
less chance of ObjC class name collisions. |
|
|
|
To help in migrating code to using this support, |
|
`proto_package_prefix_exceptions_path` can be used to provide the path |
|
to a file that contains proto package names (one per line, comments allowed |
|
if prefixed with `#`). These package won't get the derived prefix, allowing |
|
migrations to the behavior one proto package at a time across a code base. |
|
|
|
`use_package_as_prefix` currently defaults to `no` (existing behavior), but |
|
in the future (as a breaking change), that is likely to change since it |
|
helps prepare folks before they end up using a lot of protos and getting a |
|
lot of collisions. |
|
|
|
Contributing |
|
------------ |
|
|
|
Please make updates to the tests along with changes. If just changing the |
|
runtime, the Xcode projects can be used to build and run tests. If your change |
|
also requires changes to the generated code, |
|
`objectivec/DevTools/full_mac_build.sh` can be used to easily rebuild and test |
|
changes. Passing `-h` to the script will show the addition options that could |
|
be useful. |
|
|
|
Documentation |
|
------------- |
|
|
|
The complete documentation for Protocol Buffers is available via the |
|
web at: |
|
|
|
https://developers.google.com/protocol-buffers/
|
|
|