Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bridge docs for RCT_EXPORT #801

Merged
merged 2 commits into from
Apr 10, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ var GeoInfo = React.createClass({

## Extensibility

It is certainly possible to create a great app using React Native without writing a single line of native code, but React Native is also designed to be easily extended with custom native views and modules - that means you can reuse anything you've already built, and can import and use your favorite native libraries. To create a simple module in iOS, create a new class that implements the `RCTBridgeModule` protocol, and add `RCT_EXPORT` to the function you want to make available in JavaScript.
It is certainly possible to create a great app using React Native without writing a single line of native code, but React Native is also designed to be easily extended with custom native views and modules - that means you can reuse anything you've already built, and can import and use your favorite native libraries. To create a simple module in iOS, create a new class that implements the `RCTBridgeModule` protocol, and wrap the function that you want to make available to JavaScript in `RCT_EXPORT_METHOD`. Additionally, the class itself must be explicitly exported with `RCT_EXPORT_MODULE();`.

```objc
// Objective-C
Expand All @@ -130,9 +130,12 @@ It is certainly possible to create a great app using React Native without writin
@end

@implementation MyCustomModule
- (void)processString:(NSString *)input callback:(RCTResponseSenderBlock)callback

RCT_EXPORT_MODULE();

// Available as NativeModules.MyCustomModule.processString
RCT_EXPORT_METHOD(processString:(NSString *)input callback:(RCTResponseSenderBlock)callback)
{
RCT_EXPORT(); // available as NativeModules.MyCustomModule.processString
callback(@[[input stringByReplacingOccurrencesOfString:@"Goodbye" withString:@"Hello"]]);
}
@end
Expand Down
25 changes: 10 additions & 15 deletions docs/NativeModulesIOS.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,16 @@ Native module is just an Objectve-C class that implements `RCTBridgeModule` prot
@end
```

React Native will not expose any methods of `CalendarManager` to JavaScript unless explicitly asked. Fortunately this is pretty easy with `RCT_EXPORT`:
React Native will not expose any methods of `CalendarManager` to JavaScript unless explicitly asked. Fortunately this is pretty easy with `RCT_EXPORT_METHOD`:

```objective-c
// CalendarManager.m
@implementation CalendarManager

- (void)addEventWithName:(NSString *)name location:(NSString *)location
RCT_EXPORT_MODULE();

RCT_EXPORT_METHOD(addEvent:(NSString *)name location:(NSString *)location)
{
RCT_EXPORT();
RCTLogInfo(@"Pretending to create an event %@ at %@", name, location);
}

Expand All @@ -47,12 +48,10 @@ Now from your JavaScript file you can call the method like this:

```javascript
var CalendarManager = require('NativeModules').CalendarManager;
CalendarManager.addEventWithName('Birthday Party', '4 Privet Drive, Surrey');
CalendarManager.addEvent('Birthday Party', '4 Privet Drive, Surrey');
```

Notice that the exported method name was generated from first part of Objective-C selector. Sometimes it results in a non-idiomatic JavaScript name (like the one in our example). You can change the name by supplying an optional argument to `RCT_EXPORT`, e.g. `RCT_EXPORT(addEvent)`.

The return type of the method should always be `void`. React Native bridge is asynchronous, so the only way to pass a result to JavaScript is by using callbacks or emitting events (see below).
The return type of bridge methods is always `void`. React Native bridge is asynchronous, so the only way to pass a result to JavaScript is by using callbacks or emitting events (see below).

## Argument types

Expand All @@ -68,9 +67,8 @@ React Native supports several types of arguments that can be passed from JavaScr
In our `CalendarManager` example, if we want to pass event date to native, we have to convert it to a string or a number:

```objective-c
- (void)addEventWithName:(NSString *)name location:(NSString *)location date:(NSInteger)secondsSinceUnixEpoch
RCT_EXPORT_METHOD(addEvent:(NSString *)name location:(NSString *)location date:(NSInteger)secondsSinceUnixEpoch)
{
RCT_EXPORT(addEvent);
NSDate *date = [NSDate dateWithTimeIntervalSince1970:secondsSinceUnixEpoch];
}
```
Expand All @@ -80,9 +78,8 @@ As `CalendarManager.addEvent` method gets more and more complex, the number of a
```objective-c
#import "RCTConvert.h"

- (void)addEventWithName:(NSString *)name details:(NSDictionary *)details
RCT_EXPORT_METHOD(addEvent:(NSString *)name details:(NSDictionary *)details)
{
RCT_EXPORT(addEvent);
NSString *location = [RCTConvert NSString:details[@"location"]]; // ensure location is a string
...
}
Expand Down Expand Up @@ -112,9 +109,8 @@ CalendarManager.addEvent('Birthday Party', {
Native module also supports a special kind of argument- a callback. In most cases it is used to provide the function call result to JavaScript.

```objective-c
- (void)findEvents:(RCTResponseSenderBlock)callback
RCT_EXPORT_METHOD(findEvents:(RCTResponseSenderBlock)callback)
{
RCT_EXPORT();
NSArray *events = ...
callback(@[[NSNull null], events]);
}
Expand Down Expand Up @@ -142,9 +138,8 @@ The native module should not have any assumptions about what thread it is being


```objective-c
- (void)addEventWithName:(NSString *)name callback:(RCTResponseSenderBlock)callback
RCT_EXPORT_METHOD(addEvent:(NSString *)name callback:(RCTResponseSenderBlock)callback)
{
RCT_EXPORT(addEvent);
dispatch_async(dispatch_get_main_queue(), ^{
// Call iOS API on main thread
...
Expand Down
8 changes: 5 additions & 3 deletions website/src/react-native/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ var GeoInfo = React.createClass({

<h2>Extensibility</h2>
<p>
It is certainly possible to create a great app using React Native without writing a single line of native code, but React Native is also designed to be easily extended with custom native views and modules - that means you can reuse anything you{"'"}ve already built, and can import and use your favorite native libraries. To create a simple module in iOS, create a new class that implements the RCTBridgeModule protocol, and add RCT_EXPORT to the function you want to make available in JavaScript.
It is certainly possible to create a great app using React Native without writing a single line of native code, but React Native is also designed to be easily extended with custom native views and modules - that means you can reuse anything you{"'"}ve already built, and can import and use your favorite native libraries. To create a simple module in iOS, create a new class that implements the RCTBridgeModule protocol, and wrap the function that you want to make available to JavaScript in RCT_EXPORT_METHOD. Additionally, the class itself must be explicitly exported with RCT_EXPORT_MODULE();.
</p>
<Prism>
{`// Objective-C
Expand All @@ -171,9 +171,11 @@ var GeoInfo = React.createClass({

@implementation MyCustomModule

- (void)processString:(NSString *)input callback:(RCTResponseSenderBlock)callback
RCT_EXPORT_MODULE();

// Available as NativeModules.MyCustomModule.processString
RCT_EXPORT_METHOD(processString:(NSString *)input callback:(RCTResponseSenderBlock)callback)
{
RCT_EXPORT(); // available as NativeModules.MyCustomModule.processString
callback(@[[input stringByReplacingOccurrencesOfString:@"Goodbye" withString:@"Hello"];]]);
}
@end`}
Expand Down