OVERVIEW What is the bridge? What is native modules? Why 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
OVERVIEW What is the bridge? What is native modules? Why 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
WHAT IS THE BRIDGE? connector between JavaScript and native worlds collecting native modules loading bundled JavaScript calling native functions and calling JavaScript functions back
WHAT IS NATIVE MODULES? modules implemented in native platforms to 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
OVERVIEW What is the bridge? What is native modules? Why 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
ADVANTAGES FOR USERS It's possible to reimplement these components on 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
ADVANTAGES FOR DEVELOPERS it's harder to lay things out on 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
SCRIPTING NATIVE IS TRICKY our UI thread could end up 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
SCRIPTING NATIVE IS TRICKY We need to fundamentally change the 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!!
(REACT PROGRAMMING MODEL) Luckily, React gives us the perfect programming 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
OVERVIEW What is the bridge? What is native modules? Why 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
1. loading bundled JavaScript source 2. setting JavaScript executor up 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
@interface, @implementation? https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/ DefiningClasses/DefiningClasses.html The public properties and behavior are 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 https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/ WorkingwithProtocols/WorkingwithProtocols.html Objective-C allows you to define protocols, which declare the methods expected to be used for a particular situation. @protocol RCTBridgeModule + (NSString *)moduleName; @optional // snip @end A protocol to be implemented in native modules
#import "RCTBridgeModule.h" @interface CalendarManager : NSObject @end @implementation CalendarManager RCT_EXPORT_MODULE() 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
VISIBILITY? https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/CppRuntimeEnv/Articles/ SymbolVisibility.html Visibility attributes override the value specified with 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
+? A class method is a method that operates on 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
@#js_name? https://gcc.gnu.org/onlinedocs/cpp/Stringification.html#Stringification When a macro parameter is used with a 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”
LOAD? Invoked whenever a class or category is added to 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
RCTRegisterModule? void RCTRegisterModule(Class moduleClass) { // initialization RCTAssert( [moduleClass conformsToProtocol:@protocol(RCTBridgeModule)], @"%@ 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
-, __LINE__, __COUNTER__? https://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html This macro expands to the 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
OVERVIEW What is the bridge? What is native modules? Why 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? • Facade for native modules • Calling functions through NativeModules enqueue JSON data for the calling MessageQueue.enqueueNativeCall NativeModules[aModule][aMethod] https://github.com/facebook/react-native/blob/master/Libraries/BatchedBridge/NativeModules.js
TYPE CONVERSION FOR ARGUMENTS The bridge converts queued NSArray data by use of • type information from native module definitions • RCTConvert + (NSArray *)__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
RCTConvert? converter for JSON native value • JSON support • 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
OVERVIEW What is the bridge? What is native modules? Why 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
CALLING JAVASCRIPT FUNCTIONS BACK • by callback • by Promise • 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
SUMMARY • The approach “scripting native” is extremely powerful way 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.