Platform and Form Factor Specific Code in your You.i Engine One React Native Application

John Cassidy
4 min readJan 12, 2020

Out-of-Tree Platform Support

When writing Facebook React Native applications, a typical pattern is to use the Platform to split out code you want to isolate to either iOS or Android — Facebook documentation has great information on it here. In a similar fashion to both iOS and Android, which are represented by ios and android respectively, You.i Engine One applications identify (as of 5.9+) as the platform youi. Prior to 5.9, You.i applications identified as ios.

All platforms supported by You.i Engine One will report as youi when building with the You.i Engine One Solution.

This means that when using third party native modules, or even code that you write yourself, if a code path is decided upon based on Platform.OS, it will choose the path of youi. If that path does not exist, it will follow whatever default behaviour has been defined.

Platform Based Components

Since You.i Engine One applications report as youi, the same capabilities suggested for ios and android can be followed when it comes to platform based components.

Component.ios.js
Component.android.js
Component.youi.js

You can then import the correct platform specific file extension with

import Component from './Component.js';

The above is something that is considered by the framework when building the project. The appropriate files for the platform will be bundled, while the others will be blacklisted via bundler configuration to prevent them from being packaged with the application.

Platform Runtime Behaviour

There are other situations where you want to identify behaviour at runtime, this is typically done using Platform.select or with a switch statement or a conditional operator.

import {Platform, StyleSheet} from 'react-native';const styles = StyleSheet.create({
container: {
flex: 1,
...Platform.select({
ios: {
backgroundColor: 'blue',
},
android: {
backgroundColor: 'green',
},
youi: {
backgroundColor: 'red',
}, }),
},
});

Third Party Integrations

It is important to understand the above behaviour when using a third party module. If there is code in the third party module that is dependent on a particular platform, it will once again follow the default path that is defined. This includes switch statements where the behaviour would fall through to default.

Form Factor

While platform is something that can be considered either at build time or at runtime, FormFactor is often a run-time only consideration as you don’t want to necessarily create individual builds for platforms that support multiple form factors (iOS Handset vs iOS Tablet). Of course you can create a separate build for each form factor, in which case you could write some node logic to blacklist form factor specific files in your bundle, but it may be simpler to use a runtime check as suggested in the following section.

FormFactor.select

Similar to using Platform in a run-time manner as mentioned above, the same pattern can be followed using the FormFactor library provided by You.i Engine One

import {FormFactor} from '@youi/react-native-youi';const MyConstant = FormFactor.select({
TV: 15,
Handset: 10,
Tablet: 10
});

This allows us to specify constants that can be used on a per form factor basis.

Form Factor Specific File Extensions

I often get asked about Form Factor specific file extensions. As mentioned, because we don’t necessarily want to have a separate build for form factors where we would have the opportunity to blacklist certain files in your bundler configuration, we often want to do it at runtime. This can be done following the same pattern suggested for Platform specific code. Consider the following tree structure, where each Lander implementation (based on form factor) provides functionality specific to that form factor. We don’t want to import both because there would be collisions.

We can implement an index.js file whose responsibility is to determine which Form Factor is being used, as bring in the component as required.

import { FormFactor } from '@youi/react-native-youi';const Screen = FormFactor.select({
TV: () => require('./Lander.tv').default,
Handset: () => require('./Lander.mobile').default,
Tablet: () => require('./Lander.mobile').default
}).call();
export default Screen;

The above will still package the files that are not used, but they will not be included or used at run-time. If you would like to explore omitting these files at build-time, there is likely some bundler configuration wildcard you could setup and implement via the build system to exclude the appropriate files.

--

--