OutSystems has a yearly event called NextStep, where we share our vision for the coming year and thought leaders gather to discuss the state of our industry and the future.

Everyone in the company uses all their skills to make sure that once again, NextStep is not only a success, but valuable to attendees.

In our team’s case, the challenge was building a sweet mobile app to support the event. One that, besides being very helpful to all participants, also showcased the full potential of our new mobile development platform.

This is the story of how we did it. The good and the bad. Full disclosure.

Gentlemen, You May Start Your Engines

In early May 2017, OutSystems put together a team to create the NextStep mobile app using the full mobile potential of OutSystems. The plan was to have a team in place for three months to deliver the app in August, one month before the event. This way, there would be time to test it and fix bugs, if needed, before going live in September at NextStep. Solid, right?

This was the set up at the start of the project:

  • A small team (one developer, one delivery manager, and one engagement manager) with web app development experience only.
  • An app back-office that had already been developed by a different team.
  • A backlog that wasn’t closed yet.

This wasn’t going to be easy, but the team was up for going full speed ahead.

Halfway through the project, the NextStep app team took stock. They had done a lot, no question, but critical issues had been addressed in a mindset that wasn’t mobile. Mobile-specific functions such as offline behavior or network changes had not been part of the upfront planning, even though the OutSystems mobile development environment can address all of these.

So, the NextStep app team brought us in. We’re the part of the OutSystems services team with expertise in mobile, and we were asked, like in any other project, to assess the work done so far. So we took a look.

Taking a Pit Stop

To help the NextStep app team finish on time and with success, the first thing we did was stop all activities and do a two-day assessment of the app’s current state. The assessment focused on three areas:

  • Redefining the user stories
  • Assessing the existing code
  • Defining the next steps

You will find all the nerdy bits about each main assessment point in future articles and videos, but here’s a high-level overview of what was done.

Calibrating User Stories

The user stories needed refinement so everyone could have a clear vision of what was supposed to be delivered so we could close the backlog. After a user story review, we updated the scope of work. Here are a few examples:

  • Users should be able to select their NextStep Events (there were three events and additional pre-event workshops) and receive detailed information about the existing sessions and speakers.
  • Users should be able to use the app offline and in different types of mobile network scenarios.
  • Users were to be offered a series of engaging challenges to complete during the event.

After calibrating the user stories, we had a clear path forward and a clear goal for our app, which is important when doing mobile, since users don’t tolerate mobile app experiences that are less than topnotch.

Decoding the Code

In the code assessment, we found some issues mainly in four areas: page lifecycle, offline synchronization, network management, and local storage as follows:

  • All the events' information was being loaded upfront, a time-consuming process that is not advised for mobile. Also, for every OnInitialize, based on the way the data model was built, the user data was being fetched, creating a long wait time that also affected the app’s overall performance.
  • The Next Step event list was being populated with data collected directly from the server, which would, in case you were offline or had limited network access, result in an error in the app since it couldn’t retrieve the information in that state.
    Loading... a great app
  • The events offline synchronization was being completely done in the app splash screen and again for each specific event when selected. As a result, we were synchronizing data for events that our users weren’t attending while also synchronizing the data of the selected events. This data consumption duplication also lengthened wait times.
    Repeating patterns
  • The local storage entities were too normalized and too similar to what was being done on the server side. There were also too many connections to the different local storage entities, which also contributed to performance issues.

I promised full disclosure, so here it is. These are common issues, but we had to solve them. So, before returning to the race, we defined what we were going to do, in what way, and who do we need to do it.

Strategy for Success

To assure success, we needed to reinforce the team. Our initial wishful thinking needed to be corrected, and the guys from the original team needed some support to achieve success. So we ended up with a team like this:

Ninja force

It may appear to be a totally different team, but I can guarantee you that it wasn’t. We simply added a mobile expert and a UX/UI expert and redefined the role of the engagement manager so it was more like a business user. This redefined role covered not only portfolio management and prioritization, but also understanding the business value of each feature and providing the team with almost instant feedback on what we needed to tackle.

We were then ready to start to replanning the app’s development. The best way to do it is by defining all user flows to get a clear vision of how a user will interact with the app. To do it, we used mind-mapping to design them:

Great minds thinking alike

It was a great experience; everyone pitched in with insightful ideas for the new solution, and we got really creative. We learned a lot by discussing the app instead of jumping to code, which just proves that having the right team with all the necessary people is critical to the success of any project.

Now that we had the flows, it was time start to drawing the screens and adding the offline synchronization aspects. For this, we used the good old wall and pen.

Syncing our brains to offline

It was during these drawing sessions that we realized something. We live in a time where mobile apps are not utilities; rather, they are almost part of us.

Users will use their apps anywhere and in any condition. If we can’t provide them with a fully functional app at any time or at least a clever and fun way to interact with the app while offline or experiencing network limitations, we aren’t delivering well. And that’s why I think that more than ever, user experience experts and mobile developers must be aware of how important offline synchronization and network management are achieving the best technical solution without compromising a great user experience.

So, now that we were all on the same page, with a clear view of what we needed to do, we were ready to hit the road again.

Back on Track

We were finally out of the pit stop lane and back on the track, but even though we were now better equipped and prepared for what was left of this race, it wasn’t a walk in the park. So, brace yourself for some more nerdiness!

The first task was adapting the existing data model to our proposed changes. The best way we found to do it? Printing our existing model and just drawing on it. It’s fun, engaging, and it gives you a clear view of the changes you need to make.

Ink on data model - a masterpiece!

After lots of sketching and redrawing, we ended up with a new model that accommodates all the offline synchronization issues much more efficiently.

So as you can see, the new data model addressed, among a number of issues, the centralized image entity LocalImage. This is especially troublesome since it will need to make a lot of inner/left/right joins to get information. In mobile, too many inner/left/right joins are difficult for the device to process.

Page Lifecycle

Regarding the page lifecycle, we used the best approach to mobile. Instead of loading all the information upfront, the information would now be fetched only when needed. Especially images.

By not getting images entities on the page and instead isolating them inside blocks and then making a query to get the specific image, the loading of page content was definitely improved. And, having images blocks enabled us to add an IF in the code for when the image is not loaded yet, so it showed a container with a blurred background that was the same size as the image, thereby avoiding height glitches.

Also, in OnInitialize, instead of permanently retrieving the local data, we created a user session variable that loaded all the user information on the splash screen and a global JavaScript variable that saved the session information. By saving the session in a global variable instead of calling the entity for each page, we used the global variable content to filter parallel aggregates or fill content inside the page, which is much faster than a call to local storage.

Offline Synchronization

To deal with offline and offline synchronization, we used the Sync Unit property to achieve the best possible results as follows:

  • Sync Unit is a way of identifying what subset to synchronize so we had control over the quantity and type of data we wanted to synchronize.
  • These Sync Units enabled us to avoid synchronizing all the data each time an offline synchronization was triggered.
  • We used a Switch to concatenate all our Sync Units instead of going through them all when a synchronization was needed.

Also, the following practices were used throughout the offline synchronization:

  • We used the TriggerOfflineDataSync(asynchronous) when we needed to synchronize data instead of calling the OfflineDataSync(synchronous) directly, because this would cause the UI to freeze.
  • Having just a serverDataSync call instead of having several ones inside client actions, thereby isolating server calls in one place when they are called in a client action.

Network Management

To address network management issues, we connected our devices to our computers to simulate a lousy network. Also, we further tested the app while using public transportation and in our daily lives to get an idea how the app would work under unpredictable circumstances.

To simulate different connection scenarios  we used Chrome dev tools as you can see in this picture:

Join us, fellows of the F12 brotherhood

The most important scenarios were dealing with network exceptions, like going from 4G or 3G to 2G or going from online to offline.

Through NetworkStatusChanged, a private Silk UI block, the OutSystems mobile development environment provided us with a few events for letting us know if our synchronization was already completed, if we had an error during synchronization, or if the network had changed during synchronization. We were, therefore, able to create a good UX when there was a network failure.

Good UX withstands the trials of offline

Crossing the Finish Line

In the end, everything was delivered on time and with quality. The app was tested on several devices and was delivered in the stores as it should be. It was a collective effort, where everyone gave their best to achieve this goal. But during this bumpy race we learned some things that we feel important to share with you:

  • Don’t rush. We know that there is always a great deal of pressure to go live, but taking the time to define your app and the flows will mean a successful go-live.
  • Agree on your user stories and commit to them. New features can always be added later. Keep in mind that this is an endurance race, not a drag race. With the number of mobile apps being produced these days, if you fail, your customers will not give you the benefit of the doubt.
  • Discuss and plan what you are going to do. Map all the app flows and understand if everything is covered. Only then start to create your app.
  • Remember that user experience is key to the success of your App. And that’s why you should take your time with it, especially for those cases where you don’t have perfect conditions. Be gracious when you are not able to provide everything to the user.

And probably the most important thing. There is such a thing as a mobile mindset. Train your team to use the mobile mindset. It is really important to read and study the themes, and look for mobile best practices and use cases, successful or not. Always keep in mind that UX/UI can’t be an afterthought in mobile, since the way people interact with mobile apps so different. So, think like a user, and surround yourself with people who can help you with their expertise.

If you use the best practices we cover here and check our best practices videos, you will certainly avoid the most common mistakes during mobile development, making you closer to success. We had ours; there’s no reason why you shouldn’t be able to have yours too.

P.S. Check out our mobile best practices videos for further information on mobile dos and don’ts. And, if you’re interested in how to build not only a mobile app, but also a mobile app team, there’s a playbook for that.