the bridge is needed? advantages for users advantages for developers scripting native with React How does the bridge work? collecting native modules calling native functions calling JavaScript functions back
the bridge is needed? advantages for users advantages for developers scripting native with React How does the bridge work? collecting native modules calling native functions calling JavaScript functions back
use platform-specific features to process heavy tasks with multi-thread React Native have lots of native modules and theirs bindings bridge native module native module native module … bundled JavaScript
the bridge is needed? advantages for users advantages for developers scripting native with React How does the bridge work? collecting native modules calling native functions calling JavaScript functions back
the web, but our reimplementations never feel exactly like their native counterparts, and they also don't get updated automatically with changes to the platform https://code.facebook.com/posts/1014532261909640/react-native-bringing-modern-web-techniques-to-mobile/ Why native is necessary Native behaviors help users to work with your app Apache Cordova reimplements components
the screen, and we often have to manually compute the size and position of all our views https://code.facebook.com/posts/1014532261909640/react-native-bringing-modern-web-techniques-to-mobile/ On native, however, we need to recompile after every change, even if we just want to shift text a few pixels over on the screen. Why native is difficult Appcelerator Titanium needs recompile
being blocked on JavaScript execution. To make this efficient, we know we want to execute our JavaScript off the main thread, but doing so is hard. The first reason it's hard is resource contention. The second reason this is tough is that there's some fixed amount of overhead associated with every round trip between the native environment and the JavaScript virtual machine. https://code.facebook.com/posts/1014532261909640/react-native-bringing-modern-web-techniques-to-mobile/ Scripting native is tricky
programming model and ensure that our system always passes messages across the thread boundary asynchronously and that we can batch up as many of these messages per frame as possible, minimizing cross-thread communication overhead. https://code.facebook.com/posts/1014532261909640/react-native-bringing-modern-web-techniques-to-mobile/ Scripting native is tricky In order to this goal, the bridge is needed!!
model to do this correctly. Since React components are just pure, side-effect-free functions that return what our views look like at any point in time, we never need to read from our underlying rendered view implementation in order to write to it. https://code.facebook.com/posts/1014532261909640/react-native-bringing-modern-web-techniques-to-mobile/ Introducing React Native
the bridge is needed? advantages for users advantages for developers scripting native with React How does the bridge work? collecting native modules calling native functions calling JavaScript functions back
3. collecting native modules HOW DOES THE BRIDGE WORK? AppDelegate RCTRootView : UIView RCTBridge : NSObject RCTBatchedBridge : RCTBridge * AppDelegate: implementations about app lifecycle * UIView: base class for all views * NSObject: base class for all objects * RCT: abbr. ReaCT
defined inside the @interface declaration. Once you’ve defined the interface for a class, including the properties and methods intended for public access, you need to write the code to implement the class behavior. @interface CalendarManager : NSObject<RCTBridgeModule>
declare the methods expected to be used for a particular situation. @protocol RCTBridgeModule <NSObject> + (NSString *)moduleName; @optional // snip @end A protocol to be implemented in native modules
RCT_EXPORT_METHOD(addEvent:(NSString *)name at:(NSString *)location) { RCTLogInfo(@"Create an event: %@ at %@", name, location); } RCT_EXPORT_METHOD(findEvents:(RCTResponseSenderBlock)callback) { NSArray *events = @[@"talk in 21cafe", @"write slides"]; callback(@[[NSNull null], events]); } @end NATIVE MODULE EXAMPLE This is needed to be collected as a native module by the bridge
the -fvisibility flag at compile-time. Thus, adding the default visibility attribute causes a symbol to be exported in all cases, whereas adding the hidden visibility attribute hides it. extern __attribute__((visibility("default"))) void RCTRegisterModule(Class); + (NSString *)moduleName { return @""; } + (void)load { RCTRegisterModule(self); } Visibility “default” specifies exporting symbols to out of file scope
class objects rather than instances of the class. In Objective-C, a class method is denoted by a plus (+) sign at the beginning of the method declaration and implementation extern __attribute__((visibility("default"))) void RCTRegisterModule(Class); + (NSString *)moduleName { return @""; } + (void)load { RCTRegisterModule(self); } Plus (+) sign to declare / implement class methods https://developer.apple.com/library/content/documentation/General/Conceptual/DevPedia-CocoaCore/ ClassMethod.html
leading ‘#’, the preprocessor replaces it with the literal text of the actual argument, converted to a string constant. Unlike normal parameter replacement, the argument is not macro-expanded first. This is called stringification. #define RCT_EXPORT_MODULE(js_name) \ RCT_EXTERN void RCTRegisterModule(Class); \ + (NSString *)moduleName { return @#js_name; } \ A combination of • string “@“ • stringification feature in C-lang macro “#js_name”
the Objective-C runtime; implement this method to perform class- specific behavior upon loading. https://developer.apple.com/reference/objectivec/nsobject/1418815-load?language=objc extern __attribute__((visibility("default"))) void RCTRegisterModule(Class); + (NSString *)moduleName { return @""; } + (void)load { RCTRegisterModule(self); } A method to set up conditions for the class
@"%@ does not conform to the RCTBridgeModule protocol", moduleClass); // Register module [RCTModuleClasses addObject:moduleClass]; } https://developer.apple.com/reference/objectivec/nsobject/1418893-conformstoprotocol Returns a Boolean value that indicates whether the receiver conforms to a given protocol. conformsToProtocol
new]; for (Class moduleClass in RCTGetModuleClasses()) { NSString *moduleName = RCTBridgeModuleNameForClass(moduleClass); // snip moduleData = [[RCTModuleData alloc] initWithModuleClass:moduleClass bridge:self]; moduleDataByName[moduleName] = moduleData; // snip } Native modules can call JavaScript through the bridge by this
current input line number, in the form of a decimal integer constant. __LINE__ This macro expands to sequential integral values starting from 0. __COUNTER__ https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/ DefiningClasses/DefiningClasses.html - The minus sign (-) at the front of the method name indicates that it is an instance method
the bridge is needed? advantages for users advantages for developers scripting native with React How does the bridge work? collecting native modules calling native functions calling JavaScript functions back
NativeModules enqueue JSON data for the calling MessageQueue.enqueueNativeCall NativeModules[aModule][aMethod] https://github.com/facebook/react-native/blob/master/Libraries/BatchedBridge/NativeModules.js
by use of • type information from native module definitions • RCTConvert + (NSArray<NSString *> *)__rct_export__142 { return @[@"", @"addEvent:(NSString *)name at:(NSString *)location"]; } - (void)addEvent:(NSString *)name at:(NSString *)location { RCTLogInfo(@"Create an event: %@ at %@", name, location); } type information https://github.com/facebook/react-native/blob/master/React/Base/RCTModuleMethod.m processed by the bridge
• NSString • NSNumber • BOOL • NSArray • NSDictionary and more And you can define converter for your type like Enumerations https://github.com/facebook/react-native/search?q=RCTConvert
the bridge is needed? advantages for users advantages for developers scripting native with React How does the bridge work? collecting native modules calling native functions calling JavaScript functions back
• by sending event 3 ways to call JavaScript functions back BatchedBridge enqueueCallback BatchedBridge enqueueJSCall https://github.com/facebook/react-native/blob/master/React/Base/RCTBatchedBridge.m arguments are converted to JSON
for Web / native engineers. • “Learn once, write anywhere” for Web engineers • compile-less development for native engineers • Building native modules is simple enough. • Don’t be afraid, Let’s try.