Improve setup documentation

Summary:
Random observations

1. RN already generates the Flipper initialization code out of the box
2. This code assumes a prefixed namespace: `facebook.flipper`. Maybe it would be better if that were `appname`, but that seems an unnecessary burden at this point, preventing direct copy / paste possibilities
3. Out of the box, the generated code by RN doesn't align with the code provided here, because no `ReactInstanceManager` argument is passed in (nor does it seem to be available in a straight-forward way)
4. patch MainApplication.java with `getReactNativeHost().getReactInstanceManager()`
5. turn this into an explicit section: https://fbflipper.com/docs/tutorial/js-table.html#dynamic-plugin-loading. Also explain that when using `node_modules`, config doesn't need to be changed?
6. xcode 10! sudo xcode-select -s /Applications/Xcode_10.XXX/Contents/Developer/
7. Also tried to install Reactotron plugins by Infinite Red, got that compilable in the end, but the andoid / ios implementations still seems to be stub, so I'll try to follow up with them later, to be notified when they actually have something

Reviewed By: passy

Differential Revision: D18349098

fbshipit-source-id: 233bbe20a37c57c7dfe08c8fccdd4508bdefe96f
This commit is contained in:
Michel Weststrate
2019-11-08 04:39:02 -08:00
committed by Facebook Github Bot
parent 9a8e267f2a
commit 2f5096ddc8
5 changed files with 107 additions and 94 deletions

View File

@@ -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)._ _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. Integrating Flipper with React Native is a bit different than with a native app.
### Android ### Android
@@ -326,7 +328,6 @@ Add the following permissions to your `AndroidManifest.xml`. The SDK needs these
`android/app/src/main/AndroidManifest.xml` `android/app/src/main/AndroidManifest.xml`
```xml ```xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
``` ```
@@ -358,6 +359,8 @@ android {
dependencies { dependencies {
... ...
implementation 'com.facebook.soloader:soloader:0.6.0+'
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") { debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
exclude group:'com.facebook.yoga' exclude group:'com.facebook.yoga'
exclude group:'com.facebook.flipper', module: 'fbjni' 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: These are the suggested plugins integrations:
@@ -380,7 +383,7 @@ These are the suggested plugins integrations:
- React devtools - React devtools
```java ```java
package com.yourappname; package com.yourappname; // <--- use your own namespace chosen above!
import android.content.Context; import android.content.Context;
import com.facebook.flipper.android.AndroidFlipperClient; import com.facebook.flipper.android.AndroidFlipperClient;
@@ -402,6 +405,10 @@ import okhttp3.OkHttpClient;
public class ReactNativeFlipper { public class ReactNativeFlipper {
public static void initializeFlipper(Context context) {
ReactNativeFlipper.initializeFlipper(context, null);
}
public static void initializeFlipper(Context context, final ReactInstanceManager reactInstanceManager) { public static void initializeFlipper(Context context, final ReactInstanceManager reactInstanceManager) {
if (!FlipperUtils.shouldEnableFlipper(context)) { if (!FlipperUtils.shouldEnableFlipper(context)) {
return; return;
@@ -427,7 +434,7 @@ public class ReactNativeFlipper {
// Fresco Plugin needs to ensure that ImagePipelineFactory is initialized // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized
// Hence we run if after all native modules have been 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) { if (reactContext == null) {
reactInstanceManager.addReactInstanceEventListener( reactInstanceManager.addReactInstanceEventListener(
new ReactInstanceManager.ReactInstanceEventListener() { new ReactInstanceManager.ReactInstanceEventListener() {
@@ -456,42 +463,38 @@ 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. For this, we edit the `android/app/src/main/java/com/yourappname/MainApplication.java` file.
```java ```java
package com.yourappname; package com.yourappname;// <--- use your own namespace chosen above!
import ... import ...
import com.facebook.react.ReactInstanceManager; import com.facebook.react.ReactInstanceManager; // <---- add this import
public class MainApplication extends Application implements ReactApplication { public class MainApplication extends Application implements ReactApplication {
... ...
@Override @Override
public void onCreate() { public void onCreate() {
... super.onCreate();
initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); SoLoader.init(this, /* native exopackage */ false);
initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); // <---- start flipper integration
} }
}
```
/** In the same file, modify the generated `initializeFlipper` method to
* Loads Flipper in React Native templates. Call this in the onCreate method with something like
* initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); ```java
*
* @param context
*/
private static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { private static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
if (BuildConfig.DEBUG) { if (BuildConfig.DEBUG) {
try { try {
Class<?> aClass = Class.forName("com.yourappname.ReactNativeFlipper"); /*
aClass We use reflection here to pick up the class that initializes Flipper,
.getMethod("initializeFlipper", Context.class, ReactInstanceManager.class) since Flipper library is not available in release mode
.invoke(null, context, reactInstanceManager); */
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) { } catch (ClassNotFoundException e) {
e.printStackTrace(); /* All catch clauses as generated by RN */
} catch (NoSuchMethodException e) { ...
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} }
} }
} }
@@ -501,6 +504,8 @@ Finally, open the Flipper desktop app, and run `yarn android` in your terminal.
### iOS ### 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. 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 #### CocoaPods
@@ -514,7 +519,7 @@ We support both Swift and Objective-C for Flipper with CocoaPods as build and di
platform :ios, '9.0' platform :ios, '9.0'
def flipper_pods() def flipper_pods()
flipperkit_version = '0.25' flipperkit_version = '0.27'
pod 'FlipperKit', '~>' + flipperkit_version, :configuration => 'Debug' pod 'FlipperKit', '~>' + flipperkit_version, :configuration => 'Debug'
pod 'FlipperKit/FlipperKitLayoutPlugin', '~>' + flipperkit_version, :configuration => 'Debug' pod 'FlipperKit/FlipperKitLayoutPlugin', '~>' + flipperkit_version, :configuration => 'Debug'
pod 'FlipperKit/SKIOSNetworkPlugin', '~>' + flipperkit_version, :configuration => 'Debug' pod 'FlipperKit/SKIOSNetworkPlugin', '~>' + flipperkit_version, :configuration => 'Debug'
@@ -549,10 +554,12 @@ end
target 'your-app-name' do target 'your-app-name' do
... ...
target 'your-app-nameTests' do
inherit! :complete # Replace the existing yoga import with the following (adding modular_headers):
# Pods for testing pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga', :modular_headers => true
end
...
use_native_modules!
# For enabling Flipper. # For enabling Flipper.
# Note that if you use_framework!, flipper will not work. # Note that if you use_framework!, flipper will not work.
@@ -566,14 +573,6 @@ end
<!--END_DOCUSAURUS_CODE_TABS--> <!--END_DOCUSAURUS_CODE_TABS-->
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.
<div class="warning">
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.
</div>
Install the dependencies by running `cd ios && pod install`. You can now import and initialize Flipper in your Install the dependencies by running `cd ios && pod install`. You can now import and initialize Flipper in your
`ios/your-app-name/AppDelegate.m`. `ios/your-app-name/AppDelegate.m`.

64
docs/tutorial/js-setup.md Normal file
View File

@@ -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.

View File

@@ -3,63 +3,8 @@ id: js-table
title: Showing a 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) ![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 ## Building a Table
We have found that one of the most useful things you can do to understand how your app works We have found that one of the most useful things you can do to understand how your app works

View File

@@ -160,6 +160,10 @@
"title": "Publishing your Plugin", "title": "Publishing your Plugin",
"sidebar_label": "Publishing" "sidebar_label": "Publishing"
}, },
"tutorial/js-setup": {
"title": "Building a Flipper desktop plugin",
"sidebar_label": "Building a desktop plugin"
},
"tutorial/js-table": { "tutorial/js-table": {
"title": "Showing a table" "title": "Showing a table"
} }

View File

@@ -36,6 +36,7 @@
"tutorial/intro", "tutorial/intro",
"tutorial/ios", "tutorial/ios",
"tutorial/android", "tutorial/android",
"tutorial/js-setup",
"tutorial/js-table", "tutorial/js-table",
"tutorial/js-custom", "tutorial/js-custom",
"tutorial/js-publishing" "tutorial/js-publishing"