📜 ⬆️ ⬇️

Notes freelancer: the development of the first React Native-application

The author of the material, the translation of which we publish, recently released its first mobile application, written in React Native. It so happened that this application was his first project, which he created as a freelance programmer. Here he will talk about what he had to deal with in the course of his work - from the initialization of the project to its publication in the App Store and Google Play.



Why did I choose freelancing?


Last May, I turned up a wonderful freelancing project. At that time, I was a full-stack developer in a startup in Stockholm. This was my first programmer work, I got there just a year ago ( here I am talking about this in more detail).

The summer was fast approaching, the pace of work, which was crazy before, became calmer every day. Once there was such a week when I, in turn, had to do technical support. It was necessary to deal with some errors, I was a little bored, the work did not please me.
')
It was when I was in such a gloomy mood that my father informed me about his intentions to create a mobile application for his company's clients. Although he knew that I was very busy at work, and did not expect that I would give all my time to implement his ideas, he still asked if I would like to become something like a consultant in this new project. I then felt that I was hungry for interesting mental work and therefore I answered his question positively. Although I didn’t initially plan this, from a consultant I, as a result, turned into a lead application developer.

Here you may wonder why someone might even try to do mobile development after not having worked for a year in the role of a professional web developer? Wouldn't it be wiser to continue to gain experience in a chosen niche, grow professionally, form an impressive resume?

I fully agree that this would be much more reasonable. But I am a hopeless “multi-channel”, who several years ago decided to make career decisions based not on a certain strategy, but on his own preferences. I decided to do what brings me joy. In other words, my resume already looks like this now that it can hardly be brought into an even more disorderly state.

Of course, doing what you like and following a career strategy are not necessarily mutually exclusive. In fact, I really liked my previous job and my employer. It just so happened that I got another project, the craving for which turned out to be stronger than the desire to do what I was doing before.

What made this project so attractive for me? What made it more interesting to work on the rapidly developing product, which is used by thousands of companies, as part of a team consisting of the best people I have ever met? This question can be answered like this: this is freedom, this is the challenge that threw me to the need to solve a difficult task, and this is the desire for self-development.

Why was it decided to use React Native?


By the time I joined the project, my client had already received several offers from local digital agencies. Even before I considered the opportunity to independently develop an application, I was friendly asked to evaluate these proposals. When I looked at them, I was simply amazed by their low quality.

One of the agencies sent an outline of the design of the application, which, besides the fact that it looked untidy, also did not correspond to the corporate style reflected on the client's website. One more offered transcendental prices - both for the development and for the support of the project. The third, it seems, sent the offer, even without having studied properly the requirements of the client. All the agencies that sent the proposals had a common feature: they were going to create an application using the Cordova hybrid framework.

But that's not all. Although Cordova is a completely free and open source tool, one of the agencies even tried to hide information about the specific technology it uses. Instead, representatives of the agency talked about the "own" platform for developing mobile applications, created within the company. It seems that it was a small add-on over Cordova, made only to firmly secure for this agency the exclusive rights to service the application and make the possible future transition of the customer to another developer difficult and expensive. In general, the proposals in question were not very impressive.

It should be noted that I have nothing against hybrid frameworks. I constantly use applications that are built on their basis. This, for example, Gmail, Slack, Atom, Figma. However, I have heard about React Native for some time, how this library allows you to create cross-platform mobile applications using JavaScript that were not hybrid!

And now what? Is it necessary, in some tricky way, to support iOS and Android when developing native JavaScript applications? I had this question because when I was interested in similar applications, it turned out that iOS applications are written using Objective-C or Swift, and Java or Kotlin are used to develop Android applications.

Of course, there are no special tricks here. So I had another question. How can you call React Native applications real native applications? If you answer this question in a nutshell, it turns out that the whole thing is in the API. It took me more time to understand this than I would like to admit, but how React Native applications, called native, work with mobile platforms, is not to run JavaScript code and not to compile such code in native code The thing is that these applications perform requests to the API, which derive the native components using Objective-C on the iPhone and using Java on Android.

If you want to learn more about the basics of React Native - I recommend this answer to Quora, this presentation from React Conf, and this material, which tells about the release of React Native.

Although at that time I did not know what exactly was happening in the depths of React Native-applications, I knew that the work of such applications comes down to the execution of native code. This was my main argument against choosing one of the Cordova-based solutions offered by the agencies. I thought that if companies need a mobile application, then this application should be native. If someone needs an application built on the basis of HTML / CSS / JS, then the money will be better spent just to improve the mobile capabilities of its web application.

When I shared these thoughts with the client, he asked me a question about whether I know someone who can create such an application. I replied that I did not know. Then I was asked if I could do it myself. “I can't,” I replied. However, by that time I was already interested in all of this and simply could not experiment with React Native, taking the application specifications as the basis of my experiments.

Before I realized it myself, I managed to create a framework for the application. As a result, just a few weeks after the conversation, we agreed with the client that I would develop the application for it.

Application Specifications


Before we dive into the technical details, I want to tell you a little about which application we are dealing with.

The client for whom the application is being developed is a company in Stockholm that manages coworkings and collective offices. In other words, we are talking about office spaces that can be rented by various companies. At the moment, my client has about 10 such operating offices, in which approximately 400 companies with 1,400 employees are renting places. These here are the tenants of offices and are the target audience of the application.


Recreation area in one of the coworkings

After discussing the future of the application with the project manager, I was able to figure out some of the requirements for the project:


You may notice that this project has quite modest requirements. Perhaps it is something in this spirit that can be called a good example of the first application that someone is going to develop using a new set of technologies. If you are interested in looking at what I finally got (and simultaneously decide whether to spend time reading the story about exactly how it all happened) - here is an overview of the first version of the application.


The first version of the application

Read more? Great, then let's move on.

Learn from the best


Imagine that you promised your friends to build a house for them. But you do not know how it is done. You really do not even know where to start. What should be done in the first place in this situation? The answer is obvious: to find someone who knows how to build houses and learn from him.

In fact, this is what I tried to do. And I was very lucky to find exactly what you need. So, after just a few hours of searching for training materials on React Native, I found a Harvard video course on React Native, consisting of 13 parts, on YouTube. Each lecture lasting 90-120 minutes was devoted to a separate topic. As a result, I had about 23 hours of high-quality teaching materials.

Having found this course, I immediately began studying as if I was obsessed. As a result, after several weeks of classes, which I could take evenings and weekends, I finished this course and created a good foundation for the application.

Now I can say that that course, without a doubt, is the best that I managed to find. Compressed and well-prepared classes, of course, played a huge positive role in the study, but I can not fail to note the skill of the teacher. I would describe the style of conducting these classes in the following words: speed, extreme practicality, purposefulness. No water, no irrelevant jokes or life stories. Unlike what your humble servant writes here ...

One way or another, there was such a feeling that so much useful information was packed into each lecture that it would take them two more time to present them to many other teachers. In other words, this course is very similar to the well-known Harvard CS50.

As a result, if you want to find a foothold for your first Native React application, I will definitely recommend this course to you. Although there should be noted one feature. That course uses a set of tools Expo . This is an excellent tool that is suitable for most simple applications, which takes on all the subtleties regarding working with mobile platforms. But if you, like me, want to create a basis for a project that, rather sooner than later, can turn into a rather large and complex application, and you also want complete freedom of action, you will probably be better off initializing the project React Native.

The second “learning resource” that I could use was my colleagues. By a lucky chance, in the company where I worked then, we also started developing the React Native-project. Although I did not work on this project myself, I learned a lot just by talking to those who worked on this project and analyzing their code.

Now that we have discussed everything that accompanies the development of React Native-applications, it's time to move on to technical issues.

Development environment


After using a command of the form react-native init MyApp , I created the basis of the application, one of the first tasks that I react-native init MyApp was the development of a new development environment.

If you came to React Native-environment from the usual web development, then it should be noted that much will seem familiar to you here. For me, this meant that I continued to use Atom as a code editor, iTerm as a terminal, and GitUp as an interface for working with git. (If fans of Vim are reading this now, I suggest everyone to stay with their opinion.) But, in addition to the tools listed above, I needed something else to develop React Native-applications.

For example, I needed to get used to the iOS emulator. While execution, by means of the command line, the react-native run-ios command, seems to be deceptively simple, at the very beginning of the work, simply invoking this command was not enough for the emulator to work properly. Since new npm packages were added to the project almost daily (and later many quite native CocoaPod modules), I, much closer than I would have liked, had to get acquainted with the unpleasant ritual of cleaning Watchman resources and the Haste cache, deleting the node_modules folder, reinstalling modules and resetting the Metro Bundler cache. Fortunately, all these tasks can be solved with the help of the following command:

 watchman watch-del-all && rm -rf tmp/haste-map-react-native-packager && rm -rf node_modules && yarn && npm start --reset-cache 

In 9 out of 10 cases, a similar “dance with a tambourine” allowed the emulator to return to life. Sometimes, however, even this was not enough. Then it was necessary to go deep into descriptions of error messages on GitHub and to get a grasp on discussions on StackOverflow.

The root of some other problems was the fact that I had long believed that in order to solve some problems, it was necessary to run Xcode. And, believe me, you will strive to stay in this house of horrors IDE as little time as possible.

A similar story was with the launch of the emulator with a certain version of the iPhone. If someone would have told me earlier that the command given below solves this problem directly from the command line, then perhaps it would be a little easier for me to live in my first months of React development.

 react-native run-ios --simulator='iPhone X' 

Other examples of the difficulty of getting used to a new development environment include a three-step process for preparing a release version of an application (for placement on the App Store or in some kind of continuous integration environment, such as Visual Studio App Center or Firebase) and the transition from release version to version intended for debugging (to development mode). Perhaps, it will seem obvious to many that the necessary changes to the project can be made with the help of any text editor. In any case, this is just an example of a couple of little things that had an unexpectedly big impact on my workflow when working in development mode.

And finally, it took some time getting used to the need to constantly switch between the various macOS applications needed to solve the problems that I, developing web applications, usually solved using only Chrome.

In order to look at what JavaScript code writes to the console, and to analyze, for debugging purposes, the output HTML / CSS code, I turned to React Native Debugger . In order to monitor the state of the application, the actions sent, the requests to the API and the responses received, I used Reactotron . Although I found both of these applications extremely useful, I could not help thinking about my usual workflow used to create Ember.js applications, when I could solve all these tasks in the same environment in which my applications were running (using the Ember Inspector for Chrome).

Navigation


Navigating / routing seems to be a very difficult task for React Native. During the existence of this framework, many different solutions to this problem have appeared, but there is still no such thing that could be called a generally accepted standard. I decided to use the react-navigation library, my choice was mainly influenced by what was told about this library in the course on React Native, which I went through, and also that my colleagues used it.

If I had invested some time in a sufficiently deep study of this question, I could find out the following:


But even if we take into account the above, I would probably still choose react-navigation, since I did not have time to try out all these libraries, as, for example, did the author of this report. And finally, as was said in this report, the choice of a tool for organizing navigation is an issue whose solution depends not on which of these tools can be called the best, but on which one best suits the needs of a particular project.

After I worked with react-navigation for about 9 months, I have to say that I really have nothing to complain about. If you compare this library with the usual router.js library I use in Ember.js , I can note that this is something completely new.

It was quite easy for me to deal with the three main types of react-navigation navigation tools. These are StackNavigator , TabNavigator and DrawerNavigator . It was much harder to understand how to combine these tools in order to create the system for navigating the application I needed.

For example, the fact that the DrawerNavigator component should be the root element of the navigation system (one step above the main component of the TabNavigation ) was completely unclear to me. If this is hard to imagine, this is what the DrawerNavigator looks DrawerNavigator in action (in a real application, everything works much more smoothly).


React-navigation DrawerNavigator in action

As you can see, I needed the side navigation panel to be opened with a swipe from any application screen.

I perceived the sidebar as something secondary in comparison with the main navigation bar located at the bottom of the application. Therefore, it seemed to me that the DrawerNavigator should be placed in the route tree (shown below) either under the main BottomTabNavigator or at the same level as this element.

However, after I had suffered badly, trying to force the side panel by force to go where it turned out to be not the place, I realized that, in accordance with the features of react-navigation, DrawerNavigator should be placed one step above BottomTabNavigator , that is, root of the navigation tree. I hope that this find of mine will help someone of the readers of this material save time, which otherwise would have been spent on reading the documentation and materials on GitHub.

Here is the application's navigation tree. Here, as the root element, MainDraverNavigation used.


Summary navigation tree of the first version of the application

Here you may wonder why, for the Community and Conference StackNavigator , both TabNavigator and TabNavigator . StackNavigator TabNavigator ?

, , TabNavigator . .


TabNavigator,

, , react-navigation. , MaterialTopTabNavigator , , , . , , , , StackNavigator , , , - «» .

react-navigation, , . , , FlatList . Home Selection StackNavigator , , , .

Community Conference , StackNavigator , — TabNavigator , . , .


TabNavigator StackNavigator

, Iphone X, , 20% . - , — .

TabNavigator Destination. , , TabNavigator Coworking Spaces , Info, Members Contact.

TabNavigator - , ( ). JS-, react-native-swiper , . , , , . , .


TabNavigator react-navigation react-native-swiper ( , )

:


-


, react-native init , , , - ( «-»).

, -, , . , , . :


-,

iOS, , , . , , WiFi 4G- . iPhone , , - . «» - . .

, react-native-splash-screen , , -.

— info.plist UIStatusBarHidden , true , , SplashScreen.hide() , false hidden React Native StatusBar .


, , Convention over Configuration (CoC). . , , , Ruby on Rails, — Ember.js — , CoC. , , , React Native .

, , React, , - , , Redux MobX . JS- Ember Data ( — Ember ).

Redux , ( React Native, ), , -, . .

Ember 90% . , . , React, Redux — . , 90% .

, , , , , — . , , , , 7 :

  1. : SOME_ACTION_REQUEST , SOME_ACTION_FAILED , SOME_ACTION_SUCCEEDED .
  2. .
  3. , , , .
  4. , , , (, , redux-saga ).
  5. API.
  6. React-.
  7. SOME_ACTION_REQUEST React-.

Redux redux-saga, , , , , , 7 — , Redux.


, React Native-, , . ? . .

React Native -, . , LocalStorage , , React Native AsyncStorage . — , - . , , .

Lists


, , React Native . , . , , , , , , ScrollView . , , , , FlatList . , , , , SectionList .

, , FlatList . , , , , , . .

â–Ť


FlatList , refreshControl . , , , , . , React Native , . — RefreshControl . , .


RefreshControl

, , , refreshControl , RefreshControl , , . , , :


— .

, , , , . , , , GitHub.

, refreshControl onEndReached ( ) fetching . , - , false true , — , , 250 , RefreshControl , .

, setTimeout() fetching 350 . . , , setTimeout — , , handleRefresh() handleLoadMore() — refreshing loadingMore . , , , , - .

, onRefresh refreshing refreshControl . , refreshControl , , , , .

â–Ť


, . — , , Load More , , , , .


FlatList. , , 2, onEndReached , 2-

, onEndReached . .

onEndReachedThreshold , FlatList , , onEndReached . .

100 , , 10 , 1, onEndReachedThreshold , , onEndReached , , 90-. 2, , 2- , — 80- , .

, , , , FlatList . , , , , handleLoadMore() , onEndReached , , — 10 .

, , loadingMore , , handleLoadMore() , , , !loadingMore . , , .

â–Ť


ListLoadingComponent FlatList , , ListHeaderComponent , ListEmptyComponent ListFooterComponent , , - , , , .

, render() .

â–Ť


, , , . , , .

, scrollToOffset FlatList , , . , . ref FlatList :

 <FlatList ref={(ref) => { this.newsListRef = ref; }} ... /> 

, . ScrollToOffset handleScrollToTop() , , , react-navigation, , :

 componentDidMount() { this.props.navigation.setParams({   scrollToTop: this.handleScrollToTop, }); } handleScrollToTop = () => { this.newsListRef.ScrollToOffset({   x: 0, y: 0, animated: true, }); }; 

, react-navigation 3 ref , BottomTabNavigator .

Images


, , . , , 4G- ( , , 3G), , , , , .

, , , , , , , . . , , , , .

, , . 7 , image , , ( , ).

â–Ť


, , . react-native-image-picker , Cloudinary Carrierwawe Rails-.

, Node-API Cloudinary react-native-fetch-blob . , , , , , .

, , react-native-fetch-blob, . , react-native-fetch-blob , API JS FormData . , react-native-fetch-blob rn-fetch-blob , .

â–Ť


, React Native Image style , source resizeMode . , , - , , , .

, , , . , , , . . Avatar react-native-elements.

, Image . , - , .

, , . .


react-native-slideshow

react-native-slideshow , , . , , , , , , .

â–Ť


7 , , . , — , , . , - . .

, , -, , , , - ( — ), , , , Facebook . , .

, , React Native-. , . — react-native-loading-placeholder , , , . — react-native-linear-gradient , . , , , , , , , , .


react-native-loading-placeholder react-native-linear-gradient

â–Ť


— . , React Native Image . , - CachedImage react-native-cached-image .

npm- Image , , , CachedImage . Reactotron , , .

, , , . , , Cloudinary, 95% , , 4%. .

, . CachedImage activityIndicatorProps={{ animating: false }} , .

date and time


â–Ť


React Native - Picker . - , ( - ), JS-, . , react-native-picker-select , <select> iOS Android .

JS-, React Native- ( lodash , ), , , , . , , - . , .

â–Ť


react-native-calendars Wix. :


, . , , — .


react-native-calendars react-native-picker-select

â–Ť


— , .
SaaS-, . SOAP, API Conference. , , , , .

, , , 5 . - , JavaScript Date UTC, , . , , , , , - . « », — .

, , moment-js , React Native, timezone , :

 const timeSthlmAfterFive = moment().isAfter(moment.tz('17:00:00', 'HH:mm:ss', 'Europe/Stockholm'), 'second'); 


, , , . React Native -, , , , , , font-face CSS.

. , . , 10 -. react-native-vector-icons .

, ,


CI/CD, DevOps- -, .

( ) , - . , . GitHub- . , :


. , , , , , , push-. , , , , .

Visual Studio App Center (VSAC). Chain React 2017 . , , , DevOps-, . , , , , push-, Codepush . -. , , , , iOS, Android. , - , , , , , - .


Visual Studio App Center ( )

« », — , . , (API — ). , , , , -, (, , ).

How is this possible? Microsoft, , VSAC « ». , , Codepush ( React Native-) HockeyApp ( ), - . , «developers, developers, developers, developers» .

, VSAC , - Fastlane , BuddyBuild Firebase ? , , , VSAC , , , . , , ? , VSAC, , .

VSAC. , , , .

, , , VSAC Apple Developers (Apple, , , ). , , , .

, VSAC, , , CI/CD- .

Android


, iOS- , Android . Android Studio Android React Native Platform . , Platform.select() . - , , , Platform.OS .

, , Google Play , App Store. Why? , App Store Apple.

Apple


, -, React Native, . , Apple. , , , , , .


Apple

, — « ». -, , iOS-, , , , .

— Apple. , , , . Dun & Bradstreet, Apple, . , , , Apple (, , Apple , — ).

, Apple , , — , -. . , — ?

, .

, , Apple Developer . .

. . provisioning-, iOS-, , Apple .p12 push-, dSym-. , , , .

Apple, 50% 24 , 90% — 48 . , , — , , Apple-.

, . «Metadata Rejected». , - . , 5 ( App Store Review Guidelines ), .

, , , — . , , , , , . , — , () .

iOS, . , , , . , , . . , , .

Results


, React Native- . React Native-. -. , : . .

, , , , . , , — , .

, - , . . , , , 8 . . .

, . , , - .

, , , 6-7 , . , , , :


JS- , Flutter , NativeScript , Objective-C, Swift, Java Kotlin, React Native .

, -, , React Native , , , . , React Native — , . React Native .

Dear readers! ?

Source: https://habr.com/ru/post/447574/


All Articles