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.

Leave a rating/review
Save for later
Share

For most apps that require backend services, transmitting and storing data is a big job. When interfacing with a web service, developers are usually required to send and receive data using JSON or XML, building structures and parsing them later.

Although there are plenty of APIs and frameworks to help with serialization and deserialization, going this route introduces maintenance concerns, such as versioning code and updating object parsers to support backend model changes.

If you are serious about making your new backend and frontend services robust, consider using protocol buffers, which are language-agnostic methods developed by Google for serializing structured data. In many cases, they are more flexible and efficient than other common methods like JSON and XML.

One of the key features is they allow you to define your data structure once, from which a compiler can generate code in any supported language — including Swift! The generated class files provide effortless reading and writing of objects.

In this tutorial, you will start up a Python server and integrate data with an existing iOS app. To get started, you will learn how protocol buffers work, how to set up the environment, and lastly how to transmit data with protocol buffers.

Still not convinced protocol buffers is what you need? Read on!

Note: This tutorial assumes you have the basic knowledge in iOS and Swift, with some basic server-side knowledge, and using the terminal.

As well, make sure you are running Apple’s latest Xcode 8.2.

Getting Started

RWCards is an app that lets you view your conference ticket and the list of speakers at the event.

Start by downloading the Starter Project and open the root directory Starter. Familiarize yourself with the three included components listed below:

The Client

Within Starter/RWCards, open RWCards.xcworkspace and take a look at some of the key files in the project:

  • SpeakersListViewController.swift manages a table view which displays the list of speakers. The controller is currently a template since you haven’t created a model object yet.
  • SpeakersViewModel.swift acts as the data source for SpeakersListViewController. It will contain the list of speakers.
  • CardViewController.swift contains the controller code to display an attendee’s badge along with their social information.
  • RWService.swift manages the integration between the client and backend. You will use Alamofire to make the service calls.
  • Main.storyboard contains all storyboard scenes for the app.

The project uses CocoaPods to pull in two frameworks:

  • Swift Protobuf allows you to use protocol buffers in your Xcode project.
  • Alamofire is a HTTP networking library that you will use to make requests to the server.

Note: In this tutorial you will use Swift Protobuf 0.9.24 and Google’s Protoc Compiler 3.1.0. They are already packaged with the starter so you don’t need to do anything further.

How do Protocol Buffers Work?

To use protocol buffers, you must first define a .proto file. Within the file, you specify a message type that defines how your schema or data structure will look. Below is a sample of a .proto file:

syntax = "proto3";

message Contact {

  enum ContactType {
    SPEAKER = 0;
    ATTENDANT = 1;
    VOLUNTEER = 2;
  }

  string first_name = 1;
  string last_name = 2;
  string twitter_name = 3;
  string email = 4;
  string github_link = 5;
  ContactType type = 6;
  string imageName = 7;
};

This defines a Contact message along with associated attributes.

With a .proto file defined, all you have to do is pass the file into the protocol buffer compiler, and it will generate data access classes (structs in Swift) in the supported languages of your choice. You can then use the classes/structs generated in the project you are working with. It’s that simple!

protocol buffers

The compiler will interpret the message, map the value types to the chosen language and generate the appropriate model object files. You’ll cover more on how to define a message later.

Before considering protocol buffers, you should first consider if it’s an appropriate strategy for your project.

Benefits

JSON and XML may be the standard approach that developers use to store and transmit data, but here’s why protocol buffers are great:

  • Faster, and smaller: According to Google, protocol buffers are 3-10 times smaller, and 20-100 times faster than XML. Also check out this post by Damien Bod where he compares the read and write times between popular formats.
  • Type safety: Protocol buffers are type-safe like Swift. Using the protocol buffer language, you need to specify a type for every property.
  • Automatic deserialization: You no longer need to write boilerplate parsing code. You simply need to update your proto file and regenerate the data access classes.
  • Sharing is caring: The ability to share models across various platforms with supported languages means less work is required when working cross-platform.

Limitations

Protocol buffers, as useful as they are, aren’t the answer to every problem:

  • Time and effort: It may not be cost effective to adapt protocol buffers in existing systems due to conversion costs. Additionally, it requires learning a new language syntax.
  • Not human readable: XML and JSON are more descriptive, and easier to read. Protocol buffers in their raw format are not self-describing. Without the .proto file, you won’t be able to interpret the data.
  • Just not a good fit: XML is great when you want to use stylesheets like XSLT. Protocol buffers are not always the best tool for the job.
  • Not supported: The compiler may not support the language of other systems you are communicating with.

While it’s not right for every situation, there certainly are some great arguments for using protocol buffers!

Build and run the app and try it out.

protocol buffers

Unfortunately you can’t view any of the information yet because the datasource hasn’t been populated. Your job will be to call the backend service and populate the UI with the list of speakers and attendee badges. First, you’ll take a look at what the starter has provided for these two pieces.

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.