Introduction
Protocol Buffers are a way of encoding structured data in an efficient yet extensible format. For more information see the main page here.
This project contains a port of Protocol Buffers that can be used in OSX 10.5 and later and on the iPhone OS 2.0 and later.
The port includes a Protocol Buffer compiler (protoc) and a Protocol Buffer static library that you link into any project that you want protobuf support for. The protoc compiler supports almost all the features of the protobuf 2 language and when given .proto files as input will generate the specialized Objective-C classes necessary to both read and write instances of the messages contained therein. These classes, along with the supplied static library, will then allow your code to read and write protobuf instances simply and in a typesafe manner.
Quick Example
You write a .proto file like this:
message Person {
required int32 id = 1;
required string name = 2;
optional string email = 3;
}
Then you compile it with protoc, the protocol buffer compiler, to produce code in Objective-C.
You use that code like this to produce raw protobuf data from a message:
Person* person = [[[[[Person builder] setId:123]
setName:@"Bob"]
setEmail:@"bob@example.com"] build];
NSData* data = [person data];
Or like this to read a message back from raw protobuf data:
NSData* raw_data = ...;
Person* person = [Person parseFromData:raw_data];
Gory Details
Creating the Protocol Buffer Compiler (protoc
)
In order to compiler and use protoc
you must first have installed XCode and the rest of Apple's developer tools.
- Download and unzip the latest
ProtocolBuffers-*.*-Source.tar.gz
file in the download section to<install_directory>
on your computer. - Navigate to
<install_directory>
and type the following commands ./autogen.sh
./configure
make
protoc
will then be built into the <install_directory>/src
directory.
Compiler Invocation
For full details on the protobuf compiler, please see the official details here
The protocol buffer compiler (protoc
) produces Objective-C output when invoked with the --objc_out=
command-line flag. The parameter to the --objc_out=
option is the directory where you want the compiler to write your Objective-C output. The compiler creates a header file and an implementation file for each .proto
file input. The names of the output files are computed by taking the name of the .proto file and making two changes:
* The extension (.proto
) is replaced with either .pb.h
or .pb.m
for the header or implementation file, respectively.
* The proto path (specified with the --proto_path=
or -I
command-line flag) is replaced with the output path (specified with the --objc_out=
flag).
So, for example, let's say you invoke the compiler as follows:
protoc --proto_path=src --objc_out=build/gen src/foo.proto src/bar/baz.proto
The compiler will read the files src/foo.proto
and src/bar/baz.proto
and produce four output files: build/gen/foo.pb.h
, build/gen/foo.pb.m
, build/gen/bar/baz.pb.h
, build/gen/bar/baz.pb.m
. The compiler will automatically create the directory build/gen/bar
if necessary, but it will not create build
or build/gen
; they must already exist.
Project Integration
Once you have generated the .pb.h
and .pb.m
files for the .proto
file you care about, you can then add them to your project. However, in order to build properly several changes must be made to your project.
- Download and unzip the latest
ProtocolBuffers-*.*-Source.tar.gz
file in the download section to<install_directory>
on your computer. (This should have been done in the 'Creating the Protocol Buffer Compiler' step above). - Open your existing project and a reference to the
ProtocolBuffers
project found in<install_directory>
. - Add a reference to
<install_directory>/Classes/ProtocolBuffers.h
in your project and add the following line to your pch file:#import "ProtocolBuffers.h"
Get Info
on your build target- Add
ProtocolBuffers
as aDirect Dependency
of your build target. - Add
libProtocolBuffers.a
as aLinked Library
of your build target. You may have to do this by dragging and dropping the library from the referencedProtocolBuffers
project to your target'sLink Binary With Libraries
section. - Compile and enjoy!
Extensions
In order to more seamlessly integrate with Objective-C code, this library also extends the standard google.protobuf.FileOptions message with the following options:
``` // Sets the ObjectiveC package where classes generated from this .proto // will be placed. This is typically used since Objective C libraries output // all their headers into a single directory. i.e. Foundation* // AddressBook* UIKit* etc. etc. optional string package = 1;
// The string to be prefixed in front of all classes in order to make them // 'cocoa-y'. i.e. 'NS/AB/CF/PB' for the // NextStep/AddressBook/CoreFoundation/ProtocolBuffer libraries respectively. // This will commonly be the capitalized letters from the above defined // 'objectivec_directory' optional string class_prefix = 2; ```
To use these extensions you will need to add the following to your proto file:
``` import "google/protobuf/objectivec-descriptor.proto";
option (google.protobuf.objectivec_file_options).package = "" option (google.protobuf.objectivec_file_options).class_prefix = ""; ```
(note that the parent folder to 'google/protobuf/objectivec-descriptor.proto' must be in your include path when compiling your protocol buffer).
By using these options, you can integrate existing protobuf definitions, while still producing Objective-C code that meets expected styling standards. For example, this library uses those options above to emit the core protobuf Descriptor types into a "ProtocolBuffers" directory with a common "PB" prefix on all classes. Thus, while you would say the following in java:
import google.protobuf.Descriptor;
in Objective-C you would say:
import "ProtocolBuffers\PBDescriptor.h"
Example
Here's an example of how I integrate the library into my own 'Now Playing' application. Note the reference to the project, the direct dependency in the target, and the shared lib in the link section.
Help/Support
If you need any help/support with this feel free to email me at cyrus.najmabadi@gmail.com.
Cheers!