diff --git a/docs/getting-started.md b/docs/getting-started.md index 1a692b574..c128d90aa 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -310,6 +310,8 @@ Finally, you need to add plugins to your Flipper client. Above we have only adde _Inspired by [a blog post by Ram N](http://blog.nparashuram.com/2019/09/using-flipper-with-react-native.html)._ +_This version of the tutorial is written against React Native 0.61.4. You can find versions of this guide for older versions of React Native [here](https://github.com/facebook/flipper/blob/da25241f7fbb06dffd913958559044d758c54fb8/docs/getting-started.md#setup-your-react-native-app)_ + Integrating Flipper with React Native is a bit different than with a native app. ### Android @@ -326,7 +328,6 @@ Add the following permissions to your `AndroidManifest.xml`. The SDK needs these `android/app/src/main/AndroidManifest.xml` ```xml - ``` @@ -358,6 +359,8 @@ android { dependencies { ... + implementation 'com.facebook.soloader:soloader:0.6.0+' + debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") { exclude group:'com.facebook.yoga' exclude group:'com.facebook.flipper', module: 'fbjni' @@ -367,7 +370,7 @@ dependencies { } ``` -Now, we create a new file inside `android/app/src/debug/java/com/yourappname/ReactNativeFlipper.java`. +Now, we create a new file: `android/app/src/debug/java/com/yourappname/ReactNativeFlipper.java`. (Replace the `yourappname` namespace with something appropriate for your project) These are the suggested plugins integrations: @@ -380,7 +383,7 @@ These are the suggested plugins integrations: - React devtools ```java -package com.yourappname; +package com.yourappname; // <--- use your own namespace chosen above! import android.content.Context; import com.facebook.flipper.android.AndroidFlipperClient; @@ -402,6 +405,10 @@ import okhttp3.OkHttpClient; public class ReactNativeFlipper { + public static void initializeFlipper(Context context) { + ReactNativeFlipper.initializeFlipper(context, null); + } + public static void initializeFlipper(Context context, final ReactInstanceManager reactInstanceManager) { if (!FlipperUtils.shouldEnableFlipper(context)) { return; @@ -427,7 +434,7 @@ public class ReactNativeFlipper { // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized // Hence we run if after all native modules have been initialized - ReactContext reactContext = reactInstanceManager.getCurrentReactContext(); + ReactContext reactContext = reactInstanceManager == null ? null : reactInstanceManager.getCurrentReactContext(); if (reactContext == null) { reactInstanceManager.addReactInstanceEventListener( new ReactInstanceManager.ReactInstanceEventListener() { @@ -456,51 +463,49 @@ initializing SoLoader (for loading the C++ part of Flipper) and starting a `Flip For this, we edit the `android/app/src/main/java/com/yourappname/MainApplication.java` file. ```java -package com.yourappname; +package com.yourappname;// <--- use your own namespace chosen above! import ... -import com.facebook.react.ReactInstanceManager; +import com.facebook.react.ReactInstanceManager; // <---- add this import public class MainApplication extends Application implements ReactApplication { ... @Override public void onCreate() { - ... - initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); + super.onCreate(); + SoLoader.init(this, /* native exopackage */ false); + initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); // <---- start flipper integration } +} +``` - /** - * Loads Flipper in React Native templates. Call this in the onCreate method with something like - * initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); - * - * @param context - */ +In the same file, modify the generated `initializeFlipper` method to + +```java private static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { if (BuildConfig.DEBUG) { try { - Class aClass = Class.forName("com.yourappname.ReactNativeFlipper"); - aClass - .getMethod("initializeFlipper", Context.class, ReactInstanceManager.class) - .invoke(null, context, reactInstanceManager); + /* + We use reflection here to pick up the class that initializes Flipper, + since Flipper library is not available in release mode + */ + Class aClass = Class.forName("com.yourappname.ReactNativeFlipper"); // <--- use your own namespace chosen above! + aClass.getMethod("initializeFlipper", Context.class, ReactInstanceManager.class).invoke(null, context, reactInstanceManager); } catch (ClassNotFoundException e) { - e.printStackTrace(); - } catch (NoSuchMethodException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (InvocationTargetException e) { - e.printStackTrace(); + /* All catch clauses as generated by RN */ + ... } } } -} ``` Finally, open the Flipper desktop app, and run `yarn android` in your terminal. ### iOS +_Make sure you are using [XCode 10](https://download.developer.apple.com/Developer_Tools/Xcode_10.3/Xcode_10.3.xip). The following guide doesn't work (yet) for XCode 11. Run `sudo xcode-select -s /Applications/Xcode_10.XXX/Contents/Developer/` to select the right xcode version._ + We support both Swift and Objective-C for Flipper with CocoaPods as build and distribution mechanism. For CocoaPods 1.7+ following is the configuration. #### CocoaPods @@ -514,7 +519,7 @@ We support both Swift and Objective-C for Flipper with CocoaPods as build and di platform :ios, '9.0' def flipper_pods() - flipperkit_version = '0.25' + flipperkit_version = '0.27' pod 'FlipperKit', '~>' + flipperkit_version, :configuration => 'Debug' pod 'FlipperKit/FlipperKitLayoutPlugin', '~>' + flipperkit_version, :configuration => 'Debug' pod 'FlipperKit/SKIOSNetworkPlugin', '~>' + flipperkit_version, :configuration => 'Debug' @@ -549,10 +554,12 @@ end target 'your-app-name' do ... - target 'your-app-nameTests' do - inherit! :complete - # Pods for testing - end + + # Replace the existing yoga import with the following (adding modular_headers): + pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga', :modular_headers => true + + ... + use_native_modules! # For enabling Flipper. # Note that if you use_framework!, flipper will not work. @@ -566,14 +573,6 @@ end -You need to compile your project with the `FB_SONARKIT_ENABLED=1` compiler flag. The above `post_install` hook adds this compiler flag to your project settings. - -
- -On the first run of `pod install`, `FB_SONARKIT_ENABLED=1` may not be added in the "Build Settings" of your project, but in all the subsequent runs of `pod install`, the above `post_install` hook successfully adds the compiler flag. So before running your app, make sure that `FB_SONARKIT_ENABLED=1` is present in `OTHER_CFLAGS` and `OTHER_SWIFT_FLAGS` for Objective-C and Swift projects respectively. - -
- Install the dependencies by running `cd ios && pod install`. You can now import and initialize Flipper in your `ios/your-app-name/AppDelegate.m`. diff --git a/docs/tutorial/js-setup.md b/docs/tutorial/js-setup.md new file mode 100644 index 000000000..ec36791c5 --- /dev/null +++ b/docs/tutorial/js-setup.md @@ -0,0 +1,64 @@ +--- +id: js-setup +title: Building a Flipper desktop plugin +sidebar_label: Building a desktop plugin +--- + +Now that we have the native side covered, let's display the data we're sending +on the desktop side. + +![Custom cards UI for our sea mammals plugin](/docs/assets/js-custom.png) + +## Dynamic Plugin loading + +By default, Flipper will start with the plugins it was bundled with. You can +configure it to also look for plugins in custom directories. To do that, +modify the `~/.flipper/config.json` file that is created the first time +you start Flipper and add a newly created directory the `pluginPaths` attribute. + +Your file will then look something like this: + +```json +{ + "pluginPaths": [ + "~/Flipper/custom-plugins/" + ], + ... +} +``` + +## Creating the Plugin Package + +With the loading part out of the way, we can create the new plugin. For that, first +create a new folder inside the custom plugins directory. Then use `yarn init` (`npm init` if that's more your style) +to initialise a new JavaScript package: + +```bash +$ cd ~/Flipper/custom-plugins/ +$ mkdir sea-mammals +$ cd sea-mammals +$ yarn init +``` + +When choosing the package name, remember to use the name we have specified on the native side as ID. +In our case, that is "sea-mammals". Once done, open the `package.json`. In addition to the name, +you can also specify a title to show in the Flipper sidebar and an icon to display here. For instance: + +```json +{ + "name": "sea-mammals", + "version": "1.0.0", + "main": "index.tsx", + "license": "MIT", + "keywords": ["flipper-plugin"], + "icon": "apps", + "title": "Sea Mammals", + "category": "Example Plugin", + "dependencies": { + "flipper": "latest" + } +} +``` +*See [package.json](https://github.com/facebook/flipper/blob/master/src/plugins/seamammals/package.json)* + +Now that our package has been set up, we are ready to build a UI for our plugin. Either by using a standardized table-based plugin, or by creating a custom UI. diff --git a/docs/tutorial/js-table.md b/docs/tutorial/js-table.md index ab48a0c08..f91099495 100644 --- a/docs/tutorial/js-table.md +++ b/docs/tutorial/js-table.md @@ -3,63 +3,8 @@ id: js-table title: Showing a table --- -Now that we have the native side covered, let's display the data we're sending -on the desktop side. - ![Android Tutorial App](assets/android-tutorial-desktop.png) -## Dynamic Plugin loading - -By default, Flipper will start with the plugins it was bundled with. You can -configure it to also look for plugins in custom directories. To do that, -modify the `~/.flipper/config.json` file that is created the first time -you start Flipper and add a newly created directory the `pluginPaths` attribute. - -Your file will then look something like this: - -```json -{ - "pluginPaths": [ - "~/.flipper/custom-plugins/" - ], - ... -} -``` - -## Creating the Plugin Package - -With the loading part out of the way, we can create the new plugin. For that, first -create a new folder inside the custom plugins directory. Then use `yarn init` (`npm init` if that's more your style) -to initialise a new JavaScript package: - -```bash -$ cd ~/.flipper/custom-plugins/ -$ mkdir sea-mammals -$ cd sea-mammals -$ yarn init -``` - -When choosing the package name, remember to use the name we have specified on the native side as ID. -In our case, that is "sea-mammals". Once done, open the `package.json`. In addition to the name, -you can also specify a title to show in the Flipper sidebar and an icon to display here. For instance: - -```json -{ - "name": "sea-mammals", - "version": "1.0.0", - "main": "index.tsx", - "license": "MIT", - "keywords": ["flipper-plugin"], - "icon": "apps", - "title": "Sea Mammals", - "category": "Example Plugin", - "dependencies": { - "flipper": "latest" - } -} -``` -*See [package.json](https://github.com/facebook/flipper/blob/master/src/plugins/seamammals/package.json)* - ## Building a Table We have found that one of the most useful things you can do to understand how your app works diff --git a/website/i18n/en.json b/website/i18n/en.json index 0acd349bc..c4b73d3a8 100644 --- a/website/i18n/en.json +++ b/website/i18n/en.json @@ -160,6 +160,10 @@ "title": "Publishing your Plugin", "sidebar_label": "Publishing" }, + "tutorial/js-setup": { + "title": "Building a Flipper desktop plugin", + "sidebar_label": "Building a desktop plugin" + }, "tutorial/js-table": { "title": "Showing a table" } diff --git a/website/sidebars.json b/website/sidebars.json index 7810d0ff2..fc46e4e08 100644 --- a/website/sidebars.json +++ b/website/sidebars.json @@ -36,6 +36,7 @@ "tutorial/intro", "tutorial/ios", "tutorial/android", + "tutorial/js-setup", "tutorial/js-table", "tutorial/js-custom", "tutorial/js-publishing"