クイックスタート

このガイドでは、シンプルな動作例を使用して、Objective-CのgRPCをiOSプラットフォームで開始する方法を説明します。

クイックスタート

このガイドでは、シンプルな動作例を使用して、Objective-CのgRPCをiOSプラットフォームで開始する方法を説明します。

開始する前に

システム要件

  • macOS バージョン 10.11 (El Capitan) 以降
  • iOS バージョン 7.0 以降

前提条件

  • CocoaPods バージョン 1.0 以降

    システム上のCocoaPodsのステータスとバージョンを確認します。

    pod --version
    

    CocoaPodsがインストールされていない場合は、CocoaPods のインストール手順に従ってください。

  • Xcode バージョン 7.2 以降

    LaunchpadからXcodeを実行し、メニューからXcode > Xcodeについてを選択してXcodeのバージョンを確認します。

    コマンドライン開発者ツールがインストールされていることを確認します。

    xcode-select --install
    
  • Homebrew

  • autoconf, automake, libtool, pkg-config

    brew install autoconf automake libtool pkg-config
    

サンプルをダウンロードする

このクイックスタートを進めるには、サンプルアプリケーションのソースコードのローカルコピーが必要です。GitHub リポジトリからソースコードをコピーしてください。

git clone --recursive -b v1.74.0 --depth 1 --shallow-submodules https://github.com/grpc/grpc

gRPCプラグインとライブラリのインストール

cd grpc
make
[sudo] make install

protocコンパイラのインストール

brew tap grpc/grpc
brew install protobuf

サーバーを実行する

このサンプルアプリケーションでは、ローカルマシンで実行されるgRPCサーバーが必要です。gRPC Objective-C APIはgRPCクライアントの作成をサポートしますが、gRPCサーバーはサポートしません。したがって、代わりに同じリポジトリのC++サーバーをビルドして実行します。

cd examples/cpp/helloworld
make
./greeter_server &

クライアントの実行

クライアントライブラリと依存関係の生成

.protoファイルからクライアントライブラリを生成してインストールするようにCocoaPodsに指示し、いくつかの依存関係もインストールします。

cd ../../objective-c/helloworld
pod install

(この処理ではOpenSSLのコンパイルが必要になる場合があり、Cocoapodsがまだコンピュータのキャッシュに持っていない場合は15分ほどかかります。)

クライアントアプリケーションの実行

CocoaPodsによって生成されたXcodeワークスペースを開きます。

open HelloWorld.xcworkspace

これにより、Xcodeでアプリプロジェクトが開かれます。Xcodeウィンドウの左上にある実行ボタンを押して、iOSシミュレーターでアプリを実行します。main.mで呼び出しコードを確認し、Xcodeのコンソールで結果を見ることができます。

コードは、「Objective-C」という文字列を含むHLWHelloRequestをローカルサーバーに送信します。サーバーはHLWHelloResponseで応答し、その文字列「Hello Objective-C」がコンソールに出力されます。

おめでとうございます!gRPCを使用したクライアント・サーバーアプリケーションを実行できました。

gRPCサービスを更新する

次に、クライアントが呼び出すための追加メソッドをサーバーに含めてアプリケーションを更新する方法を見ていきましょう。gRPCサービスはProtocol Buffersを使用して定義されています。サービスを.protoファイルで定義する方法については、Protocol Buffersのウェブサイトで詳しく知ることができます。現時点では、サーバーとクライアントの「スタブ」の両方に、クライアントからHelloRequestパラメータを受け取り、サーバーからHelloResponseを返すSayHello RPCメソッドがあり、このメソッドは次のように定義されていることを知っておけば十分です。

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}

これを更新して、`Greeter` サービスが 2 つのメソッドを持つようにしましょう。`examples/protos/helloworld.proto` を編集し、同じリクエストとレスポンスタイプを持つ新しい `SayHelloAgain` メソッドを追加してください。

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
  // Sends another greeting
  rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}

ファイルを保存してください!

クライアントとサーバーの更新

新しいgRPCサービス定義はできましたが、例として提供されているアプリケーションの人間が書いた部分で新しいメソッドを実装し、呼び出す必要があります。

サーバーを更新する

ご存知のとおり、gRPCはObjective-C用のサーバーAPIを提供していません。代わりに、C++サンプルサーバーを更新する必要があります。examples/cpp/helloworld/greeter_server.ccを開き、新しいメソッドを次のように実装します。

class GreeterServiceImpl final : public Greeter::Service {
  Status SayHello(ServerContext* context, const HelloRequest* request,
                  HelloReply* reply) override {
    std::string prefix("Hello ");
    reply->set_message(prefix + request->name());
    return Status::OK;
  }
  Status SayHelloAgain(ServerContext* context, const HelloRequest* request,
                  HelloReply* reply) override {
    std::string prefix("Hello again ");
    reply->set_message(prefix + request->name());
    return Status::OK;
  }
};

クライアントを更新する

examples/objective-c/helloworld/main.mのメイン関数を編集して、新しいメソッドを次のように呼び出します。

int main(int argc, char * argv[]) {
  @autoreleasepool {
    HLWGreeter *client = [[HLWGreeter alloc] initWithHost:kHostAddress];

    HLWHelloRequest *request = [HLWHelloRequest message];
    request.name = @"Objective-C";

    GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
    // this example does not use TLS (secure channel); use insecure channel instead
    options.transport = GRPCDefaultTransportImplList.core_insecure;
    options.userAgentPrefix = @"HelloWorld/1.0";

    [[client sayHelloWithMessage:request
                 responseHandler:[[HLWResponseHandler alloc] init]
                     callOptions:options] start];
    [[client sayHelloAgainWithMessage:request
                      responseHandler:[[HLWResponseHandler alloc] init]
                          callOptions:options] start];

    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
  }
}

ビルドと実行

まず、バックグラウンドで実行されているサーバープロセスを終了します。

pkill greeter_server

次に、examples/cpp/helloworldディレクトリで、次のコマンドを使用して更新されたサーバーをビルドして実行します。

make
./greeter_server &

examples/objective-c/helloworldディレクトリに移動し、次のコマンドを使用してクライアントアプリのPodsをクリーンアップして再インストールします。

rm -Rf Pods
rm Podfile.lock
rm -Rf HelloWorld.xcworkspace
pod install

これにより、上記で記述した新しいprotoファイルに基づいて、Pods/HelloWorldのファイルが再生成されます。クライアントXcodeプロジェクトをXcodeで開きます。

open HelloWorld.xcworkspace

そして、クライアントアプリを実行します。コンソールメッセージを見ると、SayHelloとSayHelloAgainへの2つのRPC呼び出しが表示されます。

トラブルシューティング

CocoaPodsのインストール中に、エラーactivesupport requires Ruby version >= 2.2.2が発生します。

activesupportの古いバージョンをインストールしてから、CocoaPodsをインストールします。

[sudo] gem install activesupport -v 4.2.6
[sudo] gem install cocoapods
CocoaPodsで依存関係をインストール中に、エラーUnable to find a specification for !ProtoCompiler-gRPCPluginが発生します。

pod repo updateを実行して、ローカルのspecリポジトリのクローンを更新します。

objective_c_plugin.ccをコンパイルする際にコンパイラエラーが発生します。

gRPCをビルドする前にHomebrewでprotobufパッケージを削除すると、この問題が解決する可能性があります。より洗練された修正に取り組んでいます。

HelloWorldをビルドする際に、エラーld: unknown option: --no-as-neededが発生します。

この問題は、Apple LLVMのリンカーld--no-as-neededオプションをサポートしていないために発生します。現在修正に取り組んでおり、まもなくマージされる予定です。

grpcをビルドする際に、エラーcannot find install-sh install.sh or shtoolが発生します。

gRPCディレクトリを削除し、新しいものをクローンして再度試してください。一部の自動生成ファイルが破損している可能性が高いため、削除して再ビルドすると問題が解決する可能性があります。

grpcをビルドする際に、エラーCan't exec "aclocal"が発生します。

automakeパッケージが不足しています。automakeをインストールすると、この問題が解決するはずです。

grpcをビルドする際に、エラーpossibly undefined macro: AC_PROG_LIBTOOLが発生します。

libtoolパッケージが不足しています。libtoolをインストールすると、この問題が解決するはずです。

grpcをビルドする際に、エラーcannot find install-sh, install.sh, or shtoolが発生します。

一部の自動生成ファイルが破損しています。gRPCディレクトリ全体を削除し、GitHubからクローンし直して再度ビルドしてください。

HelloWorldのビルド時にprotocが見つかりません。

protocコンパイラを取得するには、brew install protobufを実行します。

次は何をするか