Integrating ReactViro with existing React Native projects

JH Lin
3 min readSep 6, 2021

--

ViroReact is a library for developers to rapidly build augmented reality (AR) and virtual reality (VR) experiences. ViroReact was originally developed by the Viro Media, but was open sourced in 2019. In late 2020, the Viro Community was formed to help maintain and move the project onwards, updating it so it could run with modern versions of react native, and start to add in new features.

Thanks to the community, there are detailed instructions of linking ViroReact to Android and iOS with React Native 0.60+. In this article, I simply want to list some problems I’ve encountered while integrating ViroReact with our React Native Project. Firstly, this is my environment:

react-native: 0.63.4
@viro-community/react-viro: 2.20.2
iOS: iPhone 11, 14.5
Android: pixel 4, Android 11

Here are the problems I’ve encountered:

1. The AR Sample is not working

I followed the instructions and completed the installation without any problems. Next, I create a new page in my existing App and tried the first AR Sample in the sample list. I simply copied and pasted the whole code but nothing shown. It’s turns out that we can’t simply use ViroARScene as our root component. We must wrap ViroARScene inside ViroARSceneNavigator to make it work.

const App = props => {
return(
<ViroARSceneNavigator
initialScene={{ scene: YourScene }}
/>
);
}
const YourScene = () => {
<ViroARScene>
...
</ViroARScene>
}

2. Invalid UIAccessibilityTraits

Failed prop type: Invalid prop `accessibilityRole` of value `tab` supplied to `TouchableOpacity`, expected one of 
["none","button","link","search","image","keyboardkey","text","adjustable","imagebutton","header","summary"]

This error occurred when I navigate to the page contains a tabview which I use react-native-tab-view . Unfortunately, there is still no fix for this issue. In my case, I apply postinsall to modify the props accessibilityRole of related components of react-native-tab-view from tab to none . However, that is definitely not a good solution.

3. ViroVideo does not work on iOS

It’s maybe an issue happens on React Native 0.63.4+. You can try with the minimal code:

<ViroVideo
source={require('../assets/test.mp4')}
width={width}
height={height}
/>

and you will see this error:

Exception thrown while executing UI block: -[VRTView setOnBufferEndViro:] ...

However, I found a workaround. I create a video material by ViroMaterialVideo and ViroMaterials.createMaterials() and assign this material to a ViroBox.

// Initialize material and free the material in useEffectuseEffect(() => {
ViroMaterials.createMaterials({
video_material: {
lightingModel: 'Lambert',
diffuseTexture: { uri: YOUR_VIDEO_URL },
},
});
}
return () => {
ViroMaterials.deleteMaterials(['video_material']);
};
}, []);

then in your scene:

<ViroARScene>
<>
<ViroMaterialVideo
material={'video_material'}
paused={false}
loop={true} />
<ViroBox
position={[0, 0, 0]}
height={height}
width={width}
length={length}
materials={['video_material']} />
</>
</ViroARScene>

5. onPinch and onRotate event do not fire as expect

This is a tough question. No direct solution for now. In my practice, instead of using onDrag , onRotate and onPinch provided by Viro, I customize these gestures by PanResponder . For tracking gesture with multiple touches, we can get the touches by:

onPanResponderMove: (evt, gestureState) => {
const touches = evt.nativeEvent.touches;
if(touches.length === 2){
// detect the gesture by your criteria
}
}

then, use setNativeProps to change the position/rotation/scale of ViroNode

const ARNodeRef = useRef(null);<ViroNode
ref={ref => (ARNodeRef.current = ref)}
position={position}
scale={scale}
rotation={rotation}
>
// ... your Viro components
</ViroNode>// example of setting scale
ARNodeRef.current.setNativeProps({ scale: newScale });

Thanks!

That it! Thanks for your reading. Please feel free to let me know if you have any questions or better solutions.

--

--