注意
これは 2018年5月頃に書いた古い記事です。
現在ではサーバー実装を SwiftNIO ベースで書き直した main
ブランチ と 以前のように gRPC-Core を利用する cgrpc
ブランチに分かれています。これから grpc-swift の導入を考える方は最新の main
ブランチの README を見て作業をすることをおすすめします。
grpc-swiftを見ながら。最低限の通信をするMacアプリのサーバー、iPhoneアプリのクライアント作成を試してみたので手順を記録します。
環境
- cocoapods 1.5.0
- Xcode 9.3
- Homebrew 1.6.3
- SwiftGRPC: 0.4.3
- protoc --version libprotoc 3.5.1
- protoc-gen-swift --version protoc-gen-swift 1.0.3
Protocol Buffer Compilerのインストール
protobufをhomebrewでインストールします。
$ brew install protobuf
これでProtocol Buffer Compiler(以下protoc)がインストールされました。
$ protoc --version
$ libprotoc 3.5.1
Swift用のprotocプラグインの準備
まずはgrpc-swiftリポジトリをクローンします。
$ git clone https://github.com/grpc/grpc-swift.git
クローン後のディレクトリ(以下ディレクトリルート)でmakeを叩きます。
mainブランチの場合
$ cd grpc-swift
$ make plugins
cgrpcブランチの場合
$ cd grpc-swift
$ make plugin
これでSwift Package Managerによる依存パッケージのビルドが実行され、protocのプラグインprotoc-gen-swift(.protoファイルからSwiftコードを生成する)とprotoc-gen-grpc-swift(gRPCに対応したコードを生成する)がディレクトリルートにコピーされています。(下記はただのコピーされた状態の確認です。)
$ ls | grep protoc
protoc-gen-swift
protoc-gen-grpc-swift
生成されたプラグインを/usr/local/binにコピーします。
$ cp protoc-gen-swift protoc-gen-grpc-swift /usr/local/bin
試しに適当なprotoファイルをコンパイルしてみます。
helloworld.protoという名前のファイルを作成して、以下内容に編集してから保存します。
syntax = "proto3";
package greeter;
// 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;
}
保存したら下記コマンドを実行してみてください。
helloworld.pb.swiftとhelloworld.grpc.swiftが生成されていれば、protocプラグインのインストールは完了です。
// cgrpcブランチの場合
protoc helloworld.proto --swift_out=. --swiftgrpc_out=.
// mainブランチの場合
protoc helloworld.proto --swift_out=. --grpc-swift_out=.
実プロジェクトにgrpc-swiftを導入する。
grpc-swift0.42からcocoapodsに対応したようです。
なのでそれを使います。
$ sudo gem install cocoapods`
新規でXcodeプロジェクトを作成し、プロジェクトのディレクトリ直下でpod init
します。
エディタでPodfileを開き、pod 'SwiftGRPC'
の行を加えて、pod install
を実行します。
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
target 'gRPC-Sample' do
# Comment the next line if you're not using Swift and don't want to use dynamic frameworks
use_frameworks!
# Pods for gRPC-Sample
pod 'SwiftGRPC'
target 'gRPC-SampleTests' do
inherit! :search_paths
# Pods for testing
end
target 'gRPC-SampleUITests' do
inherit! :search_paths
# Pods for testing
end
end
pod installすると下記の依存関係がインストールされます。
Installing BoringSSL (10.0.2)
Installing SwiftGRPC (0.4.2)
Installing SwiftProtobuf (1.0.3)
Installing gRPC-Core (1.11.0)
Installing nanopb (0.3.8)
サーバーでは、下記のように自動生成されたprotocolを実装します。
final class GreeterProvider: Greeter_GreeterProvider {
func sayHello(request: Greeter_HelloRequest, session: Greeter_GreeterSayHelloSession) throws -> Greeter_HelloReply {
var g = Greeter_HelloReply()
g.message = request.name + " world"
return g
}
}
クライアントでは、下記のように自動生成されたfinalなクライアントクラスを実装します。
これで最低限通信するサンプルが実装できました。
let client = Greeter_GreeterServiceClient.init(address: "127.0.0.1:50051", secure: false)
var request = Greeter_HelloRequest()
request.name = "hello"
let ret = try? client.sayHello(request)
print("gRPC Server returns " + ret!.message)
ここまでのコードは一応こちらに上げてあります。 https://github.com/tikidunpon/gRPC-Swift-Sample
また、grpc-swiftのリポジトリにSwiftPMでGoogle Cloud Natural Language APIを叩くサンプルもあるようなので、GCPのアカウントを持っているかたは試してみてはいかがでしょうか?