diff --git a/tfjs-react-native/.npmignore b/tfjs-react-native/.npmignore index 6292b5fdb8..3e79386865 100644 --- a/tfjs-react-native/.npmignore +++ b/tfjs-react-native/.npmignore @@ -25,3 +25,4 @@ tsconfig.json tslint.json yarn-error.log yarn.lock +integration_rn59 diff --git a/tfjs-react-native/README.md b/tfjs-react-native/README.md index d22b84ff49..831bc324ca 100644 --- a/tfjs-react-native/README.md +++ b/tfjs-react-native/README.md @@ -1,3 +1,82 @@ # Platform Adapter for React Native -Status: Early development. +Status: __Early development__. This is still an unpublished experimental package. + +## Adapter Docs + +TODO + +## Setting up a React Native app with tfjs-react-native + +These instructions assume that you are generally familiar with [react native](https://facebook.github.io/react-native/) developement. This library has only been tested with React Native 0.58.X & 0.59.X. React Native 0.60 is not supported. + +### Step 1. Create your react native app. + +You can use the [React Native CLI](https://facebook.github.io/react-native/docs/getting-started) or [Expo](https://expo.io/). This library relies on a couple of dependencies from the Expo project so it may be convenient to use expo but is not mandatory. + +On macOS (to develop iOS applications) You will also need to use Cocoapods to install these dependencies. + +### Step 2: Install expo related libraries + +Depending on which workflow you used to set up your app you will need to install different dependencies. + +- React Native CLI App + - Install and configure [react-native-unimodules](https://github.com/unimodules/react-native-unimodules) + - Install and configure [expo-gl-cpp](https://github.com/expo/expo/tree/master/packages/expo-gl-cpp) and [expo-gl](https://github.com/expo/expo/tree/master/packages/expo-gl) +- Expo Bare App + - Install and configure [expo-gl-cpp](https://github.com/expo/expo/tree/master/packages/expo-gl-cpp) and [expo-gl](https://github.com/expo/expo/tree/master/packages/expo-gl) +- Expo Managed App + - Install and configure [expo-gl](https://github.com/expo/expo/tree/master/packages/expo-gl) + + +Note if in a _managed_ expo application these libraries should be present and you should be able to skip this step. + +Install and configure [react-native-unimodules](https://github.com/unimodules/react-native-unimodules) +Install and configure [expo-gl-cpp](https://github.com/expo/expo/tree/master/packages/expo-gl-cpp) and [expo-gl](https://github.com/expo/expo/tree/master/packages/expo-gl) + +> After this point, if you are using XCode to build for ios, you should use a ‘.workspace’ file instead of the ‘.xcodeproj’ + +### Step 3: Configure [Metro](https://facebook.github.io/metro/en/) + +Edit your `metro.config.js` to look like the following. Changes are noted in +the comments below. + +```js +// Change 1 +const blacklist = require('metro-config/src/defaults/blacklist'); + +module.exports = { + transformer: { + getTransformOptions: async () => ({ + transform: { + experimentalImportSupport: false, + inlineRequires: false, + }, + }), + }, + resolver: { + // Change 2 (add 'bin' to assetExts) + assetExts: ['bin', 'txt', 'jpg'], + sourceExts: ['js', 'json', 'ts', 'tsx', 'jsx'], + // Change 3 + blacklistRE: blacklist([/platform_node/]) + }, +}; +``` + + +### Step 4: Install TensorFlow.js and tfjs-react-native + +- Install @tensorflow/tfjs - `npm install @tensorflow/tfjs` +- Install @tensorflow/tfjs-react-native - coming soon + +### Step 5: Test that it is working + +TODO: Add some sample code. + +For now take a look at `integration_rn59/App.tsx` for an example of what using tfjs-react-native looks like. + +### Optional Steps + +If you want use the `AsyncStorageHandler` to save and load models, add [async-storage](https://github.com/react-native-community/async-storage) to your project. + diff --git a/tfjs-react-native/integration_rn59/.buckconfig b/tfjs-react-native/integration_rn59/.buckconfig new file mode 100644 index 0000000000..934256cb29 --- /dev/null +++ b/tfjs-react-native/integration_rn59/.buckconfig @@ -0,0 +1,6 @@ + +[android] + target = Google Inc.:Google APIs:23 + +[maven_repositories] + central = https://repo1.maven.org/maven2 diff --git a/tfjs-react-native/integration_rn59/.gitattributes b/tfjs-react-native/integration_rn59/.gitattributes new file mode 100644 index 0000000000..d42ff18354 --- /dev/null +++ b/tfjs-react-native/integration_rn59/.gitattributes @@ -0,0 +1 @@ +*.pbxproj -text diff --git a/tfjs-react-native/integration_rn59/.gitignore b/tfjs-react-native/integration_rn59/.gitignore new file mode 100644 index 0000000000..448aabe7da --- /dev/null +++ b/tfjs-react-native/integration_rn59/.gitignore @@ -0,0 +1,63 @@ +# OSX +# +.DS_Store + +# Xcode +# +build/ +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata +*.xccheckout +*.moved-aside +DerivedData +*.hmap +*.ipa +*.xcuserstate +project.xcworkspace + +# Android/IntelliJ +# +build/ +.idea +.gradle +local.properties +*.iml + +# Visual Studio Code +# +.vscode/ + +# node.js +# +node_modules/ +npm-debug.log +yarn-error.log + +# BUCK +buck-out/ +\.buckd/ +*.keystore + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://docs.fastlane.tools/best-practices/source-control/ + +*/fastlane/report.xml +*/fastlane/Preview.html +*/fastlane/screenshots + +# Bundle artifact +*.jsbundle + +# CocoaPods +/ios/Pods/ \ No newline at end of file diff --git a/tfjs-react-native/integration_rn59/App.tsx b/tfjs-react-native/integration_rn59/App.tsx new file mode 100644 index 0000000000..1e948695d8 --- /dev/null +++ b/tfjs-react-native/integration_rn59/App.tsx @@ -0,0 +1,163 @@ +/** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import React, { Fragment } from 'react'; +import { Button, SafeAreaView, StyleSheet, ScrollView, View, Text, StatusBar } from 'react-native'; + +import * as tf from '@tensorflow/tfjs'; +import '@tensorflow/tfjs-react-native'; + +import { Diagnostic } from './components/diagnostic'; +import { MobilenetDemo } from './components/mobilenet_demo'; + +export type Screen = 'main' | 'diag' | 'demo'; + +interface AppState { + isTfReady: boolean; + currentScreen: Screen; +} + +export class App extends React.Component<{}, AppState> { + constructor(props: {}) { + super(props); + this.state = { + isTfReady: false, + currentScreen: 'main' + }; + + this.showDiagnosticScreen = this.showDiagnosticScreen.bind(this); + this.showDemoScreen = this.showDemoScreen.bind(this); + this.showMainScreen = this.showMainScreen.bind(this); + } + + async componentDidMount() { + await tf.setBackend('rn-webgl'); + await tf.ready(); + this.setState({ + isTfReady: true, + }); + } + + showDiagnosticScreen() { + this.setState({ currentScreen: 'diag' }); + } + + showDemoScreen() { + this.setState({ currentScreen: 'demo' }); + } + + showMainScreen() { + this.setState({ currentScreen: 'main' }); + } + + renderMainScreen() { + return + + Diagnostic +