Introduction to Protocol Buffers on iOS
Protocol buffers are a language-agnostic method for serializing structured data that can be used as an alternative to XML or JSON in your iOS apps. By Vincent Ngo.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Introduction to Protocol Buffers on iOS
25 mins
- Getting Started
- The Client
- How do Protocol Buffers Work?
- Benefits
- Limitations
- Protocol Buffer Schema
- The Backend
- Environment Setup
- Defining a .proto File
- Generating Swift Structs
- Running the Local Server
- Testing GET Requests
- Making the Service Calls
- Integrate the Attendee’s Badge
- Customizing Protocol Buffer Objects
- Integrate the List of Speakers
- Where to Go From Here?
Protocol Buffer Schema
Head back to Finder and look inside Starter/ProtoSchema. You’ll see the following files:
- contact.proto describes how a contact should be structured using the protocol buffer language. You’ll dive deeper into this later.
- protoScript.sh is a bash script that will generate Swift structs and Python classes for contact.proto using the protocol buffer compiler.
The Backend
Within the folder Starter/Server, you’ll see the following:
-
RWServer.py manages a Python server built on top of Flask. It contains two GET requests:
-
/currentUser
gets the current attendee’s information. -
/speakers
gets the list of speakers.
-
-
RWDict.py contains a dictionary of speakers that
RWServer
will read from.
Now it’s time to set up the environment to run protocol buffers. In the following section, you’ll set up the required environments to run Google’s protocol buffer compiler, Swift’s Protobuf plugin, and install Flask to run your Python server.
Environment Setup
There are a several tools and libraries that you have to install before using protocol buffers. The starter project includes a script named protoInstallation.sh that handles all of this for you. Luckily for you, it will check if any of the libraries are installed before installing each one!
This script will take a while to install, especially when installing Google’s protocol buffer libraries. Open up your terminal, cd
into the Starter directory and execute the following command:
$ ./protoInstallation.sh
Note: You may be prompted to enter your admin password while running the script.
Note: You may be prompted to enter your admin password while running the script.
When the script completes, run it again to ensure you get output similar to the following:
If you see this, the script has successfully completed. If the script failed, you might have entered the wrong admin password. In that cause, try rerunning the script; it won’t reinstall anything that happened successfully.
Here’s what the script has accomplished:
- Installed Flask to run the Python Local Server.
- Built the Google protocol buffer compiler from Starter/protobuf-3.1.0.
- Installed the protocol buffer module for Python so the server can use the Protobuf library.
- Moved the Swift Protobuf plugin protoc-gen-swift into /usr/local/bin. This allows the Protobuf compiler to generate Swift structs.
Note: For more information on how the script works, you can open the protoInstallation.sh file in a text editor to see what commands are being executed. This requires some basic bash knowledge.
Note: For more information on how the script works, you can open the protoInstallation.sh file in a text editor to see what commands are being executed. This requires some basic bash knowledge.
You now have everything you need to start using protocol buffers!
Defining a .proto File
.proto files define protocol buffer messages which describe the structure of your data. When fed through the protocol buffer compiler, they generate data accessor structs.
Note:In this tutorial, you’ll define messages with proto3, the latest protocol buffer language version. For more in-depth knowledge on syntax and how to define a proto3 file, check out Google’s guidelines.
Note:In this tutorial, you’ll define messages with proto3, the latest protocol buffer language version. For more in-depth knowledge on syntax and how to define a proto3 file, check out Google’s guidelines.
Open ProtoSchema/contact.proto in your favorite text editor. Here the .proto file has already been defined for you to generate Contact
and Speakers
messages:
syntax = "proto3";
message Contact { // 1
enum ContactType { // 2
SPEAKER = 0;
ATTENDANT = 1;
VOLUNTEER = 2;
}
string first_name = 1; //3
string last_name = 2;
string twitter_name = 3;
string email = 4;
string github_link = 5;
ContactType type = 6;
string imageName = 7;
};
message Speakers { // 4
repeated Contact contacts = 1;
};
Going over what this definition actually contains:
- The
Contact
model describes a person’s contact information. This will be displayed on their badges in the app. - Every contact should be categorized so it will be easy to differentiate between guest and speakers.
- Every
message
andenum
field found in a proto definition must be assigned an incremental and unique tag. These numbers are used to identify fields in the message binary format, so it’s vital to maintaining the order. For more information on tag and field management, check out reserved fields in Google’s doc. - The
Speakers
model contains a collection of contacts. Therepeated
tag indicates an array of objects.
Generating Swift Structs
When you pass contact.proto into the protoc
program, the messages in the proto file will generate Swift structs. These structs will conform to ProtobufMessage
. protoc
will provide properties for every Swift field, initializer, and methods to serialize and deserialize data.
Note: For more information about the capabilities of Swift’s protobuf API, please refer to Apple’s Protobuf API documentation.
Note: For more information about the capabilities of Swift’s protobuf API, please refer to Apple’s Protobuf API documentation.
In terminal, navigate to the Starter/ProtoSchema directory. Open protoScript.sh in a text editor and you’ll see the following:
#!/bin/bash
echo 'Running ProtoBuf Compiler to convert .proto schema to Swift'
protoc --swift_out=. contact.proto // 1
echo 'Running Protobuf Compiler to convert .proto schema to Python'
protoc -I=. --python_out=. ./contact.proto // 2
The script runs protoc
twice against contact.proto — once to create the Swift source and then once again for Python.
Back in the terminal, execute the script by running the following:
$ ./protoScript.sh
You should see this output:
Running ProtoBuf Compiler to convert .proto schema to Swift
protoc-gen-swift: Generating Swift for contact.proto
Running Protobuf Compiler to convert .proto schema to Python
You’ve created Swift and Python source files from the contact.proto
file.
Within the ProtoSchema directory, you should see two generated files one in Swift, and one in Python. Notice that each generated file will have a corresponding .pb.swift
or .pb.py
The prefix pb represents that it’s a protocol buffer generated class.
Drag contact.pb.swift into Xcode’s project navigator and place it in the Protocol Buffer Objects group folder. Check “Copy items if needed” when prompted. In either Finder or Terminal, copy contact_pb2.py to the Starter/Server folder.
Feel free to look inside the contents of contact.pb.swift and contact_pb2.py to see how the proto messages map to structures in the output languages.
Now that you have your generated model objects, it’s time to integrate!