クイックスタート

このガイドでは、iOSプラットフォームでObjective-Cを使用してgRPCを始めるための簡単な動作例を紹介します。

クイックスタート

このガイドでは、iOSプラットフォームでObjective-Cを使用してgRPCを始めるための簡単な動作例を紹介します。

始める前に

システム要件

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

前提条件

  • CocoaPods バージョン 1.0 以降

    システム上のCocoaPodsのステータスとバージョンを確認してください

    $ pod --version
    

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

  • Xcode バージョン 7.2 以降

    LauchpadからXcodeを実行し、メニューの **Xcode > Xcodeについて** を選択して、Xcodeのバージョンを確認してください。

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

    $ xcode-select --install
    
  • Homebrew

  • autoconfautomakelibtoolpkg-config

    $ brew install autoconf automake libtool pkg-config
    

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

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

$ git clone --recursive -b v1.62.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 &

クライアントを実行する

クライアントライブラリと依存関係を生成する

CocoaPodsに、.protoファイルからクライアントライブラリを生成してインストールさせ、さらにいくつかの依存関係をインストールさせます

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

(CocoapodsがコンピュータのキャッシュにOpenSSLを持っていない場合、約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`パッケージを削除すると、この問題が解決する可能性があります。より洗練された修正に取り組んでいます。

HellowWorldのビルド時に、エラー`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`が見つかりません

`brew install protobuf`を実行して、`protoc`コンパイラを取得します。

次のステップ