快速入门
本指南将通过一个简单的运行示例,带您开始在 iOS 平台上使用 Objective-C 进行 gRPC 开发。
快速入门
准备工作
系统要求
- macOS 10.11 (El Capitan) 或更高版本
- iOS 7.0 或更高版本
先决条件
CocoaPods 1.0 或更高版本
检查系统上 CocoaPods 的状态和版本
pod --version如果尚未安装 CocoaPods,请遵循 CocoaPods 安装说明。
Xcode 7.2 或更高版本
通过从 Launchpad 运行 Xcode 来检查您的 Xcode 版本,然后在菜单中选择 Xcode > About Xcode。
确保已安装命令行开发工具
xcode-select --installautoconf,automake,libtool,pkg-configbrew install autoconf automake libtool pkg-config
下载示例
您需要一份示例应用源代码的本地副本才能完成本快速入门。请从 GitHub 仓库 复制源代码
git clone --recursive -b v1.78.1 --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
(这可能需要编译 OpenSSL,如果您的计算机缓存中还没有该库,则大约需要 15 分钟。)
运行客户端应用
打开由 CocoaPods 创建的 Xcode 工作区
open HelloWorld.xcworkspace
这将在 Xcode 中打开应用项目。点击 Xcode 窗口左上角的“运行”按钮,在 iOS 模拟器中运行该应用。您可以查看 main.m 中的调用代码,并在 Xcode 控制台中看到结果。
该代码向本地服务端发送了一个包含字符串“Objective-C”的 HLWHelloRequest 请求。服务端返回一个包含字符串“Hello Objective-C”的 HLWHelloResponse 响应,该响应随后被输出到控制台。
恭喜!您刚刚运行了一个使用 gRPC 的客户端-服务器应用程序。
更新 gRPC 服务
现在,让我们看看如何通过在服务端添加额外方法来更新应用程序。我们的 gRPC 服务是使用 Protocol Buffers 定义的;您可以在 Protocol Buffers 网站 上了解更多关于如何在 .proto 文件中定义服务的信息。目前您只需知道,服务端和客户端“桩 (stub)”都有一个 SayHello RPC 方法,该方法接收来自客户端的 HelloRequest 参数并返回来自服务端的 HelloResponse,且该方法的定义如下所示
// 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 服务有两个方法。编辑 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
并运行客户端应用。如果您查看控制台消息,将会看到两个 RPC 调用,一个是 SayHello,另一个是 SayHelloAgain。
故障排除
- 安装 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 运行
brew install protobuf以获取protoc编译器。