This guide gets you started with gRPC on the iOS platform in Objective-C with a simple working example.

  • macOS version 10.11 (El Capitan) or higher
  • iOS version 7.0 or higher

Prerequisites

  • CocoaPods version 1.0 or higher

Check the status and version of CocoaPods on your system:

If CocoaPods is not installed, follow theCocoaPods installinstructions.

  • Xcode version 7.2 or higher

Check your Xcode version by running Xcode from Lauchpad, then selectXcode > About Xcode in the menu.

Make sure the command line developer tools are installed:

  • autoconf, automake, libtool, pkg-config

  1. $ brew install autoconf automake libtool pkg-config

Download the example

You’ll need a local copy of the sample app source code to work through thisQuickstart. Copy the source code from GitHub:

  1. $ git clone --recursive -b v1.28.1 https://github.com/grpc/grpc.git

Install gRPC plugins and libraries

  1. $ cd grpc
  2. $ make
  3. $ [sudo] make install
  1. $ brew tap grpc/grpc
  2. $ brew install protobuf

Run the server:

For this sample app, we need a gRPC server running on the local machine. gRPCObjective-C API supports creating gRPC clients but not gRPC servers. Thereforeinstead we build and run the C++ server in the same repository:

Run the client:

Have CocoaPods generate and install the client library from our .proto files, aswell as installing several dependencies:

  1. $ cd ../../objective-c/helloworld
  2. $ pod install

(This might have to compile OpenSSL, which takes around 15 minutes if Cocoapodsdoesn’t have it yet on your computer’s cache.)

Run the client app

Open the Xcode workspace created by CocoaPods:

  1. $ open HelloWorld.xcworkspace

The code sends a HLWHelloRequest containing the string “Objective-C” to alocal server. The server responds with a HLWHelloResponse, which contains astring “Hello Objective-C” that is then output to the console.

Congratulations! You’ve just run a client-server application with gRPC.

Now let’s look at how to update the application with an extra method on theserver for the client to call. Our gRPC service is defined using ProtocolBuffers; you can find out lots more about how to define a service in a .protofile in Protocol Bufferswebsite. For now all youneed to know is that both the server and the client “stub” have a SayHelloRPC method that takes a HelloRequest parameter from the client and returns aHelloResponse from the server, and that this method is defined like this:

  1. // The greeting service definition.
  2. service Greeter {
  3. // Sends a greeting
  4. }
  5. // The request message containing the user's name.
  6. message HelloRequest {
  7. string name = 1;
  8. }
  9. // The response message containing the greetings
  10. message HelloReply {
  11. }

Let’s update this so that the Greeter service has two methods. Editexamples/protos/helloworld.proto and update it with a new SayHelloAgainmethod, with the same request and response types:

  1. // The greeting service definition.
  2. service Greeter {
  3. // Sends a greeting
  4. rpc SayHello (HelloRequest) returns (HelloReply) {}
  5. // Sends another greeting
  6. rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
  7. }
  8. // The request message containing the user's name.
  9. message HelloRequest {
  10. string name = 1;
  11. }
  12. // The response message containing the greetings
  13. message HelloReply {
  14. string message = 1;
  15. }

Remember to save the file!

Update the client and server

We now have a new gRPC service definition, but we still need to implement andcall the new method in the human-written parts of our example application.

As you remember, gRPC doesn’t provide a server API for Objective-C. Instead, weneed to update the C++ sample server. Openexamples/cpp/helloworld/greeter_server.cc. Implement the new method like this:

  1. class GreeterServiceImpl final : public Greeter::Service {
  2. Status SayHello(ServerContext* context, const HelloRequest* request,
  3. HelloReply* reply) override {
  4. std::string prefix("Hello ");
  5. reply->set_message(prefix + request->name());
  6. return Status::OK;
  7. }
  8. Status SayHelloAgain(ServerContext* context, const HelloRequest* request,
  9. std::string prefix("Hello again ");
  10. reply->set_message(prefix + request->name());
  11. return Status::OK;
  12. };

Update the client

Edit the main function in examples/objective-c/helloworld/main.m to call the new method like this:

Build and run

First terminate the server process already running in the background:

  1. $ pkill greeter_server

Then in directory examples/cpp/helloworld, build and run the updated serverwith the following commands:

  1. $ make
  2. $ ./greeter_server &

Change directory to examples/objective-c/helloworld, then clean up andreinstall Pods for the client app with the following commands:

  1. $ rm -Rf Pods
  2. $ rm Podfile.lock
  3. $ rm -Rf HelloWorld.xcworkspace
  4. $ pod install

This regenerates files in Pods/HelloWorld based on the new proto file we wroteabove. Open the client Xcode project in Xcode:

  1. $ open HelloWorld.xcworkspace
  • When installing CocoaPods, error activesupport requires Ruby version >= 2.2.2
  • Install an older version of activesupport, then install CocoaPods:
  1. $ [sudo] gem install activesupport -v 4.2.6
  2. $ [sudo] gem install cocoapods
  • When installing dependencies with CocoaPods, error Unable to find a specification for !ProtoCompiler-gRPCPlugin
  • Update the local clone of spec repo by running pod repo update

  • Compiler error when compiling objective_c_plugin.cc

  • Removing protobuf package with Homebrew before building gRPC may solve thisproblem. We are working on a more elegant fix.

  • When building HellowWorld, error ld: unknown option: —no-as-needed

  • This problem is due to linker ld in Apple LLVM not supporting the—no-as-needed option. We are working on a fix right now and will merge thefix very soon.

  • When building grpc, error cannot find install-sh install.sh or shtool

  • Remove the gRPC directory, clone a new one and try again. It is likely thatsome auto generated files are corrupt; remove and rebuild may solve theproblem.

  • When building grpc, error Can't exec "aclocal"

  • The package automake is missing. Install automake should solve this problem.

  • When building grpc, error possibly undefined macro: AC_PROG_LIBTOOL

  • The package libtool is missing. Install libtool should solve this problem.

  • When building grpc, error cannot find install-sh, install.sh, or shtool

  • Cannot find protoc when building HelloWorld

  • Run brew install protobuf to get the compiler.

What’s next