Mobile Development

The Agile Utopia

Woody Rousseau

Deputy CTO - Theodo UK

https://twitter.com/WoodyRousseau

https://github.com/wrousseau

Theodo

Helping our clients seize the opportunity of the digital transformation since 2009

 

Theodo

2009

2015

100

15

25

2014

2016

10

Succeeding a Project

Happy client

Succeeding a Project

Theodo Standards Met

Customer Satisfaction Implications

Super fast team of developers

Amazing user experience (UI, UX, 60 FPS)

Scrum

DevOps

Lean

The Web Development Utopia

Top engineers

PHP, Python and Javascript experts

The Web Development Utopia

Development Tools

The Web Development Utopia

Build Tools

The Web Development Utopia

Easy Deployment Process

Provision

Amazon EC2

Web App

The WebView approach

WebView

HTML

JS

CSS

Apache

Cordova

Write once, run everywhere

The Issues

  • Performance issues: is 60fps reachable?
  • Writing reusable code is hard
  • No native look & feel

Our Current Stack

  • React Native
  • Fastlane
  • Code-Push

The React Native Approach

React Code

+

Vendors

Going Fast

Reusability

Goal

Spend 0 time re-writing code

const Button = props => (
  <TouchableOpacity onPress={props.onPress}>
    <View style={styles.container}>
      <Text bold style={styles.text}>{props.text}</Text>
    </View>
  </TouchableOpacity>
);

Button.propTypes = {
  text: PropTypes.string.isRequired,
  onPress: PropTypes.func,
};

React Component

const borderRadius = (Platform.OS === 'android') ? 5 : 0;

const Button = props => (
  <TouchableOpacity onPress={props.onPress}>
    <View style={[styles.container, { borderRadius }]}>
      <Text bold style={styles.text}>{props.text}</Text>
    </View>
  </TouchableOpacity>
);

Button.propTypes = {
  text: PropTypes.string.isRequired,
  onPress: PropTypes.func,
};

React Component

const Button = props => (
  <TouchableOpacity onPress={props.onPress}>
    <View style={styles.container}>
      <Text bold style={styles.text}>
        {props.text}
      </Text>
    </View>
  </TouchableOpacity>
);

Button.propTypes = {
  text: PropTypes.string.isRequired,
  onPress: PropTypes.func,
};

React Component

const Button = props => (
  <TouchableHighlight onPress={props.onPress}>
    <View style={styles.container}>
      <Text bold style={styles.text}>
        Button: {props.text}
      </Text>
    </View>
  </TouchableHighlight>
);

Button.propTypes = {
  text: PropTypes.string.isRequired,
  onPress: PropTypes.func,
};

Button.ios.js

Button.android.js

<Button text="Wow" onPress={Actions.home} />

React Component

Using the component

Reusability

  • 0 line of native code on my latest 8 weeks React Native project
  • 8 uses of Platform.OS
  • 2 cases of custom component (Tab and TabBar)

Productivity

Deployment

Goal

- Deploy fast

The Native Situation

1. Build with Gradle

2. Sign

The Native Situation

1. Create signing certificate

2. Create app id

3. Create push notification certificate

3. Set entitlements for the app id

4. Create a provisioning profile

5. Feed to XCode

6. Hope it works

Fastlane

platform :ios do
  lane :deploy do |options|
    if options[:env] == 'prod' then
      sh('./update-pbxproj.sh')
    end
    match
    gym
    if options[:env] == 'staging' then
      hockey
    elsif options[:env] == 'prod' then
      deliver
    end
  end
end

Apple

Developer

Git Repository

Encryption

Can I get this at home?

https://github.com/bamlab/generator-rn-toolbox

Testing

Quality

 Speed

Tests

  • Unit tests (state management)
  • Shallow Rendering Testing
describe('<NavBar />', () => {
  it('should get to a user profile when clicking', () => {
    const wrapper = shallow((
      <NavBar
        rightComponentIcon="Profile"
        rightComponentAction={() => Actions.profile({ userId: 2 })}
      />
    ));
    expect(wrapper.find(TouchableOpacity)).to.have.length(1);
    wrapper.find(TouchableOpacity).at(0).simulate('press');
    expect(Actions.profile.calledWithExactly({
      userId: 2,
    })).to.be.true;
  });
});

End to end testing

Phase 1 : The Honeymoon

End to end testing

Phase 2 : Mourning

1. Denial and isolation

2. Anger

3. Bargaining

4. Depression

5. Acceptance

End to end testing

If you want to give it a shot...

https://github.com/wix/detox

End to end testing

Otherwise: Snapshot testing

it('renders with a provided email and password', () => {
  const store = mockStore({ credentials: Map({
    email: 'myemail@gmail.com',
    password: 'mypassword',
  }) });
  const tree = renderer.create(
    <Provider store={store}>
      <Login resetState={() => {}} />
    </Provider>,
  ).toJSON();
  expect(tree).toMatchSnapshot();
});

Super Deployment

How can we go even faster?

Let's mess with Apple

Let's mess with Apple

React Code

+

Vendors

Code Push

  • Bypass Apple validation
  • Multi-env deployment
  • Progressive rollout
  • ...
  • Can't do "native changes" 

Have we succeeded?

Weekly Deploy in Production

Client satisfaction through speed

Getting customer feedback

Thank You!

Woody Rousseau — Theodo UK

twitter.com/WoodyRousseau

github.com/wrousseau

Mobile utopia

By Woody Rousseau

Mobile utopia

  • 643