快速入门

本指南通过一个简单的示例,帮助您开始在 Objective-C 中使用 iOS 平台上的 gRPC。

快速入门

本指南通过一个简单的示例,帮助您开始在 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
    
  • Homebrew

  • 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 编译器。

下一步是什么

上次修改时间:2024 年 11 月 25 日:feat: move the $ shell line indicator to scss (#1354) (ab8b3af)