Table of Contents
- Xcode - iOS Simulators
- Android Studio - Android Emulator
- Node.js > 18 - Running the Expo Dev Server
- Git - Version Control
- EAS CLI - Expo build tool
- Yarn - JavaScript Package Manager
- Fast Lane - Build & Releasing Apps
- Cocoa Pods - Dependency manager for Swift
This project is developed using Expo, an ecosystem for creating and developing native apps based on React Native.
After installing all tools listed in the dependencies section, clone the project from GitHub using Git and install the necessary packages. Execute the following commands in your terminal, one at a time:
git clone https://github.com/milad-alizadeh/Apperitif.git
cd Apperitif
yarn
Start the development server, which enables real-time communication with the app, allowing immediate reflection of code changes. To start the dev server, run:
yarn run start
To run the project on an iOS simulator, follow these steps:
- Create a Development Build
- Set up the iOS Simulator (First-time Setup)
- Install the Development Build
Create an EAS Development Build, a binary bundle for installation on your iOS simulator. In simpler terms every app on any phone is a single file (binary) that can be installed on the device (or simulator). The development bundle communicates with the Expo Dev Server for real-time code reflection. To create a development build, run:
yarn run build:dev:ios-simulator
This may take 5-15 minutes, depending on your machine's speed. If successful, a new file development-simulator.tar.gz
will appear in the ./artifact
folder.
Open Xcode, accept the terms, and access the simulator by selecting Xcode -> Open Developer Tool -> Simulator
. Choose a specific device simulator, such as iPhone 15 Pro
, via File -> Open Simulator -> iPhone 15 Pro
.
Install the Development Build on the simulator with:
yarn build:run:dev:ios-simulator
Upon successful installation, the app icon should appear in the simulator. Open the app and select http://localhost:8081
to start. If you are using a physical device, chances are the dev server might be automatically detected. In that case you need to click enter manually and replace the localhost
with the IP of your Mac on the network. e.g https://192.168.0.64:8081
Running the build on an iPhone requires creating a separate development build. The steps are similar to the simulator setup:
- Create a Development Build for iPhone
- Install EAS profile on your device
- Install the Development Build using Xcode
Create a development build for iPhone with:
yarn run build:dev:ios
This also takes 5-15 minutes. Upon success, development.ipa
will be in the ./artifact
folder.
Note: During the process you might face an error. Error: Distribution certificate with fingerprint *************** hasn't been imported successfully
. This is to do with your machine missing the new ""Apple Worldwide Developer Relations Certification Authority". To install download it here and install this certificate. Once done you should no longer get this error
Note: Make sure you have iOS Simulators in Xcode before runnning the build command as it will fail without.
In order for development build to work on an iPhone it needs to be signed by Expo to install EAS profile run:
yarn add:test-device
Choose to login to the Apple Account and choose the first option Website - generates a registration URL to be opened on your devices
. You then will recieve a QR code which you can scan with your phone and install the profile. Once the profile is installed you should a confirmation message and then move to the next section
Once the build is finished you should recieve a QR code in the terminal. Scan it with your Phone and you're asked to install the app. Confirm and the build should install on your phone
For Android, the same development build works for both emulators and physical devices:
- Create a Development Build (Android)
- Set up Android Emulator (AKA Virtual Device)
- Install the Development Build (Android)
Create a development build for Android with:
yarn run build:dev:android
Upon success, development.apk
will be in the ./artifact
folder.
For a virtual device:
- Open Android Studio and select
... -> Virtual Device Manager
. - Click
Create Device
and choose, for example,Pixel 7
withAPI 34
.
For a physical device:
- Connect the device to your Mac.
- Enable USB debugging and developer mode.
Install the build on Android with:
yarn run build:run:android-emulator
For virtual devices, drag and drop development.apk
into the running emulator.
Once the build is finished you should recieve a QR code in the terminal. Scan it with your Phone and you're asked to install the app. Confirm and the build should install on your phone
The deployment process uses GitHub Actions and EAS build for CI/CD, submitting builds to Apple Connect and Google Play. EAS Build is a part of Expo Application Services (EAS), which automates the process of compiling and deploying React Native apps to iOS and Android platforms. This tool is crucial for producing final production-ready binaries that can be distributed through app stores.
For ease of testing, there are separate environments: staging
and production
. The process is:
- Review and test code changes locally on the Development Build.
- Increment the
version
number inapp.config.js
and commit. - Create a pull request (PR) against
staging-build
. - Once merged, builds are triggered for both platforms using EAS Build and submitted for testing.
- After staging tests, create a PR from
staging-build
toproduction-build
. - Once approved, the same process repeats for the production app.
- Manually Submit the app for review on Android & iOS store.
Note: The production environment is separate from staging and uses a different backend.
EAS Update, also part of Expo Application Services, allows for expedited updates of non-native code changes. It's a powerful tool for pushing quick updates directly to users' devices without going through the standard app store review process. This mean the user does not need to download a new version of the from app store. This feature is particularly useful for bug fixes, performance improvements, and small feature enhancements that don't involve native code changes.
The process for using EAS Update is:
- Review and test code changes locally.
- Create a PR against
staging
. - Once merged, an EAS Update package is sent to devices.
- Repeat the process for the
production
branch.
Note: EAS updates do not require updating the version
in app.config.js
.
Use EAS Build for major changes, particularly those involving native code or significant feature additions. EAS Update is ideal for minor changes and bug fixes that don't require a full build process. This ensures users always have access to the latest version of the app, even for small updates. EAS updates only trigger upon app launch.
This project follows a standard Expo structure, resulting in opinionated code that facilitates consistency and ease of understanding throughout the development process.
We use Expo Router for navigation and routing. This offers a Next.js-like folder-based structure, simplifying navigation significantly. All main routes are located in the src/app
folder. Our setup closely follows Expo's standard conventions. For more details on using Expo Router, refer to their guide.
Our project incorporates two types of testing:
Unit tests are conducted for each component. These tests run automatically whenever code is pushed to the staging
, staging-build
, production
, and production-build
branches. The build process halts if any unit test fails. To run unit tests locally, execute:
yarn test:unit
E2E tests, currently not integrated into the CI/CD pipeline (WIP), can be run locally using:
yarn test:e2e
Note: Ensure Maestro is installed before running E2E tests. Follow the Maestro installation guide for setup instructions.
For network communication with the server, we use Apollo Client and Supabase JavaScript Client. Queries and mutations are managed in the src/graphql
folder. As we use TypeScript, it's necessary to regenerate types whenever a query or mutation is added, changed, or deleted. Type checking is facilitated by Codegen, allowing for end-to-end type safety with minimal effort. To generate types after any changes, run:
yarn run generate:gql
To automatically watch for changes and generate types, use:
yarn run generate:gql:watch
Local state management is also done using Apollo client to remove the need of using another state management library such as Redux or Mobx.
The store files are found in src/store
. For more information on how to use local state management with Apollo please refer to this guide.
In certain cases where there is limitation with the graphQL database we are using Supabase client to fetch data
This app uses Supabase Auth to handle user authentications. There are several ways to authenticate the user:
Each of these are handled by components are located in src/components/Authentication
. The necessary setup and keys are located in Supabase Auth dashboard.
There's also a SessionProvider
component in src/providers/SessionProvider
. This allows supabase to check whether a user is logged in already and if so fetch the current session (not asking the user to login again). If the session is expired then the user will be redirected.
The user token is saved in Expo SecureStore and the setup can be found in src/sevices/api
.
The styling in the entier application leverages Nativewind. NativeWind uses Tailwind CSS as scripting language to create a universal style system for React Native. The scope of why to use Tailwind is outside of this guide but you can read through why utility-based styling is a good idea and much less verbose than traditional CSS/StyleSheet.
A simple example of how to use this in a component is
import { Text, View } from "react-native";
const App = () => {
return (
<View className="flex-1 items-center justify-center">
<Text className="text-slate-800">Styling just works! π</Text>
</View>
);
};
Please refer NativeWind guide on how to use it within the project.