Reviewery: Music rating iOS application built in React Native

Vadym Markov
hyperoslo
8 min readApr 26, 2017

--

This is the first part in the Reviewery series. Check out the second part Reviewery: Music rating iOS application, a year later when you’re done with this one.

Personal projects are funny. At first you think of a simple webpage without any styles and then catch yourself making a good looking logo for an app you’ve just implemented. Even though I knew that my app will be used only by 2 people I couldn’t stop myself from adding more and more features. And one of the reasons was that I stepped away from my comfort zone and was trying something new.

Introduction

  • I love searching for and listening to good music. So does my wife.
    We both are Spotify users, and playlists like “Discover Weekly”, “Release Radar” and “Your Daily Mix” serve as a source for creating our own monthly playlists with recently released songs we liked.
  • Family playlists are cool, but do you know what is even coolier? That’s right, a family music chart. You know, all the charts seem unfair. Billboard ranks songs according to sales and airplay, Pitchfork reviews are too independent and subjective. But it’s not the case for your own chart, when your vote is counted and can be decisive. We have similar music tastes with my wife, but “similar” doesn’t mean “the same”. So when it comes to making playlists like “March Top 20” or “2017 Top 100”, where chart positions matter, we need a possibility to vote for one or another song.

Based on that, I’ve decided to make an iOS app that shows a list of selected
Spotify playlists, and as a user you can rate songs from 0 to 10. Playlists are
grouped by charts, so for example “Top 2017” chart consists of songs from
“January 2017”, “February 2017” playlists and so on. Then it’s easy to sort
songs by rating and create your own “hit parade” of the year.

React Native adventures

I’m an iOS engineer, so the most obvious way of doing an app would be to create a new Xcode project and start writing beautiful Swift code with a help of a few time proven frameworks. But surprisingly (or not) I went with React Native, so you may be wondering why.

It’s a great time to be an iOS developer nowadays. Almost 3 years ago we got
Swift, and now we can participate in making the world’s best general purpose programming language. Swift is awesome, it’s a modern
programming language we can use not only for iOS development, but for
scripting, backend and even Android. We build great frameworks and tools,
contribute, share and learn together. But this story is not about Swift.
It’s about React Native, a framework that lets you build native mobile apps
using JavaScript.

Even though there is a lot to be excited about in the world of native iOS
development, one could argue that web is the future of mobile. And it’s not so hard to be convinced:

  • A lot of innovations are driven by web technologies.
  • There is a huge JavaScript community producing a tremendous amount of libraries every day.
  • Hybrid app frameworks have come a long way to simplify mobile app development, they cover both iOS and Android, shorten development cycles and deployment time.

As an iOS developer, I’ve always been sceptical about frameworks like that. But it’s not smart to criticize without trying it first, especially seeing that
more and more companies are leaning towards React Native. So when it came to building a small personal application I considered it as a good opportunity to try this trending framework from Facebook.

Libraries

Ok, so now you probably understand all the “whys”, so let’s take a look at dependencies I have in the project:

"react": "15.4.2",    
"react-native": "0.41.2",
"react-native-config": "^0.3.1",
"react-native-fbsdk": "^0.5.0",
"react-native-navigation": "^2.0.0-experimental.233",
"react-native-star-rating": "^1.0.6"

The first 2 lines are obvious, that is what you get by using React Native command line interface to generate a new React Native project:

react-native init Reviewery
  • react-native-config is kind of nice, it helps you in managing environment variables, which is handy when you have staging and production setup.
  • react-native-fbsdk is a React Native wrapper around the Facebook SDKs for Android and iOS. I’ve decided to go with Facebook login because it is an easy and secure way to sign into the app without creating new accounts, usernames and passwords. And there was the first unpleasant surprise. Documentation says that you need to follow all the steps in the Getting Started Guide for Facebook SDK for iOS, which means you have to download iOS SDK, open your application’s Xcode project, add all the required frameworks and then copy-paste code to AppDelegate. There is nothing new for me, plus I went further and set up CocoaPods, but I can imagine what it takes for JavaScript developer to configure and maintain both Xcode and Android Studio projects, link packages and don’t get lost in a bunch of workarounds, suggestions and tutorials found on Web.
  • react-native-navigation is a great navigation solution for React Native. It supports both iOS and Android and comes with pretty straight forward API to add navigation bars, tab bars, drawers and modals to your application. I have no complains about the library itself, but then again, CocoaPods is not supported and installation is not as easy as adding a new framework to your Podfile. And from my experience it’s a problem of many React Native libraries.
  • react-native-star-rating is a React Native component for generating and displaying interactive star ratings. With a bit of voodoo magic I managed to set up react-native-vector-icons and then the project was ready for adding some cool stars to my app 🌟.

In addition to that I also have a few dev dependencies in my package.json file, such as jest and flow-bin. But when I went to my node_modules I was a bit shocked: there are 566 subfolders, which means that my tiny app is built on top of 566 packages. I know that it became normal in JavaScript world, but it’s not usually the case for native iOS projects.

What I liked about React Native

  • Declarative way of building UI using components and state.
  • Layout with Flexbox and styling with StyleSheet.
  • Faster iterations with live and hot reloading.

What I didn’t like

  • You don’t get everything you need out of the box. Even such a standard functionality as navigation could be confusing. You are reading through documentation of NavigatorIOS, Navigator and NavigationExperimental until you realize that all of them are actually depreciated, so you start looking for some open source solution.
  • Amount of dependencies that my small app is using makes me worry about project stability and maintenance.
  • JavaScript. Yes, I must admit that the language has got better over the years, but it still feels like a “downgrade” after using Swift, even with all ES7 features and thousands of community-driven libraries that are trying to solve everything that the language doesn’t support. I don’t have anything against JavaScript, but I simply don’t see it as a “silver bullet” for cross-platform development.

I can highly recommend this great article if you want to read more about pros and cons of using React Native from an iOS developer perspective.

Backend

On the server side of things I went with Express. There is not much to talk about, it is the de facto standard server framework for Node.js, and since I wanted to feel myself as a full stack JavaScript developer 😎 it was an obvious choice for me. In addition to that I use:

Relations between base entities in the system could be represented by the following simplified diagram:

There is a list of all the API endpoints I ended up with:

GET /users
GET /users/:id
GET /charts
GET /charts/:id
POST /charts
DELETE /charts/:id
PATCH /charts/:id/review
GET /charts/:id/top
GET /charts/:id/playlists
GET /charts/:chartId/playlists/:playlistId
DELETE /charts/:chartId/playlists/:playlistId
PATCH /charts/:chartId/playlists/:playlistId/review
GET /charts/:chartId/playlists/:playlistId/top

I was lazy and felt like it’s unnecessary to spend time doing admin panel. When I want to create a new chart or fetch a playlist from Spotify I can manually make an HTTP request from the command line or from any GUI platform for API development. And I usually do it only once per month, when my monthly playlist is completed.

iOS Application

I could go further and try React Native cross platform possibilities, but I simply didn’t need an Android app. Sorry, Android lovers.

There are 7 screens in the app:

  • Facebook login
  • Profile screen with the possibility to logout
  • A list of charts
  • Chart detail screen with a list of attached playlists
  • Playlist detail screen with a list of songs
  • Review popup to rate songs
  • Result screen with a list of songs sorted by rating. It should be accessible only when the chart is marked as completed.

Summary

“Reviewery” is an app for personal use only, it will never be published in AppStore and repository is not going to be trending on GiHub. Would I use React Native over iOS development in Swift? Probably not. But I solved a problem that I was experiencing with a new software development platform, new libraries and tools. The first 2 playlists have already got their deserved reviews and by the end of the year we’ll know the name of the best song of 2017. By doing a hobby project you can feed two birds with one scone. It’s a good opportunity to learn and experiment.

That’s all, folks. Explore, learn and create. 🎶

https://github.com/vadymmarkov/reviewery-mobile

https://github.com/vadymmarkov/reviewery-server

--

--

Vadym Markov
hyperoslo

iOS Developer at @hyperoslo, independent artist at @hypnocrates. Believe that delightful code and beautiful music will save the world.