Implement gRPC in an iOS React Native app

Viewed 2261

As described in this issue, we can't implement a gRPC client using the Node implementation because "RN is not pure Node".

So I started working on an Objective-C implementation using the Native Modules.

[service postWithRequest:request handler:^(RequestConfirmation * _Nullable response, NSError * _Nullable error) {
    if (response) {
        // This prints correctly in my JS console
        RCTLogInfo(@"%@", response.message);

        // This generates an error, see below
        resolve(response);

        // This works
        NSDictionary *formattedResponse = @{
            @"id": response.id_p,
            @"message": response.message
        };
        resolve(formattedResponse);
    } else {
        reject(@"error", @"An error occurred while saving", error);
    }
}];

Error :

RCTJSONStringify() encountered the following error: Invalid type in JSON write (RequestConfirmation)

As you can see the problem is with the resolve method. I suppose React does not find any way to convert my proto message to JSON.

How can I keep the response as is and pass it to the resolve method ? Then I can decode it in my JS code.

Thanks.

EDIT 1 :

RequestConfirmation is defined in my proto file like this :

message RequestConfirmation {
    string id = 1;
    string message = 2;
}

And then it is generated in Objective-C :

@interface RequestConfirmation : GPBMessage

@property(nonatomic, readwrite, copy, null_resettable) NSString *id_p;

@property(nonatomic, readwrite, copy, null_resettable) NSString *message;

@end
2 Answers

Maybe the following is a potential solution for this.

Improbable Engineering have coded:

  • grpc-web - Typescript/Javascript, browser or NodeJS!

Aside from the unfortunate naming, this appears not to be a mere fork of the official, C++-using, grpc-web project).

Quoting the Improbable project's own grpc-web-client page:

This library is intended for both JavaScript and TypeScript usage from either a browser or Node.js

The possible benefits of Improbable's version seem to be:

  1. It doesn't appear to use native code (i.e. no C/C++/Java)
  2. It can generate Typescript (therefore JavaScript) for Node.JS

So, maybe, we could get GRPC-on-RN working, when point No. 2 is coupled with a NodeJS-on-RN project such as rn-nodeify.

Please provide feedback, if you have any success with this.

At the time of writing, Improbable Engineering's gRP-Web can't be used with React Native.

Instead you must use React Native Native Modules and build native modules in Swift or Objective-C. Since React Native doesn't talk to Swift directly, you must create an Objective-C bridge if you choose to use Swift.

You will:

  1. implement a gRPC client in the native language of your device,
  2. export it using React Native's Native module framework
  3. access the native module and its gRPC methods through React Native
  4. Call those exported methods in React your Native code

The basic structure of this relationship is:

# Swift project
Reat Native <-> ObjC Bridge <-> Swift <-> gRPC

# Objective-C project
Reat Native <-> ObjC <-> gRPC

It's a pretty lengthy explanation of how to integrate these components. I've written a tutorial for Building a gPRC Client in React Native on iOS/Swift. I hope people find that useful.

Related