Could you introduce your app in a few sentences?
Mapsy is a free social feed of the world which lets users to pin their thoughts and photos around a live world map. Using push updates, new content continuously pops onto the map in real time, enabling users to watch events unfold as they happen, from anywhere around the globe. As posts gain in popularity, they become increasingly prominent on the world map, turning the world as we know it into a leaderboard for whatever interests you.
Mapsy is available for both Android and iOS, and as a native Android developer, that’s something I thought I’d never say!
What made you decide to use/switch to React Native?
I think I was lucky, more than anything. I worked alongside a passionate and talented developer who was working on Single-Page-Application (SPA) whose front-end was built using React. He was fortunate enough to choose his own implementation technologies for the project; and he settled on React for its simplicity, render performance and natural talent for isomorphism. He became increasingly curious about how transferable his knowledge was from pure React into the mobile world using React Native, and after a while, so did I.
We started out spending our lunch breaks together discussing some of the core concepts in React and JavaScript ES6, alongside working through simple project configuration. I didn’t like the idea of wasting his time with stupid questions, so each night I’d go home and practice what he’d taught me during the day. I didn’t know it at the time, but I had already started working on the pieces that would eventually become Mapsy.
What surprised me was that it became increasingly clear how much time I’d been wasting on traditional native development. I’d been oblivious to much JavaScript had changed since reading The Good Parts as an undergraduate; I had no idea how much more expressive, fun and intuitive programming in JavaScript had become since then. All the while, I was learning techniques that could be so easily applied to web development, something that I’d decided was closed off to me a very long time ago.
In short, I hot-reloaded a native application for the first time, and have never looked back since. I had to shake my device to trigger the reload as well, which I meant I was finally getting some sort of exercise!
How did you transition to React Native?
To start out, my hand was held through all of the core concepts in modern React development, paying extra-special attention to Redux, Thunk and Promises. After you use a single programming language for such a long time, especially one with as much formal structure as Java, it was definitely a challenge to phrase my conventional approach to problem solving in a format that was best suited to React Native. This isn’t to say that it was difficult to transition into, quite the contrary, there were so many ways to go about writing what I wanted; but there was a definite sense that I was writing inefficiently, and that I wasn’t taking proper advantage of the core language constructs that React had to offer.
Like any task in programming, there was a great deal of trial and error before I felt truly at home. I had to go through the same kind of teething issues as you would with any language, but this time, the final reward was much greater than usual. For the first time, I wasn’t solving the problem for one type of platform; I was solving it for many.
I had never used npm
or yarn
before, and the amount of open source projects to reuse and build upon was outstanding. It had never been easier or quicker to integrate someone else’s work, toy around, and make a decision on whether to incorporate it after some exploratory development effort. The code that was freely available was vetted, performant and had clearly stood the test of time. In my experience, I’d been defining build paths and performing manual, exhaustive library management, constantly resolving missing dependencies and compatibility issues. Then suddenly it was no longer a part of the development cycle.
Overall, it was a wholly gratifying experience.
Have your tried other cross platform technologies before using React Native?
I come from a background with extensive application of cross-platform languages, since I’d always hated the idea of solving a problem that would only execute in one runtime. I’ve always felt that solutions in programming should be universally true.
I’ve mainly worked with Java until this point, which will run on anything, probably even a banana. Alongside this, I’d spent a significant amount of time working with platform-independent scientific modelling and automation languages. These pre-existing technologies had been around far longer than RN, but they never seemed to maintain the graphical identity of the application between different operating system themes. Often, I found myself at the mercy of how well a language had been optimised for a particular platform, instead of how powerful the runtime environment was. React Native, by contrast, feels like a pure function of the hardware.
Designing a truly native look-and-feel with a consistent experience had always been problematic, and yet React Native accomplished this effortlessly. My understanding is that React Native strikes the balancing act so very well; countless predecessors attempted to abstract away the native environment, and pose as the be-all-end-all, rather than take advantage of the technical diversity. No languages I’d previously experienced had such a succinct equivalent to Platform.select()
, and in a way, it’s a simple reflection of how RN opted to leverage the benefits of what the native runtime has to offer, rather than treat it as some kind of homogenous entity.
What’s most striking of all, is that every single piece of the application can be handled natively, if you wished it to be. There is no limit to you as a developer, except of course your imagination. Or how much coffee is remaining.
What has your experience been working with React Native in terms of app performance, have you noticed any impacts?
I stopped caring about performance, in some ways. I know this may sounds strange, but let me explain! I’ve found the DOM render hierarchy to be very astute in minimizing the amount of computation that your application needs to update. Whenever I’ve found React to be slow, it was usually because I had some misguided idea over how a task should be performed.
Mapsy, in particular, relies heavily upon the animation of gorgeous Lottie Animations and is in a constant state of asking the GPU to render a lot of polygons, vector graphics, bitmaps and standard layout elements. All the while, the JS Runtime is required to maintain deep synchronization between the array of user generated content pulled from the server, and rapid changes in visible region of the map; ensuring that geographically-relevant content is fetched, parsed and displayed to the user. We ask so much from the client device, and yet the end result feels fluid, looks cute and is above all simple.
To achieve the reliability and performance that RN provides out of the box in a native environment is of course possible, but a substantial development task. At no point have I needed to concern myself with threading or synchronisation, caching or the idiosyncrasies of system-level life cycle handling. These approaches, and many more, with all their complexities, limitations and edge cases, would have rested at the forefront of my development effort, had Mapsy been a native application. And I would still be writing it now.
I began to question some of the fundamental aspects of contemporary mobile application development. Namely, why do I find myself wasting development effort on low-level mechanisms that have been implemented time and time before? Shouldn’t my real focus should be on the user journey? I mean, sure, there is all of the precision and efficiency in the world to gain by rolling your own solutions from the ground up; but modern devices are so powerful that any reasonably-designed approach to problem solving rarely seems to hit the performance bottleneck these days. Mapsy has yet to.
How has adopting React Native affected developer productivity?
I would like to talk about how much faster and efficient it has made me a developer, but in all fairness, that has to be counterbalanced against the amount of time I now spend evangelising about it.
The compile time alone is a reason to start React Native development. With no word of exaggeration, the changes you make are instantaneous. However, compiling is only half of the problem in native development; people often forget to discuss the effects of recompiling; the loss of application state! How much time do you spend rebuilding, logging back in, navigating to the region of the application you’re working on and waiting for your events to fire… just to execute a small test and find that your code didn’t work? Then you repeat that, over, and over again for weeks on end. You start to forget it is even a severe blocker, and accept it as a normal part of the development cycle.
With Hot Reloading, you don’t just recompile instantaneously, you don’t even have to lose your state after doing so. This way, I find that I’m able to program for far, far longer before I inevitably start pulling my hair out and wondering why I ever started programming. If you combine this with the extraordinary amount of high quality open source code provided by NPM, and the fact you can gain confidence executing your algorithms on your local machine before even attempting to deploy, I’m sure you can imagine one very productive developer.
Did I forget to mention Mapsy runs really beautifully on iOS? I’ve never written a line of Objective-C or Swift. How could you even measure that in terms of productivity?
Oh, I know.
It has made me really, really productive.
Which tools, libraries and frameworks are part of your development process with React Native?
In terms of my development tools, Mapsy runs on both Android and iOS, so we therefore need to make an obligatory shout-out to Android Studio and XCode. The role these environments play is minimal; Android Studio is occasionally useful when I need to work through Gradle’s stack trace with more ease than what’s directly available from logs, but nearly everything for Mapsy for Android can be accomplished using the CLI. XCode, by contrast, plays a much heavier role, as I often need to reconfigure build settings when altering the schema of the application workspace or open it up when I wish to begin a new development session.
Mapsy was written using Atom, a really beautiful and extensible IDE, making day-to-day development fast, simple and clean. However recently, I’ve been watching a lot of convincing videos about vim
, so I intend to write the upcoming release using it. React Native as a whole is tied very closely the command line, so I feel like vim
would be a natural extension of that. The only caveat to this is that I feel like I’m learning to type for the first time again, and not in a good way.
Mapsy was made possible by the following libraries:
-
firebase
(Firestore)
The app that lives behind the app icon on your home screen is only half of the story. Mapsy is powered by Firebase Firestore, a No-SQL database solution which enables distributed management of served data without the need for abstraction via an API layer. Firestore was one of the simplest libraries to add to the core project architecture, and yet is responsible some of the most advanced functionality, such as push notification driven updates and session management. Firestore structures data in terms of a hierarchical collection of Collections and Documents, enabling more complex data structures that were previously achievable in Firebase Realtime Database, without the need to duplicate information and maintain distributed references. Data integrity and security can be assured through the definition of database rules, which define the valid context for particular actions to take place. These rules for example prevent somebody from continuously positively rating their own document, or spamming other users with notifications. Firebase is a comprehensive platform solution which supported simple integrations with Facebook, Twitter and Google to enable secure user authentication, and provides a cost-effective and performant file storage module, Firebase Storage, out of the box. The simplicity of Firebase enabled the production of an effective prototype for Mapsy within a matter of a couple of days, and no, this isn’t the version currently available on the App Store! -
react-native-maps
At the very heart of Mapsy is the ability to quickly and easily render a clear and people-friendly map of the world.react-native-maps
is profoundly good at this; it allows the systemMapView
to be customised deeply through a simple caller interface. In addition, it is capable of unifying the interaction between both Apple Maps and Google Maps from both a development and application perspective, enhancing ease of use, avoiding unnecessary application bloat and helping maintain a consistent theme per runtime. -
redux
,react-redux
redux-thunk
,redux-persist
Redux is a powerful framework for managing application state, ensuring an immutable, functional application core in conjunction with a variable/function visibility interface that can be finely managed. Thanks to React-Redux, these state transitions can be easily synchronized with the React render life-cycle and React DOM, allowing the GUI to maintain consistency with the application state through seamless routing of state variables to component props. Changes to application state seamlessly benefit from efficient render updates as Redux-connected components rest within the conventional React DOM. Redux-Thunk has been pivotal in distributing shared functionality across the frontend, and ranges in use from firing events across the application, orchestrating state transitions and ensuring the correctness and reliability of asynchronous actions and recovery from inevitable failure conditions. Redux-Persist, meanwhile, acted as an invisible layer of reliable serialization for the application state, which greatly simplified the management of persistent sessions without any need as a developer to deviate from the conventional render model, or pollute the application hierarchy with synchronization guards or unclear state dependencies. -
lottie-react-native
lottie-react-native
empowers developers to embed high quality native vector animations exported from Adobe XD to their application. If this weren’t amazing enough, the animations come in.json
format, meaning that it is trivial to manipulate open-source animations to fit in with your application; vector paths and fills inside Lottie files can be recoloured, re-ordered, or even removed by eye. This library was pivotal in helping every screen in Mapsy feel dynamic, playful and welcoming.
What resources have you used to learn React Native? Books, tutorials, courses etc. Anything you can recommend?
I’ve always found StackOverflow and Medium to be very powerful sources of React Native goodness, you know, around the time you find something going wrong with some code you’ve pulled from GitHub.
What are some things that you don’t like about React Native or that need to be improved?
There’s very few things I’d change about React Native. Alas, here they are.
Less strange hacks.
There are a few times during development when I’ve had to do something just plain crazy to get something to work. For example, the marker pin you drag around on Mapsy to make a post? The PanResponder
you use to detect the touch works absolutely perfectly on Android. On iOS, it completely fails, except of course if you give it a background color. Yes, that’s right, the marker actually has a backgroundColor
on iOS; it has a value of #00000001
! Nothing else seemed to work. Occasionally, some layout operations appear to occur in a different manner for some key events in the application, meaning that extra care in synchronization of certain state-changing operations should be taken. These are little things, but their solutions are often obscure.
Even greater support for useNativeDriver
.
useNativeDriver
is incredible; a single line converts smooth animations with occasional choppiness into smooth as butter, zero effort. And, from my understanding, it’s unburdening your JS code, which is even better! However, you can only currently use it for basic animations; it’s not possible to use these for more complex operations on React’s layout, such as shape-changing transitions.
My iOS environment sucks.
Working in React Native requires you to perform a native compile once, then you run all of your JavaScript ES6 code over the top of the compiled build. iOS currently takes a huge amount of time to compile, so I normally have to execute my build first thing in the morning and make a cup of tea before iOS is ready to go. The development experience is fine after this, but it makes testing from a fresh install problematic. I’m not convinced this issue is React Native’s fault though; I’m no iOS developer, and it’s more than likely my project structure is atrocious.
Even better linking.
react-native-link
is a simple and powerful command line instruction that invisibly threads together the native dependencies of your project so that they can be recognized by the React Native Bridge. However, very often there are extra manual configuration steps that need to be performed for more complex native dependencies that I believe as of yet can’t be expressed using the platform. I can see this being very problematic for developers who do not have a background in native applications.
What can I say? Nobody is perfect. React Native gets pretty close though.
Anything else you would like to mention?
If there is anything to take away from this article, I want to emphasise that I don’t think a project of this scale would ever have been possible for me as a lone developer, even for just a single Android build. Mapsy was developed during my spare time only, and there is no telling how far behind I’d be if I were to develop against the native bottlenecks.
Please keep in mind that Mapsy is still brand new, and relies on user generated content from cool people just like you. Otherwise, it’s just an empty map! Feel free to post as much as you want, and I’m sure you’ll find many exciting uses for it. Mapsy is currently updated bimonthly, so remember to keep an eye out for new features!
The source code behind Mapsy is not yet available publicly, but I want people to know that it will be once the core functionality has been perfected.
Finally, I want to give a huge shout-out to my friend Sheraz for taking the time out to teach me all about the exciting world of React. I mean, he’s just become a father and he still took out the time to teach me. What a guy.
If anybody wants to get in touch with me, you can contact me at hello@cawfree.com. I don’t bite.