| 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 13.3.1 (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 `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. | |
| All message fields *always* have a value when accessed. For primitive type | |
| fields (ints, floats, bools, enum) there the concept of *presence*, that allows | |
| you to tell the difference between when the field is the *default* value because | |
| it *was not* set and when it *was* set, but *explicitly* to the *default* | |
| value for the field. For fields with that do support *presence*, you can test | |
| if the value was *explicitly* set via the `has\[NAME\]` property. If the value | |
| has been set, and you want to clear it, you can set the `has\[NAME\]` to `NO`. | |
| 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 options `package_to_prefix_mappings_path` and | |
| `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. | |
| * `package_to_prefix_mappings_path`: The `value` used for this key is a | |
| path to a file containing a list of proto packages and prefixes. | |
| The generator will use this to locate which ObjC class prefix to use when | |
| generating sources _unless_ the `objc_class_prefix` file option is set. | |
| This option can be useful if multiple apps consume a common set of | |
| proto files but wish to use a different prefix for the generated sources | |
| between them. This option takes precedent over the `use_package_as_prefix` | |
| option. | |
| The format of the file is: | |
| * An entry is a line of "package=prefix". | |
| * Comments start with `#`. | |
| * A comment can go on a line after a expected package/prefix pair. | |
| (i.e. - "package=prefix # comment") | |
| * For files that do NOT have a proto package (not recommended), an | |
| entry can be made as "no_package:PATH=prefix", where PATH is the | |
| path for the .proto file. | |
| * `use_package_as_prefix`, `package_as_prefix_forced_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. | |
| `package_as_prefix_forced_prefix` can be used to provide a value that will | |
| be used before all prefixes derived from the packages to help group all of | |
| these types with a common prefix. Thus it only makes sense to use it when | |
| `use_package_as_prefix` is also enabled. For example, setting this to | |
| "XYZ\_" and generating a file with the package "something" defining | |
| "MyMessage", would have Objective-C class be `XYZ_Something_MyMessage`. | |
| `use_package_as_prefix` currently defaults to `no` (existing behavior), but | |
| that could change in the future as it helps avoid collisions when more | |
| protos get added to the build. Note that this would be a breaking change. | |
| * `headers_use_forward_declarations`: The `value` for this can be `yes` or | |
| `no`, and indicates if the generated headers use forward declarations for | |
| Message and Enum types from other .proto files or if the files should be | |
| imported into the generated header instead. | |
| By using forward declarations, less code is likely to recompile when the | |
| files do change, but Swift generally doesn't like forward declarations and | |
| will fail to include properties when the concrete definition of the type is | |
| known at import time. If your proto usages span modules, this can be a | |
| problem. | |
| `headers_use_forward_declarations` currently defaults to `yes` (existing | |
| behavior), but in a future release, that default may change to provide | |
| better Swift support by default. | |
| 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/ |