快速入门
本指南通过一个简单的示例,帮助您开始在 Objective-C 中使用 iOS 平台上的 gRPC。
快速入门
开始之前
系统要求
- macOS 10.11 (El Capitan) 或更高版本
- iOS 7.0 或更高版本
先决条件
CocoaPods 1.0 或更高版本
检查系统上 CocoaPods 的状态和版本
pod --version
如果未安装 CocoaPods,请按照 CocoaPods 安装说明进行安装。
Xcode 7.2 或更高版本
通过从启动台运行 Xcode 来检查您的 Xcode 版本,然后在菜单中选择 Xcode > 关于 Xcode。
确保已安装命令行开发人员工具
xcode-select --install
autoconf
,automake
,libtool
,pkg-config
brew install autoconf automake libtool pkg-config
下载示例
您需要一份示例应用程序源代码的本地副本,才能完成此快速入门。从 GitHub 存储库复制源代码。
git clone --recursive -b v1.66.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
(这可能需要编译 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 定义的;您可以在 Protocol Buffers 网站中找到更多关于如何在 .proto
文件中定义服务的信息。现在您需要知道的是,服务器和客户端“存根”都有一个 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
中的 main 函数,像这样调用新方法
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 repo 的本地克隆- 编译
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
编译器。