<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mohamed Saad</title>
    <description>The latest articles on DEV Community by Mohamed Saad (@dvmhmdsd).</description>
    <link>https://dev.to/dvmhmdsd</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F271389%2F4ecbded2-37bf-40a5-b362-fe177b9fb66b.jpg</url>
      <title>DEV Community: Mohamed Saad</title>
      <link>https://dev.to/dvmhmdsd</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dvmhmdsd"/>
    <language>en</language>
    <item>
      <title>[Boost]</title>
      <dc:creator>Mohamed Saad</dc:creator>
      <pubDate>Sun, 29 Dec 2024 21:29:15 +0000</pubDate>
      <link>https://dev.to/dvmhmdsd/-2jl9</link>
      <guid>https://dev.to/dvmhmdsd/-2jl9</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/dvmhmdsd" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F271389%2F4ecbded2-37bf-40a5-b362-fe177b9fb66b.jpg" alt="dvmhmdsd"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/dvmhmdsd/from-days-to-minutes-build-and-publish-react-native-apps-using-fastlane-and-github-actions-5107" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;From days to minutes: Build and publish React Native apps using Fastlane and Github Actions&lt;/h2&gt;
      &lt;h3&gt;Mohamed Saad ・ Dec 29&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#githubactions&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#fastlane&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#reactnative&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#cicd&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>reactnative</category>
      <category>githubactions</category>
      <category>cicd</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>From days to minutes: Build and publish React Native apps using Fastlane and Github Actions</title>
      <dc:creator>Mohamed Saad</dc:creator>
      <pubDate>Sun, 29 Dec 2024 21:27:32 +0000</pubDate>
      <link>https://dev.to/dvmhmdsd/from-days-to-minutes-build-and-publish-react-native-apps-using-fastlane-and-github-actions-5107</link>
      <guid>https://dev.to/dvmhmdsd/from-days-to-minutes-build-and-publish-react-native-apps-using-fastlane-and-github-actions-5107</guid>
      <description>&lt;p&gt;In the fast-paced world of mobile app development, delivering updates and new features quickly is critical. For teams managing multiple white-label applications, the challenge intensifies. This article delves into how I automated the build and release process for 20+ white-label React Native apps across Android and iOS using GitHub Actions and Fastlane, reducing release time from over three working days to just 20–30 minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Our team faced several challenges that requires us to build this solution:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;High Manual Overhead:&lt;/strong&gt;&lt;br&gt;
Managing over 20 white-label apps with the same codebase but unique app identifiers meant manually building and releasing separate versions for Android and iOS. This process was time-consuming and error-prone.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Platform-Specific Complexity:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Android: Required keystore management and distinct build formats (APK vs AAB).&lt;/li&gt;
&lt;li&gt;iOS: Involved handling provisioning profiles, certificates, and Apple’s two-factor authentication (2FA).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;A Single Point of Failure:&lt;/strong&gt;&lt;br&gt;
One person was responsible for the entire process of building and releasing the apps, causing delays and introducing a significant bottleneck.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Budget Constraints:&lt;/strong&gt;&lt;br&gt;
Third-party CI/CD solutions like CodeMagic, Bitrise, and Appcircle were unaffordable, forcing us to explore open-source and free alternatives.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Impossible to onboard new team members:&lt;/strong&gt;&lt;br&gt;
The process was complex and required a deep understanding of the build and release process, making it difficult to onboard new team members.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Comparing different CI/CD solutions and Trade-offs
&lt;/h2&gt;

&lt;p&gt;We evaluated several CI/CD solutions, including GitHub Actions, Bitrise, Appcircle and other solutions. Here’s a comparison of the tools based on our requirements:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;GitHub Actions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pros:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Free for public repositories.&lt;/li&gt;
&lt;li&gt;Integrates seamlessly with GitHub.&lt;/li&gt;
&lt;li&gt;Supports custom workflows.&lt;/li&gt;
&lt;li&gt;Offers a wide range of actions.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cons:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Limited build minutes for private repositories.&lt;/li&gt;
&lt;li&gt;Requires manual setup and configuration.&lt;/li&gt;
&lt;li&gt;1 minute in mac OS runner equals 10 minutes in bill payment.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Bitrise:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pros:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Easy to set up and configure.&lt;/li&gt;
&lt;li&gt;Offers a wide range of integrations.&lt;/li&gt;
&lt;li&gt;Provides a user-friendly interface.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cons:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Expensive for multiple apps.&lt;/li&gt;
&lt;li&gt;Limited build minutes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Appcircle:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pros:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Supports multiple platforms.&lt;/li&gt;
&lt;li&gt;Offers a wide range of integrations.&lt;/li&gt;
&lt;li&gt;Provides a user-friendly interface.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cons:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Expensive for multiple apps.&lt;/li&gt;
&lt;li&gt;Limited build minutes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Codemagic:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pros:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Easy to set up and configure.&lt;/li&gt;
&lt;li&gt;Offers a wide range of integrations.&lt;/li&gt;
&lt;li&gt;Provides a user-friendly interface.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cons:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Expensive for multiple apps.&lt;/li&gt;
&lt;li&gt;Limited build minutes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Gitlab CI:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pros:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Free for public repositories.&lt;/li&gt;
&lt;li&gt;Integrates seamlessly with Gitlab.&lt;/li&gt;
&lt;li&gt;Supports custom workflows.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cons:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Limited build minutes for private repositories.&lt;/li&gt;
&lt;li&gt;Requires manual setup and configuration.&lt;/li&gt;
&lt;li&gt;Mac OS runner is not stable.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After evaluating the options, we decided to go with GitHub Actions due to its seamless integration with GitHub, custom workflows, and cost-effectiveness.&lt;/p&gt;

&lt;h2&gt;
  
  
  Github actions
&lt;/h2&gt;

&lt;p&gt;GitHub Actions is a powerful tool for automating workflows directly within your repository. It allows you to define workflows that are triggered by events, such as pushing code, opening pull requests, or even on-demand through manual dispatch. Here’s a breakdown of the essential concepts:&lt;/p&gt;




&lt;h4&gt;
  
  
  &lt;strong&gt;1. Syntax &amp;amp; Skeleton&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;GitHub Actions workflows are defined in YAML files located in the &lt;code&gt;.github/workflows/&lt;/code&gt; directory. The general structure of a workflow file includes:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;name&lt;/code&gt;&lt;/strong&gt;: The workflow's name.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;on&lt;/code&gt;&lt;/strong&gt;: The event that triggers the workflow. e.g. &lt;code&gt;push&lt;/code&gt;, &lt;code&gt;workflow_dispatch&lt;/code&gt;, ...etc&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;jobs&lt;/code&gt;&lt;/strong&gt;: A collection of jobs to be executed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example Skeleton:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: Build &amp;amp; Test

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main
  workflow_dispatch:

jobs:
  example-job:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  &lt;strong&gt;2. Jobs:&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Jobs define units of work in a workflow. They run either:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;In parallel&lt;/strong&gt;: By default, jobs are independent and run simultaneously.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chained&lt;/strong&gt;: Using the &lt;code&gt;needs&lt;/code&gt; keyword to specify dependencies.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example of Parallel Jobs:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Build project
        run: echo "Building project"

  test:
    runs-on: ubuntu-latest
    steps:
      - name: Run tests
        run: echo "Running tests"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example of Chained Jobs:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Build project
        run: echo "Building project"

  deploy:
    runs-on: ubuntu-latest
    needs: build
    steps:
      - name: Deploy project
        run: echo "Deploying project"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  &lt;strong&gt;3. Steps&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Steps define the individual tasks within a job. They can include:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;run&lt;/code&gt; commands&lt;/strong&gt;: To execute shell scripts.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reusable actions&lt;/strong&gt;: Third-party or custom actions from the GitHub Marketplace.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example Steps:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;steps:
  - name: Checkout repository
    uses: actions/checkout@v2

  - name: Install dependencies
    run: npm install

  - name: Run tests
    run: npm test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  &lt;strong&gt;4. Reusable Actions&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Reusable actions simplify workflows by allowing you to use pre-built logic. These are either official GitHub Actions or custom ones stored in a repository.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example of a Reusable Action:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- name: Checkout repository
  uses: actions/checkout@v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also create custom actions for your specific needs and share them across workflows or repositories.  &lt;/p&gt;




&lt;h4&gt;
  
  
  &lt;strong&gt;5. Conditions&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Conditions control when specific jobs or steps should run. This is particularly useful for implementing logic based on branch names, event types, or custom environment variables.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example Using Conditions:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Run only on main branch
        run: echo "This runs on main"
        if: github.ref == 'refs/heads/main'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can use conditions for:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Branch-specific actions.
&lt;/li&gt;
&lt;li&gt;Running based on the success/failure of previous steps or jobs.
&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  &lt;strong&gt;6. Secrets&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Secrets are encrypted environment variables stored securely in your GitHub repository or organization. They are used to protect sensitive data like API keys, credentials, and tokens.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example of Using Secrets:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- name: Use secret key
  run: echo "Your secret is ${{ secrets.SECRET_KEY }}"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To add secrets:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to your repository settings.
&lt;/li&gt;
&lt;li&gt;Go to &lt;strong&gt;Secrets and variables&lt;/strong&gt; &amp;gt; &lt;strong&gt;Actions&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Add your secret and reference it in the workflow.
&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;By combining these elements, you can create sophisticated workflows tailored to your CI/CD needs. GitHub Actions’ flexibility allows for robust automation, enhancing productivity and reducing manual effort.&lt;/p&gt;

&lt;h2&gt;
  
  
  Steps to build each platform manually
&lt;/h2&gt;

&lt;p&gt;Before automating the build, we need to understand first how we can build for every platform manually to know what is the background for every decision needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Build for Android
&lt;/h3&gt;

&lt;p&gt;Building an Android app manually requires setting up the development environment and understanding the key steps in the process. Here's a breakdown of what's needed and how to do it:&lt;/p&gt;




&lt;h4&gt;
  
  
  &lt;strong&gt;1. Install Java&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Java is a fundamental requirement for building Android apps. Android builds rely on the Java Development Kit (JDK).  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ensure Java is installed&lt;/strong&gt;: Version 11 or higher is commonly used.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify Installation&lt;/strong&gt;: Run the command:
&lt;code&gt;java -version&lt;/code&gt;
This should display the installed Java version.
&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  &lt;strong&gt;2. Install Gradle&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Gradle is the build system used by Android to automate the compilation, testing, and packaging process.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Install Gradle&lt;/strong&gt;: Download it from the &lt;a href="https://gradle.org/releases/" rel="noopener noreferrer"&gt;official Gradle website&lt;/a&gt;.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify Installation&lt;/strong&gt;: Run the command:
&lt;code&gt;gradle -v&lt;/code&gt;
This should display the installed Gradle version.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Gradle is typically managed automatically by Android Studio, but for manual builds, you'll need it installed on your system.&lt;/p&gt;




&lt;h4&gt;
  
  
  &lt;strong&gt;3. Obtain a Keystore File&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;The keystore file is a critical component for signing your Android app before release. It ensures that your app is verified and allows updates to be trusted by the Play Store.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Create a Keystore File Locally&lt;/strong&gt;:
Use the &lt;code&gt;keytool&lt;/code&gt; command to generate a keystore:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  keytool -genkey -v -keystore your-app.keystore -keyalg RSA -keysize 2048 -validity 10000 -alias your-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will prompt you to enter a password and other details.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Problem in CI/CD Pipelines&lt;/strong&gt;:
In CI/CD workflows, storing the keystore securely can be a challenge. Exposing the keystore file directly in the repository is a &lt;strong&gt;security risk&lt;/strong&gt;. We will come back to this challenge and see how to solve it.&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  &lt;strong&gt;4. Understanding APK vs. AAB&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;When building Android apps, you can output two types of artifacts: APK and AAB.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;APK (Android Package)&lt;/strong&gt;:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The traditional format for Android apps.
&lt;/li&gt;
&lt;li&gt;Contains all the code, resources, and assets required to run the app.
&lt;/li&gt;
&lt;li&gt;Suitable for direct installation or distribution outside the Play Store.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;AAB (Android App Bundle)&lt;/strong&gt;:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A modern packaging format introduced by Google.
&lt;/li&gt;
&lt;li&gt;Optimized for Play Store distribution.
&lt;/li&gt;
&lt;li&gt;The Play Store dynamically generates an APK tailored to the user’s device from the AAB.
&lt;/li&gt;
&lt;li&gt;Results in smaller app downloads and improved performance.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key Differences:&lt;/strong&gt;  &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;APK&lt;/th&gt;
&lt;th&gt;AAB&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Size&lt;/td&gt;
&lt;td&gt;Larger&lt;/td&gt;
&lt;td&gt;Smaller (device-specific)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Distribution&lt;/td&gt;
&lt;td&gt;Direct or via Play Store&lt;/td&gt;
&lt;td&gt;Play Store only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Customization&lt;/td&gt;
&lt;td&gt;Single package for all devices&lt;/td&gt;
&lt;td&gt;Device-specific APKs on demand&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For Play Store submissions, Google now mandates using the AAB format. However, APKs are still useful for testing and distributing apps directly to users.&lt;/p&gt;




&lt;p&gt;These steps and understanding the differences between APK and AAB will help building Android apps manually while ensuring they are properly signed and ready for distribution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Build for iOS
&lt;/h3&gt;

&lt;p&gt;Building an iOS app requires specific tools, configurations, and processes to ensure compatibility with Apple’s ecosystem. Here’re the steps to build and iOS version manually:&lt;/p&gt;




&lt;h4&gt;
  
  
  &lt;strong&gt;1. Install and Manage CocoaPods&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;CocoaPods is a dependency manager for iOS projects. It helps manage libraries and frameworks needed for your app.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Install CocoaPods&lt;/strong&gt;:
Use the following command to install CocoaPods if it’s not already installed:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  sudo gem install cocoapods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Install Dependencies&lt;/strong&gt;:
Navigate to your iOS project directory and run:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  pod install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command reads the &lt;code&gt;Podfile&lt;/code&gt; and installs the necessary dependencies into a &lt;code&gt;Pods&lt;/code&gt; directory.  &lt;/p&gt;




&lt;h4&gt;
  
  
  &lt;strong&gt;2. Install Xcode&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Xcode is the IDE used to build, test, and deploy iOS applications.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Install Xcode&lt;/strong&gt;: Download it from the &lt;a href="https://apps.apple.com/" rel="noopener noreferrer"&gt;Mac App Store&lt;/a&gt;.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ensure Compatibility&lt;/strong&gt;: Ensure the installed version of Xcode is compatible with your iOS project and dependencies.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Command Line Tools&lt;/strong&gt;: Install Xcode Command Line Tools by running:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  xcode-select --install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  &lt;strong&gt;3. Signing Certificate&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;iOS apps must be signed with a valid certificate to run on devices or be submitted to the App Store.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Generate a Certificate&lt;/strong&gt;:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to &lt;a href="https://developer.apple.com/" rel="noopener noreferrer"&gt;Apple Developer Account&lt;/a&gt;.
&lt;/li&gt;
&lt;li&gt;Navigate to Certificates, Identifiers &amp;amp; Profiles, and create a new signing certificate.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Import Certificate to Keychain&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;&lt;br&gt;
Download the &lt;code&gt;.p12&lt;/code&gt; file and double-click it to add it to your macOS Keychain.  &lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;




&lt;h4&gt;
  
  
  &lt;strong&gt;4. Provisioning Profile&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;The provisioning profile connects your app ID, signing certificate, and device(s) for testing or distribution.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Generate a Provisioning Profile&lt;/strong&gt;:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the Apple Developer account, create a profile for either development or distribution.
&lt;/li&gt;
&lt;li&gt;Associate the profile with your app ID and the necessary devices (for development).
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Download and Use the Profile&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;&lt;br&gt;
Download the &lt;code&gt;.mobileprovision&lt;/code&gt; file and add it to your project in Xcode.  &lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;




&lt;h4&gt;
  
  
  &lt;strong&gt;5. Submit via TestFlight&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;TestFlight is Apple's official tool for beta testing iOS apps.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Build and Archive the App&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
In Xcode, go to &lt;strong&gt;Product &amp;gt; Archive&lt;/strong&gt; to create an archive of your app.  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Handle Two-Factor Authentication (2FA)&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Apple requires 2FA for logging into App Store Connect. This can pose challenges in a CI/CD pipeline.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Solution&lt;/strong&gt;: Use an API key to authenticate instead of an Apple ID. Here’s an example using Fastlane:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  api_key = app_store_connect_api_key({
    key_id: "&amp;lt;key id&amp;gt;",
    issuer_id: "&amp;lt;issuer id&amp;gt;",
    key_filepath: "path/to/AuthKey.p8"
  })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Upload to TestFlight&lt;/strong&gt;:
Once authenticated, upload the build using Xcode or Fastlane:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  fastlane pilot upload
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  &lt;strong&gt;6. App Versioning&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Apple enforces strict versioning rules for apps on the App Store.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Update the Version Number&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Each release must have a new version. Unlike npm packages, the same version cannot be reused.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Update the version in Xcode: &lt;strong&gt;General &amp;gt; Version&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Use semantic versioning (e.g., &lt;code&gt;1.0.1&lt;/code&gt;, &lt;code&gt;1.1.0&lt;/code&gt;).
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Automate Version Updates&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;&lt;br&gt;
Use Fastlane to increment the version number:&lt;br&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  fastlane run increment_version_number
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Now you can build, sign, and submit your iOS app while addressing common challenges like signing, provisioning, and two-factor authentication for App Store submission.&lt;/p&gt;

&lt;p&gt;After knowing how to build for every platform manually, we can start automating the build process using GitHub Actions and Fastlane.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fastlane: Automating iOS and Android Builds
&lt;/h2&gt;

&lt;p&gt;Fastlane is a popular tool for automating repetitive tasks in mobile app development, such as building, signing, and deploying apps. It simplifies CI/CD workflows and reduces manual overhead.&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;What is Fastlane?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Fastlane is an open-source platform that automates the deployment process for iOS and Android apps.  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Language&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Fastlane is written in Ruby, and its configuration is managed through specific files like &lt;code&gt;Fastfile&lt;/code&gt;, &lt;code&gt;Appfile&lt;/code&gt;, and &lt;code&gt;Matchfile&lt;/code&gt;.  &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  &lt;strong&gt;2. Fastfile&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;Fastfile&lt;/code&gt; defines lanes, which are sequences of tasks you want to automate. Each lane can perform specific actions like building, testing, or deploying.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example Fastfile&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;default_platform(:ios)

platform :ios do
  desc "Build and deploy to TestFlight"
  lane :beta do
    build_app(scheme: "MyApp")       # Build the app
    upload_to_testflight             # Upload to TestFlight
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Key Components&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;build_app&lt;/code&gt;: Compiles the app.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;upload_to_testflight&lt;/code&gt;: Submits the app to TestFlight.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;And a lot of other actions can be found in the Fastlane documentation.&lt;/p&gt;




&lt;h4&gt;
  
  
  &lt;strong&gt;3. Appfile&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;Appfile&lt;/code&gt; contains metadata about the app, such as the app identifier and developer account details.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example Appfile&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app_identifier("com.example.app")  # Dynamically set the app ID
apple_id("developer@example.com")  # Your Apple Developer account email

itc_team_id("ABC123")  # App Store Connect Team ID
team_id("DEF456")  # Developer Team ID
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  &lt;strong&gt;4. Certificates and Provisioning Profiles&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Fastlane uses the &lt;code&gt;match&lt;/code&gt; action to manage and install certificates and provisioning profiles. This eliminates the need to manually download and install these files.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Certificates and Profiles Bottleneck&lt;/strong&gt;:
Storing certificates and profiles directly in the repository is insecure. Fastlane resolves this by storing them in a secure, version-controlled Git repository.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Matchfile Example&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git_url("https://username:#{ENV["GH_ACCESS_TOKEN"]}@github.com/your-org/certificates-repo.git")
type("appstore")                       # Type of profile: appstore, adhoc, development
app_identifier(ENV["APP_IDENTIFIER"])  # get app ID from env
username("developer@example.com")      # Apple Developer account
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see here, I created a separate private repo for certificates and profiles so that &lt;code&gt;match&lt;/code&gt; can use to automatically store and retrieve them when needed.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Installation in CI&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  fastlane match appstore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  &lt;strong&gt;5. Authentication with &lt;code&gt;.p8&lt;/code&gt; Auth Key&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;For App Store submission, Apple requires authentication. The &lt;code&gt;.p8&lt;/code&gt; Auth Key provides a secure, CI-friendly alternative to two-factor authentication (2FA).  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using the Auth Key in Fastlane&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;api_key = app_store_connect_api_key({
  key_id: "&amp;lt;YOUR_KEY_ID&amp;gt;",
  issuer_id: "&amp;lt;YOUR_ISSUER_ID&amp;gt;",
  key_filepath: "path/to/AuthKey.p8"
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  &lt;strong&gt;6. Dynamically Handling Multiple App IDs&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Managing app IDs dynamically is crucial when building multiple apps without hardcoding the identifiers. The app ID, such as &lt;code&gt;com.x.y&lt;/code&gt;, is required in every Fastlane configuration.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Use environment variables to dynamically assign the app ID in the CI pipeline.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Set the App ID&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  export APP_IDENTIFIER="com.example.myapp"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Use in Fastlane&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  app_identifier(ENV["APP_IDENTIFIER"])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we are hardcoded the app ID in the Fastfile. But this can be a challenge when automating the build process for multiple apps. We'll come back to this later.&lt;/p&gt;




&lt;h3&gt;
  
  
  Fastfile explained
&lt;/h3&gt;

&lt;p&gt;The building blocks for the Fastfile is &lt;code&gt;lanes&lt;/code&gt; which are like methods in OOP paradigm. Each lane is a collection of tasks that are executed in a specific order. These lanes can be executed with the &lt;code&gt;fastlane run &amp;lt;lane_name&amp;gt;&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;Let's walk through the Fastfile in detail:&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Global Configuration&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;default_platform(:ios)&lt;/code&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Sets the default platform to &lt;code&gt;:ios&lt;/code&gt; so that you don't need to explicitly specify it when running lanes. This is helpful if you're only working with iOS or if it's the primary platform.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Platform Block: &lt;code&gt;platform :ios do&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This block contains all the lanes specific to the iOS platform.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Lane: &lt;code&gt;:prepare&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This lane prepares the environment for building the app, such as setting up keychains, certificates, and provisioning profiles.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Steps in the &lt;code&gt;:prepare&lt;/code&gt; lane:&lt;/strong&gt;
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Define the path for the AuthKey file&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   auth_key_path = File.expand_path(File.join(File.dirname(__FILE__), '&amp;lt;name of AuthKey file&amp;gt;.p8'))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Defines the absolute path to the &lt;code&gt;.p8&lt;/code&gt; authentication key file required for App Store Connect API.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create an API key object&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   api_key = app_store_connect_api_key({
     key_id: "&amp;lt;key id&amp;gt;",
     issuer_id: "&amp;lt;issuer id&amp;gt;",
     key_filepath: auth_key_path,
   })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Authenticates with App Store Connect using the specified &lt;code&gt;key_id&lt;/code&gt;, &lt;code&gt;issuer_id&lt;/code&gt;, and &lt;code&gt;key_filepath&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;This step is crucial to authenticate with apple so that you can upload the app to App Store Connect without two-factor authentication.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create a keychain&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   create_keychain(
     name: 'ios_app_keychain',
     password: ENV['KEYCHAIN_PASSWORD'],
     timeout: 1800,
     default_keychain: true,
     unlock: true,
     lock_when_sleeps: false,
     add_to_search_list: true
   )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Creates a custom keychain for storing signing certificates and provisioning profiles. The keychain:

&lt;ul&gt;
&lt;li&gt;Uses the password stored in the &lt;code&gt;KEYCHAIN_PASSWORD&lt;/code&gt; environment variable. Which we will set in the workflow file.&lt;/li&gt;
&lt;li&gt;Is set as the default keychain and unlocked for 30 minutes (&lt;code&gt;timeout: 1800&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Fetch certificates and provisioning profiles using &lt;code&gt;match&lt;/code&gt;&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   match(
     type: 'appstore',
     app_identifier: ENV["APP_IDENTIFIER"],
     readonly: false,
     keychain_name: 'ios_app_keychain', # Use the previously created keychain, notice that it's the same name as in create_keychain step
     keychain_password: ENV['KEYCHAIN_PASSWORD'],
     api_key: api_key
   )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Retrieves the required certificates and provisioning profiles for the &lt;code&gt;appstore&lt;/code&gt; type.&lt;/li&gt;
&lt;li&gt;Uses the &lt;code&gt;api_key&lt;/code&gt; for authentication and installs the profiles in the created keychain.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Update project provisioning&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   update_project_provisioning(
     xcodeproj: "&amp;lt;name of the app&amp;gt;.xcodeproj",
     target_filter: "&amp;lt;name of the app&amp;gt;",
     profile: ENV["sigh_#{ENV["APP_IDENTIFIER"]}_appstore_profile-path"],
     build_configuration: "Release"
   )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Updates the Xcode project with the appropriate provisioning profile for the &lt;code&gt;Release&lt;/code&gt; configuration.&lt;/li&gt;
&lt;li&gt;Notice the &lt;code&gt;ENV["sigh_#{ENV["APP_IDENTIFIER"]}_appstore_profile-path"]&lt;/code&gt; which is the path to the provisioning profile stored in the env variables used by &lt;code&gt;fastlane&lt;/code&gt;. The syntax is &lt;code&gt;sigh_&amp;lt;app_identifier&amp;gt;_&amp;lt;type&amp;gt;_&amp;lt;profile-name&amp;gt;&lt;/code&gt; so here in our case it's &lt;code&gt;sigh_com.example.app.appstore_profile-name&lt;/code&gt; which is name of the env variable used by fastlane to get the path to provisioning profile (which is something handled by &lt;code&gt;match&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Lane: &lt;code&gt;:beta&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This lane is used to push a new beta build to TestFlight.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Steps in the &lt;code&gt;:beta&lt;/code&gt; lane:&lt;/strong&gt;
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Define the path for the AuthKey file&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Same as in the &lt;code&gt;:prepare&lt;/code&gt; lane.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Create an API key object&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Same as in the &lt;code&gt;:prepare&lt;/code&gt; lane.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Retrieve the current build number&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   build_number = app_store_build_number(api_key: api_key, live: false)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Fetches the latest build number for the app on TestFlight (non-live version) so that we can increment it for the next build.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Increment the build number&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   increment_build_number(xcodeproj: "&amp;lt;name of the app&amp;gt;.xcodeproj", build_number: build_number + 1)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Updates the build number in the Xcode project file (&lt;code&gt;&amp;lt;name of the app&amp;gt;.xcodeproj&lt;/code&gt;) by incrementing it by 1. The &lt;code&gt;&amp;lt;name of the app&amp;gt;&lt;/code&gt; should be replaced with the actual name of your app.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Update code signing settings&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   update_code_signing_settings(
     use_automatic_signing: false,
     path: "&amp;lt;name of the app&amp;gt;.xcodeproj",
     build_configurations: ["Release"]
   )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Configures the Xcode project to use manual code signing for the &lt;code&gt;Release&lt;/code&gt; configuration. This is required for submitting the app to TestFlight.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Build the app using &lt;code&gt;gym&lt;/code&gt;&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   gym(
     workspace: "&amp;lt;name of the app&amp;gt;.xcworkspace",
     scheme:"&amp;lt;name of the app&amp;gt;",
     configuration: "Release",
     clean: true,
     export_method: "app-store",
     output_directory:"./build/",
     export_options: {
       method: "app-store",
       provisioningProfiles: { 
         ENV["APP_IDENTIFIER"] =&amp;gt; ENV["sigh_#{ENV["APP_IDENTIFIER"]}_appstore_profile-name"] # Dynamically set the provisioning profile env variable
       }
     },
     codesigning_identity: "&amp;lt;signing identity&amp;gt;", # get it from apple connect
     output_name: "test_prod.ipa"
   )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Builds the app with the following parameters:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Workspace&lt;/strong&gt;: &lt;code&gt;&amp;lt;name of the app&amp;gt;.xcworkspace&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scheme&lt;/strong&gt;: &lt;code&gt;&amp;lt;name of the app&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configuration&lt;/strong&gt;: &lt;code&gt;Release&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Provisioning Profiles&lt;/strong&gt;: Dynamically sets the provisioning profile based on environment variables.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Output&lt;/strong&gt;: Saves the &lt;code&gt;.ipa&lt;/code&gt; file as &lt;code&gt;test_prod.ipa&lt;/code&gt; in the &lt;code&gt;./build/&lt;/code&gt; directory.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Upload the build to TestFlight&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   upload_to_testflight(api_key: api_key)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Submits the &lt;code&gt;.ipa&lt;/code&gt; to TestFlight for testing, skipping the wait for Apple's processing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now the final &lt;code&gt;Fastfile&lt;/code&gt; is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;default_platform(:ios)

platform :ios do

  desc "Push a new beta build to TestFlight"
  lane :beta do
    auth_key_path = File.expand_path(File.join(File.dirname(__FILE__), '&amp;lt;name of AuthKey file&amp;gt;.p8'))
    api_key = app_store_connect_api_key({
      key_id: "&amp;lt;key id&amp;gt;",
      issuer_id: "&amp;lt;issuer id&amp;gt;",
      key_filepath: auth_key_path,
    })
    build_number = app_store_build_number(api_key: api_key, live: false)
    increment_build_number(xcodeproj: "&amp;lt;name of the app&amp;gt;.xcodeproj", build_number: build_number + 1)
    update_code_signing_settings(
      use_automatic_signing: false,
      path: "&amp;lt;name of the app&amp;gt;.xcodeproj",
      build_configurations: ["Release"]
    )
    gym(
      workspace: "&amp;lt;name of the app&amp;gt;.xcworkspace",
      scheme:"&amp;lt;name of the app&amp;gt;",
      configuration: "Release",
      clean: true,
      export_method: "app-store",
      output_directory:"./build/",
      export_options: {
        method: "app-store",
        provisioningProfiles: { 
          ENV["APP_IDENTIFIER"] =&amp;gt; ENV["sigh_#{ENV["APP_IDENTIFIER"]}_appstore_profile-name"]
        }
      },
      codesigning_identity: "&amp;lt;signing identity&amp;gt;", # get it from apple connect
      output_name: "test_prod.ipa"
    )
    upload_to_testflight(api_key: api_key)
  end

  lane :prepare do
    auth_key_path = File.expand_path(File.join(File.dirname(__FILE__), '&amp;lt;name of AuthKey file&amp;gt;.p8'))
    api_key = app_store_connect_api_key({
      key_id: "&amp;lt;key id&amp;gt;",
      issuer_id: "&amp;lt;issuer id&amp;gt;",
      key_filepath: auth_key_path,
    })
    create_keychain(
      name: 'ios_app_keychain',
      password: ENV['KEYCHAIN_PASSWORD'],
      timeout: 1800,
      default_keychain: true,
      unlock: true,
      lock_when_sleeps: false,
      add_to_search_list: true
    )

    match(
      type: 'appstore',
      app_identifier: ENV["APP_IDENTIFIER"],
      readonly: false,
      keychain_name: 'ios_app_keychain',
      keychain_password: ENV['KEYCHAIN_PASSWORD'],
      api_key: api_key
    )

    update_project_provisioning(
      xcodeproj: "&amp;lt;name of the app&amp;gt;.xcodeproj",
      target_filter: "&amp;lt;name of the app&amp;gt;",
      profile: ENV["sigh_#{ENV["APP_IDENTIFIER"]}_appstore_profile-path"],
      build_configuration: "Release"
    )
  end
end

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We now have a good grasp of what in the Fastfile and how it works. With this knowledge, we can now use the Fastfile to build and deploy the app to TestFlight.&lt;/p&gt;

&lt;p&gt;But we still have 2 issues for our &lt;code&gt;CI/CD&lt;/code&gt; pipeline to work:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Hardcoded app ID in the Fastfile, Matchfile and Appfile.&lt;/li&gt;
&lt;li&gt;Creating the &lt;code&gt;keystore&lt;/code&gt; file in the repository for android build to work.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's address these issues while we are working on the workflow for GitHub Actions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Github workflow file
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Build Android version and submit to store
&lt;/h3&gt;

&lt;p&gt;The requirement is to build the android version with 2 versions of the app, one for production (&lt;code&gt;.aab&lt;/code&gt;) and one for staging (&lt;code&gt;.apk&lt;/code&gt;). We'll use action's conditions here for this requirement.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Setup node: we'll use the &lt;code&gt;actions/setup-node@v2&lt;/code&gt; action to set up Node.js environment.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   - name: Setup Node
     uses: actions/setup-node@v2
     with:
       node-version: '20.16.0'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Setup Java: we'll use the &lt;code&gt;actions/setup-java@v4&lt;/code&gt; action to set up Java environment.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   - name: Setup Java
     uses: actions/setup-java@v4
     with:
       distribution: 'zulu'
       java-version: '17'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Validate Gradle wrapper: we'll use the &lt;code&gt;gradle/wrapper-validation-action@v1&lt;/code&gt; action to validate the Gradle wrapper.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   - name: Validate Gradle wrapper
     uses: gradle/wrapper-validation-action@v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Install Deps:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   - name: Install Deps
     shell: bash
     run: yarn --frozen-lockfile &amp;amp;&amp;amp; yarn env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create keystore file: the keystore file should not be pushed to the repository. to achieve this, we'll do the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Encrypt the local keystore file using &lt;code&gt;base64&lt;/code&gt; encoding.&lt;/li&gt;
&lt;li&gt;Add this encrypted keystore file to the secrets.&lt;/li&gt;
&lt;li&gt;Use the &lt;code&gt;mobiledevops/secret-to-file-action@v1&lt;/code&gt; action to create the keystore file.
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- name: Create keystore file
  uses: mobiledevops/secret-to-file-action@v1
  with:
    base64-encoded-secret: ${{ secrets.KEYSTORE_FILE }}
    filename: '&amp;lt;name of the app&amp;gt;.keystore'
    is-executable: false
    working-directory: './android/app'
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generate apk: we'll run the &lt;code&gt;yarn g-c-build&lt;/code&gt; (which is an npm script in our &lt;code&gt;package.json&lt;/code&gt; file) command to generate the &lt;code&gt;.apk&lt;/code&gt; file if the pipeline is in the dev branch.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   - name: Generate apk
     if: github.ref_name == env.DEV_BRANCH
     run: yarn g-c-build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Generate aab: we'll run the &lt;code&gt;yarn g-c-build&lt;/code&gt; (which is an npm script in our &lt;code&gt;package.json&lt;/code&gt; file) command to generate the &lt;code&gt;.aab&lt;/code&gt; file if the pipeline is not in the dev branch.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   - name: Generate aab
     if: github.ref_name != env.DEV_BRANCH
     run: yarn g-c-bundle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Upload the &lt;code&gt;.apk&lt;/code&gt; file to firebase for &lt;code&gt;QA&lt;/code&gt; to download and install it. This will require us to set the app id from firebase as an env variable to use it while pushing to firebase using &lt;code&gt;wzieba/Firebase-Distribution-Github-Action@v1&lt;/code&gt; action (optional).
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   - name: Set App ID taken from firebase as env variable
     if: github.ref_name == env.DEV_BRANCH
     id: set-app-id
     run: |
       echo FIREBASE_APP_ID=$(cat android/firebase_app_id.txt) &amp;gt;&amp;gt; $GITHUB_OUTPUT

   - name: Upload artifact to Firebase App Distribution
     if: github.ref_name == env.DEV_BRANCH
     uses: wzieba/Firebase-Distribution-Github-Action@v1
     with:
       appId: ${{ env.FIREBASE_APP_ID }}
       serviceCredentialsFileContent: ${{ secrets.CREDS_FILE_CONTENT }}
        groups: testers
       file: android/app/build/outputs/apk/release/app-release.apk
     env:
       FIREBASE_APP_ID: ${{ steps.set-app-id.outputs.FIREBASE_APP_ID }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice here that I stored the app id from firebase in a text file called &lt;code&gt;firebase_app_id.txt&lt;/code&gt; and used it to set the app id as an env variable. Also, the &lt;code&gt;$GITHUB_OUTPUT&lt;/code&gt; variable is used to store the output of the &lt;code&gt;echo&lt;/code&gt; command which is a reserved variable in GitHub Actions.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Upload the &lt;code&gt;.aab&lt;/code&gt; file to google play using &lt;code&gt;KevinRohn/github-action-upload-play-store@v1.0.0&lt;/code&gt; action.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   - name: Upload artifact to Google Play
     if: github.ref_name != env.DEV_BRANCH
     uses: KevinRohn/github-action-upload-play-store@v1.0.0
     with:
       service_account_json: ${{ secrets.SERVICE_ACCOUNT_JSON }}
       package_name: ${{ github.ref_name }} # will explain this later in ios steps
       aab_file_path: 'android/app/build/outputs/bundle/release/app-release.aab'
       track: 'production'
       release_status: 'completed'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Build IOS version and submit to store
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Setup Node: we'll use the &lt;code&gt;actions/setup-node@v2&lt;/code&gt; action to set up Node.js environment. Same as in android.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   - name: Setup Node
     uses: actions/setup-node@v2
     with:
       node-version: '20.16.0'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Install Deps: same as in android.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   - name: Install Deps
     shell: bash
     run: yarn --frozen-lockfile &amp;amp;&amp;amp; yarn env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Install pods:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   - name: Install pods
     shell: bash
     run: |
       cd ios/
       rm -rf Pods Podfile.lock
       pod install --repo-update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Run fastlane's &lt;code&gt;prepare&lt;/code&gt; and &lt;code&gt;beta&lt;/code&gt; actions with required env variables.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   - name: Prepare and build IOS
     run: cd ios/ &amp;amp;&amp;amp; fastlane prepare &amp;amp;&amp;amp; fastlane beta
     env:
        FASTLANE_USER: ${{ secrets.FASTLANE_USER }}
        FASTLANE_PASSWORD: ${{ secrets.FASTLANE_PASSWORD }}
        P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
        KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
        MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
        ITMSTRANSPORTER_FORCE_ITMS_PACKAGE_UPLOAD: false
        APP_IDENTIFIER: ${{ github.ref_name }} # we will use the branch name as app id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Notice here that we used the branch name as app id so that we have addressed the issue of hardcoded app id in the Fastfile, Appfile and Matchfile. For each client we'll have a different app id. For example, if we have a client app id in apple called `com.example.client` then we'll name the branch `com.example.client` and the app id will be `com.example.client` by using `github.ref_name`.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The resulting workflow will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: Build &amp;amp; submit to stores
on:
  workflow_dispatch:

env:
  DEV_BRANCH: 'staging'

jobs:
  build-ios:
    name: Build IOS
    runs-on: macos-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v1

      - name: Setup Node
        uses: actions/setup-node@v2
        with:
          node-version: '20.16.0'

      - name: Install Deps
        shell: bash
        run: yarn install --ignore-scripts &amp;amp;&amp;amp; yarn env

      - name: Install pods
        shell: bash
        run: |
          cd ios/
          rm -rf Pods Podfile.lock
          pod install --repo-update

      - name: Prepare and build IOS
        run: cd ios/ &amp;amp;&amp;amp; fastlane prepare &amp;amp;&amp;amp; fastlane beta
        env:
          FASTLANE_USER: ${{ secrets.FASTLANE_USER }}
          FASTLANE_PASSWORD: ${{ secrets.FASTLANE_PASSWORD }}
          P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
          KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
          MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
          ITMSTRANSPORTER_FORCE_ITMS_PACKAGE_UPLOAD: false
          APP_IDENTIFIER: ${{ github.ref_name }}


  build-android:
    name: Build Android
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v1

      - name: Setup Node
        uses: actions/setup-node@v2
        with:
          node-version: '20.16.0'

      - name: Setup Java
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: '17'

      - name: Validate Gradle wrapper
        uses: gradle/wrapper-validation-action@v1

      - name: Install Deps
        shell: bash
        run: yarn --frozen-lockfile &amp;amp;&amp;amp; yarn env

      - name: Create keystore file
        uses: mobiledevops/secret-to-file-action@v1
        with:
          base64-encoded-secret: ${{ secrets.KEYSTORE_FILE }}
          filename: '&amp;lt;app name&amp;gt;.keystore'
          is-executable: false
          working-directory: './android/app'

      - name: Generate apk
        if: github.ref_name == env.DEV_BRANCH
        run: yarn g-c-build

      - name: Generate aab
        if: github.ref_name != env.DEV_BRANCH
        run: yarn g-c-bundle

      - name: Set App ID taken from firebase as env variable
        if: github.ref_name == env.DEV_BRANCH
        id: set-app-id
        run: |
          echo FIREBASE_APP_ID=$(cat android/firebase_app_id.txt) &amp;gt;&amp;gt; $GITHUB_OUTPUT

      - name: Upload artifact to Firebase App Distribution
        if: github.ref_name == env.DEV_BRANCH
        uses: wzieba/Firebase-Distribution-Github-Action@v1
        with:
          appId: ${{ env.FIREBASE_APP_ID }}
          serviceCredentialsFileContent: ${{ secrets.CREDS_FILE_CONTENT }}
          groups: testers
          file: android/app/build/outputs/apk/release/app-release.apk
        env:
          FIREBASE_APP_ID: ${{ steps.set-app-id.outputs.FIREBASE_APP_ID }}

      - name: Upload artifact to Google Play
        if: github.ref_name != env.DEV_BRANCH
        uses: KevinRohn/github-action-upload-play-store@v1.0.0
        with:
          service_account_json: ${{ secrets.SERVICE_ACCOUNT_JSON }}
          package_name: ${{ github.ref_name }}
          aab_file_path: 'android/app/build/outputs/bundle/release/app-release.aab'
          track: 'production'
          release_status: 'completed'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We made the pipeline to run manually by using &lt;code&gt;workflow_dispatch&lt;/code&gt; action, which makes it easy to trigger the workflow manually which is good for minutes consumption. Also this event will help us trigger the workflow run through github APIs as well.&lt;/p&gt;

&lt;p&gt;After we ran this workflow, we can see the artifacts uploaded to &lt;code&gt;firebase&lt;/code&gt; and &lt;code&gt;google play&lt;/code&gt; stores and also to &lt;code&gt;testflight&lt;/code&gt;. But, we saw that the minutes consumption is 40 minutes for &lt;code&gt;ios&lt;/code&gt; and 27 minutes for &lt;code&gt;android&lt;/code&gt; which is very high.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimizing the workflow
&lt;/h2&gt;

&lt;p&gt;To reduce the consumption time, we can do the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Cache dependencies: we can use the &lt;code&gt;actions/cache&lt;/code&gt; action to cache the dependencies to speed up the workflow.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   - name: Cache node_modules
     id: modules-cache
     uses: actions/cache@v3
     with:
        path: ./node_modules
        key: ${{ runner.os }}-modules-${{ hashFiles('yarn.lock') }}
        restore-keys: |
        ${{ runner.os }}-modules-
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will cache the dependencies and only install them if they are not cached. Also skip the install step if the dependencies are cached.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   - name: Install Deps if necessary
     if: steps.modules-cache.outputs.cache-hit != 'true'
     shell: bash
     run: yarn install --ignore-scripts &amp;amp;&amp;amp; yarn env 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Cache pods: we can use the &lt;code&gt;actions/cache&lt;/code&gt; action to cache the pods to speed up the workflow.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   - name: Cache pods
     id: pods-cache
     uses: actions/cache@v3
     with:
        path: ./ios/Pods
        key: ${{ runner.os }}-pods-${{ hashFiles('ios/Podfile.lock') }}
        restore-keys: |
        ${{ runner.os }}-pods-
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will cache the pods and only install them if they are not cached. Also skip the install step if the pods are cached.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   - name: Install pods if necessary
     if: steps.pods-cache.outputs.cache-hit != 'true'
     shell: bash
     run: |
        cd ios/
        rm -rf Pods Podfile.lock
        pod install --repo-update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Skip waiting for build to be processed in testflight:
In the Fastfile we used the &lt;code&gt;upload_to_testflight&lt;/code&gt; action which will wait for the build to be processed in testflight. But we can skip this step by using the &lt;code&gt;skip_waiting_for_build_processing: true&lt;/code&gt; option.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   upload_to_testflight(api_key: api_key, skip_waiting_for_build_processing: true)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The resulting workflow will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: Build &amp;amp; submit to stores
on:
  workflow_dispatch:

env:
  DEV_BRANCH: 'staging'

jobs:
  build-ios:
    name: Build IOS
    runs-on: macos-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v1

      - name: Setup Node
        uses: actions/setup-node@v2
        with:
          node-version: '20.16.0'

      - name: Cache node_modules
        id: modules-cache
        uses: actions/cache@v3
        with:
          path: ./node_modules
          key: ${{ runner.os }}-modules-${{ hashFiles('yarn.lock') }}
          restore-keys: |
            ${{ runner.os }}-modules-

      - name: Install Deps if necessary
        if: steps.modules-cache.outputs.cache-hit != 'true'
        shell: bash
        run: yarn install --ignore-scripts &amp;amp;&amp;amp; yarn env

      - name: Cache Pods
        uses: actions/cache@v3
        id: pods-cache
        with:
          path: ./ios/Pods
          key: ${{ runner.os }}-pods-${{ hashFiles('ios/Podfile.lock') }}
          restore-keys: |
            ${{ runner.os }}-pods-

      - name: Install pods
        if: steps.pods-cache.outputs.cache-hit != 'true'
        shell: bash
        run: |
          cd ios/
          rm -rf Pods Podfile.lock
          pod install --repo-update
          cd ..
      - name: Prepare and build IOS
        if: github.ref_name != env.DEV_BRANCH
        run: cd ios/ &amp;amp;&amp;amp; fastlane prepare &amp;amp;&amp;amp; fastlane beta
        env:
          FASTLANE_USER: ${{ secrets.FASTLANE_USER }}
          FASTLANE_PASSWORD: ${{ secrets.FASTLANE_PASSWORD }}
          P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
          KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
          MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
          ITMSTRANSPORTER_FORCE_ITMS_PACKAGE_UPLOAD: false
          APP_IDENTIFIER: ${{ github.ref_name }}


  build-android:
    name: Build Android
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v1

      - name: Setup Node
        uses: actions/setup-node@v2
        with:
          node-version: '20.16.0'

      - name: Setup Java
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: '17'

      - name: Validate Gradle wrapper
        uses: gradle/wrapper-validation-action@v1

      - name: Cache node_modules
        id: modules-cache
        uses: actions/cache@v3
        with:
          path: ./node_modules
          key: ${{ runner.os }}-modules-${{ hashFiles('yarn.lock') }}
          restore-keys: |
            ${{ runner.os }}-modules-

      - name: Install Deps if necessary
        if: steps.modules-cache.outputs.cache-hit != 'true'
        shell: bash
        run: yarn --frozen-lockfile &amp;amp;&amp;amp; yarn env

      - name: Create keystore file
        uses: mobiledevops/secret-to-file-action@v1
        with:
          base64-encoded-secret: ${{ secrets.KEYSTORE_FILE }}
          filename: '&amp;lt;app name&amp;gt;.keystore'
          is-executable: false
          working-directory: './android/app'

      - name: Generate apk
        if: github.ref_name == env.DEV_BRANCH
        run: yarn g-c-build

      - name: Generate aab
        if: github.ref_name != env.DEV_BRANCH
        run: yarn g-c-bundle

      - name: Set App ID taken from firebase as env variable
        if: github.ref_name == env.DEV_BRANCH
        id: set-app-id
        run: |
          echo FIREBASE_APP_ID=$(cat android/firebase_app_id.txt) &amp;gt;&amp;gt; $GITHUB_OUTPUT

      - name: Upload artifact to Firebase App Distribution
        if: github.ref_name == env.DEV_BRANCH
        uses: wzieba/Firebase-Distribution-Github-Action@v1
        with:
          appId: ${{ env.FIREBASE_APP_ID }}
          serviceCredentialsFileContent: ${{ secrets.CREDS_FILE_CONTENT }}
          groups: testers
          file: android/app/build/outputs/apk/release/app-release.apk
        env:
          FIREBASE_APP_ID: ${{ steps.set-app-id.outputs.FIREBASE_APP_ID }}

      - name: Upload artifact to Google Play
        if: github.ref_name != env.DEV_BRANCH
        uses: KevinRohn/github-action-upload-play-store@v1.0.0
        with:
          service_account_json: ${{ secrets.SERVICE_ACCOUNT_JSON }}
          package_name: ${{ github.ref_name }}
          aab_file_path: 'android/app/build/outputs/bundle/release/app-release.aab'
          track: 'production'
          release_status: 'completed'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, the resulting workflow will run in 20-30 minutes instead of 40 minutes which reduces the minutes consumbtion by 20%-50%.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Automating the build and release process with GitHub Actions and Fastlane transformed a time-intensive bottleneck into a streamlined, scalable solution. This pipeline is a testament to the power of automation in solving real-world challenges, enabling teams to focus on what matters most: building great products.&lt;/p&gt;

&lt;p&gt;If you're managing multiple apps or facing similar bottlenecks, consider leveraging GitHub Actions and Fastlane. It’s not just about saving time—it’s about empowering your team to achieve more.&lt;/p&gt;

</description>
      <category>githubactions</category>
      <category>fastlane</category>
      <category>reactnative</category>
      <category>cicd</category>
    </item>
    <item>
      <title>Coercion: Deep Dive</title>
      <dc:creator>Mohamed Saad</dc:creator>
      <pubDate>Sat, 23 Nov 2019 16:11:46 +0000</pubDate>
      <link>https://dev.to/dvmhmdsd/coercion-deep-dive-3634</link>
      <guid>https://dev.to/dvmhmdsd/coercion-deep-dive-3634</guid>
      <description>&lt;p&gt;From the beginning of history of &lt;code&gt;Javascript&lt;/code&gt;, developers thought that &lt;code&gt;coercion&lt;/code&gt; is evil and confusing and start to ran away from it. First, let's see what's coercion really.&lt;/p&gt;

&lt;h3&gt;
  
  
  Definition
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Coercion:&lt;/strong&gt; it's the conversion from data type into another in javascript. It's called in other programming languages &lt;code&gt;Type Casting&lt;/code&gt;. There's a lot of arguments around this definition, but what I liked is that (&lt;code&gt;Type Casting&lt;/code&gt;) is the conversion in statically typed languages like &lt;em&gt;Java &amp;amp; C++&lt;/em&gt;, while (&lt;code&gt;coercion&lt;/code&gt;) is the conversion in dynamically typed languages like &lt;em&gt;Javascript&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Types
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Explicit Coercion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It's the conversion from type into another by intention. like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// "23"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we converted the number 23 into string "23" by explicitly calling &lt;code&gt;String()&lt;/code&gt; constructor. This process is very similar to &lt;em&gt;Type casting&lt;/em&gt; in java as we do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;int(23)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;String()&lt;/code&gt; constructor uses what's called &lt;strong&gt;Abstract operations&lt;/strong&gt; which defined in the &lt;code&gt;specification&lt;/code&gt; of the language, &lt;code&gt;ToString&lt;/code&gt;. These operations is used internally only by the engine and we don't use it in our code. Also, we can use &lt;code&gt;.toString()&lt;/code&gt; like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// "23"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;..&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// "23"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you might saw, when we use the number directly without storing it in a variable, we put extra (.) before &lt;code&gt;.toString()&lt;/code&gt;, that's because the JS engine consider the first dot as a floating point like we type: &lt;code&gt;23.5&lt;/code&gt;, while the second dot is related to the toString() method.&lt;/p&gt;

&lt;p&gt;Also, when we explicitly converting from &lt;code&gt;String&lt;/code&gt; into &lt;code&gt;Number&lt;/code&gt; we use &lt;strong&gt;Number()&lt;/strong&gt; constructor, e.g:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;23&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 23&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;23&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 23&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice I used &lt;em&gt;+&lt;/em&gt; operator for explicit coercion from string to number which is a unary operator that get a single operand and converting it into number. The &lt;code&gt;Number()&lt;/code&gt; uses the abstract operation &lt;strong&gt;ToNumber&lt;/strong&gt; which defined in the specification.&lt;/p&gt;

&lt;h5&gt;
  
  
  Explicitly conversion into Boolean
&lt;/h5&gt;

&lt;p&gt;We can convert any &lt;code&gt;non-boolean&lt;/code&gt; value into &lt;code&gt;boolean&lt;/code&gt; by using surprisingly the &lt;code&gt;Boolean()&lt;/code&gt; constructor :) e.g:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;23&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or we can use &lt;code&gt;!!&lt;/code&gt; operator&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice here we use double &lt;code&gt;!&lt;/code&gt; as the single &lt;code&gt;!&lt;/code&gt; operator used to convert the value into &lt;code&gt;Boolean&lt;/code&gt; then reverse it. Then the second &lt;code&gt;!&lt;/code&gt; reverse the value again as it's reverse the reversion so the result is &lt;strong&gt;true&lt;/strong&gt;.&lt;/p&gt;

&lt;h5&gt;
  
  
  Coercion of objects
&lt;/h5&gt;

&lt;p&gt;When we explicitly convert object to any other data type, the engine uses an abstract operation which called &lt;strong&gt;ToPrimitive&lt;/strong&gt; that uses &lt;code&gt;valueOf()&lt;/code&gt; method which convert the object into its primitive value equivalent and if the &lt;code&gt;valueOf()&lt;/code&gt; fails to get a primitive value then the &lt;strong&gt;ToPrimitive&lt;/strong&gt; operation fall back into &lt;code&gt;toString()&lt;/code&gt; method that converts the object into string which is primitive, e.g:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;valueOf&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;33&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 33&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;33&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 33&lt;/span&gt;

&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt; &lt;span class="c1"&gt;// 0&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the last example, the array is converted into number which produces 0.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implicit Coercion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The second type of coercion is implicit coercion which is the conversion of type without intentionally convert it as it's hidden, non-obvious. This type of conversion confuse a lot of developers and make them avoid it and consider it a bug in javascript.&lt;/p&gt;

&lt;p&gt;As the most of developers see &lt;code&gt;implicit coercion&lt;/code&gt; evil, I see it from a different perspective as it's used to reduce a lot of boilerplate and details that's unnecessary. As &lt;strong&gt;Kyle Sympthon&lt;/strong&gt; said in his book &lt;em&gt;YDKJS - Types &amp;amp; Grammar&lt;/em&gt; : &lt;strong&gt;"Don't throw the baby out with the bathwater"&lt;/strong&gt; because the developers see implicit coercion evil they throw it away just to be safe, which is wrong.&lt;/p&gt;

&lt;p&gt;Let's see how we can implicitly convert from type to another.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;number&lt;/code&gt; is implicitly converted into &lt;code&gt;string&lt;/code&gt; by putting it in concatenation expression with a string, e.g:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// "22"&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// "22"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the &lt;em&gt;number&lt;/em&gt; 2 converted into &lt;em&gt;string&lt;/em&gt; by concatenate it with &lt;code&gt;string&lt;/code&gt; "2". Let's consider this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="c1"&gt;// "2, 43, 6"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait! What!, confusing hah! No, Not really.&lt;/p&gt;

&lt;p&gt;While none of two operand are &lt;code&gt;string&lt;/code&gt; the operation produces string. As the &lt;em&gt;ES5 Specification&lt;/em&gt; said that when "+" operator receive an object it uses &lt;em&gt;ToPrimitive&lt;/em&gt; operation which convert an object which is &lt;code&gt;non-primitive&lt;/code&gt; into &lt;code&gt;primitive&lt;/code&gt;, but which type? &lt;em&gt;Number&lt;/em&gt;? or &lt;em&gt;String&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;Actually, the &lt;strong&gt;ToPrimitive&lt;/strong&gt; operation uses under the hood the &lt;strong&gt;ToNumber&lt;/strong&gt; operation which fails to produce a number then it falls back into &lt;code&gt;toString&lt;/code&gt; method that convert the first array into string ("2, 4") and the second one into ("3, 6") then the operation becomes a normal string concatenation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2, 4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;3, 6&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// "2, 43, 6"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Obvious, hah!&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;string&lt;/code&gt; is converted into &lt;code&gt;number&lt;/code&gt; by adding the string in mathematical operation, e.g:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let a = "42";

a - 0; // 42
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Implicitly converting from any value into Boolean
&lt;/h5&gt;

&lt;p&gt;This's the most confusing part in implicit coercion. There's cases where implicit coercion to boolean happens:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Expression in &lt;code&gt;if()&lt;/code&gt; statement&lt;/li&gt;
&lt;li&gt;The test expression in &lt;code&gt;for(;..;)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The test expression in &lt;code&gt;while()&lt;/code&gt; loop&lt;/li&gt;
&lt;li&gt;The test expression in ternary operators&lt;/li&gt;
&lt;li&gt;The left hand side in logical operators, &lt;code&gt;||, &amp;amp;&amp;amp;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;It's true !&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// It's true !&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here &lt;code&gt;num&lt;/code&gt; implicitly converted into &lt;code&gt;Boolean&lt;/code&gt; "true", then the test run and the alert fires because the number (2) is a &lt;em&gt;truthy&lt;/em&gt; value which means it converted into true when put in context of boolean.&lt;/p&gt;

&lt;p&gt;You may notice that I said &lt;strong&gt;"The left hand side in logical operators"&lt;/strong&gt;, the truth is these operators is not working like you expect they do similar to other languages like &lt;code&gt;PHP / Java&lt;/code&gt;, actually it works differently, so, how is it working ? let's take an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hi&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// "Hi"&lt;/span&gt;

&lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 23 &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, in the first expression, the test goes for the left hand side of the (&amp;amp;&amp;amp;) operator, convert it to boolean - which is truthy - then, return the right hand side. In the second expression the test goes for the left hand side, convert it to boolean - which is truthy also - then return it and doesn't go to the right hand side. This process is called &lt;strong&gt;"Short circuit evaluation"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The use case for this concept is when you want to return a value depending on truthiness of another value like we do in &lt;code&gt;react&lt;/code&gt;, so we use the (&amp;amp;&amp;amp;), also when you want to return a value and provide a fall back when the first value is falsy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// here we check if the array is empty, so don't return any thing or return a paragraphs containing the items of the array&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// here if the foo() returned undefined or null or any falsy values, the "no value returned" will be returned or the value returned from foo() will be returned either&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;no value returned&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  == vs. ===
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;

&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most of us will respond to this title: "== compares only values while === compares both types and values", actually this's completely wrong !&lt;/p&gt;

&lt;p&gt;Both of them compares types and values, but the difference is if one of them permit coercion or not. In the first expression we'll notice that == operator permit the coercion from &lt;code&gt;string&lt;/code&gt; to &lt;code&gt;number&lt;/code&gt; so the result was &lt;code&gt;true&lt;/code&gt;, while in the second expression the === doesn't permit coercion so the value was &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;

&lt;h6&gt;
  
  
  Which is better ?
&lt;/h6&gt;

&lt;p&gt;Other developers will argue wether is better and their teammates will respond: "of course === because it's much faster than ==", this's also wrong !&lt;/p&gt;

&lt;p&gt;Um, yeah, there's a bit difference in performance but it's not considered because they are very close to each other, so, the final answer is: it doesn't matter which is faster, if you want to permit coercion, use ==, otherwise use ===, simply as that.&lt;/p&gt;

&lt;h6&gt;
  
  
  Comparing non-boolean to boolean
&lt;/h6&gt;

&lt;p&gt;The most risky and confusing example that a lot if developers fall in is when comparing any value to &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt;. Let's consider this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;

&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;5&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What ! How come !&lt;/p&gt;

&lt;p&gt;The ES5 Spec said:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;if one of the two operand (x) is boolean return &lt;strong&gt;ToNumber(x)&lt;/strong&gt; and compare them to each other.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, when we compare 1 to &lt;code&gt;true&lt;/code&gt; the boolean value "true" implicitly converted into number which is &lt;em&gt;1&lt;/em&gt;, then &lt;strong&gt;1 == 1&lt;/strong&gt; is obviously true, while in the second example when we compare "5" to &lt;code&gt;true&lt;/code&gt;, the boolean value implicitly converted into number which is &lt;em&gt;1&lt;/em&gt; and the "5" converted into number which is &lt;em&gt;5&lt;/em&gt;, so, &lt;strong&gt;5 == 1&lt;/strong&gt; is obviously false.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If either side of the comparison can be implicitly converted into &lt;code&gt;true&lt;/code&gt; / &lt;code&gt;false&lt;/code&gt;, Don't never ever use ==.&lt;/li&gt;
&lt;/ul&gt;

&lt;h6&gt;
  
  
  Comparing non-objects to objects
&lt;/h6&gt;

&lt;p&gt;If an object is compared to a primitive value the ES5 Spec said:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If any one of the two operands (x) is object and the other is primitive, return &lt;strong&gt;ToPrimitive(x)&lt;/strong&gt; and compare them to each other.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's consider this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the [2] converted into its primitive value which is &lt;em&gt;2&lt;/em&gt;, then compare it to 2 which is obviously true.&lt;/p&gt;

&lt;p&gt;Simple, hah!&lt;/p&gt;

&lt;p&gt;Let's see this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;

&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the first example, false is converted into number - as we said above - which is &lt;em&gt;0&lt;/em&gt; and [] converted into number by ToPrimitive operation which is &lt;em&gt;0&lt;/em&gt; so the result was &lt;code&gt;true&lt;/code&gt;, while in the second example, [] converted into number by ToPrimitive operation which is &lt;em&gt;0&lt;/em&gt; and {} converted into its primitive value which is &lt;em&gt;NaN&lt;/em&gt; so the result is &lt;code&gt;false&lt;/code&gt;, as &lt;code&gt;NaN&lt;/code&gt; never equal to itself or any other value.&lt;/p&gt;

&lt;p&gt;Let's see this final example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whaaaaaaaaat !&lt;/p&gt;

&lt;p&gt;This's completely crazy !&lt;/p&gt;

&lt;p&gt;Let's take it from right hand side, the ![] - by remember the rules of converting objects - the [] is first converted into boolean which is &lt;em&gt;true&lt;/em&gt; then negate it, so, the result of ![] is false, then compare true to [], &lt;strong&gt;[] == false&lt;/strong&gt;, we saw this before and the result was &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If either side of comparison is object, Don't never ever use ==.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Conclusion
&lt;/h4&gt;

&lt;p&gt;Coercion was - for many developers - an evil and confusing concept, it's the conversion from data type into another, it has 2 types, first is the &lt;code&gt;explicit coercion&lt;/code&gt;, which is the intentionally converting from type into another, and &lt;code&gt;implicit coercion&lt;/code&gt;, which is the hidden converting from type into another.&lt;/p&gt;

&lt;p&gt;Implicit Coercion hides unnecessary details and simplify the implicitly.&lt;/p&gt;

&lt;p&gt;When comparing any value to Boolean or to Object consider not using &lt;code&gt;==&lt;/code&gt; operator as the coercion here make confusing and unpredicted results.&lt;/p&gt;

&lt;h4&gt;
  
  
  Sources
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;You Don't Know Javascript - Types &amp;amp; Grammar&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Type_coercion"&gt;MDN Reference&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>javascript</category>
      <category>coercion</category>
    </item>
    <item>
      <title>Coercion: Deep Dive</title>
      <dc:creator>Mohamed Saad</dc:creator>
      <pubDate>Sat, 23 Nov 2019 15:29:11 +0000</pubDate>
      <link>https://dev.to/dvmhmdsd/coercion-deep-dive-4gbe</link>
      <guid>https://dev.to/dvmhmdsd/coercion-deep-dive-4gbe</guid>
      <description>&lt;p&gt;From the beginning of history of &lt;code&gt;Javascript&lt;/code&gt;, developers thought that &lt;code&gt;coercion&lt;/code&gt; is evil and confusing and start to ran away from it. First, let's see what's coercion really.&lt;/p&gt;

&lt;h2&gt;
  
  
  Definition
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Coercion&lt;/strong&gt;: it's the conversion from data type into another in javascript. It's called in other programming languages &lt;em&gt;Type Casting&lt;/em&gt;. There's a lot of arguments around this definition, but what I liked is that (Type Casting) is the conversion in statically typed languages like Java &amp;amp; C++, while (coercion) is the conversion in dynamically typed languages like Javascript.&lt;/p&gt;

&lt;h2&gt;
  
  
  Types
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Explicit Coercion
&lt;/h3&gt;

&lt;p&gt;It's the conversion from type into another by intention. like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// "23"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we converted the number 23 into string "23" by explicitly calling &lt;code&gt;String()&lt;/code&gt; constructor. This process is very similar to Type casting in java as we do&lt;/p&gt;

&lt;p&gt;&lt;code&gt;int(23)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;String()&lt;/code&gt; constructor uses what's called &lt;em&gt;Abstract operations&lt;/em&gt; which defined in the specification of the language, &lt;code&gt;ToString&lt;/code&gt;. These operations is used internally only by the engine and we don't use it in our code. Also, we can use &lt;code&gt;.toString()&lt;/code&gt; like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// "23"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;..&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// "23"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you might saw, when we use the number directly without storing it in a variable, we put extra (.) before &lt;code&gt;.toString()&lt;/code&gt;, that's because the JS engine consider the first dot as a floating point like we type: 23.5, while the second dot is related to the &lt;code&gt;.toString()&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;Also, when we explicitly converting from String into Number we use &lt;code&gt;Number()&lt;/code&gt; constructor, e.g:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;23&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 23&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;23&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 23&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice I used &lt;code&gt;+&lt;/code&gt; operator for explicit coercion from string to number which is a unary operator that get a single operand and converting it into number. The &lt;code&gt;Number()&lt;/code&gt; uses the abstract operation &lt;strong&gt;ToNumber&lt;/strong&gt; which defined in the specification.&lt;/p&gt;

&lt;h4&gt;
  
  
  Explicitly conversion into Boolean
&lt;/h4&gt;

&lt;p&gt;We can convert any non-boolean value into boolean by using surprisingly the &lt;code&gt;Boolean()&lt;/code&gt; constructor 😅 e.g:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;23&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or we can use &lt;code&gt;!!&lt;/code&gt; operator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice here we use double &lt;code&gt;!&lt;/code&gt; as the single ! operator used to convert the value into Boolean then reverse it. Then the second ! reverse the value again as it's reverse the reversion so the result is &lt;strong&gt;true&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Coercion of objects
&lt;/h4&gt;

&lt;p&gt;When we explicitly convert object to any other data type, the engine uses an abstract operation which called &lt;strong&gt;ToPrimitive&lt;/strong&gt; that uses &lt;code&gt;valueOf()&lt;/code&gt; method which convert the object into its primitive value equivalent and if the &lt;code&gt;valueOf()&lt;/code&gt; fails to get a primitive value then the &lt;strong&gt;ToPrimitive&lt;/strong&gt; operation fall back into &lt;code&gt;toString()&lt;/code&gt; method that converts the object into string which is primitive, e.g:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;valueOf&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;33&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 33&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;33&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 33&lt;/span&gt;

&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt; &lt;span class="c1"&gt;// 0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the last example, the array is converted into number which produces 0.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implicit Coercion
&lt;/h3&gt;

&lt;p&gt;The second type of coercion is implicit coercion which is the conversion of type without intentionally convert it as it's hidden, non-obvious. This type of conversion confuse a lot of developers and make them avoid it and consider it a bug in javascript.&lt;/p&gt;

&lt;p&gt;As the most of developers see implicit coercion evil, I see it from a different perspective as it's used to reduce a lot of boilerplate and details that's unnecessary. As Kyle Sympthon said in his book &lt;strong&gt;YDKJS - Types &amp;amp; Grammar&lt;/strong&gt; : &lt;em&gt;"Don't throw the baby out with the bathwater"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;because the developers see implicit coercion evil they throw it away just to be safe, which is wrong.&lt;/p&gt;

&lt;p&gt;Let's see how we can implicitly convert from type to another.&lt;/p&gt;

&lt;p&gt;A number is implicitly converted into string by putting it in concatenation expression with a string, e.g:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// "22"&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// "22"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the number 2 converted into string by concatenate it with string "2". Let's consider this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="c1"&gt;// "2, 43, 6"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait! What!, confusing hah! No, Not really.&lt;/p&gt;

&lt;p&gt;While none of two operand are string the operation produces string. As the ES5 Specification said that when "+" operator receive an object it uses &lt;strong&gt;ToPrimitive&lt;/strong&gt; operation which convert an object which is non-primitive into primitive, but which type? Number? or String?&lt;/p&gt;

&lt;p&gt;Actually, the &lt;strong&gt;ToPrimitive&lt;/strong&gt; operation uses under the hood the &lt;strong&gt;ToNumber&lt;/strong&gt; operation which fails to produce a number then it falls back into &lt;code&gt;toString&lt;/code&gt; method that convert the first array into string &lt;code&gt;("2, 4")&lt;/code&gt; and the second one into &lt;code&gt;("3, 6")&lt;/code&gt; then the operation becomes a normal string concatenation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2, 4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;3, 6&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// "2, 43, 6"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Obvious, hah!&lt;/p&gt;

&lt;p&gt;A string is converted into number by adding the string in mathematical operation, e.g:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;42&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 42&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Implicitly converting from any value into Boolean
&lt;/h4&gt;

&lt;p&gt;This's the most confusing part in implicit coercion. There's cases where implicit coercion to boolean happens:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Expressions on &lt;code&gt;if()&lt;/code&gt; statement&lt;/li&gt;
&lt;li&gt;The test expression on &lt;code&gt;for(;..;)&lt;/code&gt; statement&lt;/li&gt;
&lt;li&gt;The test expression on &lt;code&gt;while()&lt;/code&gt; loop&lt;/li&gt;
&lt;li&gt;The test expression on ternary operators&lt;/li&gt;
&lt;li&gt;The left hand side in logical operators, &lt;code&gt;||&lt;/code&gt;, &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;It's true !&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// It's true !&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here &lt;code&gt;num&lt;/code&gt; implicitly converted into Boolean &lt;strong&gt;"true"&lt;/strong&gt;, then the test run and the alert fires because the number (2) is a &lt;em&gt;truthy&lt;/em&gt; value which means it converted into true when put in context of boolean.&lt;/p&gt;

&lt;p&gt;You may notice that I said "*&lt;em&gt;The left hand side in logical operators&lt;/em&gt;#", the truth is these operators is not working like you may expect they do similar to other languages like PHP / Java, actually it works differently, so, how is it working ? let's take an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hi&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// "Hi"&lt;/span&gt;

&lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 23 &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, in the first expression, the test goes for the left hand side of the &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; operator, convert it to boolean - which is truthy - then, return the right hand side. In the second expression the test goes for the left hand side, convert it to boolean - which is truthy also - then return it and doesn't go to the right hand side. This process is called "&lt;strong&gt;Short circuit evaluation&lt;/strong&gt;".&lt;/p&gt;

&lt;p&gt;The use case for this concept is when you want to return a value depending on truthiness of another value like we do in react, so we use the (&amp;amp;&amp;amp;), also when you want to return a value and provide a &lt;em&gt;fall back&lt;/em&gt; when the first value is falsy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// here we check if the array is empty, so don't return any thing or return a paragraphs containing the items of the array&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// here if the foo() returned undefined or null or any falsy values, the "no value returned" will be returned or the value returned from foo() will be returned either&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;no value returned&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  == vs. ===
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;

&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most of us will respond to this title: "== compares only values while === compares both types and values", actually this's &lt;strong&gt;completely wrong&lt;/strong&gt; !&lt;/p&gt;

&lt;p&gt;Both of them compares types and values, but the difference is if one of them &lt;em&gt;permits&lt;/em&gt; &lt;code&gt;coercion&lt;/code&gt; or not. In the first expression we'll notice that &lt;code&gt;==&lt;/code&gt; operator permits the coercion from string to number so the result was true, while in the second expression the &lt;code&gt;===&lt;/code&gt; doesn't permit coercion so the value was &lt;strong&gt;false&lt;/strong&gt;.&lt;/p&gt;

&lt;h5&gt;
  
  
  Which is better ?
&lt;/h5&gt;

&lt;p&gt;Other developers will argue wether is better and their teammates will respond: &lt;em&gt;"of course === because it's much faster than =="&lt;/em&gt;, this's also wrong !&lt;/p&gt;

&lt;p&gt;Um, yeah, there's a bit difference in performance but it's not considered because they are very close to each other, so, the final answer is: it doesn't matter which is faster, if you want to permit coercion, use &lt;code&gt;==&lt;/code&gt;, otherwise use &lt;code&gt;===&lt;/code&gt;, simply as that.&lt;/p&gt;

&lt;h5&gt;
  
  
  Comparing non-boolean to boolean
&lt;/h5&gt;

&lt;p&gt;The most risky and confusing example that a lot if developers fall in is when comparing any value to true or false. Let's consider this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;

&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;5&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What ! How come !&lt;/p&gt;

&lt;p&gt;The ES5 Spec said:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;if one of the two operand (x) is boolean return ToNumber(x) and compare them to each other&lt;/strong&gt;.&lt;br&gt;
So, when we compare 1 to true the boolean value &lt;em&gt;"true"&lt;/em&gt; implicitly converted into number which is 1, then &lt;code&gt;1 == 1&lt;/code&gt; is obviously &lt;code&gt;true&lt;/code&gt;, while in the second example when we compare &lt;code&gt;"5"&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt;, the boolean value implicitly converted into number which is 1 and the &lt;code&gt;"5"&lt;/code&gt; converted into number which is 5, so, &lt;code&gt;5 == 1&lt;/code&gt; is obviously &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;*&lt;em&gt;If either side of the comparison can be implicitly converted into true / false, Don't never ever use ==&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  Comparing non-objects to objects
&lt;/h5&gt;

&lt;p&gt;If an object is compared to a primitive value the ES5 Spec said:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;If any one of the two operands (x) is object and the other is primitive, return ToPrimitive(x) and compare them to each other&lt;/strong&gt;.
Let's consider this example:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the &lt;code&gt;[2]&lt;/code&gt; converted into its primitive value which is &lt;code&gt;2&lt;/code&gt;, then compare it to &lt;code&gt;2&lt;/code&gt; which is obviously &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Simple, hah!&lt;/p&gt;

&lt;p&gt;Let's see this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;

&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the first example, &lt;code&gt;false&lt;/code&gt; is converted into number - as we said above - which is &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;[]&lt;/code&gt; converted into number by &lt;strong&gt;ToPrimitive&lt;/strong&gt; operation which is &lt;code&gt;0&lt;/code&gt; so the result was &lt;code&gt;true&lt;/code&gt;, while in the second example, &lt;code&gt;[]&lt;/code&gt; converted into number by &lt;strong&gt;ToPrimitive&lt;/strong&gt; operation which is &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;{}&lt;/code&gt; converted into its primitive value which is &lt;code&gt;NaN&lt;/code&gt; so the result is &lt;code&gt;false&lt;/code&gt;, as &lt;code&gt;NaN&lt;/code&gt; never equal to itself or any other value.&lt;/p&gt;

&lt;p&gt;Let's see this final example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whaaaaaaaaat !&lt;/p&gt;

&lt;p&gt;This's completely crazy !&lt;/p&gt;

&lt;p&gt;Let's take it from right hand side, the &lt;code&gt;![]&lt;/code&gt; - by remembering the rules of converting objects - the &lt;code&gt;[]&lt;/code&gt; is first converted into &lt;em&gt;boolean&lt;/em&gt; which is &lt;code&gt;true&lt;/code&gt; then negate it, so, the result of &lt;code&gt;![]&lt;/code&gt; is &lt;strong&gt;false&lt;/strong&gt;, then compare &lt;strong&gt;true&lt;/strong&gt; to &lt;code&gt;[]&lt;/code&gt;, &lt;code&gt;[] == false&lt;/code&gt;, we saw this before and the result was &lt;strong&gt;true&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;"If either side of comparison is object, Don't never ever use ==."&lt;/em&gt;&lt;/strong&gt; - by &lt;code&gt;Me&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Coercion&lt;/strong&gt; was - for many developers - an evil and confusing concept, it's the conversion from data type into another, it has 2 types, first is the &lt;code&gt;*explicit coercion*&lt;/code&gt;, which is the intentionally converting from type into another, and &lt;code&gt;*implicit coercion*&lt;/code&gt;, which is the hidden converting from type into another.&lt;/p&gt;

&lt;p&gt;Implicit Coercion hides unnecessary details and simplify the implicitly.&lt;/p&gt;

&lt;p&gt;When comparing any value to Boolean or to Object consider not using &lt;code&gt;==&lt;/code&gt; operator as the coercion here make confusing and unpredicted results.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>coercion</category>
    </item>
  </channel>
</rss>
