SlideShare a Scribd company logo
1 of 116
Download to read offline
React Native for React Developers
By: Nikola Gorgiev
December 2022
v.2.0
About me 4
Introduction 5
Mobile apps vs Web 5
What is React Native? 6
How does React Native work? 6
React Native architecture 8
Getting Started: React Native CLI vs Expo 13
Expo 13
React Native CLI 14
Setting up the Development Environment 15
iOS Setup 16
Android Setup 19
Folder Structure of a React Native project 22
xCode and Android Studio 23
xCode 23
Android Studio 27
React Native Core Components 31
Styling 33
Platform Specific Code 35
Permissions 36
iOS 36
Android 36
Adding custom Fonts 37
Navigation 38
Installing 38
Add stack screen navigation 38
Add Bottom Tab navigation 43
Deep Links 47
Push Notifications 53
Introduction 53
Implementation 53
iOS Setup 55
Android Setup 66
Building the App 70
Manual Building 70
2
Android 70
APK with Android Studio 71
APK with Command Line 73
iOS 74
Dealing with Apple Hell 74
Generating p12 signing certificate 74
Generating BundleId 80
Generating Distribution Provision Profile 82
IPA with xCode 84
IPA with Command Line 86
Azure Devops Pipelines 87
Android 87
iOS 90
Dealing with Apple hell 90
Generating p12 signing certificate 90
Generating BundleId 96
Generating Distribution Provision Profile 98
The pipeline 100
Optimizations 115
Debugging 115
Testing 115
Advanced Features 115
QuickActions & AppShortcuts 115
Home Widgets 115
CarPlay & Android Auto 115
Over the Air Updates 115
Native/Turbo Module 115
React Native Everywhere 115
Best Practices 116
Organizing your code/Atom 116
State Management 116
Typescript 116
Useful Terms 116
Useful Links 116
3
About me
My name is Nikola Gorgiev, and I am a software developer with
a passion for technology and programming. I was born in August
1990 in Macedonia, and I received my bachelor's degree in
Computer Science from the University of Goce Delchev in Shtip.
I started my professional career in June 2014 as a Game
Developer, but I quickly realized that my interests were not
limited to just game development. I have been working in a
variety of software development fields since then, starting with
Game Development, then Web Development and now I am
working with cross-platform frameworks like React Native and
Flutter. Over the course of my 9-year career, I've gained a
wealth of knowledge and experience in a variety of programming
languages and technologies.
In addition to my professional career, I am also a dedicated
family man. I am married and have a 5-month-old son. My family is my top priority and I always
try to make time for them, despite my busy schedule.
Also, I used to record videos on my YouTube channel SmileySolutionsMKD where I was
recording video tutorials related to programming in my native language, Macedonian. I am
planning to rebrand it as Smiley Tech. MKD in the near future with some new content.
Overall, my goal is to be constantly learning and growing as a software developer, and to share
my knowledge and experience with others through my YouTube channel, LinedIn and Medium
Articles, and now this document that I am sharing with the community.
4
Introduction
This guide, written by Nikola Gorgiev, was initially created for the employees of Melon, a
subsidiary of Kin+Carta, to assist them in smoothly transitioning to React Native and expanding
their understanding of the technology. The guide is designed to provide a comprehensive
introduction to React Native and help ReactJS developers at Melon to easily adopt the
technology.
It is important to note that the purpose of this document is not to be a full technical specification,
but rather a starting point for further exploration. While the guide covers the basics of React
Native, it is not exhaustive and there will be useful links included to help developers research
further.
The guide has been written keeping in mind the needs of ReactJS developers at Melon, and it is
tailored to their specific requirements. The goal is to help developers understand the key
concepts and principles of React Native, and to provide them with the necessary tools and
resources to start building their own applications.
In short, this guide is a valuable resource for ReactJS developers at Melon, part of Kin+Carta,
who are looking to broaden their knowledge of React Native and start building their own
applications.
Mobile apps vs Web
There are numerous benefits to creating a mobile application as opposed to a website for
mobile devices. One of the most significant advantages is the ability to replicate the same
experience as native mobile elements, something that is not possible with HTML. For instance,
a custom-made DatePicker created with HTML will never look or function as seamlessly as the
one provided by the mobile operating system.
Additionally, the way users interact with mobile devices differs significantly from the way they
interact with the web. On the web, users typically use a mouse to navigate and interact with
elements, whereas on mobile devices, users have the ability to use finger gestures, opening up
a wide range of new possibilities for interaction. This allows for a more intuitive and user-friendly
experience that is tailored to the unique capabilities of mobile devices.
Another advantage of mobile apps over mobile websites is the ability to access the device's
features and sensors, such as the camera, GPS, and accelerometer. This allows for a more
immersive and interactive experience that is not possible with a website. Additionally, mobile
apps can work offline, which can be very useful in areas with poor or no internet connectivity.
Furthermore, mobile apps offer better performance compared to mobile websites. Mobile apps
are built specifically for a particular platform and can take full advantage of the device's
resources, resulting in faster load times and a smoother overall experience.
5
In conclusion, creating a mobile app instead of a website for mobile devices provides a more
intuitive, interactive, and immersive experience, allows access to the device's features and
sensors, and offers better performance. While mobile websites can be useful in certain
situations, mobile apps are the best choice for most businesses and organizations looking to
reach and engage users on mobile devices.
What is React Native?
React Native is a cross-platform mobile software development kit (SDK) that was developed by
Meta, formerly known as Facebook, and released as an open-source project in 2015. Since its
release, React Native has become one of the most widely used frameworks for building mobile
applications. This is largely due to its ease of use and the ability to build apps for multiple
platforms using a single codebase.
One of the main advantages of React Native is its use of the JavaScript programming language,
which is widely known and used by developers worldwide. This makes it easy for developers to
learn and use React Native, as opposed to other mobile app development frameworks that
require developers to learn new languages and frameworks.
Another advantage of React Native is its ability to build apps for both iOS and Android using a
single codebase. This can significantly reduce the development time and costs associated with
building separate apps for each platform. In addition to this, the codebase can be shared among
multiple development teams, and the app can be easily maintained and updated.
The development community of React Native is also very active and supportive, with a large
number of libraries, plugins, and tools available to help developers with their projects. This
makes it easier to add new features, improve performance, and fix bugs.
In summary, React Native is a cross-platform mobile SDK that enables developers to build
mobile apps using a single codebase. Its ease of use, ability to build apps for multiple platforms,
and active development community make it a popular choice among developers worldwide.
Learn More…
How does React Native work?
React Native is a framework for building cross-platform mobile applications. Unlike older
frameworks like Ionic, which essentially runs a web app as a standalone mobile app, React
Native generates a true native app that utilizes the same components provided by the
corresponding mobile operating system (iOS and Android).
6
One of the key differences between React Native and other frameworks like Flutter is that React
Native does not replicate the components provided by the mobile operating system. Flutter, for
example, renders every component "pixel by pixel" and works like a game engine. This means it
has replicas of all the system components provided by iOS and Android.
When the operating system receives an update and some components are changed, Flutter
needs to make those changes internally. This requires developers to update their Flutter version
and make changes to the code if necessary, before pushing a new update to the app. In
contrast, React Native uses the system-provided components. This means that when a new
operating system update changes a component, such as a button, your app will automatically
render the new button when the user updates the app.
This approach has several advantages. First, it ensures that your app is always up-to-date with
the latest design changes, without requiring additional development work to maintain
compatibility. Second, it allows developers to take full advantage of the native capabilities of the
7
device, such as camera, GPS, and accelerometer, resulting in a more immersive and interactive
experience.
In summary, React Native is a powerful framework for building cross-platform mobile apps that
utilizes the same components provided by the mobile operating system. Its approach of using
system-provided components rather than replicating them, enables developers to take full
advantage of the native capabilities of the device and ensures the app is always up-to-date with
the latest design changes. You can learn more about it here.
React Native architecture
With the release of React Native version 0.70, the new architecture has finally been
implemented. This new architecture was first introduced in version 0.68 and was available for
testing by changing a flag in the code. The new architecture brings several significant changes
to React Native, which are depicted in the picture below, with the old architecture on the left and
the new architecture on the right.
The most notable change in the new architecture is the absence of the "bridge." The bridge was
a key component of the old architecture, which was responsible for communicating between the
JavaScript code and the native code. The bridge was known to cause performance issues and
was a source of complexity in the codebase.
The new architecture introduces several new components such as JSI (JavaScript Interface),
CodeGen, Fabric, and Turbo Modules. JSI is a new JavaScript engine that improves
performance and reduces the size of the binary. CodeGen is a new code generator that
improves the performance of the application by generating optimized code. Fabric is a new
rendering engine that improves the performance of the application by reducing the number of
calls to the native components. Turbo Modules is a new system for managing the modules,
which improves the performance of the application by reducing the number of calls to the native
code.
8
In summary, the new architecture of React Native brings several significant changes, the most
important being the absence of the "bridge" and the introduction of new components such as
JSI, CodeGen, Fabric, and Turbo Modules. These changes aim to improve the performance of
the application and reduce the complexity of the codebase. The new architecture is expected to
provide developers with a better experience when building mobile apps with React Native.
● Bridge: The bridge, which existed in the old architecture of React Native, was one of the
main reasons why the development team at Meta decided to re-architect the entire
React Native core. The bridge was responsible for communicating between the
JavaScript code and the native code, and it worked by using JSON serialization.
With every interaction in the app, the JavaScript would send a JSON object containing
data about the interaction over the bridge. On the native side, the JSON object would
then be deserialized. This process became a bottleneck when the app had a lot of user
interactions, such as when scrolling through a large list of items. This would cause a
delay in the data being displayed and resulted in empty white rows appearing for a split
second before the data was loaded. This was caused by the high number of
serialization-deserialization operations of JSON objects happening.
The bridge was known to cause performance issues and was a source of complexity in
the codebase. The new architecture introduced in React Native version 0.70 aims to
address these issues by eliminating the need for a bridge and introducing new
components such as JSI (JavaScript Interface), CodeGen, Fabric, and Turbo Modules
which improve the performance and reduce the complexity of the codebase.
9
● JSI (JavaScript Interface): JSI (JavaScript Interface) is a new component that was
introduced in the latest version of React Native, version 0.70, as a replacement for the
old bridge. JSI aims to improve performance and reduce the complexity of the codebase.
Unlike the old bridge, which relied on serializing and deserializing JSON objects, JSI
allows for direct access to the native code via C++. This means that developers can now
directly invoke native code from JavaScript, allowing for more efficient communication
between the JavaScript code and the native code. This is particularly useful for
interacting with device features and sensors, such as Bluetooth or the camera.
JSI is designed to be more efficient and lightweight than the old bridge, which was
known to cause performance issues. It eliminates the need for
serialization-deserialization of JSONs and allows for more direct access to the native
code. This improves performance and allows for a more seamless and efficient
communication between the JavaScript and native code.
In summary, JSI (JavaScript Interface) is a new component that was introduced in React
Native version 0.70, as a replacement for the old bridge. It allows for direct access to the
native code via C++, which improves performance and reduces complexity of the
codebase, it eliminates the need for serialization-deserialization of JSONs and allows for
more direct access to the native. You can learn more here and here.
● Fabric: Fabric is a new component that was introduced in React Native version 0.70 as
a replacement for the UI Manager in the old architecture. In the old approach, when an
application is run, React creates a ReactElementTree in JavaScript, which is then used
to create a ReactShadow tree in C++ on the native side. Based on this Shadow tree, the
Layout Engine calculates the positions of all UI elements and creates a HostViewTree,
10
which consists of the actual native elements such as ViewGroups for Android and
UIViews for iOS.
The communication between the different threads (JavaScript and native) happens over
the bridge, which, as previously mentioned, was a known issue due to the
performance-expensive operation of serialization-deserialization of JSONs and because
it meant that two copies of the same data were kept on both sides of the bridge. This
also meant that when there was a lot of traffic, crossing the bridge was slow, resulting in
data being out of sync and causing laggy scrolling in large lists.
Fabric solves these issues with the help of JSI. It allows the JavaScript and UI threads to
be in sync, which means that user interactions are prioritized and executed
synchronously in the main or native thread, while other tasks such as API requests are
executed asynchronously. Additionally, the Shadow Tree is now immutable and shared
between the JavaScript and UI threads, which eliminates the need for keeping two
copies of the same data. This improves performance and ensures that user interactions
are executed smoothly and without delay. Learn more here, here and here.
● Turbo Modules:Turbo Modules is a new system for managing modules that was
introduced in React Native version 0.70. In the current architecture, all the native
modules used by JavaScript (such as Bluetooth, geo location, and file storage) have to
be initialized before the app is opened. This means that even if the user doesn’t require
a particular module, it still has to be initialized at start-up, which can negatively impact
the performance of the app.
Turbo Modules addresses this issue by allowing JavaScript to hold references to the
modules, which means that each module is only loaded when it is required. This
improves the start-up time of React Native apps by reducing the number of modules that
are initialized at start-up. This can significantly improve the overall performance of the
app and provide a better user experience.
In summary, Turbo Modules is a new system for managing modules that was introduced
in React Native version 0.70. It allows JavaScript to hold references to the modules,
which means that each module is only loaded when it is required, significantly improving
the start-up time of React Native apps. This can improve the performance of the app and
provide a better user experience.
● CodeGen: The new architecture of React Native includes a static type checker called
CodeGen, which helps ensure smooth communication between the dynamically typed
JavaScript and the statically typed C++ used in JSI and Turbo Modules.
CodeGen uses the typed JavaScript as the source of truth and defines the interface
elements used by Turbo Modules and Fabric. This allows for better communication
11
between the JavaScript and C++ code, and improves the performance of the app by
reducing the amount of code that needs to be generated at runtime.
CodeGen generates native code at build time, instead of runtime, which improves the
performance of the app by reducing the amount of computation required at runtime. This
results in a faster and more efficient app that performs better and provides a better user
experience.
In summary, CodeGen is a static type checker that was introduced in the new
architecture of React Native. It helps ensure smooth communication between the
dynamically typed JavaScript and the statically typed C++ used in JSI and Turbo
Modules. CodeGen uses the typed JavaScript as the source of truth, generates native
code at build time, instead of runtime which improves the performance of the app by
reducing the amount of computation required at runtime, resulting in a faster and more
efficient app that performs better and provides a better user experience.
12
Getting Started: React Native CLI vs Expo
When starting to work with React Native, one of the first decisions you will need to make is
whether to use Expo or React Native CLI. Both tools have their own advantages and
disadvantages, and the choice between them will depend on your specific needs and goals.
Expo is a toolchain built around React Native that makes it easy to start building a new React
Native app. It provides a set of tools and services that simplify the setup process, allowing you
to start building your app quickly. Expo also provides a managed workflow, which means that
you don't have to worry about setting up the development environment, configuring native
modules, or dealing with platform-specific code. Additionally, Expo provides a set of features out
of the box such as push notifications, camera, and geolocation.
On the other hand, React Native CLI provides a more traditional way of building React Native
apps. It requires you to set up your development environment, configure native modules, and
deal with platform-specific code. This can be more time-consuming, but it also provides more
flexibility and control over your app. React Native CLI is more suitable for advanced developers
who want to have more control over their app and want to use third-party libraries that are not
supported by Expo.
Expo
As we have already mentioned, Expo is a set of tools built on top of React Native that helps
developers with the troubles of dealing with the native side of app development such as Xcode
and Android Studio. It allows developers to focus on the business code logic of their app,
instead of worrying about setting up the development environment and configuring native
modules. It also provides several helpful features such as the ability to build and run the app on
iOS and Android in the cloud, without the need for a Mac machine.
One of the biggest limitations of Expo is that it does not allow for custom native code to be
added to the app, or for changes to be made in the Xcode or Android project. This means that
third-party push notification services, and manual linking of some third-party libraries are not
supported by Expo. Additionally, not all iOS and Android APIs are available, and developers
have to wait for Expo to implement them. You can read about all the existing limitations of Expo
here. You can also see all the pending Feature requests here.
However, there are also several advantages to using Expo. For example, linking of third-party
libraries can be an advantage because it eliminates the need to deal with CocoaPods
installation, which can be messy. Additionally, developers don't need to have their phone
plugged into their machine to build the app, and they can do it over wifi. Deploying the app on
the Apple or Google stores is also much easier, since Expo takes care of most of the necessary
steps.
13
Expo also offers Expo modules, which allows developers to use some Expo features in a React
Native project built with React Native CLI. Additionally, Expo projects can be "ejected" which will
"convert" the Expo app into a real React Native app, allowing developers to continue with React
Native CLI and use all the benefits that React Native provides. However, this process is not
reversible and not recommended. You can learn more about it here.
In summary, Expo is a set of tools built on top of React Native that simplifies the process of
dealing with the native side of app development, such as Xcode and Android Studio, and
provides several helpful features. However, it does not allow for custom native code to be added
to the app, or for changes to be made in
React Native CLI
React Native CLI, on the other hand, is a more advanced option for building React Native apps.
Unlike Expo, it requires developers to be familiar with Xcode and Android Studio, as well as
other tools and processes required for native mobile development such as dealing with Gradle,
CocoaPods, and similar technologies. Setting up the development environment, especially on
Macs with Apple Silicon, can be challenging and you may encounter errors that only appear on
certain types of machines.
React Native CLI is also more suitable for developers who want more control over their app, and
want to use third-party libraries that are not supported by Expo. This includes older third-party
libraries that require manual linking, which means making changes to the code inside the ios
and android folders, and changing properties in the Xcode and Android Studio projects. You can
learn more about Linking Libraries here.
In summary, React Native CLI is a more advanced option for building React Native apps,
suitable for developers who want more control over their app, and want to use third-party
libraries that are not supported by Expo. It requires developers to be familiar with Xcode and
Android Studio, as well as other tools and processes required for native mobile development,
and setting up the development environment can be challenging.
14
Setting up the Development Environment
Setting up the development environment for React Native can be a challenging task, especially
if you're new to mobile app development. It is crucial to read the official environment setup guide
carefully and not to skip any steps. Failure to do so may result in the need to reinstall everything
and start from scratch.
When you open the official environment setup guide, you will have a guide for Expo and a guide
for React Native CLI. Make sure to select the appropriate guide for your needs. The guide for
Expo is relatively straightforward, but for React Native CLI, there are some additional steps that
need to be taken.
If you are using a Mac with Apple Silicon, it is important to be aware that there may be some
issues that can occur during the setup process. These issues are not as common on Windows,
Linux, or Macs with Intel CPUs, but they can happen. It is important to pay extra attention to the
instructions provided in the official guide, and if you encounter any issues, refer to the
troubleshooting section or seek help from the React Native community.
Before diving into the setup process for React Native CLI, there are a few tools that are
essential for a smooth and successful setup.
● Homebrew: For Mac and Linux users, installing Homebrew is highly recommended.
Homebrew is a package manager that makes it easy to install and manage software on
your machine. You can find the installation guide here.
● xCode: For Mac users, installing Xcode is also necessary. It is the official development
environment for iOS and macOS apps. It is important to note that for the latest version of
React Native (v0.70), it is recommended to use Xcode 14.0.1, as there have been some
issues reported with React Native and Xcode 14.1.0.
● Android Studio: For Android development, Android Studio is required. It is the official
development environment for Android apps and the latest version can be downloaded
from the official website.
● Node/Ruby: Additionally, to ensure that you have the right version of Node.js and Ruby,
it is recommended to install NVM (Node Version Manager) and RVM (Ruby Version
Manager) respectively. NVM allows you to easily switch between different versions of
Node.js and manage them on your machine. You can find the installation guide
here.RVM serves the same purpose as NVM but for Ruby. You can find the installation
guide here.
By installing these tools before starting the setup process, you will be better equipped to handle
any issues that may arise during the setup and ensure that your development environment is
set up correctly.
*If you are working on a Mac with Apple Silicon, I would suggest turning on Rosetta mode for
both Terminal and xCode. To do that, in the Finder App, go to the Applications folder, then in the
15
Utilities folder you will find the Terminal app. Right-click on it, and select Get Info then check the
Open using Rosetta, and do the same for xCode, which you can find in the Applications folder.
Once you have set up Rosetta mode, the next step is to install Node and Watchman. It is
recommended to use Homebrew to install them, so in the Terminal app, execute the following
commands (make sure you have installed Homebrew and have restarted the Terminal after
installing it):
brew install node
brew install watchman
It's important to note that these steps are for Mac users only, if you are using Windows or
Linux, please follow the official guide for the specific setup instructions for your
operating system.
iOS Setup
After following the official guide and installing Homebrew, Node and Watchman, the next step is
to install the appropriate Ruby version for the selected React Native version. You can check
which version is required by visiting the official guide and selecting the React Native version
from the dropdown menu. Once you have determined the required version, use RVM to install
and use it by executing the following commands in the terminal:
rvm install 2.7.6
rvm use 2.7.6
After installing the appropriate Ruby version, continue following the official guide and open
xCode. In the preferences, select the Command Line tools. Keep in mind that the version of the
Command Line tools will depend on the version of xCode you are using.
16
Before proceeding, it is important to note that the React Native version you are using may have
different requirements for the Ruby version. Be sure to check the official guide for the specific
version you are working with to ensure you are using the correct version of Ruby.
With that said, once you have installed the required Ruby version, you can proceed to create a
new React Native project using NPX. To do this, execute the following command in the terminal,
replacing "AwesomeProject" with the desired name for your project:
npx react-native init AwesomeProject
If you encounter errors while downloading the template or installing the cocoa pods, try
navigating to the ios folder within your project and running the command `pod install`.
cd ios
pod install
*If you still encounter errors, you may need to switch to a different Ruby version and try
`pod install` again. One version that has been known to work well is 3.1.2. To switch to
this version, navigate to the ios folder within your project and run the following
commands:
rvm install 3.1.2
rvm use 3.1.2
pod install
17
After successfully installing the pods, you can now run the app by executing the command in the
root directory of your project. This will start the Metro bundler in a new terminal window and
launch the iOS simulator with your newly created app running inside it:
npx react-native run-ios
However, if you encounter an error stating that the simulator with a certain name is not found, or
if you want to run the app on a different simulator, you can do so by opening xCode and
launching the simulator manually. To do this, right-click on xCode in the Dock and select "Open
Developer Tool" then "Simulator". From there, you can select the desired simulator from the top
of the Simulator app. You can also specify the simulator by its name when running the app with
the command
npx react-native run-ios --simulator='iPhone SE (2nd generation)'
18
It's important to mention that, even though this guide should help you with most of the issues
you may encounter, some problems may still appear, because of different versions of the tools,
or different configurations of the machine. But don't worry, the React Native community is huge,
and you can always find some help on the official documentation, or on the forums like Stack
Overflow.
Android Setup
Before moving forward with the Android setup for React Native, it's important to ensure that you
have the necessary tools installed. The first step is to install the Java Development Kit (JDK).
This can be done easily by using Homebrew, a package manager for MacOS and Linux. To
install JDK, open your terminal and run the following commands:
brew tap homebrew/cask-versions
brew install --cask zulu11
After JDK is installed, you need to install the Android SDK. This can be done by downloading
and installing Android Studio, the official IDE for Android Development. Once Android Studio is
installed, open it and navigate to the SDK Manager. From there, select the Android SDK version
specified in the React Native guide and install it. Additionally, it's also recommended to install
the Android SDK Command-line tools, which can be found in the SDK tools tab in the SDK
Manager.
19
Next, you will need to add some system environment variable paths, so you can run the project
from the command line. One way to do this is by using VSCode. To set the environment variable
paths, you will need to edit the .zshrc file with admin permissions. To do this, open your terminal
and navigate to the home folder, then execute the following command:
sudo code .zshrc
If you get an error message saying that code cannot be found, open VSCode, press
cmd+shift+P and type "shell command" until you see the "Shell Command: Install 'code'
20
command in PATH" option and press enter. After that, restart the terminal and you should be
able to run the "code" command inside the terminal.
After that add those paths in the file:
export JAVA_HOME=/Applications/"Android Studio.app"/Contents/jre/Contents/Home
export ANDROID_HOME=$HOME/Library/Android/sdk
export PATH=$PATH:$ANDROID_HOME/emulator
export PATH=$PATH:$ANDROID_HOME/tools
export PATH=$PATH:$ANDROID_HOME/tools/bin
export PATH=$PATH:$ANDROID_HOME/platform-tools
Then, save the file, and execute the following command in the terminal:
source .zshrc
After setting up the environment variables, you can try running your application by executing the
following command in the terminal:
npx react-native run-android
If the setup was done correctly, the Android emulator should start after a few minutes and your
app should start running inside it. If you encounter an error stating that the metro bundler is not
running, simply open the terminal and navigate to the root of your project, then run:
npm start
or:
yarn start
if you are using yarn.
After that, reload the app in the emulator (there will be a Reload button below the error in the
emulator) or simply quit and start the app again. If you still encounter an error, try running the
following adb command in the terminal:
adb reverse:8081 tcp:8081
and then reload the app again.
After that, reload the app again, and it should work.
If for some reason the app doesn't build and start from the command line, it means that there is
an issue with the environment setup. You can try opening the android folder of your app inside
21
Android Studio, wait for gradle to sync and download all the dependencies, and then click the
green arrow to start the project.
If you still encounter issues, you can refer to the Troubleshooting page, which can help you
solve further problems, you can check it here.
Folder Structure of a React Native project
If you check the newly created React Native project, you will notice multiple files and folders,
and in the following text, I will try to explain those files and folders.
● __tests__: This folder contains all the tests for your application.
● android: This folder contains the Android native code for your project. Any changes to
the Android specific parts of the project such as linking libraries, adding permissions,
custom fonts, etc. should be made in this folder.
● ios: Similar to the android folder, this folder contains the iOS native code for your project.
● src: This folder serves as the root for all your source code. It contains all the JavaScript
and React-related code for your application.
● App.js: This is the entry point for your app, and it is the first component that will be
mounted and rendered.
● app.json: This file contains some configuration for your app, such as its name and other
properties that are referenced in the index.js file.
● babel.config.js: This file contains the configuration for the Babel transpiler, which
transpiles the React syntax code to something that JavaScript engines can understand.
You can find out more here.
● Gemfile: This file contains all the Ruby dependencies needed for your application.
● Index.js: This is the entry point for your application, where you specify which component
should be mounted and rendered first.
● metro.config.js: This file contains configuration for the metro bundler, which is used for
bundling your application. You can find out more here.
● package.json: This file contains all the node dependencies and other properties related
to your application. You can find out more here.
My common practice is to add the “engine” object inside the package.json, where I specify node
and yarn version, so when other developers join the project, and try to run yarn install or npm
install, the error will pop up if they don't have the same version installed, and this is to make
sure all developer work in the same setup:
"engines": {
"node": "v16.10.0",
"yarn": "1.22.19",
}
If you are not sure how to structure your new project, here and here you can find some best
practices that cover that topic more deeply.
22
xCode and Android Studio
As I have mentioned previously, while working with React Native CLI, unlike Expo, from time to
time you have to deal with xCode and Android Studio to solve different problems. Here I will give
you a short introduction to both IDEs, and the most necessary things you need to know in both.
xCode
Xcode is the official Integrated Development Environment (IDE) for iOS and macOS
development. It is a powerful tool that allows developers to create, design, and test their
applications for Apple platforms. With Xcode, you can create user interfaces, write code, and
debug your applications with ease. It provides a wide range of features that are essential for iOS
development such as a visual editor, a code editor, a debugging tool, and an integrated testing
framework.
Xcode also includes several other tools that are useful for iOS development, such as the
Interface Builder, which is a visual editor for creating user interfaces, and the Simulator, which
allows you to test your applications on different iOS devices. Additionally, Xcode has a built-in
Git integration, which allows you to easily manage and track changes to your codebase.
23
The leftmost panel is the Project Navigator (Project Structure), which allows you to navigate
through the different files and folders in your project. The center panel is the Editor area, where
you will write and edit your code. The rightmost panel is the Utilities area, which contains a
number of different tools and inspectors that you can use to further customize and debug your
project (in our case it is closed and not visible right now).
In the top of the screen, you will find the toolbar, which contains various buttons and controls
that allow you to perform various tasks, such as running your app in the simulator, debugging
your code, and more.
It is important to note that when opening your React Native iOS project in Xcode, you should
open the workspace file (.xcworkspace) rather than the project file (.xcodeproj) as the
workspace file contains the pods (dependencies) that are necessary for your project to run.
Additionally, after opening the project in Xcode, you will have to make sure that the pods are
installed. If not, you may see some errors and will have to go to the terminal and run the
command "pod install" in the ios folder of your project.
After opening the project in xCode, you will see something like the picture bellow:
If you select the Project from the Project Structure, you will see some more options, like on the
picture bellow:
24
If you want to run your application in a Release mode, without the need of the metro bundler
running in the background, you will select the project name in the top of xCode:
And select Edit Scheme… from there, and then you will see something like this:
25
From here, you can select the Build Configuration as Release and then run the project. This will
allow you to run the app on a device without being connected to your computer. Keep in mind
that if you don't have an Apple Developer account and have paid the annual fee of $100, you
will only be able to use Temporary Certificates and Provisioning Profiles for your app. These will
expire after one week, and you will need to reinstall the app or it will no longer be able to run.
Additionally, there is a limit on how many bundle IDs you can register per week, so it's best to
use one bundle ID for all test apps you create or use a bundle ID from a previous app when you
are ready to release.
To add additional capabilities such as permissions or custom fonts, you will need to edit the
Info.plist file located at PROJECT_ROOT/ios/PROJECT_NAME/Info.plist. This can be done
either by using a text editor like VSCode or by opening the file in Xcode. From here, you can
add new properties by clicking the "+" button under the Info tab and selecting the desired
property from the dropdown.
26
If you want to change the icon of your iOS app manually (there are some npm packages to help
you with this, like this one), open the project with xCode, then from the project structure select
PROJECT_NAME/PROJECT_NAME/Images. Then you will need your app icon in multiple
dimensions, so drag and drop all the files in the right place.There are also some online tools like
this one, that will auto generate all the icon dimensions for you, just upload the 1024x1024
version, and click generate. Then download the zip file, unzip it, rename the Assets.xcassets to
Images.xcassets and replace the Images.xcassets file located in your ios folder with the one
that is located in the file you have downloaded.
Here you can find some useful tips and tricks regarding xCode usage.
Android Studio
Android Studio is the official IDE for Android development, developed by Google. It is based on
JetBrains IntelliJ IDEA and offers a wide range of features that are essential for Android
development, such as a visual editor, a code editor, a debugging tool, and an integrated testing
framework.
27
Android Studio also includes several other tools that are useful for Android development, such
as the Android Virtual Device (AVD) Manager, which allows you to create and manage virtual
devices for testing your applications, and the Android Emulator, which allows you to test your
applications on different Android devices. Additionally, Android Studio has a built-in Gradle
integration, which allows you to manage dependencies and build your application with ease.
Now we will take a look at the Android World, and the Android Studio. On the welcome screen,
in the More Actions dropdown, you will find the most of the tools you will need. The most
important will be the Virtual Device Manager, which is the Simulator alternative from the iOS
world. From there you can launch and manage your Android Emulators. If your development
environment is setted up correctly, you can also launch the emulator from the Terminal, just
execute the following command to list all the emulators:
emulator -list-avds
28
Then execute the following command to start the emulator (make sure you have the '@' symbol
before the emulator name):
emulator @some_android_emulator
If you open the android folder with Android studio, gradle project will start syncing, which may
take few minutes, and then you will see this screen:
If you want to run your application in a Release mode, without the need of the metro bundler
running in the background, you will select the Build Variants from the left menu (it's shown in the
picture above, below the project structure), and from the dropdown select ‘Release’. Then try
running the app:
29
To change the app icon we will use the files from the site that generated the files from us. In the
same file, there is also an android folder with some files inside, so just copy those files, and
paste them over the existing ones in ‘PROJECT_ROOT/android/app/src/main/res’. Then try to
run the app, if some error appears that says something like ‘error: resource
mipmap/ic_launcher_round not found’, open the AndroidManifest.xml which is located under
PROJECT_NAME/app/manifests/AndroidManifest.xml, and remove the
‘android:roundIcon="@mipmap/ic_launcher_round"’, which is optional. You can also modify
some capabilities of the app in this file, same like we did in the Info.plist for iOS.
Here you can find some useful tips and tricks regarding Android Studio usage.
30
React Native Core Components
So to make one thing clear, unlike ReactJS where we have JSX that looks and feels like HTML,
here we don’t have that. Although once you get used to it will feel the same, we are dealing with
predefined components/tags like we have with JSX, but they differ a bit.
The writing of the JSX is the same, you have components, that unlike ReactJS, here we import
them either from ‘react-native’ or from some third party library. We can also have props inside
them, and values between tags.
Unlike ReactJS, React Native does not use JSX that resembles HTML. Instead, it uses
predefined components/tags that are imported from either 'react-native' or third-party libraries.
These components have props and values similar to JSX.
React Native provides a wide range of core components, and you can also find many more
online. Some of these components are platform-specific, meaning they are shared on both
Android and iOS, while others are specific to either iOS or Android. Additionally, some of the
props available are platform-specific, so it's important to keep that in mind when building your
app.
Here are some of the most commonly used core components provided by React Native:
31
● View: A basic container for other components. It can be used to create layouts, apply
styles, and handle user interactions.
● Text: A component for displaying text on the screen. It supports styling, such as bold,
italic, and underlining, as well as text wrapping.
● TextInput: A component for receiving user input, such as text, numbers, or password. It
supports various features such as keyboard type, placeholder, and validation.
● Button: A component for creating buttons with various styles and behaviors. It supports
features such as onPress, onLongPress, and disabled.
● Image: A component for displaying images on the screen. It supports various features
such as source, style, and resize mode.
● FlatList: A component for displaying lists of data. It supports features such as scrolling,
refreshing, and pagination.
● Alert: A component for displaying alerts and dialogs. It supports features such as title,
message, buttons, and callbacks.
● ActivityIndicator: A component for displaying a loading indicator. It supports features
such as size, color, and animation.
React Native also allows developers to use third-party libraries and components to add
additional functionality to their apps. These can be installed using npm or yarn and are a great
way to add features such as navigation, forms, and animations.
It's important to note that some React Native components and props are platform-specific,
meaning they are only available on either iOS or Android. This is something to keep in mind
when building your app as it may affect the way you structure and design your components.
In conclusion, React Native core components are a powerful tool for building cross-platform
mobile apps and can be customized as per need. With the help of third-party libraries,
developers can easily add additional functionality to their apps, making React Native a versatile
and efficient framework for mobile app development.
32
Styling
React Native uses Flexbox for styling and does not use pixels, but instead uses
density-independent pixels (dp or dip). This allows for consistent styling across different screen
densities and resolutions.
When it comes to styling React Native applications, there are three main options to consider:
● React Native Stylesheet object: This is the built-in way of styling in React Native and
allows for the creation of stylesheets that can be applied to components. Stylesheets
can be created using JavaScript objects and have a similar syntax to CSS. You can
learn more here.
● Styled Components: This is a popular library that allows for the creation of reusable
and composable component-based styles. It uses a syntax similar to CSS-in-JS and
allows for dynamic styling based on the component's props. You can learn more here.
● Emotion: This is another popular library that allows for the creation of component-based
styles using a similar syntax to CSS-in-JS. It also supports server-side rendering and
has a smaller bundle size compared to Styled Components. You can learn more here.
There are few more that you may consider:
● Restyle: The Restyle library provides a type-enforced system for building UI components
in React Native with TypeScript. It's a library for building UI libraries, with the ability as
the core focus.
● Tamagui: Tamagui introduces a novel optimizing compiler for React that evaluates your
code at build-time, turning heavy JS into flatter trees and much faster CSS. The result is
more codeshare %, less dev time, and lighter, faster apps.
● NativeWind: NativeWind is built upon the Tailwind CSS style language. As such the
core-concepts of Tailwind CSS apply to NativeWind.
● Dripsy: Dripsy is a responsive design system for. @expo. + @reactnative. web with one
goal: style once, run anywhere.
● NativeBase: NativeBase is an accessible, utility-first component library that helps you
build consistent UI across Android, iOS and Web.
You can find more info about their differences here.
When deciding on the styling library to use, it's important to consider the specific requirements
of the project and the skillset of the development team. All of these libraries are widely used and
well-documented, and any of them can be used to effectively style React Native applications.
In addition to the above options, there are also other styling libraries available for React Native
such as Glamorous, Aphrodite, and Radium. It's a good idea to do some research and compare
the different options to find the one that best fits your needs.
33
Another important thing to consider is the accessibility of your app, as some libraries handle
accessibility better than others. It's important to follow best practices and guidelines to ensure
that your app can be used by people with disabilities.
In conclusion, React Native provides multiple options for styling your application, each with its
own benefits and trade-offs. It's important to do your own research, understand your project
requirements, and pick the one that fits your needs best.
34
Platform Specific Code
When developing cross-platform apps, it is often necessary to handle different behaviors and
styles for different platforms. React Native provides two options for handling platform-specific
code:
● The Platform module from react-native: This module provides several static methods that
can be used to check the platform, such as Platform.OS, Platform.Version, and
Platform.select. These methods can be used in conjunction with ternary operators to
conditionally render different code depending on the platform.
● Platform-specific extensions: This approach involves creating multiple files, one for each
component, with a specific extension, and React Native will load the right one depending
on the system. For example, if you want a separate Button component for iOS and
Android, you can create two files:
○ Button.ios.js
○ Button.android.js
This way, you can write the components as separate, unique components and won’t have to do
any platform checks in them. This approach is particularly useful when the code for each
platform is vastly different and using the Platform module would lead to a large, chaotic
component.
It's worth noting that there are also platform-specific extensions for Windows and macOS
(.windows.js and .macos.js).
When deciding which approach to use, it's important to consider the complexity of the
platform-specific code. Using the Platform module is useful for small differences between
platforms, but when the code differences are large and complex, the platform-specific
extensions approach is more appropriate.
In conclusion, React Native provides several options for handling platform-specific code, such
as the Platform module and platform-specific extensions. By understanding the different options
available and the complexity of the platform-specific code, developers can make an informed
decision on which approach to use, and write efficient and maintainable code.
You can learn more about handling platform specific code here.
35
Permissions
When we want to use some extra device capabilities, we need to inform the user that our
application will need that permission in the Application Store, and we need to ask the user for
that permission.
iOS
In iOS we can specify the new permissions in the Info.plist file
(PROJECT_ROOT/ios/PROJECT/_NAME/Info.plist), and we can edit that file either with some
code/text editor, or from within xCode. To add for Example camera permissions we need to add
this two properties in the Info.plist file:
<key>NSCameraUsageDescription</key>
<string>we need to use the camera to take some Photos</string>
As you can tell, the properties go in pairs, where the key value is very important, and under the
string we need to describe why we need that permission with our own words.
Android
For android we are adding the permissions in the AndroidManifest.xml
(PROJECT_ROOT/src/main/AndroidManifest.xml), and to add the camera permission for our
app, we need to add this properties in the AndroidManifest:
<uses-permission android:name="android.permission.CAMERA" />
And we add the permissions before the <application> property but inside the <manifest> one.
36
Adding custom Fonts
Adding a custom font was a little bit challenging before React Native v0.69 (before 0.60 it was
even harder, you can read more about it here), but with React Native v0.69, the
react-native-assets command was added for the npx, so with running that command, the new
assets will be automatically linked.
So let's say we want to add the Roboto font into our app. We can download that font from
Google Fonts here. After downloading it, create a folder called assets/fonts in the root of our
project.
Than create a file called react-native.config.js in the root of our project, with the following
content:
module.exports = {
project: {
ios: {},
android: {},
},
assets: ['./assets/fonts/'],
};
Next is to link the assets, so run the following command from the root of our project:
npx react-native-asset
The terminal will ask you to install the react-native-asset dependency, enter Y and it will install it.
Now simply change the fontFamily for some of the style objects, and you will see it with the new
font:
fontFamily: 'Roboto',
37
Navigation
When we want to introduce multiple screens to our application with some nice navigation
capabilities I would suggest using this third party library, which is used by most of the
developers.
Installing
To begging, we first need to install the react-navigation package by executing this command in
the terminal (I am simply following the getting started guide which you can find here):
npm install @react-navigation/native
This package depends on some other dependencies, so we need to install those too:
npm install react-native-screens react-native-safe-area-context
Then we need to make some changes in the android project, so open the MainActivity.java
(which is located in android/app/src/main/java/PROJECT_NAME/MainActivity.java), and in the
MainActivity class add the following code:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(null);
}
And don't forget to add the needed import on the top of MainActivity.java:
import android.os.Bundle;
Now you can try running both iOS and Android apps, by running yarn run ios and yarn run
android (these are short commands you can use instead of using npx react-native, and you can
use them with yarn or npm).
Add stack screen navigation
We can think of a Stack navigation as an Array, where we are maintaining the screens in the
Stack navigation by pushing and popping different screens, you can read more about it here.
38
To use the stack navigation we need to instal the native-stack dependency:
yarn add @react-navigation/native-stack
And after that we need to update the pods by executing pod install in the ios folder of the
Project.
Then we need to create our Stack, and you can do this outside our App component for example,
like this:
const Stack = createNativeStackNavigator();
function App() {
.
.
.
Next we need to wrap our entire App in a NavigationContainer and its best practice to do this in
the App.js. Then we can start creating our Stack navigation:
function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen
name="Home"
component={HomeScreen}
options={{title: 'Overview'}}
/>
<Stack.Screen
name="Details"
39
component={DetailsScreen}
options={{title: 'Info'}}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
As you can see, first we need to put all our Screens inside a Stack.Navigator where we can also
define our initialRoute, which will be our Home screen in our case, and our screens are
identified by the name property, so make sure that the names of our screens are unique and
have in mind that they are case sensitive. Then as we can already see from the code above, we
are defining all our screens for this Stack navigator where we provide the name and the
component for every screen, and we can also add some options to it, in our case we re
modifying the title which we can see on the top of the screen, and in our case we have change
the ‘Home’ to ‘Overview’ (the name value will be the Screen title by default), you can read more
about the different screen options here:
40
The components we use for the screen are normal components, in which you can also access
the navigation prop which can be used for manipulating the Screen stack:
function HomeScreen({navigation}) {
return (
<View style={styles.screenContainer}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}
From the example above you can see that we can use the navigation prop object to navigate to
a different screen, the Details screen in our example, and by calling the navigate() function we
are simply pushing the DetailsScreen on the top of our Stack ‘array’.
We can also send some extra info to our screens when navigating to them like this:
navigation.navigate('Details', {
itemId: Math.floor(Math.random() * 100),
otherParam: 'anything here take two',
});
And we can access the data we sent from the route prop that we can access from our screen
like this:
function DetailsScreen({navigation, route}) {
const {itemId, otherParam} = route.params;
return (
<View style={styles.screenContainer}>
<Text>Details Screen</Text>
<Text>otherParam: {JSON.stringify(otherParam)}</Text>
<Text>itemId: {JSON.stringify(itemId)}</Text>
Here is the entire code of our simple Stack example:
import * as React from 'react';
import {Button, View, Text, StyleSheet} from 'react-native';
import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
function HomeScreen({navigation}) {
return (
<View style={styles.screenContainer}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
41
onPress={() =>
navigation.navigate('Details', {
itemId: Math.floor(Math.random() * 100),
otherParam: 'anything you want here',
})
}
/>
</View>
);
}
function DetailsScreen({navigation, route}) {
const {itemId, otherParam} = route.params;
return (
<View style={styles.screenContainer}>
<Text>Details Screen</Text>
<Text>otherParam: {JSON.stringify(otherParam)}</Text>
<Text>itemId: {JSON.stringify(itemId)}</Text>
<Button
title="Go to Details... again"
onPress={() =>
navigation.navigate('Details', {
itemId: Math.floor(Math.random() * 100),
otherParam: 'anything here take two',
})
}
/>
<Button title="Go back" onPress={() => navigation.goBack()} />
</View>
);
}
const Stack = createNativeStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen
name="Home"
component={HomeScreen}
options={{title: 'Overview'}}
/>
<Stack.Screen
name="Details"
component={DetailsScreen}
options={{title: 'Info'}}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
42
export default App;
const styles = StyleSheet.create({
screenContainer: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
});
Add Bottom Tab navigation
Another type of navigation we can use in our app is the Tab navigation, and in this document I
will only cover the bottom tab navigation, but react-native-navigation provides multiple APIs for
tab navigation:
● Bottom Tabs: A simple tab bar on the bottom of the screen.
● Material Bottom: Tabs A material-design-themed tab bar on the bottom of the screen.
● Material Top Tabs: A material-design-themed tab bar on the top of the screen.
To add bottom tab navigation to our app first we need to install the needed dependencies:
yarn add @react-navigation/bottom-tabs
And install the pods by running pod install inside the ios folder.
Next we will modify the previous example and add a Bottom Tab Navigation with two tabs, and
we will keep the stack navigation from the previous example too, and our example will look
something like this:
43
To begging we will need to create the Bottom Tab Navigator in the similar way we did with the
Stack Navigator:
const Tab = createBottomTabNavigator();
Next we will move the JSX from the HomeScreen into a new Component and we can call it
HomeTab and in the HomeScreen we will put our Tab Navigation like this:
function HomeScreen() {
return (
<Tab.Navigator
44
screenOptions={{
tabBarActiveTintColor: '#d2e245',
tabBarActiveBackgroundColor: '#20434f',
tabBarInactiveBackgroundColor: '#20434f',
headerStyle: {
backgroundColor: '#20434f',
},
headerShadowVisible: false,
headerTintColor: '#d2e245',
}}>
<Tab.Screen name="Home" component={HomeTab} />
<Tab.Screen name="Settings" component={SettingsTab} />
</Tab.Navigator>
);
}
As you can see we have something similar like with the Stack Navigation, and we put our
screens inside a Tab.Navigator. We can also change some options for our Tab.Navigator within
the screenOptions object.
The final code of our App.js looks something like this:
import * as React from 'react';
import {Button, View, Text, StyleSheet} from 'react-native';
import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
const Stack = createNativeStackNavigator();
const Tab = createBottomTabNavigator();
function HomeScreen() {
return (
<Tab.Navigator
screenOptions={{
tabBarActiveTintColor: '#d2e245',
tabBarActiveBackgroundColor: '#20434f',
tabBarInactiveBackgroundColor: '#20434f',
headerStyle: {
backgroundColor: '#20434f',
},
headerShadowVisible: false,
headerTintColor: '#d2e245',
}}>
<Tab.Screen name="Home" component={HomeTab} />
<Tab.Screen name="Settings" component={SettingsTab} />
</Tab.Navigator>
);
}
function HomeTab({navigation}) {
45
return (
<View style={styles.screenContainer}>
<Text>Home Tab</Text>
<Button
title="Go to Details"
onPress={() =>
navigation.navigate('Details', {
itemId: Math.floor(Math.random() * 100),
otherParam: 'anything you want here',
})
}
/>
</View>
);
}
function SettingsTab({navigation}) {
return (
<View style={styles.screenContainer}>
<Text>Settings Screen</Text>
<Button
title="Go to Details"
onPress={() =>
navigation.navigate('Details', {
itemId: Math.floor(Math.random() * 100),
otherParam: 'anything you want here',
})
}
/>
</View>
);
}
function DetailsScreen({navigation, route}) {
const {itemId, otherParam} = route.params;
return (
<View style={styles.screenContainer}>
<Text>Details Screen</Text>
<Text>otherParam: {JSON.stringify(otherParam)}</Text>
<Text>itemId: {JSON.stringify(itemId)}</Text>
<Button
title="Go to Details... again"
onPress={() =>
navigation.navigate('Details', {
itemId: Math.floor(Math.random() * 100),
otherParam: 'anything here take two',
})
}
/>
<Button title="Go back" onPress={() => navigation.goBack()} />
</View>
);
46
}
function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen
name="Home"
component={HomeScreen}
options={{title: 'Overview'}}
/>
<Stack.Screen
name="Details"
component={DetailsScreen}
options={{title: 'Info'}}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;
const styles = StyleSheet.create({
screenContainer: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
});
There is also a Drawer Navigation but I won’t write about it here, you can learn more here.
Deep Links
https://medium.com/bumble-tech/universal-links-for-android-and-ios-1ddb1e70cab0
https://medium.com/@ertemishakk/implement-universal-links-in-react-native-d3602ae6ea2
https://www.bam.tech/article/how-to-make-a-complete-app-site-association-with-universal-links
https://blog.logrocket.com/understanding-deep-linking-in-react-native/
Now we are going to take a look at one nice feature that we can add to our app which is called
deep links.
Deep linking allows users to access specific pages, products, or actions within an app directly
from a link, rather than having to navigate through the app to find the content. This can make
the user experience more seamless, as users are taken directly to the content they are looking
for.
Deep links can also be used to personalize the user experience by pre-filling forms or
automatically logging users into the app.
47
Deep linking can also be used for marketing and advertising purposes, such as by allowing
advertisers to direct users to a specific page within an app to encourage them to make a
purchase or by allowing app developers to track user behavior within the app.
Deep links can be used within apps or across different apps, which means that a user can be
directed to a specific location within an app even if they were not previously using that app.
Deep linking can be implemented using various technologies, such as Universal Linking (iOS),
App Link (Android) and URI Schemes.
Universal Linking (iOS) is a feature that allows developers to associate their website with their
iOS app, so that when a user taps a link to the website on an iOS device, the corresponding
page in the app will open instead of the website. This allows for a seamless user experience, as
users are taken directly to the content they are looking for within the app.
App Link (Android) is similar to Universal Linking, but for Android devices. It allows developers
to associate their website with their Android app, so that when a user taps a link to the website
on an Android device, the corresponding page in the app will open instead of the website.
URI Schemes are a way to launch an app using a specific URL format. By using a specific URL
format, an app can be launched and directed to a specific location within the app. For example,
the URL "myapp://product/1234" could open the "My App" app and take the user directly to the
product page for product 1234.
Deep links can also be used in push notifications, email and social media campaigns. By
including a deep link in a notification or email, users can be directed to a specific location within
an app, even if the app is not currently running on their device.
In summary, deep linking is a powerful tool that allows users to access specific pages, products,
or actions within an app directly from a link, and also allows developers to track user behavior,
personalize the user experience and to use it for marketing and advertising purposes. It can be
implemented using various technologies such as Universal Linking (iOS), App Link (Android)
and URI Schemes.
Now we are going to follow the React Navigation guide for implementing deep links which can
be found here.
Basically our idea is to open our app and some specific screen and maybe pass some data
which can be used on that screen, same like we do it on the web, for example on our website
we can have some url like this https://www.example.com/details/?itemId=123 and in our code
we can pick up the query string “?itemId=123” and we can use that itemId and its value on our
details page.
The idea with the deep links its the same, we want to have a custom “protocol” (URI scheme)
and we can name it whatever we want, and for our example we will use “melonapp://” and use
that to access our app, for example we can put this link on some website
48
“myapp://details/?ItemId=123” and if we click on that link from our phone, our app will open to
the details screen and we can access the itemId we have passed in the deep link and show it on
the screen.
So let's start. If we follow the documentation, it says that first we need to make some changes in
the ios project.
Open the AppDelegate.mm with VsCode or xCode and first import RCTLinkingManager.h (make
sure you put it before “#if RCT_NEW_ARCH_ENABLED” or your app won't build):
And add this peace of code at the end of the file, before the @end:
// Add this inside `@implementation AppDelegate` above `@end`:
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
return [RCTLinkingManager application:application openURL:url
options:options];
}
49
Next we need to add our custom uri-scheme, so we can either do it manually from xcode, or
from the terminal, and in our case I will use the terminal. To do that, execute the following
command from the root of our project:
npx uri-scheme add melonapp --ios
To test if everything works we can run the following command from our terminal:
npx uri-scheme open melonapp:// --ios
If you have done everything right the popup will appear to open the link into your app, or the app
will start automatically.
To setup the deep link for android, simply run the following command from the root of our
project:
npx uri-scheme add melonapp --android
And now if you run the following command the app should start:
npx uri-scheme open melonapp:// --android
You can also add this link to a note or a contact on your device (ios/android) or the simulator,
and when you click on that link the app should start, but have in mind that if you type the link in
the browser it won't work, it only work if the link is clicked and handled by the OS.
50
For this example we will add two deep links, one which we can use to go to the settings screen,
and one for the details screen on which we will pass the itemId.
First we need to add some configuration for our deep links:
const config = {
screens: {
Home: {
screens: {
Settings: 'settings',
},
},
Details: 'details/:itemId',
},
};
const linking = {
prefixes: ['melonapp://'],
config,
};
In our config object we have our routes configured, and since our Setting screen is a screen
from a nested navigation in our Home screen, first we need to add the Home screen and inside
its screens we add the Settings. Have in mind that the property names in this object (“Home”
and “Settings” must be exactly the same as the name property of the actual screen in the
navigation).
To add a parameter in our deep link we use SCREEN/:PARAMETER_NAME, or in our case we
want to pass itemId to our details screen or in our case “melonapp://details/123” and in our code
we will have the item ide under route.params.itemId.
As a final part we add the linking object as a part to our NavigationContainer and we are done:
<NavigationContainer linking={linking}>
Now if we execute the following command from the terminal:
npx uri-scheme open melonapp://settings --ios
The setting screen will open in our app, and if we execute the following one:
npx uri-scheme open melonapp://details/1414 --ios
The details screen will open and we will have the 1414 value printed in its place.
51
52
Push Notifications
https://enappd.com/blog/firebase-push-notifications-in-react-native/81/
https://developers.connectycube.com/reactnative/push-notifications
Introduction
Push notifications are messages or alerts delivered by an application to a device, even when
the user is not actively using the app. They are typically used to inform the user of new events
or updates within the app, such as receiving a message or a friend request. These notifications
can appear on the lock screen or in a notification center, and can also include sounds or
vibration alerts. They are often used to keep users engaged with an app and to remind them to
open it.
Push notifications can be used for a variety of purposes such as to inform the user of new
events, updates, or messages within the app, to remind the user to take an action within the
app, or to provide personalized recommendations or deals. They are a powerful tool for keeping
users engaged with an app and increasing app retention.
However, with great power comes great responsibility. Push notifications, if not implemented
well, can quickly become a nuisance and lead to users disabling or uninstalling the app. It is
important for developers to strike the right balance between providing useful and relevant
information, without overwhelming the users with too many notifications or irrelevant messages.
Push notifications are delivered through a service called a push notification service, which is
provided by the operating system or a third-party service. The service is responsible for routing
the notification to the correct device and displaying it to the user.
Push notifications have become an essential part of the mobile ecosystem, allowing apps to
communicate with users in real-time and providing them with relevant and timely information.
These notifications are delivered to a user's device even when the app is not actively being
used, and can appear on the lock screen or in a notification center. They can also include
sounds or vibration alerts to draw the user's attention.
https://www.desuvit.com/step-by-step-guide-for-implementing-push-notifications-in-ios-using-rea
ct-native/
Implementation
Before we start we need to prepare a few things. First is the Firebase Account. You can register
here. Next is to create a Firebase Project, and to do that, go on the firebase console page and
from there click on the Add project button and follow the instructions.
53
After your project is created, open the project, and click on it, and you will see like this:
After this we will need to create separate firebase apps for iOS and Android.
54
iOS Setup
To create an ios app click the iOS+ button, and to complete this we will need a paid apple
developer account where we can create a new bundle id for our app, and you can do that on the
apple developer site, in the Identifiers section click the + button, from the next screen select
“App IDs”, next select “App” (not “App Clip”), and from the final screen you can enter a
description for this bundle id, and in the “Bundle ID” make sure that Explicit is selected, and
enter your bundle id there, and from the Capabilities make sure that “Push Notifications” is
selected.
Now you can complete the creation of the Firebase App by entering your newly created bundle
id, and the end you can download the GoogleService-Info.plist file:
55
After this you will need to open our React Native project with xCode (the ios folder) and you can
drag the plist file in the folder where the AppDelegate files are (make sure copy if needed is
selected from the windows that appears when you drop the file):
Next we will need to create a Key from our apple developer account, and now instead of
Identifiers, go in the Keys section, and press the + button:
On the next screen make sure that you have “Apple Push Notifications service (APNs)”
selected, enter a Key Name and Click Continue. With this your Key will be created and you will
need to download it, which will download a .p8 file, and you will also need the Key ID which you
can copy from this page.
56
Now go back to the Firebase console page, and from your project page, select the gear button
next to the Project Overview:
From here go in the in the “Cloud Messaging” tab, and scroll to the “Apple app configuration”
section, and here click the Upload button inside the APNs Authentication Key:
57
Click the Upload button, and from the next screen attach the p8 file we have downloaded when
generating the Key on the apple developer account, and enter the KeyID which we had on the
same page where we have downloaded the p8 file:
Now again go back in xCode, and first make sure you have updated the bundle id in the Signing
and Capabilities:
From the same screen click the “+ Capability” button to add a new capability for our App, and
from that screen search for Push Notifications and add it by double clicking on it, after that add
one more, and this time search for “Background Modes” and add that one. To finish this, scroll
58
to the end of this window where you will see the Capabilities you have added and in the
Background Modes make sure “Background Fetch” and “Remote Notifications” is checked:
With this our Firebase App is ready for iOS, and now we can focus on our code. To implement
Push notifications we are going to use a package called react-native-firebase-push-notifications,
and you can follow the installation guide from their page, which is just a dependency installation
with npm or yarn, and pod install after that. After this we will need to make some changes in
some files in the ios folder.
First open the AppDelegate.mm file and just before #if RCT_NEW_ARCH_ENABLED add the
following imports:
#import "Firebase.h"
#import "RNFirebaseMessaging.h"
#import "FirebasePushNotifications.h"
Next after the @implementation AppDelegate add the following lines:
- (void)application:(UIApplication *)application
didReceiveLocalNotification:(UILocalNotification *)notification {
[[FirebasePushNotifications instance] didReceiveLocalNotification:notification];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(nonnull
NSDictionary *)userInfo
fetchCompletionHandler:(nonnull void
(^)(UIBackgroundFetchResult))completionHandler{
[[FirebasePushNotifications instance] didReceiveRemoteNotification:userInfo
59
fetchCompletionHandler:completionHandler];
}
- (void)application:(UIApplication *)application
didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
[[RNFirebaseMessaging instance] didRegisterUserNotificationSettings:notificationSettings];
}
And finally locate the didFinishLaunchingWithOptions method and add the following lines:
[FIRApp configure];
[FirebasePushNotifications configure];
This is how it look like in my code:
Next we are going to do the JavaScript part. Open the App.js file and in our App components (or
whichever components is first in your app), import the following dependency:
import {notifications} from 'react-native-firebase-push-notifications';
Next the flow for our Push Notifications is the following one:
1. Get the Push Notifications Token
2. Check if the Push Notification permissions are granted, and if not ask for Permissions
3. If permissions are granted start listening for permissions
So our entire code for this will look something like this:
function App() {
const [token, setToken] = React.useState();
const [permissionGranted, setPermissionGranted] = React.useState(false);
React.useEffect(() => {
60
// get token
getToken().then(t => {
console.log(`----- TOKE: ${t}`);
setToken(t);
});
// check for permission and request if necessary
hasPermission().then(async granted => {
if (!granted) {
await requestPermission().then(() => {});
} else {
setPermissionGranted(true);
onNotificationListener();
onNotificationOpenedListener();
getInitialNotification();
}
});
}, [token, permissionGranted]);
const hasPermission = async () => {
//only works on iOS
return await notifications.hasPermission();
};
const requestPermission = async () => {
try {
const granted = await notifications.requestPermission();
if (granted) {
setPermissionGranted(true);
onNotificationListener();
onNotificationOpenedListener();
getInitialNotification();
}
} catch (error) {
console.log(error);
}
};
const getToken = async () => {
//get the messaging token
const _token = await notifications.getToken();
//you can also call messages.getToken() (does the same thing)
return _token;
};
const getInitialNotification = async () => {
//get the initial token (triggered when app opens from a closed state)
const notification = await notifications.getInitialNotification();
console.log('getInitialNotification', notification);
return notification;
};
const onNotificationOpenedListener = () => {
61
//remember to remove the listener on un mount
//this gets triggered when the application is in the background
this.removeOnNotificationOpened = notifications.onNotificationOpened(
notification => {
console.log('onNotificationOpened', notification);
//do something with the notification
},
);
};
const onNotificationListener = () => {
//remember to remove the listener on un mount
//this gets triggered when the application is in the forground/runnning
//for android make sure you manifest is setup - else this wont work
this.removeOnNotification = notifications.onNotification(notification => {
//do something with the notification
console.log('onNotification', notification);
});
};
Now we can reinstall our app, may need to uninstall it and install it again, and make sure you
are testing the Push Notifications on a real device, not a simulator, since google is not
allowing Push Notifications on the Simulator. Start the app and from the xCode console we can
get the token (to easily find it put something like firebase in the filter field so it filter you only
messages containing firebase):
Now open the Firebase Console one more time, open your Application there, and scroll until you
see the Cloud Messaging card:
62
Now from the next screen click on the “Create your first campaign” button:
And from the next screen make sure that you select Firebase Notification messages:
Click “Create” and in the next window enter the Notification title, and the Notification text, and
click on the Send Message button:
63
Now add the Token we have found in the xCode console previously, and add it in the “Add an
FCM registration token” field, and click the plus button to add it.
64
Now if you click the “Test” button (with our app running in the background on our device) you will
see or Push Notification:
65
Android Setup
For the Android part we still need to do some setup on our Firebase Console and in our Android
Project.
Let's start by creating a new app inside the Firebase project we have created previously, and
this time instead of iOS select Android app:
Enter the Android package name, which you can find inside your code by opening the
MainActivity.java file, and copy the package name which is usually the first line in this file:
And in the next step make sure to download the google-services.json file.
66
After this, open your android project with Android Studio, and drag and drop the
google-services.json file you have downloaded to the app folder ():
67
Next we are going to make some more changes in our Android Studio Project. First we need to
add the google-services dependency in our build.gradle (the one inside the android folder,
not the one inside android/app!), so inside the dependencies add the following line:
classpath 'com.google.gms:google-services:4.3.12'
Next open the build.gradle file which is in the app folder, and add this plugin:
apply plugin: 'com.google.gms.google-services'
68
Next we need to modify the AndroidManifest.xml, so add the following lines inside the
<manifest>:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
And inside the <activity change the property of launchMode to “singleTop”:
Now you can run your app on a real device, and in the terminal you can get the token:
Now to test if everything works, minimize your app, and open the Firebase Console and inside
the Cloud Messaging Compose notification add the title and text for our test notification and
click the Send test message button:
In the next window add the new token we got in the terminal select the newly added token and
click the Test button, and you should see our notification on our Android device:
69
https://www.npmjs.com/package/react-native-firebase-push-notifications
https://firebase.google.com/docs/cloud-messaging/ios/client
Building the App
While we are working on our React Native app from time to time there is a need to rebuild it
mostly because of adding some third party library which in most cases would require to rebuild
the app, while if we are only changing the JavaScript and the JSX the hot reloading will make
sure we everything is uptodate.
When dealing with building the app we had two options, either to build it manually everytime we
needed a build, or to set up an automatic build pipeline that would build our app when we made
some changes in the code.
Manual Building
When considering a manual building process, the building steps are different for all platforms, so
we will try to explain the manual build process for Android and iOS separately.
*Before trying to build the app for any platform, make sure that your app runs without
any errors.
Android
To build the APK of your React Native you need to use Android Studio or you can do it from the
command line. First let's try to build it from Android Studio, so open the ‘android’ folder of your
React Native project with Android Studio.
70
APK with Android Studio
Now to build the actual APK, you need to select ‘Build->Gnerate Signed Bundle / APK…’:
Then from the next window select ‘APK’. In the next window we need to select a keystore if we
have one or create a new one, and in our case we want to create a new one:
Then we first need to select a folder where we will store our keystore, and I usually create a
folder named ‘keystore’ in the root of my repo, so we will do the same here, and fill the rest of
the fields in the form, and we click OK once we are done:
71
After this we click ‘Next’ and select a Build Variant in the final window, and in our case we will
select Release, because if we chose Debug inorder for our app to work on any device we will
need to have the Metro Bundler Server running on our machine and the device to be connected
to that machine via USB or Wifi:
72
After clicking Finish here, our APK build process will start and after ~5 min (depending on your
machine) your APK will be generated (it should be inside ‘android/app/release’):
APK with Command Line
To generate an APK file for a React Native app via terminal/command line, you can follow these
steps:
1. Make sure you have installed the necessary software: Android Studio, the Android SDK,
and the React Native command line interface (CLI).
2. Open a terminal/command line window and navigate to your React Native project
directory.
3. Run the following command to generate a debug APK (make sure you run the command
from within the android folder):
./gradlew assembleDebug
4. Run the following command to generate a release APK:
./gradlew assembleRelease
Those commands will create an APK file in the project's android/app/build/outputs/apk/
directory, where you will have a debug or release folder which holds your APK.
If you want to generate a release APK, you will need to create a keystore and sign the APK with
it. You can use the following command to generate a keystore:
keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias
-keyalg RSA -keysize 2048 -validity 10000
This will prompt you to enter a password and other information for the keystore.
Once you have the keystore, you can add the following lines to your project's
android/gradle.properties file:
MYAPP_RELEASE_STORE_FILE=my-release-key.keystore
MYAPP_RELEASE_KEY_ALIAS=my-key-alias
73
MYAPP_RELEASE_STORE_PASSWORD=<password>
MYAPP_RELEASE_KEY_PASSWORD=<password>
Replace <password> with the password you used to create the keystore.
iOS
To build an IPA you will need a machine with MacOS because you will need xCode and Apple
Developer Account (paid one is preferred since it will make your life so easier when dealing with
Apple Development stuff).
Dealing with Apple Hell
First thing is to enroll in the Apple Developer program, which has a 99$ annual fee. We will need
this account to generate the apple related stuff for deploying our app like bundle id, signing
certificate and provision profiles.
Generating p12 signing certificate
After we have enrolled into the Apple Developer program, we will need to generate our p12
certificate. To do that we will need a Mac machine with MacOS. First thing to do is to open the
Keychain Access application on our MacOS machine:
74
From there we need to click on Keychain Access->Certificate Assistant->Request a Certificate
From a Certificate Authority, and also make sure that the login is selected in the Default
Keychains on the left panel in Keychain Access (check the photo above).
In the next screen, enter your email (the one used for the apple developer account) , make sure
that Save to disk is selected and click Continue.
75
With this we are done with the Keychain Access. Now we need to go to the Apple Developer
website and in the Certificates tab you need to click the “+” button to generate a new certificate:
76
On the next screen select Apple Distribution, because we need a distribution certificate:
Now in the next screen we need to attach the file which we have previously generated with the
help of Keychain Access (the file should have .certSignalRequest extension):
Now our certificate should be generated, and we can download it. Keep in mind this is not a
p12, we still need to do some work to create a p12 which is required on Azure DevOps.
77
Once you have downloaded the certificate, you can double click it in order to install it. Now to
generate a p12, we should open the Keychain Access one more time, and click the login button
in the Default Keychains. Now locate the certificate we have previously installed (it should have
something like “Apple Distribution …” in the name), right click on it and select “Export: Apple
Distribution …”:
In the next screen from File Format we chose “Personal Information Exchange (.p12)” and click
on the Save button:
78
After clicking the Save button, one more window will appear, to enter and verify the certificate
password, and make sure to remember this password. I usually keep it in a text file in the same
folder where I keep the p12, but this is not very safe to do.
79
With this we are done, and our p12 is ready.
Generating BundleId
Next is to create an Identifier or bundle id for our app. To do that we need to head to the Apple
Developer website in the Identifiers section, and click the “+” button to generate a new Identifier
(App ID/bundle id):
80
From the next screen select “App IDs” and click Continue:
In the next screen make sure that you have App and not App Clip selected and click Continue:
In the next screen we need to enter some information regarding our App Id like description and
the actual bundle id. In the description field enter the description, and in the next section make
sure that “Explicit” is selected for Bundle ID, and your bundle id should look like a reversed URL
(example: “com.myapplication.testing”)
81
Now click Continue and then Register and with this we are done with the registration of our App
ID.
Generating Distribution Provision Profile
To generate the Provision Profile once again we will head to our Apple Developer website, and
this time we will go to the Profiles section, and we click the “+” button there to generate a new
Provision Profile.
On the next screen we need to select “App Store” from the Distribution section and click
Continue:
82
On the next screen we need to select the App ID we have generated previously, and click
Continue:
Next we select the certificate we have generated and click Continue:
83
And finally we enter the name for our Provision Profile and click Generate:
IPA with xCode
To start, open the ios folder of your React Native project with xCode (the .xcworkspace file).
Then you may need to deal with the “Apple Hell” a bit, and after generating the needed things
like certificates, bundle id and provision profile, apply the needed changes to the xCode project:
● Install the development certificates you have generated
● Change the bundle/app identifier in xCode for your app
● If you plan to use manual signing make sure you update the provision profiles too.
Now in xCode select Product->Archive and the Archiving process will start, and after few
minutes you will see something like this:
84
From here click on the ‘Distribute App’ button on the right side.
From the next window we will select Ad Hoc as a method of distribution, and you can learn more
about the other methods here.
Then just click Next:
Then choose ‘Automatically Manage signing’ and click on the Next button again. On the last
window you can click the Export button and select a folder where you want your IPA to be
generated:
85
IPA with Command Line
To generate IPA with the command line you still need to have xCode installed, but you may
need to use the command line for a lot of reasons. Before trying to generate the IPA make sure
that you are able to run the ios app in the simulator or on a physical iOS device.
Then first run this command in the terminal (make sure that you are inside the ios folder of your
React Native project):
xcodebuild -workspace MelonReactNative.xcworkspace -scheme MelonReactNative
-sdk iphoneos -configuration Release -archivePath
MelonReactNative.xcarchive archive
*make sure that you use names from your project in the command for the workspace,
schema and the archivePath.
This will generate a file with .xcarchive inside the ios folder. Then you need to create one plist
file inside the ios folder, and we will name it exportOptions.plist and it will look something like
this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>compileBitcode</key>
86
<false/>
<key>method</key>
<string>ad-hoc</string>
<key>provisioningProfiles</key>
<dict>
<key>com.melon.react.native.test</key>
<string>yourprovisioningprofile</string>
</dict>
</dict>
</plist>
*make sure you put your app bundle id on the place where i have
‘com.melon.react.native.test’
Next run the following command to export the ipa
xcodebuild -exportArchive -archivePath MelonReactNative.xcarchive
-exportOptionsPlist exportOptions.plist -exportPath ipa
*make sure that you use names from your project in the command for the archivePath
and exportOptionsPlist.
If this command runs successfully you will have and IPA file inside a folder named ‘ipa’ (ios/ipa).
Azure Devops Pipelines
Now let's focus on atomizing our build process, and for that we are going to use Azure Devops.
If you are not familiar with Azure Devops and how to set up an Azure account, you can learn
more here. Also if you want some more in-depth guide for making the Azure Devops Pipelines
for React Native, you can find one here, which I was also using as a reference when I was
writing this text.
Before we can start working on the actual pipeline, we needed to setup the Azure DevOps
account, and in order to do that, we had to create a free subscription that is valid for 30 days,
and you have 200$ free credits to use on the Azure Services, and after that period it would be
required to enter payment method (credit card) and you will be charged per use, but to be
honest in the 30 day I was using my free account I haven’t spent a penny from the free credit,
since I was only running the pipelines, while my code was on a Bitbucket repository.
Android
If we follow the guide I have provided in the link above, at the end we will find the full yaml
pipeline which we will need to modify to make it work with the latest version of React Native,
87
which at the moment is 0.70. So first thing is to update the Node version in the NodeTool@0
task:
- task: NodeTool@0
displayName: 'Install Node'
inputs:
versionSpec: '12.19.0' # you can use your desired version here
Next is to update the Java version in the same task, and instead of Java 8 (1.8) which is I
believe a default value, we need to use Java 11 (1.11), so our updated task would look
something like this:
- task: Gradle@2
displayName: 'Build APK'
inputs:
gradleWrapperFile: 'android/gradlew'
workingDirectory: 'android/'
options: '-PversionName=$(NEW_VERSION)
-PversionCode=$(Build.BuildId)'
tasks: 'assembleRelease'
publishJUnitResults: false
javaHomeOption: 'JDKVersion'
jdkVersionOption: '1.11'
gradleOptions: '-Xmx3072m'
sonarQubeRunAnalysis: false
With this our yaml pipeline should work, and the final yaml for the Android part would look like
this:
trigger:
branches:
include:
- master
variables:
- group: Mobile # change it to the name you have set
pool:
vmImage: 'ubuntu-latest'
steps:
- checkout: self
persistCredentials: true
clean: true
- task: NodeTool@0
displayName: 'Install Node'
88
inputs:
versionSpec: '16.10.0' # you can use your desired version here
- script: yarn install
displayName: Install Dependencies
- script: |
# Disable autocommit on version bump
yarn config set version-sign-git-tag false
yarn config set version-git-tag false
yarn config set version-commit-hooks false
# Checkout branch where the build is triggered
git checkout $(Build.SourceBranchName)
# Extract existing version of package.json
oldVer=$(jq -r ".version" package.json)
# Bump version
yarn version --patch
# Add bumped version to staging
git add *
# Extract new version of package.json
newVer=$(jq -r ".version" package.json)
# Set environment variables
echo "##vso[task.setvariable variable=OLD_VERSION]$oldVer"
echo "##vso[task.setvariable variable=NEW_VERSION]$newVer"
displayName: 'Bump version and set variables'
- task: Gradle@2
displayName: 'Build APK'
inputs:
gradleWrapperFile: 'android/gradlew'
workingDirectory: 'android/'
options: '-PversionName=$(NEW_VERSION) -PversionCode=$(Build.BuildId)'
tasks: 'assembleRelease'
publishJUnitResults: false
javaHomeOption: 'JDKVersion'
jdkVersionOption: '1.11'
gradleOptions: '-Xmx3072m'
sonarQubeRunAnalysis: false
- task: AndroidSigning@3
displayName: 'Sign APK'
inputs:
apkFiles: 'android/app/build/outputs/apk/release/*.apk'
apksignerKeystoreFile: 'keystore.keystore'
apksignerKeystorePassword: '$(AndroidKeyStorePassword)'
apksignerKeystoreAlias: '$(AndroidKeyAlias)'
apksignerKeyPassword: '$(AndroidKeyAliasPassword)'
89
React Native for React Developers v.2.0.pdf
React Native for React Developers v.2.0.pdf
React Native for React Developers v.2.0.pdf
React Native for React Developers v.2.0.pdf
React Native for React Developers v.2.0.pdf
React Native for React Developers v.2.0.pdf
React Native for React Developers v.2.0.pdf
React Native for React Developers v.2.0.pdf
React Native for React Developers v.2.0.pdf
React Native for React Developers v.2.0.pdf
React Native for React Developers v.2.0.pdf
React Native for React Developers v.2.0.pdf
React Native for React Developers v.2.0.pdf
React Native for React Developers v.2.0.pdf
React Native for React Developers v.2.0.pdf
React Native for React Developers v.2.0.pdf
React Native for React Developers v.2.0.pdf
React Native for React Developers v.2.0.pdf
React Native for React Developers v.2.0.pdf
React Native for React Developers v.2.0.pdf
React Native for React Developers v.2.0.pdf
React Native for React Developers v.2.0.pdf
React Native for React Developers v.2.0.pdf
React Native for React Developers v.2.0.pdf
React Native for React Developers v.2.0.pdf
React Native for React Developers v.2.0.pdf
React Native for React Developers v.2.0.pdf

More Related Content

What's hot

Introduction to Version Control
Introduction to Version ControlIntroduction to Version Control
Introduction to Version ControlJeremy Coates
 
Implementing DevOps
Implementing DevOpsImplementing DevOps
Implementing DevOpsMike McGarr
 
Android Development with Kotlin, Part 1 - Introduction
Android Development with Kotlin, Part 1 - IntroductionAndroid Development with Kotlin, Part 1 - Introduction
Android Development with Kotlin, Part 1 - IntroductionAndreas Jakl
 
Build web apps with react js
Build web apps with react jsBuild web apps with react js
Build web apps with react jsdhanushkacnd
 
Continuous Integration/Deployment with Gitlab CI
Continuous Integration/Deployment with Gitlab CIContinuous Integration/Deployment with Gitlab CI
Continuous Integration/Deployment with Gitlab CIDavid Hahn
 
BDD WITH CUCUMBER AND JAVA
BDD WITH CUCUMBER AND JAVABDD WITH CUCUMBER AND JAVA
BDD WITH CUCUMBER AND JAVASrinivas Katakam
 
Gitlab ci, cncf.sk
Gitlab ci, cncf.skGitlab ci, cncf.sk
Gitlab ci, cncf.skJuraj Hantak
 
Behavior Driven Development Pros and Cons
Behavior Driven Development Pros and ConsBehavior Driven Development Pros and Cons
Behavior Driven Development Pros and ConsIosif Itkin
 
CICD Pipeline Using Github Actions
CICD Pipeline Using Github ActionsCICD Pipeline Using Github Actions
CICD Pipeline Using Github ActionsKumar Shìvam
 
Intro to react native
Intro to react nativeIntro to react native
Intro to react nativeModusJesus
 
Dev ops != Dev+Ops
Dev ops != Dev+OpsDev ops != Dev+Ops
Dev ops != Dev+OpsShalu Ahuja
 
Introduction to React Native
Introduction to React NativeIntroduction to React Native
Introduction to React NativeSambhu Lakshmanan
 
Overview of React.JS - Internship Presentation - Week 5
Overview of React.JS - Internship Presentation - Week 5Overview of React.JS - Internship Presentation - Week 5
Overview of React.JS - Internship Presentation - Week 5Devang Garach
 
Container Runtime Security with Falco
Container Runtime Security with FalcoContainer Runtime Security with Falco
Container Runtime Security with FalcoMichael Ducy
 
DevOps Training | DevOps Training Video | DevOps Tools | DevOps Tutorial For ...
DevOps Training | DevOps Training Video | DevOps Tools | DevOps Tutorial For ...DevOps Training | DevOps Training Video | DevOps Tools | DevOps Tutorial For ...
DevOps Training | DevOps Training Video | DevOps Tools | DevOps Tutorial For ...Simplilearn
 
Introduction to react native
Introduction to react nativeIntroduction to react native
Introduction to react nativeDani Akash
 
Introduction to Github Actions
Introduction to Github ActionsIntroduction to Github Actions
Introduction to Github ActionsKnoldus Inc.
 
Kotlin vs Java | Edureka
Kotlin vs Java | EdurekaKotlin vs Java | Edureka
Kotlin vs Java | EdurekaEdureka!
 
CI/CD (DevOps) 101
CI/CD (DevOps) 101CI/CD (DevOps) 101
CI/CD (DevOps) 101Hazzim Anaya
 

What's hot (20)

Introduction to Version Control
Introduction to Version ControlIntroduction to Version Control
Introduction to Version Control
 
Implementing DevOps
Implementing DevOpsImplementing DevOps
Implementing DevOps
 
Android Development with Kotlin, Part 1 - Introduction
Android Development with Kotlin, Part 1 - IntroductionAndroid Development with Kotlin, Part 1 - Introduction
Android Development with Kotlin, Part 1 - Introduction
 
Build web apps with react js
Build web apps with react jsBuild web apps with react js
Build web apps with react js
 
Continuous Integration/Deployment with Gitlab CI
Continuous Integration/Deployment with Gitlab CIContinuous Integration/Deployment with Gitlab CI
Continuous Integration/Deployment with Gitlab CI
 
BDD WITH CUCUMBER AND JAVA
BDD WITH CUCUMBER AND JAVABDD WITH CUCUMBER AND JAVA
BDD WITH CUCUMBER AND JAVA
 
Gitlab ci, cncf.sk
Gitlab ci, cncf.skGitlab ci, cncf.sk
Gitlab ci, cncf.sk
 
Behavior Driven Development Pros and Cons
Behavior Driven Development Pros and ConsBehavior Driven Development Pros and Cons
Behavior Driven Development Pros and Cons
 
CICD Pipeline Using Github Actions
CICD Pipeline Using Github ActionsCICD Pipeline Using Github Actions
CICD Pipeline Using Github Actions
 
Intro to react native
Intro to react nativeIntro to react native
Intro to react native
 
Dev ops != Dev+Ops
Dev ops != Dev+OpsDev ops != Dev+Ops
Dev ops != Dev+Ops
 
Introduction to React Native
Introduction to React NativeIntroduction to React Native
Introduction to React Native
 
Overview of React.JS - Internship Presentation - Week 5
Overview of React.JS - Internship Presentation - Week 5Overview of React.JS - Internship Presentation - Week 5
Overview of React.JS - Internship Presentation - Week 5
 
Container Runtime Security with Falco
Container Runtime Security with FalcoContainer Runtime Security with Falco
Container Runtime Security with Falco
 
Introduction to DevOps
Introduction to DevOpsIntroduction to DevOps
Introduction to DevOps
 
DevOps Training | DevOps Training Video | DevOps Tools | DevOps Tutorial For ...
DevOps Training | DevOps Training Video | DevOps Tools | DevOps Tutorial For ...DevOps Training | DevOps Training Video | DevOps Tools | DevOps Tutorial For ...
DevOps Training | DevOps Training Video | DevOps Tools | DevOps Tutorial For ...
 
Introduction to react native
Introduction to react nativeIntroduction to react native
Introduction to react native
 
Introduction to Github Actions
Introduction to Github ActionsIntroduction to Github Actions
Introduction to Github Actions
 
Kotlin vs Java | Edureka
Kotlin vs Java | EdurekaKotlin vs Java | Edureka
Kotlin vs Java | Edureka
 
CI/CD (DevOps) 101
CI/CD (DevOps) 101CI/CD (DevOps) 101
CI/CD (DevOps) 101
 

Similar to React Native for React Developers v.2.0.pdf

React Native- The Future of Mobile App Development.
React Native- The Future of Mobile App Development.React Native- The Future of Mobile App Development.
React Native- The Future of Mobile App Development.Techugo
 
When to choose and avoid react native for mobile app development
When to choose and avoid react native for mobile app developmentWhen to choose and avoid react native for mobile app development
When to choose and avoid react native for mobile app developmentFullestop
 
A Complete Guide On React Native App Development.pdf
A Complete Guide On React Native App Development.pdfA Complete Guide On React Native App Development.pdf
A Complete Guide On React Native App Development.pdfWDP Technologies
 
Why big organizations like tesla, facebook, walmart, skype are using react na...
Why big organizations like tesla, facebook, walmart, skype are using react na...Why big organizations like tesla, facebook, walmart, skype are using react na...
Why big organizations like tesla, facebook, walmart, skype are using react na...MoonTechnolabsPvtLtd
 
the benefits of react native to developing ios and android application from s...
the benefits of react native to developing ios and android application from s...the benefits of react native to developing ios and android application from s...
the benefits of react native to developing ios and android application from s...Whitelotus Corporation
 
How react native app is an ideal choice for every start up businesses
How react native app is an ideal choice for every start up businessesHow react native app is an ideal choice for every start up businesses
How react native app is an ideal choice for every start up businessesOrange Mantra
 
10 Key Reasons To Choose React Native For Mobile App Development.pdf
10 Key Reasons To Choose React Native For Mobile App Development.pdf10 Key Reasons To Choose React Native For Mobile App Development.pdf
10 Key Reasons To Choose React Native For Mobile App Development.pdfOrange Mantra
 
Native script vs react native for native app development in 2022
Native script vs react native for native app development in 2022Native script vs react native for native app development in 2022
Native script vs react native for native app development in 2022Katy Slemon
 
Why is React Native the Best Choice for Cross-Platform Mobile App Development...
Why is React Native the Best Choice for Cross-Platform Mobile App Development...Why is React Native the Best Choice for Cross-Platform Mobile App Development...
Why is React Native the Best Choice for Cross-Platform Mobile App Development...Techugo
 
Why react native is recommended over other frameworks for mobile app development
Why react native is recommended over other frameworks for mobile app developmentWhy react native is recommended over other frameworks for mobile app development
Why react native is recommended over other frameworks for mobile app developmentFullestop
 
React Native App Development_ The Ultimate Guide In 2022.pdf
React Native App Development_ The Ultimate Guide In 2022.pdfReact Native App Development_ The Ultimate Guide In 2022.pdf
React Native App Development_ The Ultimate Guide In 2022.pdfMoon Technolabs Pvt. Ltd.
 
Why Consider React Native for the Travel Industry.pdf
Why Consider React Native for the Travel Industry.pdfWhy Consider React Native for the Travel Industry.pdf
Why Consider React Native for the Travel Industry.pdfReactJS
 
Reasons to Choose React Native for building Social Media/Networking Apps!
Reasons to Choose React Native for building Social Media/Networking Apps!Reasons to Choose React Native for building Social Media/Networking Apps!
Reasons to Choose React Native for building Social Media/Networking Apps!Shelly Megan
 
Reasons why react native is the future of mobile app development
Reasons why react native is the future of mobile app developmentReasons why react native is the future of mobile app development
Reasons why react native is the future of mobile app developmentThinkTanker Technosoft PVT LTD
 
Choose between flutter and react native
Choose between flutter and react nativeChoose between flutter and react native
Choose between flutter and react nativeSmith Daniel
 
Advantages of building Social Media Apps in React Native
Advantages of building Social Media Apps in React Native			Advantages of building Social Media Apps in React Native
Advantages of building Social Media Apps in React Native Shelly Megan
 
Cost of React Native App Development in 2023.pdf
Cost of React Native App Development in 2023.pdfCost of React Native App Development in 2023.pdf
Cost of React Native App Development in 2023.pdfTechugo
 
Future Scope of React Native for Mobile App Development.pdf
Future Scope of React Native for Mobile App Development.pdfFuture Scope of React Native for Mobile App Development.pdf
Future Scope of React Native for Mobile App Development.pdfFuGenx Technologies
 
React Native App Development in 2023-Tips to Practice.pdf
React Native App Development in 2023-Tips to Practice.pdfReact Native App Development in 2023-Tips to Practice.pdf
React Native App Development in 2023-Tips to Practice.pdfTechugo
 
Why is React Native the Best Choice for Mobile App Development.pdf
Why is React Native the Best Choice for Mobile App Development.pdfWhy is React Native the Best Choice for Mobile App Development.pdf
Why is React Native the Best Choice for Mobile App Development.pdfTechugo
 

Similar to React Native for React Developers v.2.0.pdf (20)

React Native- The Future of Mobile App Development.
React Native- The Future of Mobile App Development.React Native- The Future of Mobile App Development.
React Native- The Future of Mobile App Development.
 
When to choose and avoid react native for mobile app development
When to choose and avoid react native for mobile app developmentWhen to choose and avoid react native for mobile app development
When to choose and avoid react native for mobile app development
 
A Complete Guide On React Native App Development.pdf
A Complete Guide On React Native App Development.pdfA Complete Guide On React Native App Development.pdf
A Complete Guide On React Native App Development.pdf
 
Why big organizations like tesla, facebook, walmart, skype are using react na...
Why big organizations like tesla, facebook, walmart, skype are using react na...Why big organizations like tesla, facebook, walmart, skype are using react na...
Why big organizations like tesla, facebook, walmart, skype are using react na...
 
the benefits of react native to developing ios and android application from s...
the benefits of react native to developing ios and android application from s...the benefits of react native to developing ios and android application from s...
the benefits of react native to developing ios and android application from s...
 
How react native app is an ideal choice for every start up businesses
How react native app is an ideal choice for every start up businessesHow react native app is an ideal choice for every start up businesses
How react native app is an ideal choice for every start up businesses
 
10 Key Reasons To Choose React Native For Mobile App Development.pdf
10 Key Reasons To Choose React Native For Mobile App Development.pdf10 Key Reasons To Choose React Native For Mobile App Development.pdf
10 Key Reasons To Choose React Native For Mobile App Development.pdf
 
Native script vs react native for native app development in 2022
Native script vs react native for native app development in 2022Native script vs react native for native app development in 2022
Native script vs react native for native app development in 2022
 
Why is React Native the Best Choice for Cross-Platform Mobile App Development...
Why is React Native the Best Choice for Cross-Platform Mobile App Development...Why is React Native the Best Choice for Cross-Platform Mobile App Development...
Why is React Native the Best Choice for Cross-Platform Mobile App Development...
 
Why react native is recommended over other frameworks for mobile app development
Why react native is recommended over other frameworks for mobile app developmentWhy react native is recommended over other frameworks for mobile app development
Why react native is recommended over other frameworks for mobile app development
 
React Native App Development_ The Ultimate Guide In 2022.pdf
React Native App Development_ The Ultimate Guide In 2022.pdfReact Native App Development_ The Ultimate Guide In 2022.pdf
React Native App Development_ The Ultimate Guide In 2022.pdf
 
Why Consider React Native for the Travel Industry.pdf
Why Consider React Native for the Travel Industry.pdfWhy Consider React Native for the Travel Industry.pdf
Why Consider React Native for the Travel Industry.pdf
 
Reasons to Choose React Native for building Social Media/Networking Apps!
Reasons to Choose React Native for building Social Media/Networking Apps!Reasons to Choose React Native for building Social Media/Networking Apps!
Reasons to Choose React Native for building Social Media/Networking Apps!
 
Reasons why react native is the future of mobile app development
Reasons why react native is the future of mobile app developmentReasons why react native is the future of mobile app development
Reasons why react native is the future of mobile app development
 
Choose between flutter and react native
Choose between flutter and react nativeChoose between flutter and react native
Choose between flutter and react native
 
Advantages of building Social Media Apps in React Native
Advantages of building Social Media Apps in React Native			Advantages of building Social Media Apps in React Native
Advantages of building Social Media Apps in React Native
 
Cost of React Native App Development in 2023.pdf
Cost of React Native App Development in 2023.pdfCost of React Native App Development in 2023.pdf
Cost of React Native App Development in 2023.pdf
 
Future Scope of React Native for Mobile App Development.pdf
Future Scope of React Native for Mobile App Development.pdfFuture Scope of React Native for Mobile App Development.pdf
Future Scope of React Native for Mobile App Development.pdf
 
React Native App Development in 2023-Tips to Practice.pdf
React Native App Development in 2023-Tips to Practice.pdfReact Native App Development in 2023-Tips to Practice.pdf
React Native App Development in 2023-Tips to Practice.pdf
 
Why is React Native the Best Choice for Mobile App Development.pdf
Why is React Native the Best Choice for Mobile App Development.pdfWhy is React Native the Best Choice for Mobile App Development.pdf
Why is React Native the Best Choice for Mobile App Development.pdf
 

Recently uploaded

Sports & Fitness Value Added Course FY..
Sports & Fitness Value Added Course FY..Sports & Fitness Value Added Course FY..
Sports & Fitness Value Added Course FY..Disha Kariya
 
Beyond the EU: DORA and NIS 2 Directive's Global Impact
Beyond the EU: DORA and NIS 2 Directive's Global ImpactBeyond the EU: DORA and NIS 2 Directive's Global Impact
Beyond the EU: DORA and NIS 2 Directive's Global ImpactPECB
 
Advanced Views - Calendar View in Odoo 17
Advanced Views - Calendar View in Odoo 17Advanced Views - Calendar View in Odoo 17
Advanced Views - Calendar View in Odoo 17Celine George
 
BAG TECHNIQUE Bag technique-a tool making use of public health bag through wh...
BAG TECHNIQUE Bag technique-a tool making use of public health bag through wh...BAG TECHNIQUE Bag technique-a tool making use of public health bag through wh...
BAG TECHNIQUE Bag technique-a tool making use of public health bag through wh...Sapna Thakur
 
fourth grading exam for kindergarten in writing
fourth grading exam for kindergarten in writingfourth grading exam for kindergarten in writing
fourth grading exam for kindergarten in writingTeacherCyreneCayanan
 
1029 - Danh muc Sach Giao Khoa 10 . pdf
1029 -  Danh muc Sach Giao Khoa 10 . pdf1029 -  Danh muc Sach Giao Khoa 10 . pdf
1029 - Danh muc Sach Giao Khoa 10 . pdfQucHHunhnh
 
1029-Danh muc Sach Giao Khoa khoi 6.pdf
1029-Danh muc Sach Giao Khoa khoi  6.pdf1029-Danh muc Sach Giao Khoa khoi  6.pdf
1029-Danh muc Sach Giao Khoa khoi 6.pdfQucHHunhnh
 
Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...
Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...
Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...fonyou31
 
Measures of Central Tendency: Mean, Median and Mode
Measures of Central Tendency: Mean, Median and ModeMeasures of Central Tendency: Mean, Median and Mode
Measures of Central Tendency: Mean, Median and ModeThiyagu K
 
social pharmacy d-pharm 1st year by Pragati K. Mahajan
social pharmacy d-pharm 1st year by Pragati K. Mahajansocial pharmacy d-pharm 1st year by Pragati K. Mahajan
social pharmacy d-pharm 1st year by Pragati K. Mahajanpragatimahajan3
 
Activity 01 - Artificial Culture (1).pdf
Activity 01 - Artificial Culture (1).pdfActivity 01 - Artificial Culture (1).pdf
Activity 01 - Artificial Culture (1).pdfciinovamais
 
Arihant handbook biology for class 11 .pdf
Arihant handbook biology for class 11 .pdfArihant handbook biology for class 11 .pdf
Arihant handbook biology for class 11 .pdfchloefrazer622
 
Interactive Powerpoint_How to Master effective communication
Interactive Powerpoint_How to Master effective communicationInteractive Powerpoint_How to Master effective communication
Interactive Powerpoint_How to Master effective communicationnomboosow
 
Unit-IV- Pharma. Marketing Channels.pptx
Unit-IV- Pharma. Marketing Channels.pptxUnit-IV- Pharma. Marketing Channels.pptx
Unit-IV- Pharma. Marketing Channels.pptxVishalSingh1417
 
Russian Escort Service in Delhi 11k Hotel Foreigner Russian Call Girls in Delhi
Russian Escort Service in Delhi 11k Hotel Foreigner Russian Call Girls in DelhiRussian Escort Service in Delhi 11k Hotel Foreigner Russian Call Girls in Delhi
Russian Escort Service in Delhi 11k Hotel Foreigner Russian Call Girls in Delhikauryashika82
 
Key note speaker Neum_Admir Softic_ENG.pdf
Key note speaker Neum_Admir Softic_ENG.pdfKey note speaker Neum_Admir Softic_ENG.pdf
Key note speaker Neum_Admir Softic_ENG.pdfAdmir Softic
 
Class 11th Physics NEET formula sheet pdf
Class 11th Physics NEET formula sheet pdfClass 11th Physics NEET formula sheet pdf
Class 11th Physics NEET formula sheet pdfAyushMahapatra5
 

Recently uploaded (20)

Sports & Fitness Value Added Course FY..
Sports & Fitness Value Added Course FY..Sports & Fitness Value Added Course FY..
Sports & Fitness Value Added Course FY..
 
Beyond the EU: DORA and NIS 2 Directive's Global Impact
Beyond the EU: DORA and NIS 2 Directive's Global ImpactBeyond the EU: DORA and NIS 2 Directive's Global Impact
Beyond the EU: DORA and NIS 2 Directive's Global Impact
 
Advanced Views - Calendar View in Odoo 17
Advanced Views - Calendar View in Odoo 17Advanced Views - Calendar View in Odoo 17
Advanced Views - Calendar View in Odoo 17
 
BAG TECHNIQUE Bag technique-a tool making use of public health bag through wh...
BAG TECHNIQUE Bag technique-a tool making use of public health bag through wh...BAG TECHNIQUE Bag technique-a tool making use of public health bag through wh...
BAG TECHNIQUE Bag technique-a tool making use of public health bag through wh...
 
fourth grading exam for kindergarten in writing
fourth grading exam for kindergarten in writingfourth grading exam for kindergarten in writing
fourth grading exam for kindergarten in writing
 
1029 - Danh muc Sach Giao Khoa 10 . pdf
1029 -  Danh muc Sach Giao Khoa 10 . pdf1029 -  Danh muc Sach Giao Khoa 10 . pdf
1029 - Danh muc Sach Giao Khoa 10 . pdf
 
1029-Danh muc Sach Giao Khoa khoi 6.pdf
1029-Danh muc Sach Giao Khoa khoi  6.pdf1029-Danh muc Sach Giao Khoa khoi  6.pdf
1029-Danh muc Sach Giao Khoa khoi 6.pdf
 
Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...
Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...
Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...
 
Measures of Central Tendency: Mean, Median and Mode
Measures of Central Tendency: Mean, Median and ModeMeasures of Central Tendency: Mean, Median and Mode
Measures of Central Tendency: Mean, Median and Mode
 
INDIA QUIZ 2024 RLAC DELHI UNIVERSITY.pptx
INDIA QUIZ 2024 RLAC DELHI UNIVERSITY.pptxINDIA QUIZ 2024 RLAC DELHI UNIVERSITY.pptx
INDIA QUIZ 2024 RLAC DELHI UNIVERSITY.pptx
 
social pharmacy d-pharm 1st year by Pragati K. Mahajan
social pharmacy d-pharm 1st year by Pragati K. Mahajansocial pharmacy d-pharm 1st year by Pragati K. Mahajan
social pharmacy d-pharm 1st year by Pragati K. Mahajan
 
Activity 01 - Artificial Culture (1).pdf
Activity 01 - Artificial Culture (1).pdfActivity 01 - Artificial Culture (1).pdf
Activity 01 - Artificial Culture (1).pdf
 
Arihant handbook biology for class 11 .pdf
Arihant handbook biology for class 11 .pdfArihant handbook biology for class 11 .pdf
Arihant handbook biology for class 11 .pdf
 
Código Creativo y Arte de Software | Unidad 1
Código Creativo y Arte de Software | Unidad 1Código Creativo y Arte de Software | Unidad 1
Código Creativo y Arte de Software | Unidad 1
 
Advance Mobile Application Development class 07
Advance Mobile Application Development class 07Advance Mobile Application Development class 07
Advance Mobile Application Development class 07
 
Interactive Powerpoint_How to Master effective communication
Interactive Powerpoint_How to Master effective communicationInteractive Powerpoint_How to Master effective communication
Interactive Powerpoint_How to Master effective communication
 
Unit-IV- Pharma. Marketing Channels.pptx
Unit-IV- Pharma. Marketing Channels.pptxUnit-IV- Pharma. Marketing Channels.pptx
Unit-IV- Pharma. Marketing Channels.pptx
 
Russian Escort Service in Delhi 11k Hotel Foreigner Russian Call Girls in Delhi
Russian Escort Service in Delhi 11k Hotel Foreigner Russian Call Girls in DelhiRussian Escort Service in Delhi 11k Hotel Foreigner Russian Call Girls in Delhi
Russian Escort Service in Delhi 11k Hotel Foreigner Russian Call Girls in Delhi
 
Key note speaker Neum_Admir Softic_ENG.pdf
Key note speaker Neum_Admir Softic_ENG.pdfKey note speaker Neum_Admir Softic_ENG.pdf
Key note speaker Neum_Admir Softic_ENG.pdf
 
Class 11th Physics NEET formula sheet pdf
Class 11th Physics NEET formula sheet pdfClass 11th Physics NEET formula sheet pdf
Class 11th Physics NEET formula sheet pdf
 

React Native for React Developers v.2.0.pdf

  • 1. React Native for React Developers By: Nikola Gorgiev December 2022 v.2.0
  • 2. About me 4 Introduction 5 Mobile apps vs Web 5 What is React Native? 6 How does React Native work? 6 React Native architecture 8 Getting Started: React Native CLI vs Expo 13 Expo 13 React Native CLI 14 Setting up the Development Environment 15 iOS Setup 16 Android Setup 19 Folder Structure of a React Native project 22 xCode and Android Studio 23 xCode 23 Android Studio 27 React Native Core Components 31 Styling 33 Platform Specific Code 35 Permissions 36 iOS 36 Android 36 Adding custom Fonts 37 Navigation 38 Installing 38 Add stack screen navigation 38 Add Bottom Tab navigation 43 Deep Links 47 Push Notifications 53 Introduction 53 Implementation 53 iOS Setup 55 Android Setup 66 Building the App 70 Manual Building 70 2
  • 3. Android 70 APK with Android Studio 71 APK with Command Line 73 iOS 74 Dealing with Apple Hell 74 Generating p12 signing certificate 74 Generating BundleId 80 Generating Distribution Provision Profile 82 IPA with xCode 84 IPA with Command Line 86 Azure Devops Pipelines 87 Android 87 iOS 90 Dealing with Apple hell 90 Generating p12 signing certificate 90 Generating BundleId 96 Generating Distribution Provision Profile 98 The pipeline 100 Optimizations 115 Debugging 115 Testing 115 Advanced Features 115 QuickActions & AppShortcuts 115 Home Widgets 115 CarPlay & Android Auto 115 Over the Air Updates 115 Native/Turbo Module 115 React Native Everywhere 115 Best Practices 116 Organizing your code/Atom 116 State Management 116 Typescript 116 Useful Terms 116 Useful Links 116 3
  • 4. About me My name is Nikola Gorgiev, and I am a software developer with a passion for technology and programming. I was born in August 1990 in Macedonia, and I received my bachelor's degree in Computer Science from the University of Goce Delchev in Shtip. I started my professional career in June 2014 as a Game Developer, but I quickly realized that my interests were not limited to just game development. I have been working in a variety of software development fields since then, starting with Game Development, then Web Development and now I am working with cross-platform frameworks like React Native and Flutter. Over the course of my 9-year career, I've gained a wealth of knowledge and experience in a variety of programming languages and technologies. In addition to my professional career, I am also a dedicated family man. I am married and have a 5-month-old son. My family is my top priority and I always try to make time for them, despite my busy schedule. Also, I used to record videos on my YouTube channel SmileySolutionsMKD where I was recording video tutorials related to programming in my native language, Macedonian. I am planning to rebrand it as Smiley Tech. MKD in the near future with some new content. Overall, my goal is to be constantly learning and growing as a software developer, and to share my knowledge and experience with others through my YouTube channel, LinedIn and Medium Articles, and now this document that I am sharing with the community. 4
  • 5. Introduction This guide, written by Nikola Gorgiev, was initially created for the employees of Melon, a subsidiary of Kin+Carta, to assist them in smoothly transitioning to React Native and expanding their understanding of the technology. The guide is designed to provide a comprehensive introduction to React Native and help ReactJS developers at Melon to easily adopt the technology. It is important to note that the purpose of this document is not to be a full technical specification, but rather a starting point for further exploration. While the guide covers the basics of React Native, it is not exhaustive and there will be useful links included to help developers research further. The guide has been written keeping in mind the needs of ReactJS developers at Melon, and it is tailored to their specific requirements. The goal is to help developers understand the key concepts and principles of React Native, and to provide them with the necessary tools and resources to start building their own applications. In short, this guide is a valuable resource for ReactJS developers at Melon, part of Kin+Carta, who are looking to broaden their knowledge of React Native and start building their own applications. Mobile apps vs Web There are numerous benefits to creating a mobile application as opposed to a website for mobile devices. One of the most significant advantages is the ability to replicate the same experience as native mobile elements, something that is not possible with HTML. For instance, a custom-made DatePicker created with HTML will never look or function as seamlessly as the one provided by the mobile operating system. Additionally, the way users interact with mobile devices differs significantly from the way they interact with the web. On the web, users typically use a mouse to navigate and interact with elements, whereas on mobile devices, users have the ability to use finger gestures, opening up a wide range of new possibilities for interaction. This allows for a more intuitive and user-friendly experience that is tailored to the unique capabilities of mobile devices. Another advantage of mobile apps over mobile websites is the ability to access the device's features and sensors, such as the camera, GPS, and accelerometer. This allows for a more immersive and interactive experience that is not possible with a website. Additionally, mobile apps can work offline, which can be very useful in areas with poor or no internet connectivity. Furthermore, mobile apps offer better performance compared to mobile websites. Mobile apps are built specifically for a particular platform and can take full advantage of the device's resources, resulting in faster load times and a smoother overall experience. 5
  • 6. In conclusion, creating a mobile app instead of a website for mobile devices provides a more intuitive, interactive, and immersive experience, allows access to the device's features and sensors, and offers better performance. While mobile websites can be useful in certain situations, mobile apps are the best choice for most businesses and organizations looking to reach and engage users on mobile devices. What is React Native? React Native is a cross-platform mobile software development kit (SDK) that was developed by Meta, formerly known as Facebook, and released as an open-source project in 2015. Since its release, React Native has become one of the most widely used frameworks for building mobile applications. This is largely due to its ease of use and the ability to build apps for multiple platforms using a single codebase. One of the main advantages of React Native is its use of the JavaScript programming language, which is widely known and used by developers worldwide. This makes it easy for developers to learn and use React Native, as opposed to other mobile app development frameworks that require developers to learn new languages and frameworks. Another advantage of React Native is its ability to build apps for both iOS and Android using a single codebase. This can significantly reduce the development time and costs associated with building separate apps for each platform. In addition to this, the codebase can be shared among multiple development teams, and the app can be easily maintained and updated. The development community of React Native is also very active and supportive, with a large number of libraries, plugins, and tools available to help developers with their projects. This makes it easier to add new features, improve performance, and fix bugs. In summary, React Native is a cross-platform mobile SDK that enables developers to build mobile apps using a single codebase. Its ease of use, ability to build apps for multiple platforms, and active development community make it a popular choice among developers worldwide. Learn More… How does React Native work? React Native is a framework for building cross-platform mobile applications. Unlike older frameworks like Ionic, which essentially runs a web app as a standalone mobile app, React Native generates a true native app that utilizes the same components provided by the corresponding mobile operating system (iOS and Android). 6
  • 7. One of the key differences between React Native and other frameworks like Flutter is that React Native does not replicate the components provided by the mobile operating system. Flutter, for example, renders every component "pixel by pixel" and works like a game engine. This means it has replicas of all the system components provided by iOS and Android. When the operating system receives an update and some components are changed, Flutter needs to make those changes internally. This requires developers to update their Flutter version and make changes to the code if necessary, before pushing a new update to the app. In contrast, React Native uses the system-provided components. This means that when a new operating system update changes a component, such as a button, your app will automatically render the new button when the user updates the app. This approach has several advantages. First, it ensures that your app is always up-to-date with the latest design changes, without requiring additional development work to maintain compatibility. Second, it allows developers to take full advantage of the native capabilities of the 7
  • 8. device, such as camera, GPS, and accelerometer, resulting in a more immersive and interactive experience. In summary, React Native is a powerful framework for building cross-platform mobile apps that utilizes the same components provided by the mobile operating system. Its approach of using system-provided components rather than replicating them, enables developers to take full advantage of the native capabilities of the device and ensures the app is always up-to-date with the latest design changes. You can learn more about it here. React Native architecture With the release of React Native version 0.70, the new architecture has finally been implemented. This new architecture was first introduced in version 0.68 and was available for testing by changing a flag in the code. The new architecture brings several significant changes to React Native, which are depicted in the picture below, with the old architecture on the left and the new architecture on the right. The most notable change in the new architecture is the absence of the "bridge." The bridge was a key component of the old architecture, which was responsible for communicating between the JavaScript code and the native code. The bridge was known to cause performance issues and was a source of complexity in the codebase. The new architecture introduces several new components such as JSI (JavaScript Interface), CodeGen, Fabric, and Turbo Modules. JSI is a new JavaScript engine that improves performance and reduces the size of the binary. CodeGen is a new code generator that improves the performance of the application by generating optimized code. Fabric is a new rendering engine that improves the performance of the application by reducing the number of calls to the native components. Turbo Modules is a new system for managing the modules, which improves the performance of the application by reducing the number of calls to the native code. 8
  • 9. In summary, the new architecture of React Native brings several significant changes, the most important being the absence of the "bridge" and the introduction of new components such as JSI, CodeGen, Fabric, and Turbo Modules. These changes aim to improve the performance of the application and reduce the complexity of the codebase. The new architecture is expected to provide developers with a better experience when building mobile apps with React Native. ● Bridge: The bridge, which existed in the old architecture of React Native, was one of the main reasons why the development team at Meta decided to re-architect the entire React Native core. The bridge was responsible for communicating between the JavaScript code and the native code, and it worked by using JSON serialization. With every interaction in the app, the JavaScript would send a JSON object containing data about the interaction over the bridge. On the native side, the JSON object would then be deserialized. This process became a bottleneck when the app had a lot of user interactions, such as when scrolling through a large list of items. This would cause a delay in the data being displayed and resulted in empty white rows appearing for a split second before the data was loaded. This was caused by the high number of serialization-deserialization operations of JSON objects happening. The bridge was known to cause performance issues and was a source of complexity in the codebase. The new architecture introduced in React Native version 0.70 aims to address these issues by eliminating the need for a bridge and introducing new components such as JSI (JavaScript Interface), CodeGen, Fabric, and Turbo Modules which improve the performance and reduce the complexity of the codebase. 9
  • 10. ● JSI (JavaScript Interface): JSI (JavaScript Interface) is a new component that was introduced in the latest version of React Native, version 0.70, as a replacement for the old bridge. JSI aims to improve performance and reduce the complexity of the codebase. Unlike the old bridge, which relied on serializing and deserializing JSON objects, JSI allows for direct access to the native code via C++. This means that developers can now directly invoke native code from JavaScript, allowing for more efficient communication between the JavaScript code and the native code. This is particularly useful for interacting with device features and sensors, such as Bluetooth or the camera. JSI is designed to be more efficient and lightweight than the old bridge, which was known to cause performance issues. It eliminates the need for serialization-deserialization of JSONs and allows for more direct access to the native code. This improves performance and allows for a more seamless and efficient communication between the JavaScript and native code. In summary, JSI (JavaScript Interface) is a new component that was introduced in React Native version 0.70, as a replacement for the old bridge. It allows for direct access to the native code via C++, which improves performance and reduces complexity of the codebase, it eliminates the need for serialization-deserialization of JSONs and allows for more direct access to the native. You can learn more here and here. ● Fabric: Fabric is a new component that was introduced in React Native version 0.70 as a replacement for the UI Manager in the old architecture. In the old approach, when an application is run, React creates a ReactElementTree in JavaScript, which is then used to create a ReactShadow tree in C++ on the native side. Based on this Shadow tree, the Layout Engine calculates the positions of all UI elements and creates a HostViewTree, 10
  • 11. which consists of the actual native elements such as ViewGroups for Android and UIViews for iOS. The communication between the different threads (JavaScript and native) happens over the bridge, which, as previously mentioned, was a known issue due to the performance-expensive operation of serialization-deserialization of JSONs and because it meant that two copies of the same data were kept on both sides of the bridge. This also meant that when there was a lot of traffic, crossing the bridge was slow, resulting in data being out of sync and causing laggy scrolling in large lists. Fabric solves these issues with the help of JSI. It allows the JavaScript and UI threads to be in sync, which means that user interactions are prioritized and executed synchronously in the main or native thread, while other tasks such as API requests are executed asynchronously. Additionally, the Shadow Tree is now immutable and shared between the JavaScript and UI threads, which eliminates the need for keeping two copies of the same data. This improves performance and ensures that user interactions are executed smoothly and without delay. Learn more here, here and here. ● Turbo Modules:Turbo Modules is a new system for managing modules that was introduced in React Native version 0.70. In the current architecture, all the native modules used by JavaScript (such as Bluetooth, geo location, and file storage) have to be initialized before the app is opened. This means that even if the user doesn’t require a particular module, it still has to be initialized at start-up, which can negatively impact the performance of the app. Turbo Modules addresses this issue by allowing JavaScript to hold references to the modules, which means that each module is only loaded when it is required. This improves the start-up time of React Native apps by reducing the number of modules that are initialized at start-up. This can significantly improve the overall performance of the app and provide a better user experience. In summary, Turbo Modules is a new system for managing modules that was introduced in React Native version 0.70. It allows JavaScript to hold references to the modules, which means that each module is only loaded when it is required, significantly improving the start-up time of React Native apps. This can improve the performance of the app and provide a better user experience. ● CodeGen: The new architecture of React Native includes a static type checker called CodeGen, which helps ensure smooth communication between the dynamically typed JavaScript and the statically typed C++ used in JSI and Turbo Modules. CodeGen uses the typed JavaScript as the source of truth and defines the interface elements used by Turbo Modules and Fabric. This allows for better communication 11
  • 12. between the JavaScript and C++ code, and improves the performance of the app by reducing the amount of code that needs to be generated at runtime. CodeGen generates native code at build time, instead of runtime, which improves the performance of the app by reducing the amount of computation required at runtime. This results in a faster and more efficient app that performs better and provides a better user experience. In summary, CodeGen is a static type checker that was introduced in the new architecture of React Native. It helps ensure smooth communication between the dynamically typed JavaScript and the statically typed C++ used in JSI and Turbo Modules. CodeGen uses the typed JavaScript as the source of truth, generates native code at build time, instead of runtime which improves the performance of the app by reducing the amount of computation required at runtime, resulting in a faster and more efficient app that performs better and provides a better user experience. 12
  • 13. Getting Started: React Native CLI vs Expo When starting to work with React Native, one of the first decisions you will need to make is whether to use Expo or React Native CLI. Both tools have their own advantages and disadvantages, and the choice between them will depend on your specific needs and goals. Expo is a toolchain built around React Native that makes it easy to start building a new React Native app. It provides a set of tools and services that simplify the setup process, allowing you to start building your app quickly. Expo also provides a managed workflow, which means that you don't have to worry about setting up the development environment, configuring native modules, or dealing with platform-specific code. Additionally, Expo provides a set of features out of the box such as push notifications, camera, and geolocation. On the other hand, React Native CLI provides a more traditional way of building React Native apps. It requires you to set up your development environment, configure native modules, and deal with platform-specific code. This can be more time-consuming, but it also provides more flexibility and control over your app. React Native CLI is more suitable for advanced developers who want to have more control over their app and want to use third-party libraries that are not supported by Expo. Expo As we have already mentioned, Expo is a set of tools built on top of React Native that helps developers with the troubles of dealing with the native side of app development such as Xcode and Android Studio. It allows developers to focus on the business code logic of their app, instead of worrying about setting up the development environment and configuring native modules. It also provides several helpful features such as the ability to build and run the app on iOS and Android in the cloud, without the need for a Mac machine. One of the biggest limitations of Expo is that it does not allow for custom native code to be added to the app, or for changes to be made in the Xcode or Android project. This means that third-party push notification services, and manual linking of some third-party libraries are not supported by Expo. Additionally, not all iOS and Android APIs are available, and developers have to wait for Expo to implement them. You can read about all the existing limitations of Expo here. You can also see all the pending Feature requests here. However, there are also several advantages to using Expo. For example, linking of third-party libraries can be an advantage because it eliminates the need to deal with CocoaPods installation, which can be messy. Additionally, developers don't need to have their phone plugged into their machine to build the app, and they can do it over wifi. Deploying the app on the Apple or Google stores is also much easier, since Expo takes care of most of the necessary steps. 13
  • 14. Expo also offers Expo modules, which allows developers to use some Expo features in a React Native project built with React Native CLI. Additionally, Expo projects can be "ejected" which will "convert" the Expo app into a real React Native app, allowing developers to continue with React Native CLI and use all the benefits that React Native provides. However, this process is not reversible and not recommended. You can learn more about it here. In summary, Expo is a set of tools built on top of React Native that simplifies the process of dealing with the native side of app development, such as Xcode and Android Studio, and provides several helpful features. However, it does not allow for custom native code to be added to the app, or for changes to be made in React Native CLI React Native CLI, on the other hand, is a more advanced option for building React Native apps. Unlike Expo, it requires developers to be familiar with Xcode and Android Studio, as well as other tools and processes required for native mobile development such as dealing with Gradle, CocoaPods, and similar technologies. Setting up the development environment, especially on Macs with Apple Silicon, can be challenging and you may encounter errors that only appear on certain types of machines. React Native CLI is also more suitable for developers who want more control over their app, and want to use third-party libraries that are not supported by Expo. This includes older third-party libraries that require manual linking, which means making changes to the code inside the ios and android folders, and changing properties in the Xcode and Android Studio projects. You can learn more about Linking Libraries here. In summary, React Native CLI is a more advanced option for building React Native apps, suitable for developers who want more control over their app, and want to use third-party libraries that are not supported by Expo. It requires developers to be familiar with Xcode and Android Studio, as well as other tools and processes required for native mobile development, and setting up the development environment can be challenging. 14
  • 15. Setting up the Development Environment Setting up the development environment for React Native can be a challenging task, especially if you're new to mobile app development. It is crucial to read the official environment setup guide carefully and not to skip any steps. Failure to do so may result in the need to reinstall everything and start from scratch. When you open the official environment setup guide, you will have a guide for Expo and a guide for React Native CLI. Make sure to select the appropriate guide for your needs. The guide for Expo is relatively straightforward, but for React Native CLI, there are some additional steps that need to be taken. If you are using a Mac with Apple Silicon, it is important to be aware that there may be some issues that can occur during the setup process. These issues are not as common on Windows, Linux, or Macs with Intel CPUs, but they can happen. It is important to pay extra attention to the instructions provided in the official guide, and if you encounter any issues, refer to the troubleshooting section or seek help from the React Native community. Before diving into the setup process for React Native CLI, there are a few tools that are essential for a smooth and successful setup. ● Homebrew: For Mac and Linux users, installing Homebrew is highly recommended. Homebrew is a package manager that makes it easy to install and manage software on your machine. You can find the installation guide here. ● xCode: For Mac users, installing Xcode is also necessary. It is the official development environment for iOS and macOS apps. It is important to note that for the latest version of React Native (v0.70), it is recommended to use Xcode 14.0.1, as there have been some issues reported with React Native and Xcode 14.1.0. ● Android Studio: For Android development, Android Studio is required. It is the official development environment for Android apps and the latest version can be downloaded from the official website. ● Node/Ruby: Additionally, to ensure that you have the right version of Node.js and Ruby, it is recommended to install NVM (Node Version Manager) and RVM (Ruby Version Manager) respectively. NVM allows you to easily switch between different versions of Node.js and manage them on your machine. You can find the installation guide here.RVM serves the same purpose as NVM but for Ruby. You can find the installation guide here. By installing these tools before starting the setup process, you will be better equipped to handle any issues that may arise during the setup and ensure that your development environment is set up correctly. *If you are working on a Mac with Apple Silicon, I would suggest turning on Rosetta mode for both Terminal and xCode. To do that, in the Finder App, go to the Applications folder, then in the 15
  • 16. Utilities folder you will find the Terminal app. Right-click on it, and select Get Info then check the Open using Rosetta, and do the same for xCode, which you can find in the Applications folder. Once you have set up Rosetta mode, the next step is to install Node and Watchman. It is recommended to use Homebrew to install them, so in the Terminal app, execute the following commands (make sure you have installed Homebrew and have restarted the Terminal after installing it): brew install node brew install watchman It's important to note that these steps are for Mac users only, if you are using Windows or Linux, please follow the official guide for the specific setup instructions for your operating system. iOS Setup After following the official guide and installing Homebrew, Node and Watchman, the next step is to install the appropriate Ruby version for the selected React Native version. You can check which version is required by visiting the official guide and selecting the React Native version from the dropdown menu. Once you have determined the required version, use RVM to install and use it by executing the following commands in the terminal: rvm install 2.7.6 rvm use 2.7.6 After installing the appropriate Ruby version, continue following the official guide and open xCode. In the preferences, select the Command Line tools. Keep in mind that the version of the Command Line tools will depend on the version of xCode you are using. 16
  • 17. Before proceeding, it is important to note that the React Native version you are using may have different requirements for the Ruby version. Be sure to check the official guide for the specific version you are working with to ensure you are using the correct version of Ruby. With that said, once you have installed the required Ruby version, you can proceed to create a new React Native project using NPX. To do this, execute the following command in the terminal, replacing "AwesomeProject" with the desired name for your project: npx react-native init AwesomeProject If you encounter errors while downloading the template or installing the cocoa pods, try navigating to the ios folder within your project and running the command `pod install`. cd ios pod install *If you still encounter errors, you may need to switch to a different Ruby version and try `pod install` again. One version that has been known to work well is 3.1.2. To switch to this version, navigate to the ios folder within your project and run the following commands: rvm install 3.1.2 rvm use 3.1.2 pod install 17
  • 18. After successfully installing the pods, you can now run the app by executing the command in the root directory of your project. This will start the Metro bundler in a new terminal window and launch the iOS simulator with your newly created app running inside it: npx react-native run-ios However, if you encounter an error stating that the simulator with a certain name is not found, or if you want to run the app on a different simulator, you can do so by opening xCode and launching the simulator manually. To do this, right-click on xCode in the Dock and select "Open Developer Tool" then "Simulator". From there, you can select the desired simulator from the top of the Simulator app. You can also specify the simulator by its name when running the app with the command npx react-native run-ios --simulator='iPhone SE (2nd generation)' 18
  • 19. It's important to mention that, even though this guide should help you with most of the issues you may encounter, some problems may still appear, because of different versions of the tools, or different configurations of the machine. But don't worry, the React Native community is huge, and you can always find some help on the official documentation, or on the forums like Stack Overflow. Android Setup Before moving forward with the Android setup for React Native, it's important to ensure that you have the necessary tools installed. The first step is to install the Java Development Kit (JDK). This can be done easily by using Homebrew, a package manager for MacOS and Linux. To install JDK, open your terminal and run the following commands: brew tap homebrew/cask-versions brew install --cask zulu11 After JDK is installed, you need to install the Android SDK. This can be done by downloading and installing Android Studio, the official IDE for Android Development. Once Android Studio is installed, open it and navigate to the SDK Manager. From there, select the Android SDK version specified in the React Native guide and install it. Additionally, it's also recommended to install the Android SDK Command-line tools, which can be found in the SDK tools tab in the SDK Manager. 19
  • 20. Next, you will need to add some system environment variable paths, so you can run the project from the command line. One way to do this is by using VSCode. To set the environment variable paths, you will need to edit the .zshrc file with admin permissions. To do this, open your terminal and navigate to the home folder, then execute the following command: sudo code .zshrc If you get an error message saying that code cannot be found, open VSCode, press cmd+shift+P and type "shell command" until you see the "Shell Command: Install 'code' 20
  • 21. command in PATH" option and press enter. After that, restart the terminal and you should be able to run the "code" command inside the terminal. After that add those paths in the file: export JAVA_HOME=/Applications/"Android Studio.app"/Contents/jre/Contents/Home export ANDROID_HOME=$HOME/Library/Android/sdk export PATH=$PATH:$ANDROID_HOME/emulator export PATH=$PATH:$ANDROID_HOME/tools export PATH=$PATH:$ANDROID_HOME/tools/bin export PATH=$PATH:$ANDROID_HOME/platform-tools Then, save the file, and execute the following command in the terminal: source .zshrc After setting up the environment variables, you can try running your application by executing the following command in the terminal: npx react-native run-android If the setup was done correctly, the Android emulator should start after a few minutes and your app should start running inside it. If you encounter an error stating that the metro bundler is not running, simply open the terminal and navigate to the root of your project, then run: npm start or: yarn start if you are using yarn. After that, reload the app in the emulator (there will be a Reload button below the error in the emulator) or simply quit and start the app again. If you still encounter an error, try running the following adb command in the terminal: adb reverse:8081 tcp:8081 and then reload the app again. After that, reload the app again, and it should work. If for some reason the app doesn't build and start from the command line, it means that there is an issue with the environment setup. You can try opening the android folder of your app inside 21
  • 22. Android Studio, wait for gradle to sync and download all the dependencies, and then click the green arrow to start the project. If you still encounter issues, you can refer to the Troubleshooting page, which can help you solve further problems, you can check it here. Folder Structure of a React Native project If you check the newly created React Native project, you will notice multiple files and folders, and in the following text, I will try to explain those files and folders. ● __tests__: This folder contains all the tests for your application. ● android: This folder contains the Android native code for your project. Any changes to the Android specific parts of the project such as linking libraries, adding permissions, custom fonts, etc. should be made in this folder. ● ios: Similar to the android folder, this folder contains the iOS native code for your project. ● src: This folder serves as the root for all your source code. It contains all the JavaScript and React-related code for your application. ● App.js: This is the entry point for your app, and it is the first component that will be mounted and rendered. ● app.json: This file contains some configuration for your app, such as its name and other properties that are referenced in the index.js file. ● babel.config.js: This file contains the configuration for the Babel transpiler, which transpiles the React syntax code to something that JavaScript engines can understand. You can find out more here. ● Gemfile: This file contains all the Ruby dependencies needed for your application. ● Index.js: This is the entry point for your application, where you specify which component should be mounted and rendered first. ● metro.config.js: This file contains configuration for the metro bundler, which is used for bundling your application. You can find out more here. ● package.json: This file contains all the node dependencies and other properties related to your application. You can find out more here. My common practice is to add the “engine” object inside the package.json, where I specify node and yarn version, so when other developers join the project, and try to run yarn install or npm install, the error will pop up if they don't have the same version installed, and this is to make sure all developer work in the same setup: "engines": { "node": "v16.10.0", "yarn": "1.22.19", } If you are not sure how to structure your new project, here and here you can find some best practices that cover that topic more deeply. 22
  • 23. xCode and Android Studio As I have mentioned previously, while working with React Native CLI, unlike Expo, from time to time you have to deal with xCode and Android Studio to solve different problems. Here I will give you a short introduction to both IDEs, and the most necessary things you need to know in both. xCode Xcode is the official Integrated Development Environment (IDE) for iOS and macOS development. It is a powerful tool that allows developers to create, design, and test their applications for Apple platforms. With Xcode, you can create user interfaces, write code, and debug your applications with ease. It provides a wide range of features that are essential for iOS development such as a visual editor, a code editor, a debugging tool, and an integrated testing framework. Xcode also includes several other tools that are useful for iOS development, such as the Interface Builder, which is a visual editor for creating user interfaces, and the Simulator, which allows you to test your applications on different iOS devices. Additionally, Xcode has a built-in Git integration, which allows you to easily manage and track changes to your codebase. 23
  • 24. The leftmost panel is the Project Navigator (Project Structure), which allows you to navigate through the different files and folders in your project. The center panel is the Editor area, where you will write and edit your code. The rightmost panel is the Utilities area, which contains a number of different tools and inspectors that you can use to further customize and debug your project (in our case it is closed and not visible right now). In the top of the screen, you will find the toolbar, which contains various buttons and controls that allow you to perform various tasks, such as running your app in the simulator, debugging your code, and more. It is important to note that when opening your React Native iOS project in Xcode, you should open the workspace file (.xcworkspace) rather than the project file (.xcodeproj) as the workspace file contains the pods (dependencies) that are necessary for your project to run. Additionally, after opening the project in Xcode, you will have to make sure that the pods are installed. If not, you may see some errors and will have to go to the terminal and run the command "pod install" in the ios folder of your project. After opening the project in xCode, you will see something like the picture bellow: If you select the Project from the Project Structure, you will see some more options, like on the picture bellow: 24
  • 25. If you want to run your application in a Release mode, without the need of the metro bundler running in the background, you will select the project name in the top of xCode: And select Edit Scheme… from there, and then you will see something like this: 25
  • 26. From here, you can select the Build Configuration as Release and then run the project. This will allow you to run the app on a device without being connected to your computer. Keep in mind that if you don't have an Apple Developer account and have paid the annual fee of $100, you will only be able to use Temporary Certificates and Provisioning Profiles for your app. These will expire after one week, and you will need to reinstall the app or it will no longer be able to run. Additionally, there is a limit on how many bundle IDs you can register per week, so it's best to use one bundle ID for all test apps you create or use a bundle ID from a previous app when you are ready to release. To add additional capabilities such as permissions or custom fonts, you will need to edit the Info.plist file located at PROJECT_ROOT/ios/PROJECT_NAME/Info.plist. This can be done either by using a text editor like VSCode or by opening the file in Xcode. From here, you can add new properties by clicking the "+" button under the Info tab and selecting the desired property from the dropdown. 26
  • 27. If you want to change the icon of your iOS app manually (there are some npm packages to help you with this, like this one), open the project with xCode, then from the project structure select PROJECT_NAME/PROJECT_NAME/Images. Then you will need your app icon in multiple dimensions, so drag and drop all the files in the right place.There are also some online tools like this one, that will auto generate all the icon dimensions for you, just upload the 1024x1024 version, and click generate. Then download the zip file, unzip it, rename the Assets.xcassets to Images.xcassets and replace the Images.xcassets file located in your ios folder with the one that is located in the file you have downloaded. Here you can find some useful tips and tricks regarding xCode usage. Android Studio Android Studio is the official IDE for Android development, developed by Google. It is based on JetBrains IntelliJ IDEA and offers a wide range of features that are essential for Android development, such as a visual editor, a code editor, a debugging tool, and an integrated testing framework. 27
  • 28. Android Studio also includes several other tools that are useful for Android development, such as the Android Virtual Device (AVD) Manager, which allows you to create and manage virtual devices for testing your applications, and the Android Emulator, which allows you to test your applications on different Android devices. Additionally, Android Studio has a built-in Gradle integration, which allows you to manage dependencies and build your application with ease. Now we will take a look at the Android World, and the Android Studio. On the welcome screen, in the More Actions dropdown, you will find the most of the tools you will need. The most important will be the Virtual Device Manager, which is the Simulator alternative from the iOS world. From there you can launch and manage your Android Emulators. If your development environment is setted up correctly, you can also launch the emulator from the Terminal, just execute the following command to list all the emulators: emulator -list-avds 28
  • 29. Then execute the following command to start the emulator (make sure you have the '@' symbol before the emulator name): emulator @some_android_emulator If you open the android folder with Android studio, gradle project will start syncing, which may take few minutes, and then you will see this screen: If you want to run your application in a Release mode, without the need of the metro bundler running in the background, you will select the Build Variants from the left menu (it's shown in the picture above, below the project structure), and from the dropdown select ‘Release’. Then try running the app: 29
  • 30. To change the app icon we will use the files from the site that generated the files from us. In the same file, there is also an android folder with some files inside, so just copy those files, and paste them over the existing ones in ‘PROJECT_ROOT/android/app/src/main/res’. Then try to run the app, if some error appears that says something like ‘error: resource mipmap/ic_launcher_round not found’, open the AndroidManifest.xml which is located under PROJECT_NAME/app/manifests/AndroidManifest.xml, and remove the ‘android:roundIcon="@mipmap/ic_launcher_round"’, which is optional. You can also modify some capabilities of the app in this file, same like we did in the Info.plist for iOS. Here you can find some useful tips and tricks regarding Android Studio usage. 30
  • 31. React Native Core Components So to make one thing clear, unlike ReactJS where we have JSX that looks and feels like HTML, here we don’t have that. Although once you get used to it will feel the same, we are dealing with predefined components/tags like we have with JSX, but they differ a bit. The writing of the JSX is the same, you have components, that unlike ReactJS, here we import them either from ‘react-native’ or from some third party library. We can also have props inside them, and values between tags. Unlike ReactJS, React Native does not use JSX that resembles HTML. Instead, it uses predefined components/tags that are imported from either 'react-native' or third-party libraries. These components have props and values similar to JSX. React Native provides a wide range of core components, and you can also find many more online. Some of these components are platform-specific, meaning they are shared on both Android and iOS, while others are specific to either iOS or Android. Additionally, some of the props available are platform-specific, so it's important to keep that in mind when building your app. Here are some of the most commonly used core components provided by React Native: 31
  • 32. ● View: A basic container for other components. It can be used to create layouts, apply styles, and handle user interactions. ● Text: A component for displaying text on the screen. It supports styling, such as bold, italic, and underlining, as well as text wrapping. ● TextInput: A component for receiving user input, such as text, numbers, or password. It supports various features such as keyboard type, placeholder, and validation. ● Button: A component for creating buttons with various styles and behaviors. It supports features such as onPress, onLongPress, and disabled. ● Image: A component for displaying images on the screen. It supports various features such as source, style, and resize mode. ● FlatList: A component for displaying lists of data. It supports features such as scrolling, refreshing, and pagination. ● Alert: A component for displaying alerts and dialogs. It supports features such as title, message, buttons, and callbacks. ● ActivityIndicator: A component for displaying a loading indicator. It supports features such as size, color, and animation. React Native also allows developers to use third-party libraries and components to add additional functionality to their apps. These can be installed using npm or yarn and are a great way to add features such as navigation, forms, and animations. It's important to note that some React Native components and props are platform-specific, meaning they are only available on either iOS or Android. This is something to keep in mind when building your app as it may affect the way you structure and design your components. In conclusion, React Native core components are a powerful tool for building cross-platform mobile apps and can be customized as per need. With the help of third-party libraries, developers can easily add additional functionality to their apps, making React Native a versatile and efficient framework for mobile app development. 32
  • 33. Styling React Native uses Flexbox for styling and does not use pixels, but instead uses density-independent pixels (dp or dip). This allows for consistent styling across different screen densities and resolutions. When it comes to styling React Native applications, there are three main options to consider: ● React Native Stylesheet object: This is the built-in way of styling in React Native and allows for the creation of stylesheets that can be applied to components. Stylesheets can be created using JavaScript objects and have a similar syntax to CSS. You can learn more here. ● Styled Components: This is a popular library that allows for the creation of reusable and composable component-based styles. It uses a syntax similar to CSS-in-JS and allows for dynamic styling based on the component's props. You can learn more here. ● Emotion: This is another popular library that allows for the creation of component-based styles using a similar syntax to CSS-in-JS. It also supports server-side rendering and has a smaller bundle size compared to Styled Components. You can learn more here. There are few more that you may consider: ● Restyle: The Restyle library provides a type-enforced system for building UI components in React Native with TypeScript. It's a library for building UI libraries, with the ability as the core focus. ● Tamagui: Tamagui introduces a novel optimizing compiler for React that evaluates your code at build-time, turning heavy JS into flatter trees and much faster CSS. The result is more codeshare %, less dev time, and lighter, faster apps. ● NativeWind: NativeWind is built upon the Tailwind CSS style language. As such the core-concepts of Tailwind CSS apply to NativeWind. ● Dripsy: Dripsy is a responsive design system for. @expo. + @reactnative. web with one goal: style once, run anywhere. ● NativeBase: NativeBase is an accessible, utility-first component library that helps you build consistent UI across Android, iOS and Web. You can find more info about their differences here. When deciding on the styling library to use, it's important to consider the specific requirements of the project and the skillset of the development team. All of these libraries are widely used and well-documented, and any of them can be used to effectively style React Native applications. In addition to the above options, there are also other styling libraries available for React Native such as Glamorous, Aphrodite, and Radium. It's a good idea to do some research and compare the different options to find the one that best fits your needs. 33
  • 34. Another important thing to consider is the accessibility of your app, as some libraries handle accessibility better than others. It's important to follow best practices and guidelines to ensure that your app can be used by people with disabilities. In conclusion, React Native provides multiple options for styling your application, each with its own benefits and trade-offs. It's important to do your own research, understand your project requirements, and pick the one that fits your needs best. 34
  • 35. Platform Specific Code When developing cross-platform apps, it is often necessary to handle different behaviors and styles for different platforms. React Native provides two options for handling platform-specific code: ● The Platform module from react-native: This module provides several static methods that can be used to check the platform, such as Platform.OS, Platform.Version, and Platform.select. These methods can be used in conjunction with ternary operators to conditionally render different code depending on the platform. ● Platform-specific extensions: This approach involves creating multiple files, one for each component, with a specific extension, and React Native will load the right one depending on the system. For example, if you want a separate Button component for iOS and Android, you can create two files: ○ Button.ios.js ○ Button.android.js This way, you can write the components as separate, unique components and won’t have to do any platform checks in them. This approach is particularly useful when the code for each platform is vastly different and using the Platform module would lead to a large, chaotic component. It's worth noting that there are also platform-specific extensions for Windows and macOS (.windows.js and .macos.js). When deciding which approach to use, it's important to consider the complexity of the platform-specific code. Using the Platform module is useful for small differences between platforms, but when the code differences are large and complex, the platform-specific extensions approach is more appropriate. In conclusion, React Native provides several options for handling platform-specific code, such as the Platform module and platform-specific extensions. By understanding the different options available and the complexity of the platform-specific code, developers can make an informed decision on which approach to use, and write efficient and maintainable code. You can learn more about handling platform specific code here. 35
  • 36. Permissions When we want to use some extra device capabilities, we need to inform the user that our application will need that permission in the Application Store, and we need to ask the user for that permission. iOS In iOS we can specify the new permissions in the Info.plist file (PROJECT_ROOT/ios/PROJECT/_NAME/Info.plist), and we can edit that file either with some code/text editor, or from within xCode. To add for Example camera permissions we need to add this two properties in the Info.plist file: <key>NSCameraUsageDescription</key> <string>we need to use the camera to take some Photos</string> As you can tell, the properties go in pairs, where the key value is very important, and under the string we need to describe why we need that permission with our own words. Android For android we are adding the permissions in the AndroidManifest.xml (PROJECT_ROOT/src/main/AndroidManifest.xml), and to add the camera permission for our app, we need to add this properties in the AndroidManifest: <uses-permission android:name="android.permission.CAMERA" /> And we add the permissions before the <application> property but inside the <manifest> one. 36
  • 37. Adding custom Fonts Adding a custom font was a little bit challenging before React Native v0.69 (before 0.60 it was even harder, you can read more about it here), but with React Native v0.69, the react-native-assets command was added for the npx, so with running that command, the new assets will be automatically linked. So let's say we want to add the Roboto font into our app. We can download that font from Google Fonts here. After downloading it, create a folder called assets/fonts in the root of our project. Than create a file called react-native.config.js in the root of our project, with the following content: module.exports = { project: { ios: {}, android: {}, }, assets: ['./assets/fonts/'], }; Next is to link the assets, so run the following command from the root of our project: npx react-native-asset The terminal will ask you to install the react-native-asset dependency, enter Y and it will install it. Now simply change the fontFamily for some of the style objects, and you will see it with the new font: fontFamily: 'Roboto', 37
  • 38. Navigation When we want to introduce multiple screens to our application with some nice navigation capabilities I would suggest using this third party library, which is used by most of the developers. Installing To begging, we first need to install the react-navigation package by executing this command in the terminal (I am simply following the getting started guide which you can find here): npm install @react-navigation/native This package depends on some other dependencies, so we need to install those too: npm install react-native-screens react-native-safe-area-context Then we need to make some changes in the android project, so open the MainActivity.java (which is located in android/app/src/main/java/PROJECT_NAME/MainActivity.java), and in the MainActivity class add the following code: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(null); } And don't forget to add the needed import on the top of MainActivity.java: import android.os.Bundle; Now you can try running both iOS and Android apps, by running yarn run ios and yarn run android (these are short commands you can use instead of using npx react-native, and you can use them with yarn or npm). Add stack screen navigation We can think of a Stack navigation as an Array, where we are maintaining the screens in the Stack navigation by pushing and popping different screens, you can read more about it here. 38
  • 39. To use the stack navigation we need to instal the native-stack dependency: yarn add @react-navigation/native-stack And after that we need to update the pods by executing pod install in the ios folder of the Project. Then we need to create our Stack, and you can do this outside our App component for example, like this: const Stack = createNativeStackNavigator(); function App() { . . . Next we need to wrap our entire App in a NavigationContainer and its best practice to do this in the App.js. Then we can start creating our Stack navigation: function App() { return ( <NavigationContainer> <Stack.Navigator initialRouteName="Home"> <Stack.Screen name="Home" component={HomeScreen} options={{title: 'Overview'}} /> <Stack.Screen name="Details" 39
  • 40. component={DetailsScreen} options={{title: 'Info'}} /> </Stack.Navigator> </NavigationContainer> ); } As you can see, first we need to put all our Screens inside a Stack.Navigator where we can also define our initialRoute, which will be our Home screen in our case, and our screens are identified by the name property, so make sure that the names of our screens are unique and have in mind that they are case sensitive. Then as we can already see from the code above, we are defining all our screens for this Stack navigator where we provide the name and the component for every screen, and we can also add some options to it, in our case we re modifying the title which we can see on the top of the screen, and in our case we have change the ‘Home’ to ‘Overview’ (the name value will be the Screen title by default), you can read more about the different screen options here: 40
  • 41. The components we use for the screen are normal components, in which you can also access the navigation prop which can be used for manipulating the Screen stack: function HomeScreen({navigation}) { return ( <View style={styles.screenContainer}> <Text>Home Screen</Text> <Button title="Go to Details" onPress={() => navigation.navigate('Details')} /> </View> ); } From the example above you can see that we can use the navigation prop object to navigate to a different screen, the Details screen in our example, and by calling the navigate() function we are simply pushing the DetailsScreen on the top of our Stack ‘array’. We can also send some extra info to our screens when navigating to them like this: navigation.navigate('Details', { itemId: Math.floor(Math.random() * 100), otherParam: 'anything here take two', }); And we can access the data we sent from the route prop that we can access from our screen like this: function DetailsScreen({navigation, route}) { const {itemId, otherParam} = route.params; return ( <View style={styles.screenContainer}> <Text>Details Screen</Text> <Text>otherParam: {JSON.stringify(otherParam)}</Text> <Text>itemId: {JSON.stringify(itemId)}</Text> Here is the entire code of our simple Stack example: import * as React from 'react'; import {Button, View, Text, StyleSheet} from 'react-native'; import {NavigationContainer} from '@react-navigation/native'; import {createNativeStackNavigator} from '@react-navigation/native-stack'; function HomeScreen({navigation}) { return ( <View style={styles.screenContainer}> <Text>Home Screen</Text> <Button title="Go to Details" 41
  • 42. onPress={() => navigation.navigate('Details', { itemId: Math.floor(Math.random() * 100), otherParam: 'anything you want here', }) } /> </View> ); } function DetailsScreen({navigation, route}) { const {itemId, otherParam} = route.params; return ( <View style={styles.screenContainer}> <Text>Details Screen</Text> <Text>otherParam: {JSON.stringify(otherParam)}</Text> <Text>itemId: {JSON.stringify(itemId)}</Text> <Button title="Go to Details... again" onPress={() => navigation.navigate('Details', { itemId: Math.floor(Math.random() * 100), otherParam: 'anything here take two', }) } /> <Button title="Go back" onPress={() => navigation.goBack()} /> </View> ); } const Stack = createNativeStackNavigator(); function App() { return ( <NavigationContainer> <Stack.Navigator initialRouteName="Home"> <Stack.Screen name="Home" component={HomeScreen} options={{title: 'Overview'}} /> <Stack.Screen name="Details" component={DetailsScreen} options={{title: 'Info'}} /> </Stack.Navigator> </NavigationContainer> ); } 42
  • 43. export default App; const styles = StyleSheet.create({ screenContainer: { flex: 1, alignItems: 'center', justifyContent: 'center', }, }); Add Bottom Tab navigation Another type of navigation we can use in our app is the Tab navigation, and in this document I will only cover the bottom tab navigation, but react-native-navigation provides multiple APIs for tab navigation: ● Bottom Tabs: A simple tab bar on the bottom of the screen. ● Material Bottom: Tabs A material-design-themed tab bar on the bottom of the screen. ● Material Top Tabs: A material-design-themed tab bar on the top of the screen. To add bottom tab navigation to our app first we need to install the needed dependencies: yarn add @react-navigation/bottom-tabs And install the pods by running pod install inside the ios folder. Next we will modify the previous example and add a Bottom Tab Navigation with two tabs, and we will keep the stack navigation from the previous example too, and our example will look something like this: 43
  • 44. To begging we will need to create the Bottom Tab Navigator in the similar way we did with the Stack Navigator: const Tab = createBottomTabNavigator(); Next we will move the JSX from the HomeScreen into a new Component and we can call it HomeTab and in the HomeScreen we will put our Tab Navigation like this: function HomeScreen() { return ( <Tab.Navigator 44
  • 45. screenOptions={{ tabBarActiveTintColor: '#d2e245', tabBarActiveBackgroundColor: '#20434f', tabBarInactiveBackgroundColor: '#20434f', headerStyle: { backgroundColor: '#20434f', }, headerShadowVisible: false, headerTintColor: '#d2e245', }}> <Tab.Screen name="Home" component={HomeTab} /> <Tab.Screen name="Settings" component={SettingsTab} /> </Tab.Navigator> ); } As you can see we have something similar like with the Stack Navigation, and we put our screens inside a Tab.Navigator. We can also change some options for our Tab.Navigator within the screenOptions object. The final code of our App.js looks something like this: import * as React from 'react'; import {Button, View, Text, StyleSheet} from 'react-native'; import {NavigationContainer} from '@react-navigation/native'; import {createNativeStackNavigator} from '@react-navigation/native-stack'; import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'; const Stack = createNativeStackNavigator(); const Tab = createBottomTabNavigator(); function HomeScreen() { return ( <Tab.Navigator screenOptions={{ tabBarActiveTintColor: '#d2e245', tabBarActiveBackgroundColor: '#20434f', tabBarInactiveBackgroundColor: '#20434f', headerStyle: { backgroundColor: '#20434f', }, headerShadowVisible: false, headerTintColor: '#d2e245', }}> <Tab.Screen name="Home" component={HomeTab} /> <Tab.Screen name="Settings" component={SettingsTab} /> </Tab.Navigator> ); } function HomeTab({navigation}) { 45
  • 46. return ( <View style={styles.screenContainer}> <Text>Home Tab</Text> <Button title="Go to Details" onPress={() => navigation.navigate('Details', { itemId: Math.floor(Math.random() * 100), otherParam: 'anything you want here', }) } /> </View> ); } function SettingsTab({navigation}) { return ( <View style={styles.screenContainer}> <Text>Settings Screen</Text> <Button title="Go to Details" onPress={() => navigation.navigate('Details', { itemId: Math.floor(Math.random() * 100), otherParam: 'anything you want here', }) } /> </View> ); } function DetailsScreen({navigation, route}) { const {itemId, otherParam} = route.params; return ( <View style={styles.screenContainer}> <Text>Details Screen</Text> <Text>otherParam: {JSON.stringify(otherParam)}</Text> <Text>itemId: {JSON.stringify(itemId)}</Text> <Button title="Go to Details... again" onPress={() => navigation.navigate('Details', { itemId: Math.floor(Math.random() * 100), otherParam: 'anything here take two', }) } /> <Button title="Go back" onPress={() => navigation.goBack()} /> </View> ); 46
  • 47. } function App() { return ( <NavigationContainer> <Stack.Navigator initialRouteName="Home"> <Stack.Screen name="Home" component={HomeScreen} options={{title: 'Overview'}} /> <Stack.Screen name="Details" component={DetailsScreen} options={{title: 'Info'}} /> </Stack.Navigator> </NavigationContainer> ); } export default App; const styles = StyleSheet.create({ screenContainer: { flex: 1, alignItems: 'center', justifyContent: 'center', }, }); There is also a Drawer Navigation but I won’t write about it here, you can learn more here. Deep Links https://medium.com/bumble-tech/universal-links-for-android-and-ios-1ddb1e70cab0 https://medium.com/@ertemishakk/implement-universal-links-in-react-native-d3602ae6ea2 https://www.bam.tech/article/how-to-make-a-complete-app-site-association-with-universal-links https://blog.logrocket.com/understanding-deep-linking-in-react-native/ Now we are going to take a look at one nice feature that we can add to our app which is called deep links. Deep linking allows users to access specific pages, products, or actions within an app directly from a link, rather than having to navigate through the app to find the content. This can make the user experience more seamless, as users are taken directly to the content they are looking for. Deep links can also be used to personalize the user experience by pre-filling forms or automatically logging users into the app. 47
  • 48. Deep linking can also be used for marketing and advertising purposes, such as by allowing advertisers to direct users to a specific page within an app to encourage them to make a purchase or by allowing app developers to track user behavior within the app. Deep links can be used within apps or across different apps, which means that a user can be directed to a specific location within an app even if they were not previously using that app. Deep linking can be implemented using various technologies, such as Universal Linking (iOS), App Link (Android) and URI Schemes. Universal Linking (iOS) is a feature that allows developers to associate their website with their iOS app, so that when a user taps a link to the website on an iOS device, the corresponding page in the app will open instead of the website. This allows for a seamless user experience, as users are taken directly to the content they are looking for within the app. App Link (Android) is similar to Universal Linking, but for Android devices. It allows developers to associate their website with their Android app, so that when a user taps a link to the website on an Android device, the corresponding page in the app will open instead of the website. URI Schemes are a way to launch an app using a specific URL format. By using a specific URL format, an app can be launched and directed to a specific location within the app. For example, the URL "myapp://product/1234" could open the "My App" app and take the user directly to the product page for product 1234. Deep links can also be used in push notifications, email and social media campaigns. By including a deep link in a notification or email, users can be directed to a specific location within an app, even if the app is not currently running on their device. In summary, deep linking is a powerful tool that allows users to access specific pages, products, or actions within an app directly from a link, and also allows developers to track user behavior, personalize the user experience and to use it for marketing and advertising purposes. It can be implemented using various technologies such as Universal Linking (iOS), App Link (Android) and URI Schemes. Now we are going to follow the React Navigation guide for implementing deep links which can be found here. Basically our idea is to open our app and some specific screen and maybe pass some data which can be used on that screen, same like we do it on the web, for example on our website we can have some url like this https://www.example.com/details/?itemId=123 and in our code we can pick up the query string “?itemId=123” and we can use that itemId and its value on our details page. The idea with the deep links its the same, we want to have a custom “protocol” (URI scheme) and we can name it whatever we want, and for our example we will use “melonapp://” and use that to access our app, for example we can put this link on some website 48
  • 49. “myapp://details/?ItemId=123” and if we click on that link from our phone, our app will open to the details screen and we can access the itemId we have passed in the deep link and show it on the screen. So let's start. If we follow the documentation, it says that first we need to make some changes in the ios project. Open the AppDelegate.mm with VsCode or xCode and first import RCTLinkingManager.h (make sure you put it before “#if RCT_NEW_ARCH_ENABLED” or your app won't build): And add this peace of code at the end of the file, before the @end: // Add this inside `@implementation AppDelegate` above `@end`: - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options { return [RCTLinkingManager application:application openURL:url options:options]; } 49
  • 50. Next we need to add our custom uri-scheme, so we can either do it manually from xcode, or from the terminal, and in our case I will use the terminal. To do that, execute the following command from the root of our project: npx uri-scheme add melonapp --ios To test if everything works we can run the following command from our terminal: npx uri-scheme open melonapp:// --ios If you have done everything right the popup will appear to open the link into your app, or the app will start automatically. To setup the deep link for android, simply run the following command from the root of our project: npx uri-scheme add melonapp --android And now if you run the following command the app should start: npx uri-scheme open melonapp:// --android You can also add this link to a note or a contact on your device (ios/android) or the simulator, and when you click on that link the app should start, but have in mind that if you type the link in the browser it won't work, it only work if the link is clicked and handled by the OS. 50
  • 51. For this example we will add two deep links, one which we can use to go to the settings screen, and one for the details screen on which we will pass the itemId. First we need to add some configuration for our deep links: const config = { screens: { Home: { screens: { Settings: 'settings', }, }, Details: 'details/:itemId', }, }; const linking = { prefixes: ['melonapp://'], config, }; In our config object we have our routes configured, and since our Setting screen is a screen from a nested navigation in our Home screen, first we need to add the Home screen and inside its screens we add the Settings. Have in mind that the property names in this object (“Home” and “Settings” must be exactly the same as the name property of the actual screen in the navigation). To add a parameter in our deep link we use SCREEN/:PARAMETER_NAME, or in our case we want to pass itemId to our details screen or in our case “melonapp://details/123” and in our code we will have the item ide under route.params.itemId. As a final part we add the linking object as a part to our NavigationContainer and we are done: <NavigationContainer linking={linking}> Now if we execute the following command from the terminal: npx uri-scheme open melonapp://settings --ios The setting screen will open in our app, and if we execute the following one: npx uri-scheme open melonapp://details/1414 --ios The details screen will open and we will have the 1414 value printed in its place. 51
  • 52. 52
  • 53. Push Notifications https://enappd.com/blog/firebase-push-notifications-in-react-native/81/ https://developers.connectycube.com/reactnative/push-notifications Introduction Push notifications are messages or alerts delivered by an application to a device, even when the user is not actively using the app. They are typically used to inform the user of new events or updates within the app, such as receiving a message or a friend request. These notifications can appear on the lock screen or in a notification center, and can also include sounds or vibration alerts. They are often used to keep users engaged with an app and to remind them to open it. Push notifications can be used for a variety of purposes such as to inform the user of new events, updates, or messages within the app, to remind the user to take an action within the app, or to provide personalized recommendations or deals. They are a powerful tool for keeping users engaged with an app and increasing app retention. However, with great power comes great responsibility. Push notifications, if not implemented well, can quickly become a nuisance and lead to users disabling or uninstalling the app. It is important for developers to strike the right balance between providing useful and relevant information, without overwhelming the users with too many notifications or irrelevant messages. Push notifications are delivered through a service called a push notification service, which is provided by the operating system or a third-party service. The service is responsible for routing the notification to the correct device and displaying it to the user. Push notifications have become an essential part of the mobile ecosystem, allowing apps to communicate with users in real-time and providing them with relevant and timely information. These notifications are delivered to a user's device even when the app is not actively being used, and can appear on the lock screen or in a notification center. They can also include sounds or vibration alerts to draw the user's attention. https://www.desuvit.com/step-by-step-guide-for-implementing-push-notifications-in-ios-using-rea ct-native/ Implementation Before we start we need to prepare a few things. First is the Firebase Account. You can register here. Next is to create a Firebase Project, and to do that, go on the firebase console page and from there click on the Add project button and follow the instructions. 53
  • 54. After your project is created, open the project, and click on it, and you will see like this: After this we will need to create separate firebase apps for iOS and Android. 54
  • 55. iOS Setup To create an ios app click the iOS+ button, and to complete this we will need a paid apple developer account where we can create a new bundle id for our app, and you can do that on the apple developer site, in the Identifiers section click the + button, from the next screen select “App IDs”, next select “App” (not “App Clip”), and from the final screen you can enter a description for this bundle id, and in the “Bundle ID” make sure that Explicit is selected, and enter your bundle id there, and from the Capabilities make sure that “Push Notifications” is selected. Now you can complete the creation of the Firebase App by entering your newly created bundle id, and the end you can download the GoogleService-Info.plist file: 55
  • 56. After this you will need to open our React Native project with xCode (the ios folder) and you can drag the plist file in the folder where the AppDelegate files are (make sure copy if needed is selected from the windows that appears when you drop the file): Next we will need to create a Key from our apple developer account, and now instead of Identifiers, go in the Keys section, and press the + button: On the next screen make sure that you have “Apple Push Notifications service (APNs)” selected, enter a Key Name and Click Continue. With this your Key will be created and you will need to download it, which will download a .p8 file, and you will also need the Key ID which you can copy from this page. 56
  • 57. Now go back to the Firebase console page, and from your project page, select the gear button next to the Project Overview: From here go in the in the “Cloud Messaging” tab, and scroll to the “Apple app configuration” section, and here click the Upload button inside the APNs Authentication Key: 57
  • 58. Click the Upload button, and from the next screen attach the p8 file we have downloaded when generating the Key on the apple developer account, and enter the KeyID which we had on the same page where we have downloaded the p8 file: Now again go back in xCode, and first make sure you have updated the bundle id in the Signing and Capabilities: From the same screen click the “+ Capability” button to add a new capability for our App, and from that screen search for Push Notifications and add it by double clicking on it, after that add one more, and this time search for “Background Modes” and add that one. To finish this, scroll 58
  • 59. to the end of this window where you will see the Capabilities you have added and in the Background Modes make sure “Background Fetch” and “Remote Notifications” is checked: With this our Firebase App is ready for iOS, and now we can focus on our code. To implement Push notifications we are going to use a package called react-native-firebase-push-notifications, and you can follow the installation guide from their page, which is just a dependency installation with npm or yarn, and pod install after that. After this we will need to make some changes in some files in the ios folder. First open the AppDelegate.mm file and just before #if RCT_NEW_ARCH_ENABLED add the following imports: #import "Firebase.h" #import "RNFirebaseMessaging.h" #import "FirebasePushNotifications.h" Next after the @implementation AppDelegate add the following lines: - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { [[FirebasePushNotifications instance] didReceiveLocalNotification:notification]; } - (void)application:(UIApplication *)application didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo fetchCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler{ [[FirebasePushNotifications instance] didReceiveRemoteNotification:userInfo 59
  • 60. fetchCompletionHandler:completionHandler]; } - (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings { [[RNFirebaseMessaging instance] didRegisterUserNotificationSettings:notificationSettings]; } And finally locate the didFinishLaunchingWithOptions method and add the following lines: [FIRApp configure]; [FirebasePushNotifications configure]; This is how it look like in my code: Next we are going to do the JavaScript part. Open the App.js file and in our App components (or whichever components is first in your app), import the following dependency: import {notifications} from 'react-native-firebase-push-notifications'; Next the flow for our Push Notifications is the following one: 1. Get the Push Notifications Token 2. Check if the Push Notification permissions are granted, and if not ask for Permissions 3. If permissions are granted start listening for permissions So our entire code for this will look something like this: function App() { const [token, setToken] = React.useState(); const [permissionGranted, setPermissionGranted] = React.useState(false); React.useEffect(() => { 60
  • 61. // get token getToken().then(t => { console.log(`----- TOKE: ${t}`); setToken(t); }); // check for permission and request if necessary hasPermission().then(async granted => { if (!granted) { await requestPermission().then(() => {}); } else { setPermissionGranted(true); onNotificationListener(); onNotificationOpenedListener(); getInitialNotification(); } }); }, [token, permissionGranted]); const hasPermission = async () => { //only works on iOS return await notifications.hasPermission(); }; const requestPermission = async () => { try { const granted = await notifications.requestPermission(); if (granted) { setPermissionGranted(true); onNotificationListener(); onNotificationOpenedListener(); getInitialNotification(); } } catch (error) { console.log(error); } }; const getToken = async () => { //get the messaging token const _token = await notifications.getToken(); //you can also call messages.getToken() (does the same thing) return _token; }; const getInitialNotification = async () => { //get the initial token (triggered when app opens from a closed state) const notification = await notifications.getInitialNotification(); console.log('getInitialNotification', notification); return notification; }; const onNotificationOpenedListener = () => { 61
  • 62. //remember to remove the listener on un mount //this gets triggered when the application is in the background this.removeOnNotificationOpened = notifications.onNotificationOpened( notification => { console.log('onNotificationOpened', notification); //do something with the notification }, ); }; const onNotificationListener = () => { //remember to remove the listener on un mount //this gets triggered when the application is in the forground/runnning //for android make sure you manifest is setup - else this wont work this.removeOnNotification = notifications.onNotification(notification => { //do something with the notification console.log('onNotification', notification); }); }; Now we can reinstall our app, may need to uninstall it and install it again, and make sure you are testing the Push Notifications on a real device, not a simulator, since google is not allowing Push Notifications on the Simulator. Start the app and from the xCode console we can get the token (to easily find it put something like firebase in the filter field so it filter you only messages containing firebase): Now open the Firebase Console one more time, open your Application there, and scroll until you see the Cloud Messaging card: 62
  • 63. Now from the next screen click on the “Create your first campaign” button: And from the next screen make sure that you select Firebase Notification messages: Click “Create” and in the next window enter the Notification title, and the Notification text, and click on the Send Message button: 63
  • 64. Now add the Token we have found in the xCode console previously, and add it in the “Add an FCM registration token” field, and click the plus button to add it. 64
  • 65. Now if you click the “Test” button (with our app running in the background on our device) you will see or Push Notification: 65
  • 66. Android Setup For the Android part we still need to do some setup on our Firebase Console and in our Android Project. Let's start by creating a new app inside the Firebase project we have created previously, and this time instead of iOS select Android app: Enter the Android package name, which you can find inside your code by opening the MainActivity.java file, and copy the package name which is usually the first line in this file: And in the next step make sure to download the google-services.json file. 66
  • 67. After this, open your android project with Android Studio, and drag and drop the google-services.json file you have downloaded to the app folder (): 67
  • 68. Next we are going to make some more changes in our Android Studio Project. First we need to add the google-services dependency in our build.gradle (the one inside the android folder, not the one inside android/app!), so inside the dependencies add the following line: classpath 'com.google.gms:google-services:4.3.12' Next open the build.gradle file which is in the app folder, and add this plugin: apply plugin: 'com.google.gms.google-services' 68
  • 69. Next we need to modify the AndroidManifest.xml, so add the following lines inside the <manifest>: <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.VIBRATE" /> And inside the <activity change the property of launchMode to “singleTop”: Now you can run your app on a real device, and in the terminal you can get the token: Now to test if everything works, minimize your app, and open the Firebase Console and inside the Cloud Messaging Compose notification add the title and text for our test notification and click the Send test message button: In the next window add the new token we got in the terminal select the newly added token and click the Test button, and you should see our notification on our Android device: 69
  • 70. https://www.npmjs.com/package/react-native-firebase-push-notifications https://firebase.google.com/docs/cloud-messaging/ios/client Building the App While we are working on our React Native app from time to time there is a need to rebuild it mostly because of adding some third party library which in most cases would require to rebuild the app, while if we are only changing the JavaScript and the JSX the hot reloading will make sure we everything is uptodate. When dealing with building the app we had two options, either to build it manually everytime we needed a build, or to set up an automatic build pipeline that would build our app when we made some changes in the code. Manual Building When considering a manual building process, the building steps are different for all platforms, so we will try to explain the manual build process for Android and iOS separately. *Before trying to build the app for any platform, make sure that your app runs without any errors. Android To build the APK of your React Native you need to use Android Studio or you can do it from the command line. First let's try to build it from Android Studio, so open the ‘android’ folder of your React Native project with Android Studio. 70
  • 71. APK with Android Studio Now to build the actual APK, you need to select ‘Build->Gnerate Signed Bundle / APK…’: Then from the next window select ‘APK’. In the next window we need to select a keystore if we have one or create a new one, and in our case we want to create a new one: Then we first need to select a folder where we will store our keystore, and I usually create a folder named ‘keystore’ in the root of my repo, so we will do the same here, and fill the rest of the fields in the form, and we click OK once we are done: 71
  • 72. After this we click ‘Next’ and select a Build Variant in the final window, and in our case we will select Release, because if we chose Debug inorder for our app to work on any device we will need to have the Metro Bundler Server running on our machine and the device to be connected to that machine via USB or Wifi: 72
  • 73. After clicking Finish here, our APK build process will start and after ~5 min (depending on your machine) your APK will be generated (it should be inside ‘android/app/release’): APK with Command Line To generate an APK file for a React Native app via terminal/command line, you can follow these steps: 1. Make sure you have installed the necessary software: Android Studio, the Android SDK, and the React Native command line interface (CLI). 2. Open a terminal/command line window and navigate to your React Native project directory. 3. Run the following command to generate a debug APK (make sure you run the command from within the android folder): ./gradlew assembleDebug 4. Run the following command to generate a release APK: ./gradlew assembleRelease Those commands will create an APK file in the project's android/app/build/outputs/apk/ directory, where you will have a debug or release folder which holds your APK. If you want to generate a release APK, you will need to create a keystore and sign the APK with it. You can use the following command to generate a keystore: keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000 This will prompt you to enter a password and other information for the keystore. Once you have the keystore, you can add the following lines to your project's android/gradle.properties file: MYAPP_RELEASE_STORE_FILE=my-release-key.keystore MYAPP_RELEASE_KEY_ALIAS=my-key-alias 73
  • 74. MYAPP_RELEASE_STORE_PASSWORD=<password> MYAPP_RELEASE_KEY_PASSWORD=<password> Replace <password> with the password you used to create the keystore. iOS To build an IPA you will need a machine with MacOS because you will need xCode and Apple Developer Account (paid one is preferred since it will make your life so easier when dealing with Apple Development stuff). Dealing with Apple Hell First thing is to enroll in the Apple Developer program, which has a 99$ annual fee. We will need this account to generate the apple related stuff for deploying our app like bundle id, signing certificate and provision profiles. Generating p12 signing certificate After we have enrolled into the Apple Developer program, we will need to generate our p12 certificate. To do that we will need a Mac machine with MacOS. First thing to do is to open the Keychain Access application on our MacOS machine: 74
  • 75. From there we need to click on Keychain Access->Certificate Assistant->Request a Certificate From a Certificate Authority, and also make sure that the login is selected in the Default Keychains on the left panel in Keychain Access (check the photo above). In the next screen, enter your email (the one used for the apple developer account) , make sure that Save to disk is selected and click Continue. 75
  • 76. With this we are done with the Keychain Access. Now we need to go to the Apple Developer website and in the Certificates tab you need to click the “+” button to generate a new certificate: 76
  • 77. On the next screen select Apple Distribution, because we need a distribution certificate: Now in the next screen we need to attach the file which we have previously generated with the help of Keychain Access (the file should have .certSignalRequest extension): Now our certificate should be generated, and we can download it. Keep in mind this is not a p12, we still need to do some work to create a p12 which is required on Azure DevOps. 77
  • 78. Once you have downloaded the certificate, you can double click it in order to install it. Now to generate a p12, we should open the Keychain Access one more time, and click the login button in the Default Keychains. Now locate the certificate we have previously installed (it should have something like “Apple Distribution …” in the name), right click on it and select “Export: Apple Distribution …”: In the next screen from File Format we chose “Personal Information Exchange (.p12)” and click on the Save button: 78
  • 79. After clicking the Save button, one more window will appear, to enter and verify the certificate password, and make sure to remember this password. I usually keep it in a text file in the same folder where I keep the p12, but this is not very safe to do. 79
  • 80. With this we are done, and our p12 is ready. Generating BundleId Next is to create an Identifier or bundle id for our app. To do that we need to head to the Apple Developer website in the Identifiers section, and click the “+” button to generate a new Identifier (App ID/bundle id): 80
  • 81. From the next screen select “App IDs” and click Continue: In the next screen make sure that you have App and not App Clip selected and click Continue: In the next screen we need to enter some information regarding our App Id like description and the actual bundle id. In the description field enter the description, and in the next section make sure that “Explicit” is selected for Bundle ID, and your bundle id should look like a reversed URL (example: “com.myapplication.testing”) 81
  • 82. Now click Continue and then Register and with this we are done with the registration of our App ID. Generating Distribution Provision Profile To generate the Provision Profile once again we will head to our Apple Developer website, and this time we will go to the Profiles section, and we click the “+” button there to generate a new Provision Profile. On the next screen we need to select “App Store” from the Distribution section and click Continue: 82
  • 83. On the next screen we need to select the App ID we have generated previously, and click Continue: Next we select the certificate we have generated and click Continue: 83
  • 84. And finally we enter the name for our Provision Profile and click Generate: IPA with xCode To start, open the ios folder of your React Native project with xCode (the .xcworkspace file). Then you may need to deal with the “Apple Hell” a bit, and after generating the needed things like certificates, bundle id and provision profile, apply the needed changes to the xCode project: ● Install the development certificates you have generated ● Change the bundle/app identifier in xCode for your app ● If you plan to use manual signing make sure you update the provision profiles too. Now in xCode select Product->Archive and the Archiving process will start, and after few minutes you will see something like this: 84
  • 85. From here click on the ‘Distribute App’ button on the right side. From the next window we will select Ad Hoc as a method of distribution, and you can learn more about the other methods here. Then just click Next: Then choose ‘Automatically Manage signing’ and click on the Next button again. On the last window you can click the Export button and select a folder where you want your IPA to be generated: 85
  • 86. IPA with Command Line To generate IPA with the command line you still need to have xCode installed, but you may need to use the command line for a lot of reasons. Before trying to generate the IPA make sure that you are able to run the ios app in the simulator or on a physical iOS device. Then first run this command in the terminal (make sure that you are inside the ios folder of your React Native project): xcodebuild -workspace MelonReactNative.xcworkspace -scheme MelonReactNative -sdk iphoneos -configuration Release -archivePath MelonReactNative.xcarchive archive *make sure that you use names from your project in the command for the workspace, schema and the archivePath. This will generate a file with .xcarchive inside the ios folder. Then you need to create one plist file inside the ios folder, and we will name it exportOptions.plist and it will look something like this: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>compileBitcode</key> 86
  • 87. <false/> <key>method</key> <string>ad-hoc</string> <key>provisioningProfiles</key> <dict> <key>com.melon.react.native.test</key> <string>yourprovisioningprofile</string> </dict> </dict> </plist> *make sure you put your app bundle id on the place where i have ‘com.melon.react.native.test’ Next run the following command to export the ipa xcodebuild -exportArchive -archivePath MelonReactNative.xcarchive -exportOptionsPlist exportOptions.plist -exportPath ipa *make sure that you use names from your project in the command for the archivePath and exportOptionsPlist. If this command runs successfully you will have and IPA file inside a folder named ‘ipa’ (ios/ipa). Azure Devops Pipelines Now let's focus on atomizing our build process, and for that we are going to use Azure Devops. If you are not familiar with Azure Devops and how to set up an Azure account, you can learn more here. Also if you want some more in-depth guide for making the Azure Devops Pipelines for React Native, you can find one here, which I was also using as a reference when I was writing this text. Before we can start working on the actual pipeline, we needed to setup the Azure DevOps account, and in order to do that, we had to create a free subscription that is valid for 30 days, and you have 200$ free credits to use on the Azure Services, and after that period it would be required to enter payment method (credit card) and you will be charged per use, but to be honest in the 30 day I was using my free account I haven’t spent a penny from the free credit, since I was only running the pipelines, while my code was on a Bitbucket repository. Android If we follow the guide I have provided in the link above, at the end we will find the full yaml pipeline which we will need to modify to make it work with the latest version of React Native, 87
  • 88. which at the moment is 0.70. So first thing is to update the Node version in the NodeTool@0 task: - task: NodeTool@0 displayName: 'Install Node' inputs: versionSpec: '12.19.0' # you can use your desired version here Next is to update the Java version in the same task, and instead of Java 8 (1.8) which is I believe a default value, we need to use Java 11 (1.11), so our updated task would look something like this: - task: Gradle@2 displayName: 'Build APK' inputs: gradleWrapperFile: 'android/gradlew' workingDirectory: 'android/' options: '-PversionName=$(NEW_VERSION) -PversionCode=$(Build.BuildId)' tasks: 'assembleRelease' publishJUnitResults: false javaHomeOption: 'JDKVersion' jdkVersionOption: '1.11' gradleOptions: '-Xmx3072m' sonarQubeRunAnalysis: false With this our yaml pipeline should work, and the final yaml for the Android part would look like this: trigger: branches: include: - master variables: - group: Mobile # change it to the name you have set pool: vmImage: 'ubuntu-latest' steps: - checkout: self persistCredentials: true clean: true - task: NodeTool@0 displayName: 'Install Node' 88
  • 89. inputs: versionSpec: '16.10.0' # you can use your desired version here - script: yarn install displayName: Install Dependencies - script: | # Disable autocommit on version bump yarn config set version-sign-git-tag false yarn config set version-git-tag false yarn config set version-commit-hooks false # Checkout branch where the build is triggered git checkout $(Build.SourceBranchName) # Extract existing version of package.json oldVer=$(jq -r ".version" package.json) # Bump version yarn version --patch # Add bumped version to staging git add * # Extract new version of package.json newVer=$(jq -r ".version" package.json) # Set environment variables echo "##vso[task.setvariable variable=OLD_VERSION]$oldVer" echo "##vso[task.setvariable variable=NEW_VERSION]$newVer" displayName: 'Bump version and set variables' - task: Gradle@2 displayName: 'Build APK' inputs: gradleWrapperFile: 'android/gradlew' workingDirectory: 'android/' options: '-PversionName=$(NEW_VERSION) -PversionCode=$(Build.BuildId)' tasks: 'assembleRelease' publishJUnitResults: false javaHomeOption: 'JDKVersion' jdkVersionOption: '1.11' gradleOptions: '-Xmx3072m' sonarQubeRunAnalysis: false - task: AndroidSigning@3 displayName: 'Sign APK' inputs: apkFiles: 'android/app/build/outputs/apk/release/*.apk' apksignerKeystoreFile: 'keystore.keystore' apksignerKeystorePassword: '$(AndroidKeyStorePassword)' apksignerKeystoreAlias: '$(AndroidKeyAlias)' apksignerKeyPassword: '$(AndroidKeyAliasPassword)' 89