<?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: Pascal C</title>
    <description>The latest articles on DEV Community by Pascal C (@9bytes).</description>
    <link>https://dev.to/9bytes</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%2F1224355%2F4146037d-bbd9-4786-ab49-0b0ea43d2e61.png</url>
      <title>DEV Community: Pascal C</title>
      <link>https://dev.to/9bytes</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/9bytes"/>
    <language>en</language>
    <item>
      <title>How to create React Native component library</title>
      <dc:creator>Pascal C</dc:creator>
      <pubDate>Sun, 04 Feb 2024 15:18:38 +0000</pubDate>
      <link>https://dev.to/9bytes/how-to-create-react-native-component-library-3266</link>
      <guid>https://dev.to/9bytes/how-to-create-react-native-component-library-3266</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Sharing and reusing code across projects can significantly boost productivity and maintainability of software projects. One of the most efficient ways to share UI components and logic for &lt;em&gt;React Native&lt;/em&gt; is by creating a component library. This article will guide you through the process of creating a &lt;em&gt;React Native&lt;/em&gt; component library using &lt;a href="https://callstack.github.io/react-native-builder-bob/create"&gt;create-react-native-library&lt;/a&gt;, a tool designed to streamline the creation and management of &lt;em&gt;React Native&lt;/em&gt; libraries.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Create a React Native Library?
&lt;/h2&gt;

&lt;p&gt;Before diving into the how, let's explore the why. Creating a React Native library allows you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reuse code across multiple projects, reducing duplication and effort.&lt;/li&gt;
&lt;li&gt;Share components within your team or with the wider community.&lt;/li&gt;
&lt;li&gt;Encapsulate and abstract functionality, making your main project cleaner and more focused.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting Up the Environment
&lt;/h2&gt;

&lt;p&gt;Ensure &lt;a href="https://nodejs.org/en/download"&gt;Node.js&lt;/a&gt; is installed on your machine and the React Native CLI environment was set up following the &lt;a href="https://reactnative.dev/docs/environment-setup"&gt;official React Native setup guide&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Creating Your Library
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;create-react-native-library&lt;/code&gt; provides a straightforward command-line interface to scaffold a library. It containts several CLIs to streamline the process. To create a new library, open a terminal and run:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx create-react-native-library@latest awesome-library&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Replace &lt;em&gt;react-native-awesome-component&lt;/em&gt; with the name of your library. The tool will generate a new directory with the given name, including a basic project structure. Make sure to select &lt;strong&gt;JavaScript library&lt;/strong&gt; in the upcoming dialogue.&lt;/p&gt;

&lt;p&gt;Next, go into the folder via &lt;code&gt;cd react-native-awesome-component&lt;/code&gt; and run &lt;code&gt;npm i&lt;/code&gt;. It could be that you have to run it with the &lt;code&gt;--legacy-peer-deps&lt;/code&gt; option, if you get an error. There seems to be a dependency broken at the moment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Exploring the Generated Structure
&lt;/h3&gt;

&lt;p&gt;Navigate into the library's directory. There are several important files and folders:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;src/&lt;/em&gt; - This is where the library's source code for &lt;em&gt;React Native&lt;/em&gt; components will reside.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;example/&lt;/em&gt; - A generated &lt;em&gt;React Native&lt;/em&gt; app to test the library during development.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;package.json&lt;/em&gt; - Defines the library's dependencies and scripts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3: Developing a Component
&lt;/h3&gt;

&lt;p&gt;With the library scafolded, it's time to start developing a component. Edit the files within the &lt;em&gt;src/&lt;/em&gt; directory to implement components. For simplicity, we will use the &lt;code&gt;AppButton&lt;/code&gt;, created in another &lt;a href="https://dev.to/9bytes/crafting-a-custom-button-component-in-react-native-2inj"&gt;tutorial&lt;/a&gt;, to use directly in &lt;em&gt;index.tsx&lt;/em&gt; file. This is just for the sake of this tutorial. In a real world library, every component should have it's own file and just be imported into the &lt;em&gt;index.tsx&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;Pressable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;GestureResponderEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ViewStyle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;TextStyle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;buttonStyles&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;ViewStyle&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;textStyles&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;TextStyle&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;accessibilityLabel&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;onPress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GestureResponderEvent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AppButton&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FC&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&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="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Pressable&lt;/span&gt;
      &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;pressed&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disabled&lt;/span&gt;
            &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#ccc&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pressed&lt;/span&gt;
            &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#aa0000&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;red&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="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;buttonStyles&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;onPress&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onPress&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;accessible&lt;/span&gt;
      &lt;span class="na"&gt;accessibilityLabel&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accessibilityLabel&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A Button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textStyles&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Press Me&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Pressable&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;container&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;alignItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;borderRadius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;white&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;AppButton&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Testing the Component
&lt;/h3&gt;

&lt;p&gt;Leverage the generated example app to test the component:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to the &lt;em&gt;example/&lt;/em&gt; directory via &lt;code&gt;cd example&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Install dependencies with &lt;code&gt;npm install&lt;/code&gt; or &lt;code&gt;yarn&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run the app on iOS or Android using &lt;code&gt;npx react-native start&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Make sure to import and use the &lt;code&gt;AppButton&lt;/code&gt; component in the example app to see it in action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;View&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;AppButton&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native-awesome-library&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setResult&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AppButton&lt;/span&gt; &lt;span class="na"&gt;onPress&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setResult&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Multiply&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;AppButton&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Result: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;container&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;alignItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;justifyContent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&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="na"&gt;box&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;marginVertical&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5: Hosting the Library
&lt;/h3&gt;

&lt;p&gt;There are several options to host the library:&lt;/p&gt;

&lt;h4&gt;
  
  
  npm (Node Package Manager)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Public Hosting: &lt;a href="https://www.npmjs.com/"&gt;npm&lt;/a&gt; is the default package manager for &lt;em&gt;Node.js&lt;/em&gt; and is the largest ecosystem of open source libraries. The library can be publish to npm to make it publicly available.&lt;/li&gt;
&lt;li&gt;Private Hosting: &lt;em&gt;npm&lt;/em&gt; also offers private packages as part of its paid plans. This is useful for companies or teams that want to share code internally without exposing it to the public.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  GitHub Packages
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;GitHub&lt;/em&gt; Integration: &lt;a href="https://github.com/features/packages"&gt;GitHub Packages&lt;/a&gt; allows you to host your npm packages directly on &lt;em&gt;GitHub&lt;/em&gt;, making it easy to share your packages with others, either publicly or privately within an organization. It integrates closely with &lt;em&gt;GitHub&lt;/em&gt;'s permissions and workflow, making it a convenient option for teams already using GitHub for source control.&lt;/li&gt;
&lt;li&gt;Support for Multiple Registries: Besides &lt;em&gt;npm&lt;/em&gt;, &lt;em&gt;GitHub Packages&lt;/em&gt; also supports hosting for other package types, such as Docker containers, Maven packages, NuGet packages, and more.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Verdaccio
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Private Proxy Registry: &lt;a href="https://verdaccio.org/"&gt;Verdaccio&lt;/a&gt; is a lightweight, open-source private &lt;em&gt;npm&lt;/em&gt; proxy registry. It allows to set up a local &lt;em&gt;npm&lt;/em&gt; registry with minimal setup, perfect for teams needing a private registry without the cost of &lt;em&gt;npm&lt;/em&gt;'s private packages.&lt;/li&gt;
&lt;li&gt;Caching and Local Publishing: &lt;em&gt;Verdaccio&lt;/em&gt; caches downloaded public packages and allows to publish private packages.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Bit
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Component Collaboration: &lt;a href="https://bit.dev/"&gt;Bit&lt;/a&gt; is a tool designed for sharing and collaborating on individual components across projects.&lt;/li&gt;
&lt;li&gt;Versioning and Isolation: &lt;em&gt;Bit&lt;/em&gt; handles component versioning, dependency isolation, and updates, making it easier to maintain and update components across multiple projects.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 6: Publishing the Library
&lt;/h3&gt;

&lt;p&gt;After selecting where to host the library, it can be published.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Ensure that package.json is properly filled out with the library's information and &lt;code&gt;version&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Depending where the library is hosted, the &lt;code&gt;publishConfig&lt;/code&gt; has to be updated with the correct link, for example:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"publishConfig"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"registry"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://registry.npmjs.org/"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Run &lt;code&gt;npm run prepare&lt;/code&gt; to build the components and create the exports.&lt;/li&gt;
&lt;li&gt;Publish the library using &lt;code&gt;npm publish&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Creating a &lt;em&gt;React Native&lt;/em&gt; component library is a powerful way to streamline the development process and foster code reuse. Using &lt;code&gt;create-react-native-library&lt;/code&gt; simplifies the process of library creation. By following the steps outlined in this guide, it is easy to develop a reusable component library that can enhance any &lt;em&gt;React Native&lt;/em&gt; project.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>mobile</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Crafting a Custom Button Component in React Native</title>
      <dc:creator>Pascal C</dc:creator>
      <pubDate>Sun, 28 Jan 2024 18:46:26 +0000</pubDate>
      <link>https://dev.to/9bytes/crafting-a-custom-button-component-in-react-native-2inj</link>
      <guid>https://dev.to/9bytes/crafting-a-custom-button-component-in-react-native-2inj</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;React Native&lt;/em&gt;, a powerful framework for building native apps for &lt;em&gt;iOS&lt;/em&gt; and &lt;em&gt;Android&lt;/em&gt; using &lt;em&gt;JavaScript&lt;/em&gt;, often requires developers to create custom UI components, like a custom button. This article will guide you through creating a custom button in React Native, focusing on different touchable components and explaining why &lt;code&gt;Pressable&lt;/code&gt; might be a preferable choice.&lt;/p&gt;

&lt;h3&gt;
  
  
  Differences Between Touchable Components
&lt;/h3&gt;

&lt;p&gt;In &lt;em&gt;React Native&lt;/em&gt;, a button can be created using the built-in &lt;a href="https://reactnative.dev/docs/button"&gt;&lt;code&gt;Button&lt;/code&gt;&lt;/a&gt; component or through &lt;a href="https://reactnative.dev/docs/touchableopacity"&gt;&lt;code&gt;TouchableOpacity&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://reactnative.dev/docs/touchablehighlight"&gt;&lt;code&gt;TouchableHighlight&lt;/code&gt;&lt;/a&gt;, and &lt;a href="https://reactnative.dev/docs/pressable"&gt;&lt;code&gt;Pressable&lt;/code&gt;&lt;/a&gt;. While &lt;code&gt;Button&lt;/code&gt; offers simplicity by providing basic styling,  &lt;code&gt;TouchableOpacity&lt;/code&gt; and &lt;code&gt;TouchableHighlight&lt;/code&gt; provide more options for customization. However, &lt;code&gt;Pressable&lt;/code&gt;, introduced in React Native 0.63, is more flexible and nowadays the recommended option to handle touch-based input.&lt;/p&gt;

&lt;h4&gt;
  
  
  TouchableOpacity
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Feedback: Diminishes the opacity of the button on press.&lt;/li&gt;
&lt;li&gt;Use Case: Suitable for most cases where a button or an area needs to be clickable.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  TouchableHighlight
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Feedback: Displays a "highlight" or a different background color on press.&lt;/li&gt;
&lt;li&gt;Use Case: Useful when a visual feedback of a color change is needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Pressable
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Feedback: Highly customizable, can define any kind of visual feedback.&lt;/li&gt;
&lt;li&gt;Advantages:

&lt;ul&gt;
&lt;li&gt;More extensive customization options for touch interactions.&lt;/li&gt;
&lt;li&gt;Includes features like &lt;code&gt;onPressIn&lt;/code&gt;, &lt;code&gt;onPressOut&lt;/code&gt;, and &lt;code&gt;onLongPress&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Handles hover and focus in addition to press states, making it more suitable for a variety of devices.&lt;/li&gt;
&lt;li&gt;Allows to define a &lt;em&gt;HitRect&lt;/em&gt; area via the &lt;code&gt;hitSlop&lt;/code&gt; prop to widen the area a press is registered without increasing the size of the button. Essentially, &lt;code&gt;hitSlop&lt;/code&gt; specifies how far the touch area extends beyond the bounds of the visual element.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Use Case: Recommended for new React Native projects due to its versatility and comprehensive feature set.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Creating a Custom Button
&lt;/h2&gt;

&lt;p&gt;We will now create a new customizable button component, called &lt;code&gt;AppButton&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Pressable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AppButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&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="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Pressable&lt;/span&gt;
      &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;pressed&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disabled&lt;/span&gt;
            &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#ccc&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pressed&lt;/span&gt;
            &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#aa0000&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;red&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="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;buttonStyles&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;onPress&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onPress&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;accessible&lt;/span&gt;
      &lt;span class="na"&gt;accessibilityLabel&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accessibilityLabel&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A Button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textStyles&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Press Me&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Pressable&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;container&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;alignItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;borderRadius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;white&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;AppButton&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;AppButton&lt;/code&gt; has one required &lt;code&gt;prop&lt;/code&gt;, which is the &lt;code&gt;onPress&lt;/code&gt; function. It's styles can be adjusted by passing &lt;code&gt;textStyles&lt;/code&gt; or &lt;code&gt;buttonStyles&lt;/code&gt;. For this component, style can be passed as a function instead of an object. We use this to create a press effect by changing the background color on the press of a finger&lt;br&gt;
for a short time. If the button is disabled we deactivate that effect and set it to a shade of gray to indicate this to the user visually. Last but not least, &lt;code&gt;accessible&lt;/code&gt; and &lt;code&gt;accessibilityLabel&lt;/code&gt; are set so that people who use &lt;a href="https://support.apple.com/de-de/guide/iphone/iph3e2e415f/ios"&gt;VoiceOver&lt;/a&gt; or &lt;a href="https://support.google.com/accessibility/android/answer/6283677?hl=de"&gt;TalkBack&lt;/a&gt; know what element they have selected. A screen reader will verbalize this string when the associated element is selected.&lt;/p&gt;

&lt;p&gt;You can find an online version of the button &lt;a href="https://snack.expo.dev/riCJeQzUG_INM5EoDfj71"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advanced Options
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Adding Icons: Icons can be added to the button by using libraries like &lt;a href="https://www.npmjs.com/package/react-native-vector-icons"&gt;react-native-vector-icons&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Animations: Animations like changing the background color can be added by using &lt;a href="https://reactnative.dev/docs/animated"&gt;Animated&lt;/a&gt; or &lt;a href="https://reactnative.dev/docs/layoutanimation"&gt;LayoutAnimation&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Creating a custom button in &lt;em&gt;React Native&lt;/em&gt; is a straightforward process and can significantly enhance an app's user experience. By customizing styles and adding features like icons and animations, a button that perfectly fits an app's design can be created. The &lt;code&gt;Pressable&lt;/code&gt; component, with its extensive customization options, provides a versatile, future-proof and comprehensive solution for touchable interactions.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>react</category>
      <category>android</category>
      <category>ios</category>
    </item>
    <item>
      <title>Info.plist Basics für React-Native Entwickler</title>
      <dc:creator>Pascal C</dc:creator>
      <pubDate>Sun, 21 Jan 2024 13:15:58 +0000</pubDate>
      <link>https://dev.to/9bytes/infoplist-basics-fur-react-native-entwickler-2l0j</link>
      <guid>https://dev.to/9bytes/infoplist-basics-fur-react-native-entwickler-2l0j</guid>
      <description>&lt;h2&gt;
  
  
  Einleitung
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://reactnative.dev/"&gt;React Native&lt;/a&gt; ist ein auf &lt;em&gt;JavaScript&lt;/em&gt; basierendes Hybrid-Framework zur Entwicklung von nativen Apps auf &lt;em&gt;iOS&lt;/em&gt; und &lt;em&gt;Android&lt;/em&gt;. Es macht es Web-Entwicklern einfach den Umstieg zur App-Entwicklung zu finden, da die meißten mit -JavaScript* oder sogar _React* vertraut sein dürften. Schwierig wird es allerdings, wenn es um die Benutzung von Build-tools, wie bsp. &lt;a href="https://gradle.org/"&gt;Gradle&lt;/a&gt; oder der Verwendung der nativen Konfigurationsdateien wie der &lt;em&gt;AndroidManifest.xml&lt;/em&gt; oder der &lt;em&gt;Info.plist&lt;/em&gt; geht. Letztere Datei, die in jedem iOS-Projekt zu finden ist, spielt eine entscheidende Rolle bei der Definition von App-Einstellungen und Berechtigungen. In diesem Artikel wird erläutert, was die &lt;em&gt;Info.plist&lt;/em&gt;-Datei ist und wie man sie effektiv nutzen kann.&lt;/p&gt;

&lt;h2&gt;
  
  
  Was ist die &lt;em&gt;Info.plist&lt;/em&gt;-Datei?
&lt;/h2&gt;

&lt;p&gt;Die &lt;em&gt;Info.plist&lt;/em&gt; (Information Property List) ist eine Konfigurationsdatei im &lt;a href="https://developer.mozilla.org/en-US/docs/Web/XML/XML_introduction?retiredLocale=de"&gt;XML&lt;/a&gt;-Format, die wichtige Informationen über eine &lt;em&gt;iOS&lt;/em&gt;-App enthält. Sie definiert Eigenschaften wie den App-Namen, Versionsnummer, Berechtigungen und vieles mehr. &lt;a href="https://developer.apple.com/xcode/"&gt;Xcode&lt;/a&gt; liest diese Datei, um wichtige Informationen eine App zu erhalten.&lt;/p&gt;

&lt;h2&gt;
  
  
  Warum ist &lt;em&gt;Info.plist&lt;/em&gt; für React Native-Entwickler wichtig?
&lt;/h2&gt;

&lt;p&gt;Das Bearbeiten der &lt;em&gt;Info.plist&lt;/em&gt;-Datei ist oft notwendig, um:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;App-Berechtigungen festzulegen (z.B. Kamerazugriff, Standortdienste).&lt;/li&gt;
&lt;li&gt;App-Metadaten wie Version, Anzeigename und unterstützte Geräteorientierungen zu definieren.&lt;/li&gt;
&lt;li&gt;Externe Dienste zu integrieren, wie z.B. Push-Benachrichtigungen.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Anpassen der &lt;em&gt;Info.plist&lt;/em&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Zugriff auf die Datei
&lt;/h3&gt;

&lt;p&gt;Die &lt;em&gt;Info.plist&lt;/em&gt;-Datei befindet sich unter &lt;em&gt;ios/[Projektname]/Info.plist&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Definition von App-Metadaten
&lt;/h3&gt;

&lt;p&gt;Wichtige Keys für Metadaten sind bsp.:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;CFBundleDisplayName&lt;/code&gt; (Anzeigename der App)&lt;/strong&gt;:
Bestimmt den Namen der App, der auf dem Homescreen des Geräts angezeigt wird.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;CFBundleShortVersionString&lt;/code&gt; (Versionsnummer)&lt;/strong&gt;:
Die öffentliche Versionsnummer der App, die im App Store angezeigt wird, z.B. 1.6.9.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;CFBundleVersion&lt;/code&gt; (Build-Versionsnummer)&lt;/strong&gt;:
Interne Versionsnummer, die zur Unterscheidung von Builds innerhalb einer Version verwendet wird. Diese Zahl ist aufsteigend, z.B. 96.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Usage Descriptions
&lt;/h3&gt;

&lt;p&gt;Usage Descriptions (Nutzungsbeschreibungen) in &lt;em&gt;iOS&lt;/em&gt; sind erforderlich, um dem Benutzer den Zweck der Anforderung bestimmter Berechtigungen zu erklären:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;NSCameraUsageDescription&lt;/code&gt; (Kamerazugriff&lt;/strong&gt;):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;NSCameraUsageDescription&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;Diese App benötigt Zugriff auf Ihre Kamera, um Fotos aufzunehmen.&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;NSMicrophoneUsageDescription&lt;/code&gt; (Mikrofonzugriff)&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;NSMicrophoneUsageDescription&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;Diese App benötigt Zugriff auf Ihr Mikrofon, um Sprachaufnahmen zu ermöglichen.&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;NSLocationWhenInUseUsageDescription&lt;/code&gt; und &lt;code&gt;NSLocationAlwaysUsageDescription&lt;/code&gt; (Standortdienste)&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;NSLocationWhenInUseUsageDescription&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;Diese App benötigt Ihren Standort, um standortbezogene Dienste anzubieten.&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;NSPhotoLibraryUsageDescription&lt;/code&gt; (Fotobibliothekszugriff)&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;NSPhotoLibraryUsageDescription&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;Diese App benötigt Zugriff auf Ihre Fotos, um Bilder hochzuladen.&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;NSContactsUsageDescription&lt;/code&gt; (Kontaktezugriff)&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;NSContactsUsageDescription&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;Diese App benötigt Zugriff auf Ihre Kontakte, um die Integration zu erleichtern.&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  App Transport Security (ATS)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;ATS (&lt;code&gt;NSAppTransportSecurity&lt;/code&gt;)&lt;/strong&gt; ist eine Sicherheitsfunktion in &lt;em&gt;iOS&lt;/em&gt;, die standardmäßig sicherstellt, dass alle HTTP-Verbindungen, die von der App verwendet werden, HTTPS sind. Standardmässig sieht der Eintrag wie folgt aus:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;NSAppTransportSecurity&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;NSExceptionDomains&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;localhost&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;NSExceptionAllowsInsecureHTTPLoads&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;true/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unter &lt;code&gt;NSExceptionDomains&lt;/code&gt; können Ausnahmen für spezifische Domains definiert werden, für die die ATS-Regeln nicht gelten sollen. Für die App-Entwicklung gibt es standardmässig einen Eintrag für &lt;a href="https://en.wikipedia.org/wiki/Localhost"&gt;localhost&lt;/a&gt;, damit mit der App kommuniziert werden kann.&lt;br&gt;
&lt;code&gt;NSExceptionAllowsInsecureHTTPLoads&lt;/code&gt; mit dem Wert &lt;code&gt;true&lt;/code&gt; bedeutet, dass für Verbindungen zu localhost unsichere HTTP-Verbindungen erlaubt sind, anstatt HTTPS zu erzwingen. Ansonsten könnten lokal genutzte Dienste (z.B. ein Dev-server) auch nur mit https genutzt werden, was die Einrichtung eines &lt;a href="https://www.heise.de/tipps-tricks/SSL-Zertifikat-Was-ist-das-4862296.html"&gt;SSL-Zertifikates&lt;/a&gt; erfordern würde.&lt;/p&gt;

&lt;p&gt;Läuft eine App hinter einem VPN, kann es oft notwendig sein, den Server an dieser Stelle einzutragen und die Ausnahmen korrekt zu konfigurieren.&lt;/p&gt;
&lt;h3&gt;
  
  
  App-Icons, Launch-Screens und Orientierungen
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;CFBundleIcons&lt;/code&gt; (App-Icons)&lt;/strong&gt;:
Bestimmt die Icons, die für die App verwendet werden. In der Regel werden die Icons als Asset-Katalog in Xcode konfiguriert und nicht direkt in der &lt;em&gt;Info.plist&lt;/em&gt;-Datei.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;UILaunchStoryboardName&lt;/code&gt; oder &lt;code&gt;UILaunchImages&lt;/code&gt; (Launch-Screen)&lt;/strong&gt;:
Definiert die Launch-Screen-Datei oder die Bilder, die beim Starten der App angezeigt werden. Auch hier ist die übliche Methode die Verwendung eines Storyboards oder eines Asset-Katalogs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;UISupportedInterfaceOrientations&lt;/code&gt; (Orientierungen)&lt;/strong&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Legt fest, welche Bildschirmorientierungen die App unterstützt.&lt;br&gt;
  Beispiel für Portrait und Landscape:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;  &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;UISupportedInterfaceOrientations&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;array&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;UIInterfaceOrientationPortrait&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;UIInterfaceOrientationLandscapeLeft&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;UIInterfaceOrientationLandscapeRight&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/array&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Schluß
&lt;/h2&gt;

&lt;p&gt;Die &lt;em&gt;Info.plist&lt;/em&gt;-Datei ist ein wichtiges Element in der &lt;em&gt;iOS&lt;/em&gt;-Entwicklung. Ein tiefes Verständnis dieser Datei ermöglicht es Entwicklern, ihre Apps effektiv für &lt;em&gt;iOS&lt;/em&gt; zu konfigurieren und anzupassen. Dies ist für eine erfolgreiche Einreichung im Apple App Store unerlässlich, denn eine Ablehnung der App kann schwerwiegende Folgen wie eine unzufriedene Userbase nach sich ziehen.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>ios</category>
      <category>mobiledevtips</category>
      <category>iosappconfig</category>
    </item>
    <item>
      <title>Gradle Essentials für React Native Entwickler</title>
      <dc:creator>Pascal C</dc:creator>
      <pubDate>Sun, 14 Jan 2024 20:13:41 +0000</pubDate>
      <link>https://dev.to/9bytes/gradle-essentials-fur-react-native-entwickler-3imd</link>
      <guid>https://dev.to/9bytes/gradle-essentials-fur-react-native-entwickler-3imd</guid>
      <description>&lt;h2&gt;
  
  
  Einleitung
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://gradle.org/"&gt;Gradle&lt;/a&gt; ist für die Entwicklung von &lt;em&gt;React Native&lt;/em&gt; Apps auf &lt;em&gt;Android&lt;/em&gt; ein unverzichtbares Tool. Dennoch ist es vor allem für &lt;em&gt;React Native&lt;/em&gt;-Entwickler ein Buch mit sieben Siegeln, da ein Großteil einen Web-Background hat und somit eher mit &lt;em&gt;JavaScript&lt;/em&gt; vertraut ist. In diesem Artikel werden die Essentials behandelt, mit denen man als &lt;em&gt;React Native&lt;/em&gt;-Entwickler vertraut sein sollte, um effektiv mit &lt;em&gt;Gradle&lt;/em&gt; zu arbeiten.&lt;/p&gt;

&lt;h2&gt;
  
  
  Grundlagen von Gradle
&lt;/h2&gt;

&lt;p&gt;Gradle ist ein mächtiges Build-Automatisierungstool, das vor allem in der Entwicklung von &lt;em&gt;Android&lt;/em&gt;-Anwendungen verwendet wird. Es nutzt eine &lt;a href="https://en.wikipedia.org/wiki/Domain-specific_language"&gt;Domain-Specific Language&lt;/a&gt; (DSL) basierend auf &lt;a href="http://www.groovy-lang.org/"&gt;Groovy&lt;/a&gt; oder &lt;a href="https://kotlinlang.org/"&gt;Kotlin&lt;/a&gt;, um die Build-Konfiguration zu definieren. In &lt;em&gt;React Native&lt;/em&gt; wird &lt;em&gt;Groovy&lt;/em&gt; verwendet und die wichtigsten Dateien für Entwickler sind die beiden &lt;em&gt;build.gradle&lt;/em&gt; Dateien.&lt;/p&gt;

&lt;h3&gt;
  
  
  Syntax
&lt;/h3&gt;

&lt;p&gt;Ein &lt;em&gt;Gradle&lt;/em&gt;-Build besteht aus einem oder mehreren &lt;strong&gt;Projekten&lt;/strong&gt;. Jedes &lt;strong&gt;Projekt&lt;/strong&gt; repräsentiert eine Komponente des Gesamtbuilds (z.B. eine App, ein Library-Modul, ...). Die grundlegenden Aktionseinheiten in einem &lt;em&gt;Gradle&lt;/em&gt;-Build sind &lt;strong&gt;Tasks&lt;/strong&gt;. Ein &lt;strong&gt;Task&lt;/strong&gt; repräsentiert eine atomare Build-Aktion (Kompilieren von Quellcode, das Erstellen von Paketen, ...). Über &lt;strong&gt;Plugins&lt;/strong&gt; oder externe &lt;strong&gt;Repositories&lt;/strong&gt; können zusätzliche Funktionen bereitgestellt werden.&lt;/p&gt;

&lt;h3&gt;
  
  
  Build Gradle Dateien in React Native Projekten
&lt;/h3&gt;

&lt;p&gt;In &lt;em&gt;React Native&lt;/em&gt; Projekten gibt es zwei unterschiedliche &lt;em&gt;build.gradle&lt;/em&gt; Dateien. Eine im &lt;em&gt;android&lt;/em&gt; Ordner (Projektebene), sowie Eine unter &lt;em&gt;android/app&lt;/em&gt; (Modulebene).&lt;/p&gt;

&lt;h4&gt;
  
  
  Projektweite build.gradle Datei
&lt;/h4&gt;

&lt;p&gt;Die Datei direkt im &lt;em&gt;android&lt;/em&gt; Ordner dient der Konfiguration des gesamten Projekts. In der Theorie könnte es zusätzlich zu &lt;em&gt;android/app/build.gradle&lt;/em&gt; noch weitere verschiedene Module mit jeweils eigenen &lt;em&gt;build.gradle&lt;/em&gt;-Dateien geben. In einem frischen &lt;em&gt;React Native&lt;/em&gt; Projekt hat sie in der Regel folgendes Format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Top-level build file where you can add configuration options common to all sub-projects/modules.&lt;/span&gt;
&lt;span class="n"&gt;buildscript&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ext&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;kotlinVersion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"1.8.0"&lt;/span&gt;
        &lt;span class="n"&gt;buildToolsVersion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"33.0.0"&lt;/span&gt;
        &lt;span class="n"&gt;minSdkVersion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;
        &lt;span class="n"&gt;compileSdkVersion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;33&lt;/span&gt;
        &lt;span class="n"&gt;targetSdkVersion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;33&lt;/span&gt;

        &lt;span class="c1"&gt;// We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP.&lt;/span&gt;
        &lt;span class="n"&gt;ndkVersion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"23.1.7779620"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;repositories&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;google&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;mavenCentral&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;dependencies&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;classpath&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;classpath&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"com.android.tools.build:gradle"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;classpath&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"com.facebook.react:react-native-gradle-plugin"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;buildscript&lt;/code&gt; definiert die Umgebung in der das Script ausgeführt wird. Es legt fest, welche Plugins und Dependencies für die Ausführung des &lt;em&gt;Gradle&lt;/em&gt;-Build-Scripts selbst benötigt werden.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ext&lt;/code&gt; ist zuständig dafür Versionsnummern für Dependencies zu definieren sowie die SDK-Zielversionen festzulegen.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;repositories&lt;/code&gt; definiert Repositories, von denen &lt;em&gt;Gradle&lt;/em&gt; die Plugins und Dependencies herunterladen soll, die für das Build-Script benötigt werden.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dependencies&lt;/code&gt; listet die Abhängigkeiten auf, die zum Bauen der App benötigt werden, z.B. das &lt;em&gt;React Native&lt;/em&gt; Plugin oder das &lt;em&gt;Kotlin&lt;/em&gt; Plugin.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Appweite build.gradle Datei
&lt;/h4&gt;

&lt;p&gt;Die Datei im &lt;em&gt;android/app&lt;/em&gt; Ordner ist spezifisch für das verwendete Modul:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jJMh75Te--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0m6beigeytycg9t4s50l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jJMh75Te--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0m6beigeytycg9t4s50l.png" alt="Projektweite build.gradle Datei" width="800" height="2056"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Am Anfang der Datei werden die verwendeten Plugins definiert, z.B. &lt;code&gt;apply plugin: 'kotlin-android'&lt;/code&gt;, welches dafür sorgt dass in der App &lt;em&gt;Kotlin&lt;/em&gt; verwendet werden kann.&lt;/li&gt;
&lt;li&gt;Der Key &lt;code&gt;android&lt;/code&gt; definiert &lt;em&gt;Android&lt;/em&gt;-spezifische Einstellungen, wie z.B. die &lt;code&gt;compileSdkVersion&lt;/code&gt;, welche auf die in der projektweiten &lt;em&gt;build.gradle&lt;/em&gt; definierte Version via &lt;code&gt;rootProject.ext.compileSdkVersion&lt;/code&gt; zugreift.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dependences&lt;/code&gt; definiert die in diesem Modul verwendeten Abhängigkeiten, wie z.B. das &lt;em&gt;React Native&lt;/em&gt; Plugin via &lt;code&gt;implementation("com.facebook.react:react-android")&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)&lt;/code&gt; bezieht sich auf das Einbinden sowie Aufrufen einer &lt;em&gt;Gradle&lt;/em&gt; Script - Datei.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Weitere Gradle Dateien
&lt;/h3&gt;

&lt;p&gt;Neben den beiden &lt;em&gt;build.gradle&lt;/em&gt;-Dateien, die sicherlich am wichtigsten sind, gibt es noch folgende Dateien:&lt;/p&gt;

&lt;h4&gt;
  
  
  settings.gradle
&lt;/h4&gt;

&lt;p&gt;In dieser Datei werden alle Module/Subprojekte aufgelistet, die zum Gesamtprojekt gehören, sowie die Pfade zu den nativen Modulen definiert:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;rootProject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'ReactNativeDemo'&lt;/span&gt;
&lt;span class="n"&gt;apply&lt;/span&gt; &lt;span class="nl"&gt;from:&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="n"&gt;applyNativeModulesSettingsGradle&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;include&lt;/span&gt; &lt;span class="s1"&gt;':app'&lt;/span&gt;
&lt;span class="n"&gt;includeBuild&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'../node_modules/@react-native/gradle-plugin'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  gradle.properties
&lt;/h4&gt;

&lt;p&gt;Hier werden Konfigurationsoptionen und Eigenschaften festgelegt, die sowohl von Gradle als auch von &lt;em&gt;React Native&lt;/em&gt; verwendet werden können:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;Project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;wide&lt;/span&gt; &lt;span class="n"&gt;Gradle&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;IDE&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;g&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;Android&lt;/span&gt; &lt;span class="n"&gt;Studio&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nl"&gt;users:&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;Gradle&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt; &lt;span class="n"&gt;configured&lt;/span&gt; &lt;span class="n"&gt;through&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;IDE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;will&lt;/span&gt; &lt;span class="n"&gt;override&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt; &lt;span class="n"&gt;specified&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;For&lt;/span&gt; &lt;span class="n"&gt;more&lt;/span&gt; &lt;span class="n"&gt;details&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;how&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;configure&lt;/span&gt; &lt;span class="n"&gt;your&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt; &lt;span class="n"&gt;environment&lt;/span&gt; &lt;span class="n"&gt;visit&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nl"&gt;http:&lt;/span&gt;&lt;span class="c1"&gt;//www.gradle.org/docs/current/userguide/build_environment.html&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;Specifies&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;JVM&lt;/span&gt; &lt;span class="n"&gt;arguments&lt;/span&gt; &lt;span class="n"&gt;used&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;daemon&lt;/span&gt; &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;setting&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;particularly&lt;/span&gt; &lt;span class="n"&gt;useful&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;tweaking&lt;/span&gt; &lt;span class="n"&gt;memory&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;Default&lt;/span&gt; &lt;span class="nl"&gt;value:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Xmx512m&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nl"&gt;XX:&lt;/span&gt;&lt;span class="n"&gt;MaxMetaspaceSize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;
&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;gradle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jvmargs&lt;/span&gt;&lt;span class="o"&gt;=-&lt;/span&gt;&lt;span class="n"&gt;Xmx2048m&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nl"&gt;XX:&lt;/span&gt;&lt;span class="n"&gt;MaxMetaspaceSize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;512&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;When&lt;/span&gt; &lt;span class="n"&gt;configured&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Gradle&lt;/span&gt; &lt;span class="n"&gt;will&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;incubating&lt;/span&gt; &lt;span class="n"&gt;parallel&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;option&lt;/span&gt; &lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;used&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="n"&gt;decoupled&lt;/span&gt; &lt;span class="n"&gt;projects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;More&lt;/span&gt; &lt;span class="n"&gt;details&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;visit&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nl"&gt;http:&lt;/span&gt;&lt;span class="c1"&gt;//www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;gradle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parallel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;AndroidX&lt;/span&gt; &lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;structure&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;make&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="n"&gt;clearer&lt;/span&gt; &lt;span class="n"&gt;which&lt;/span&gt; &lt;span class="n"&gt;packages&lt;/span&gt; &lt;span class="n"&gt;are&lt;/span&gt; &lt;span class="n"&gt;bundled&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;Android&lt;/span&gt; &lt;span class="n"&gt;operating&lt;/span&gt; &lt;span class="n"&gt;system&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="n"&gt;which&lt;/span&gt; &lt;span class="n"&gt;are&lt;/span&gt; &lt;span class="n"&gt;packaged&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="n"&gt;your&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;APK&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nl"&gt;https:&lt;/span&gt;&lt;span class="c1"&gt;//developer.android.com/topic/libraries/support-library/androidx-rn&lt;/span&gt;
&lt;span class="n"&gt;android&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;useAndroidX&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;Automatically&lt;/span&gt; &lt;span class="n"&gt;convert&lt;/span&gt; &lt;span class="n"&gt;third&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;party&lt;/span&gt; &lt;span class="n"&gt;libraries&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="n"&gt;AndroidX&lt;/span&gt;
&lt;span class="n"&gt;android&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;enableJetifier&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;Version&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;flipper&lt;/span&gt; &lt;span class="n"&gt;SDK&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="n"&gt;React&lt;/span&gt; &lt;span class="n"&gt;Native&lt;/span&gt;
&lt;span class="n"&gt;FLIPPER_VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.182&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;Use&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;property&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;specify&lt;/span&gt; &lt;span class="n"&gt;which&lt;/span&gt; &lt;span class="n"&gt;architecture&lt;/span&gt; &lt;span class="n"&gt;you&lt;/span&gt; &lt;span class="n"&gt;want&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;You&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt; &lt;span class="n"&gt;also&lt;/span&gt; &lt;span class="n"&gt;override&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;CLI&lt;/span&gt; &lt;span class="n"&gt;using&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="o"&gt;./&lt;/span&gt;&lt;span class="n"&gt;gradlew&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;PreactNativeArchitectures&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;x86_64&lt;/span&gt;
&lt;span class="n"&gt;reactNativeArchitectures&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;armeabi&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;v7a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="n"&gt;arm64&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;v8a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="n"&gt;x86&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="n"&gt;x86_64&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;Use&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;property&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;enable&lt;/span&gt; &lt;span class="n"&gt;support&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;architecture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;will&lt;/span&gt; &lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;you&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="n"&gt;TurboModules&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;Fabric&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;your&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;You&lt;/span&gt; &lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;enable&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;flag&lt;/span&gt; &lt;span class="n"&gt;either&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;you&lt;/span&gt; &lt;span class="n"&gt;want&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;write&lt;/span&gt; &lt;span class="n"&gt;custom&lt;/span&gt; &lt;span class="n"&gt;TurboModules&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Fabric&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt; &lt;span class="n"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="n"&gt;libraries&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;are&lt;/span&gt; &lt;span class="n"&gt;providing&lt;/span&gt; &lt;span class="n"&gt;them&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;newArchEnabled&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;Use&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;property&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;enable&lt;/span&gt; &lt;span class="n"&gt;or&lt;/span&gt; &lt;span class="n"&gt;disable&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;Hermes&lt;/span&gt; &lt;span class="n"&gt;JS&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;If&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;you&lt;/span&gt; &lt;span class="n"&gt;will&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;using&lt;/span&gt; &lt;span class="n"&gt;JSC&lt;/span&gt; &lt;span class="n"&gt;instead&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;hermesEnabled&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  gradle-wrapper.properties
&lt;/h4&gt;

&lt;p&gt;Diese Datei definiert die verwendete &lt;em&gt;Gradle&lt;/em&gt;-Version und verwaltet weitere Optionen wie z.B. Downloadort:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;distributionBase&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;GRADLE_USER_HOME&lt;/span&gt;
&lt;span class="n"&gt;distributionPath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;wrapper&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;dists&lt;/span&gt;
&lt;span class="n"&gt;distributionUrl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//services.gradle.org/distributions/gradle-8.0.1-all.zip&lt;/span&gt;
&lt;span class="n"&gt;networkTimeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10000&lt;/span&gt;
&lt;span class="n"&gt;zipStoreBase&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;GRADLE_USER_HOME&lt;/span&gt;
&lt;span class="n"&gt;zipStorePath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;wrapper&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;dists&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Schlusswort
&lt;/h2&gt;

&lt;p&gt;Zusammenfassend lässt sich sagen, dass es für fortgeschrittene &lt;em&gt;React Native&lt;/em&gt;-Entwickler unverzichtbar ist, ein zumindest grundlegendes Verständnis von &lt;em&gt;Gradle&lt;/em&gt; aufzubauen, auch wenn es zunächst komplex erscheinen mag. Durch das Verständnis der verschiedenen &lt;em&gt;Gradle&lt;/em&gt;-Dateien und ihrer spezifischen Rollen kann die Konfiguration des Projekts effektiver verwaltet und angepasst werden. Es ist eine Investition, die sich langfristig auszahlt, denn ein tiefgreifendes Verständnis von &lt;em&gt;Gradle&lt;/em&gt; ermöglicht eine flexiblere und leistungsfähigere App-Entwicklung auf &lt;em&gt;Android&lt;/em&gt;.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>gradle</category>
      <category>android</category>
      <category>androiddev</category>
    </item>
    <item>
      <title>Ordnung im Code-Dschungel: TypeScript Generics erklärt</title>
      <dc:creator>Pascal C</dc:creator>
      <pubDate>Sun, 07 Jan 2024 15:57:32 +0000</pubDate>
      <link>https://dev.to/9bytes/ordnung-im-code-dschungel-typescript-generics-erklart-4988</link>
      <guid>https://dev.to/9bytes/ordnung-im-code-dschungel-typescript-generics-erklart-4988</guid>
      <description>&lt;h2&gt;
  
  
  Einleitung
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Typescript&lt;/em&gt; ist ein sehr beliebtes Werkzeug um Typsicherheit in &lt;em&gt;JavaScript&lt;/em&gt; zu erlangen. Eines der leistungsstärksten Features in diesem System sind &lt;a href="https://www.typescriptlang.org/docs/handbook/2/generics.html"&gt;&lt;strong&gt;Generics&lt;/strong&gt;&lt;/a&gt;, die eine Art von Variablen für Typen darstellen. In diesem Artikel schauen wir uns an, wie &lt;strong&gt;Generics&lt;/strong&gt; in &lt;em&gt;Typescript&lt;/em&gt; funktionieren, warum sie nützlich sind und wie sie eine Codebasis flexibler und wiederverwendbarer machen können.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Generics&lt;/strong&gt; ermöglichen, wiederverwendbare Code-Komponenten zu schreiben, die mit verschiedenen Typen arbeiten können, ohne den spezifischen Typ im Code zu verlieren. Sie funktionieren ähnlich wie die &lt;strong&gt;Generics&lt;/strong&gt; in anderen Sprachen (&lt;em&gt;Java&lt;/em&gt; oder &lt;em&gt;C#&lt;/em&gt;). In &lt;em&gt;Typescript&lt;/em&gt; erlauben &lt;strong&gt;Generics&lt;/strong&gt; es, Typen als Parameter zu übergeben, wenn man Klassen, Schnittstellen, Funktionen und Typen definiert.&lt;/p&gt;

&lt;h2&gt;
  
  
  Anwendungsfälle
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Basics
&lt;/h3&gt;

&lt;p&gt;Nehmen wir an, wir haben folgende Funktion:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sortArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
  &lt;span class="nx"&gt;compareFn&lt;/span&gt;&lt;span class="p"&gt;:&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="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arrayCopy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="nx"&gt;arrayCopy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;compareFn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;arrayCopy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;sortArray&lt;/code&gt; erwartet ein &lt;code&gt;array&lt;/code&gt; vom Typ &lt;code&gt;number&lt;/code&gt; sowie eine &lt;code&gt;function&lt;/code&gt; die an &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort"&gt;sort&lt;/a&gt; zum sortieren übergeben wird. Jetzt ist diese Funktion nicht sonderlich hilfreich, da man nur Zahlen übergeben kann. Was wäre wenn man auch &lt;code&gt;strings&lt;/code&gt; sortieren möchte? Die naive Vorgehensweise wäre Folgende:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sortArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
  &lt;span class="nx"&gt;compareFn&lt;/span&gt;&lt;span class="p"&gt;:&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="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arrayCopy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="nx"&gt;arrayCopy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;compareFn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;arrayCopy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Das funktioniert, ist aber nicht sonderlich elegant und fängt schon jetzt an die Lesbarkeit zu erschweren. Was aber wenn wir noch einen dritten, vierten, ... Typ hinzufügen? Eine Möglichkeit wäre den Typ einfach auf &lt;code&gt;any&lt;/code&gt; zu ändern, aber dann könnte man ihn auch einfach gleich weglassen, das ist mehr Workaround als Lösung. Hier kommen &lt;strong&gt;Generics&lt;/strong&gt; ins Spiel:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sortArray&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="nx"&gt;compareFn&lt;/span&gt;&lt;span class="p"&gt;:&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="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arrayCopy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="nx"&gt;arrayCopy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;compareFn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;arrayCopy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Was genau passiert hier?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;sortArray&amp;lt;T&amp;gt;&lt;/code&gt;: Das &lt;code&gt;T&lt;/code&gt; in den spitzen Klammern nach dem Funktionsnamen ist eine Konvention und steht für &lt;em&gt;Type&lt;/em&gt; (Es spricht nichts dagegen expressivere Namen zu wählen und ist bei komplizierteren Typen auch angeraten).&lt;/li&gt;
&lt;li&gt;Dieser Typ &lt;code&gt;T&lt;/code&gt; ist ein Platzhalter der nun innerhalb der Funktion für die tatsächlichen Typen verwendet wird. &lt;code&gt;T&lt;/code&gt; kann beim Aufruf der Funktion durch jeden Typ ersetzt werden.&lt;/li&gt;
&lt;li&gt;So wird beispielsweise aus:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sortArray&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="nx"&gt;compareFn&lt;/span&gt;&lt;span class="p"&gt;:&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="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;wenn man die Funktion beispielsweise mit einem &lt;code&gt;Array&lt;/code&gt; von &lt;code&gt;strings&lt;/code&gt; aufruft:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;strings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hans&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;adam&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;egon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sortedStrings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sortArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;strings&lt;/span&gt;&lt;span class="p"&gt;,&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="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;localeCompare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;im Prinzip folgendes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sortArray&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="nx"&gt;compareFn&lt;/span&gt;&lt;span class="p"&gt;:&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="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Und das ist schon die gesamte Magie dahinter. Man kann &lt;code&gt;sortArray&lt;/code&gt; jetzt mit jedem Typ aufrufen, durch das &lt;strong&gt;Generic&lt;/strong&gt; wird der Korrekte nun automatisch inferiert.&lt;/p&gt;

&lt;h3&gt;
  
  
  Weitere Anwendungsfälle
&lt;/h3&gt;

&lt;p&gt;Man kann &lt;strong&gt;Generics&lt;/strong&gt; nicht nur für Funktionen, sondern beispielsweise auch für Typen verwenden. Beliebt ist dies oft bei der Definition von Schnittstellen (&lt;a href="https://de.wikipedia.org/wiki/Programmierschnittstelle"&gt;API&lt;/a&gt;). Nehmen wir an wir haben folgenden &lt;code&gt;type&lt;/code&gt; definiert:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;APIResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nl"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Diese Definition müssten wir nun für jeden möglichen Antworttyp wiederholen. &lt;strong&gt;Generics&lt;/strong&gt; vereinfachen dies. Wir können den Code einfach wie folgt abändern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;APIResponse&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Data&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;und dann beispielsweise so nutzen:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;APIResponse&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&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="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Beatrice&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="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Um dies noch weiter zu vereinfachen, bietet es sich an verschiedene Responsetypen zu definieren, was für dieses Beispiel aber unerheblich ist. Weitere Anwendungsfälle wären z.B. die Definition von Datenstrukturen oder bei der Verwendung von &lt;strong&gt;H&lt;/strong&gt;igher &lt;strong&gt;O&lt;/strong&gt;rder &lt;strong&gt;C&lt;/strong&gt;omponents. Die Möglichkeiten sind vielfältig und die Grenze mehr oder weniger die eigene Fantasie.&lt;/p&gt;

&lt;h2&gt;
  
  
  Schluss
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Generics&lt;/strong&gt; in &lt;em&gt;TypeScript&lt;/em&gt; sind ein mächtiges Werkzeug, das Entwicklern die nötige Flexibilität bietet, um wiederverwendbare und typsichere Komponenten zu erstellen. Durch die Möglichkeit, Typen als Variablen zu behandeln, eröffnen sie ein neues Spektrum an Möglichkeiten, die weit über das hinausgehen, was in reinem &lt;em&gt;JavaScript&lt;/em&gt; verfügbar ist. Sie tragen dazu bei, die Komplexität des Codes zu reduzieren, die Wiederverwendbarkeit zu erhöhen und Fehler zu minimieren, die durch inkonsistente Typisierung entstehen können.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>generics</category>
      <category>programming</category>
    </item>
    <item>
      <title>Managing iOS Augmented Reality Views with Objective-C in React Native Apps</title>
      <dc:creator>Pascal C</dc:creator>
      <pubDate>Sun, 31 Dec 2023 13:02:53 +0000</pubDate>
      <link>https://dev.to/9bytes/managing-ios-augmented-reality-views-with-objective-c-in-react-native-apps-7ko</link>
      <guid>https://dev.to/9bytes/managing-ios-augmented-reality-views-with-objective-c-in-react-native-apps-7ko</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Integrating 3D models into AR applications can significantly enhance the user experience by providing interactive and immersive elements. For iOS applications, using &lt;em&gt;Apple's ARKit&lt;/em&gt; with the .usdz file format is often the preferred approach due to its native support and optimization for AR experiences. This introduction will guide you through the steps of integrating a 3D model into an iOS application using &lt;em&gt;ARKit&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This is part four of a multi part article series about the integration of AR services via native modules into a &lt;em&gt;React Native&lt;/em&gt; app. While React Native simplifies cross-platform app development, there are scenarios where leveraging native iOS capabilities becomes essential, especially when dealing with advanced features like augmented reality.&lt;/p&gt;

&lt;p&gt;You can find the other parts here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Part one: &lt;a href="https://dev.to/9bytes/building-ar-vr-experiences-with-react-native-part-1-bridging-the-gap-with-kotlin-1dii"&gt;Setting up a native module via Kotlin&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Part Two: &lt;a href="https://dev.to/9bytes/navigating-the-ar-landscape-in-react-native-with-kotlin-2caj"&gt;Integrating ARCore&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Part Three: &lt;a href="https://dev.to/9bytes/seamlessly-integrating-native-modules-in-ios-for-react-native-ar-apps-5alp"&gt;Setting up a native module via Objective-C&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The full code for this part is &lt;a href="https://github.com/Gh05d/RN3DWorldExplorer/tree/part-4"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  3D-Model integration
&lt;/h2&gt;

&lt;p&gt;Unfortunately, using &lt;em&gt;GLB&lt;/em&gt; files in &lt;em&gt;iOS&lt;/em&gt; AR applications is a bit of a hustle, so it is easier for us the use another format for the &lt;em&gt;iOS&lt;/em&gt; version, namely &lt;em&gt;USDZ&lt;/em&gt;, instead of using the already obtained &lt;em&gt;GLB&lt;/em&gt; file from the &lt;em&gt;Android&lt;/em&gt; version in &lt;a href="https://dev.to/9bytes/navigating-the-ar-landscape-in-react-native-with-kotlin-2caj"&gt;part 2&lt;/a&gt; of this series.&lt;/p&gt;

&lt;h3&gt;
  
  
  Download a model
&lt;/h3&gt;

&lt;p&gt;Basically, download any model you like from a site like &lt;a href="https://developer.apple.com/augmented-reality/quick-look/"&gt;this&lt;/a&gt;. I downloaded the pancakes model.&lt;/p&gt;

&lt;h3&gt;
  
  
  XCode
&lt;/h3&gt;

&lt;p&gt;The next step is to add the downloaded model to XCode. Naturally, with all things &lt;em&gt;Apple&lt;/em&gt;, this is far more annoying than it has any right to be:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Right-click on the project's root, select &lt;em&gt;New Group&lt;/em&gt; and name it &lt;em&gt;Resources&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Drag the .usdz file from Finder and drop it into the &lt;em&gt;Resources&lt;/em&gt; group in Xcode's project navigator.&lt;/li&gt;
&lt;li&gt;When you add the file, make sure the options are set correctly in the dialog that appears. Ensure the &lt;em&gt;Copy items if needed&lt;/em&gt; is checked. Also, ensure that the file is added to the app's target by checking &lt;em&gt;RN3DWorldExplorer&lt;/em&gt;, so it's included in the build.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Update info.plist
&lt;/h3&gt;

&lt;p&gt;The last step is to add the following key to your info.plist file (located at &lt;em&gt;ios/RN3dWorldExplorer&lt;/em&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;NSCameraUsageDescription&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;This app needs access to the camera to create 3D AR experiences.&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is needed as we access the users camera for the 3D-Model, which &lt;em&gt;Apple&lt;/em&gt; regards as privacy-sensitive data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coding
&lt;/h2&gt;

&lt;p&gt;We will be doing several updates to our &lt;em&gt;RCTARodule.m&lt;/em&gt; file in order to use &lt;em&gt;ARKit&lt;/em&gt;. At first, add the following imports to the top of the file to leverage the AR capabilities on &lt;em&gt;iOS&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#import &amp;lt;ModelIO/ModelIO.h&amp;gt;
#import &amp;lt;SceneKit/ModelIO.h&amp;gt;
#import &amp;lt;ARKit/ARKit.h&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we will be implementing a new interface. Copy this code between the imports and the &lt;code&gt;@implementation RCTARModule&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@interface RCTARModule () &amp;lt;ARSCNViewDelegate&amp;gt;
@property (nonatomic, strong) ARSCNView *sceneView;
@property (nonatomic, strong) SCNNode *modelNode;
@end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In essence, this code is preparing the &lt;code&gt;RCTARModule&lt;/code&gt; class to handle AR functionalities. It's setting up an AR SceneView (&lt;code&gt;ARSCNView&lt;/code&gt;) to display AR content and a node (&lt;code&gt;SCNNode&lt;/code&gt;) to load our 3D model in the AR scene. The module is also prepared to handle &lt;code&gt;ARSCNView&lt;/code&gt; events by conforming to the &lt;code&gt;ARSCNViewDelegate&lt;/code&gt; protocol.&lt;/p&gt;

&lt;p&gt;We will update our &lt;code&gt;showAR&lt;/code&gt; function in the now to be able to display the model. This will take several steps. Exchange the current code for this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RCT_EXPORT_METHOD(showAR:(NSString *)filename)
{
  dispatch_async(dispatch_get_main_queue(), ^{
    RCTLogInfo(@"Loading model: %@", filename);
    [self initializeARView];
    [self loadAndDisplayModel:filename];
    [self presentARView];
  });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we are logging the passed in parameter &lt;code&gt;filename&lt;/code&gt; before we are calling three functions to set up the AR view, load and display the model and present the view to the user in the end. Don't get shocked by the amount of errors popping up, they will go away as we are implementing the functions.&lt;/p&gt;

&lt;h3&gt;
  
  
  initializeARView
&lt;/h3&gt;

&lt;p&gt;Use this code to implement the function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- (void)initializeARView {
  self.sceneView = [[ARSCNView alloc] initWithFrame:UIScreen.mainScreen.bounds];
  self.sceneView.delegate = self;

  // Configure AR session
  ARWorldTrackingConfiguration *configuration = [ARWorldTrackingConfiguration new];
  configuration.planeDetection = ARPlaneDetectionHorizontal;
  [self.sceneView.session runWithConfiguration:configuration];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In general, the &lt;code&gt;initializeARView&lt;/code&gt; method sets up the AR environment for the application. It initializes an &lt;code&gt;ARSCNView&lt;/code&gt; to render the AR content, sets up the class as its delegate to handle AR-related events, configures the AR session to include horizontal plane detection, and finally starts the AR session with these configurations.&lt;/p&gt;

&lt;h3&gt;
  
  
  loadAndDisplayModel
&lt;/h3&gt;

&lt;p&gt;Now implement the function with this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- (void)loadAndDisplayModel:(NSString *)filename {
  NSString *filePath = [[NSBundle mainBundle] pathForResource:filename ofType:@"usdz"];
  NSURL *fileURL = [NSURL fileURLWithPath:filePath];

  NSError *error = nil;
  SCNScene *scene = [SCNScene sceneWithURL:fileURL options:nil error:&amp;amp;error];

  // Correctly set the modelNode property
  self.modelNode = [scene.rootNode.childNodes firstObject];
  if (self.modelNode) {
    self.modelNode.scale = SCNVector3Make(0.1, 0.1, 0.1);
    self.modelNode.position = SCNVector3Make(0, -1, -3); // Adjust as needed
    [self.sceneView.scene.rootNode addChildNode:self.modelNode];
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This method is designed to load a 3D model from the application's main bundle and display it in the AR scene. First it constructs a file path for a 3D model file (usdz format) based on the provided filename. Then, it creates a URL (fileURL) pointing to this file. After that, it creates a &lt;code&gt;SCNScene&lt;/code&gt; and adds the model node to the AR scene. Be aware that when you use your own model, you probably want to adjust the &lt;code&gt;scale&lt;/code&gt; and &lt;code&gt;position&lt;/code&gt;, as it could be too near / far from the camera.&lt;/p&gt;

&lt;h3&gt;
  
  
  presentARView
&lt;/h3&gt;

&lt;p&gt;Finally, add these two functions to the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- (void)presentARView {
    UIViewController *viewController = [UIViewController new];
    [viewController.view addSubview:self.sceneView];

  // Create a close button
  UIButton *closeButton = [UIButton buttonWithType:UIButtonTypeSystem];
  [closeButton setTitle:@"X" forState:UIControlStateNormal];
  [closeButton addTarget:self action:@selector(closeARView) forControlEvents:UIControlEventTouchUpInside];

  CGFloat buttonSize = 44.0;
  CGFloat padding = 16.0;
  closeButton.frame = CGRectMake(viewController.view.bounds.size.width - buttonSize - padding,
     padding,
     buttonSize,
     buttonSize);
  closeButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin;
  closeButton.backgroundColor = [UIColor blueColor];
  closeButton.layer.cornerRadius = buttonSize / 2;
  closeButton.clipsToBounds = YES;

  [viewController.view addSubview:closeButton];

    // Assuming you have access to the root view controller or the current view controller
    UIViewController *rootViewController = RCTPresentedViewController();
    [rootViewController presentViewController:viewController animated:YES completion:nil];
}

- (void)closeARView {
    UIViewController *presentingController = self.sceneView.window.rootViewController;
    [presentingController dismissViewControllerAnimated:YES completion:nil];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first half of the &lt;code&gt;presentARView&lt;/code&gt; function just adds a close button to the view and assigns the helper function &lt;code&gt;closeARView&lt;/code&gt; to it. The latter part of the method concludes by presenting the new view controller modally on top of the current view hierarchy. This is done by retrieving the current application's presented view controller (&lt;code&gt;RCTPresentedViewController()&lt;/code&gt;) and calling &lt;code&gt;presentViewController:animated:completion:&lt;/code&gt; on it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Update App.tsx
&lt;/h3&gt;

&lt;p&gt;Now we finally move to our &lt;em&gt;React Native&lt;/em&gt; code. Update the &lt;code&gt;Button&lt;/code&gt; s &lt;code&gt;onPress&lt;/code&gt; method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ARModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;showAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Platform&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;OS&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ios&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pancakes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;AR-model.glb&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;p&gt;If you use a different model, exchange pancakes for the file name. Don't forget to &lt;code&gt;import { Platform } from "react-native"&lt;/code&gt; at the top of the file. Start up the application and test the code.&lt;/p&gt;

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

&lt;p&gt;Successfully integrating a 3D model into an iOS AR application involves several critical steps, from preparing the appropriate file format to coding the interaction with &lt;em&gt;ARKit&lt;/em&gt;. While the process might seem daunting initially, especially due to platform-specific requirements like using .usdz files for &lt;em&gt;iOS&lt;/em&gt;, the result is a compelling and immersive AR experience.&lt;/p&gt;

&lt;p&gt;This concludes this series for now. Eventually there will be some articles about the integration of &lt;em&gt;VR&lt;/em&gt; functionality like 360 videos for both platforms, but the setup process is way more complicated than anything explored in this series till now. For example on Android, it involves downloading the &lt;em&gt;Cardboard SDK&lt;/em&gt; and surgically integrating it into the Android portion of the app via generating .proto files and .java files.&lt;/p&gt;

&lt;p&gt;By now, you should have a basic understanding of the integration of &lt;em&gt;AR&lt;/em&gt; services into &lt;em&gt;React Native&lt;/em&gt; apps. Your next steps would the integration of advanced functionality like moving the models around or scaling them by using pinch gestures. The sky is the limit from here now on.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>ios</category>
      <category>objectivec</category>
      <category>arkit</category>
    </item>
    <item>
      <title>Seamlessly Integrating Native Modules in iOS for React Native AR Apps</title>
      <dc:creator>Pascal C</dc:creator>
      <pubDate>Thu, 21 Dec 2023 21:11:56 +0000</pubDate>
      <link>https://dev.to/9bytes/seamlessly-integrating-native-modules-in-ios-for-react-native-ar-apps-5alp</link>
      <guid>https://dev.to/9bytes/seamlessly-integrating-native-modules-in-ios-for-react-native-ar-apps-5alp</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Welcome to the intricate world of iOS development in &lt;em&gt;React Native&lt;/em&gt;! In this tutorial, we will be learning how to create native modules for iOS using Objective-C.&lt;/p&gt;

&lt;p&gt;This is part three of a multi part article series about the integration of AR services via native modules into a &lt;em&gt;React Native&lt;/em&gt; app. While React Native simplifies cross-platform app development, there are scenarios where leveraging native iOS capabilities becomes essential, especially when dealing with advanced features like augmented reality.&lt;/p&gt;

&lt;p&gt;You can find the other parts here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Part one: &lt;a href="https://dev.to/9bytes/building-ar-vr-experiences-with-react-native-part-1-bridging-the-gap-with-kotlin-1dii"&gt;Setting up a native module via Kotlin&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Part Two: &lt;a href="https://dev.to/9bytes/navigating-the-ar-landscape-in-react-native-with-kotlin-2caj"&gt;Integrating ARCore&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Part Four: &lt;a href="https://dev.to/9bytes/seamlessly-integrating-native-modules-in-ios-for-react-native-ar-apps-5alp"&gt;Integrating ARKit&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The full code for this part is &lt;a href="https://github.com/Gh05d/RN3DWorldExplorer/tree/part-3"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://developer.apple.com/xcode/"&gt;XCODE&lt;/a&gt; is the preferred way to write native modules on &lt;em&gt;iOS&lt;/em&gt;. It is an IDE developed by Apple and has some - in theory - useful integrated appliances. In reality, like most of Apples stuff, it is a poorly cobbled together piece of software which will let you run your head through the wall in frustration many times you are forced to interact with it. Anyways, you need it, so if you haven't downloaded it yet, follow the &lt;a href="https://reactnative.dev/docs/environment-setup?os=macos&amp;amp;platform=ios"&gt;setup for iOS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Also make sure to have executed the following commands in the project folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i
npx pod-install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will install the necessary dependencies and finish the &lt;em&gt;iOS&lt;/em&gt; setup. &lt;em&gt;XCode&lt;/em&gt; will build the project in the background now. This will take some time, so maybe grab a coffee ☕. You can follow the progress in the upper right corner.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coding
&lt;/h2&gt;

&lt;p&gt;Apple uses &lt;a href="https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html"&gt;Objective-C&lt;/a&gt; or &lt;a href="https://developer.apple.com/swift/"&gt;Swift&lt;/a&gt; for writing native apps. We will closely follow the &lt;a href="https://reactnative.dev/docs/native-modules-ios"&gt;docs&lt;/a&gt; and use &lt;em&gt;Objective-C&lt;/em&gt; for our native module.&lt;/p&gt;

&lt;h3&gt;
  
  
  Writing the Bridge
&lt;/h3&gt;

&lt;p&gt;The first step is to create our main custom native module header and implementation files. Create a new file called &lt;em&gt;RCTARModule.h&lt;/em&gt;. For this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open Your React Native Project in Xcode:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Launch Xcode.&lt;/li&gt;
&lt;li&gt;Open your React Native project. You should open the .xcworkspace file if you are using CocoaPods, or the .xcodeproj file if not.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to the Project Directory:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;In the Xcode Navigator pane, select the project directory where you want to add your native module. This is typically within the main project directory.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Create a New File:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Right-click on the directory.&lt;/li&gt;
&lt;li&gt;Choose New File... from the context menu.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Select the File Type:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;In the dialog that appears, you'll be presented with several template options.&lt;/li&gt;
&lt;li&gt;Select Header File.&lt;/li&gt;
&lt;li&gt;Click Next.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Name the Header File:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;In the 'Name' field, enter RCTARModule.h.&lt;/li&gt;
&lt;li&gt;Make sure that the project is selected under Targets&lt;/li&gt;
&lt;li&gt;Click Create.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now add the following content to the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#import &amp;lt;React/RCTBridgeModule.h&amp;gt;
@interface RCTARModule : NSObject &amp;lt;RCTBridgeModule&amp;gt;
@end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The RCT prefix stands for &lt;em&gt;React Native&lt;/em&gt; by the way and it is convention to prepend class names with a substring in &lt;em&gt;Objective-C&lt;/em&gt; because of missing namespacing. Now we have to create the &lt;em&gt;Objective-C&lt;/em&gt; file. It has the same name as the header file, only with another extension, &lt;em&gt;RCTARModule.m&lt;/em&gt;. Like before, create a new file in the same folder, but this time select &lt;em&gt;Objective-C&lt;/em&gt; as the type. Then paste the following contents to it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#import "RCTARModule.h"

@implementation RCTARModule

RCT_EXPORT_MODULE();

@end

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

&lt;/div&gt;



&lt;p&gt;There is not much going on here. Basically we only import our previously created header file (which took care of bridging) and export the module. We have have the option to change the name we export the module by passing an argument to &lt;code&gt;RCT_EXPORT_MODULE&lt;/code&gt;, but we don't do this and stick with the default name &lt;em&gt;ARModule&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add a function
&lt;/h3&gt;

&lt;p&gt;Last thing to do is to add a function which will be exposed to &lt;em&gt;JavaScript&lt;/em&gt;. Let's add the following code to the &lt;em&gt;RCTARModule.m&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#import &amp;lt;React/RCTLog.h&amp;gt;

RCT_EXPORT_METHOD(showAR:(NSString *)location)
{
 RCTLogInfo(@"Pretending to load a file named %@", location);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;RCT_EXPORT_METHOD declares a method that &lt;em&gt;JavaScript&lt;/em&gt; can call. This method takes a single NSString argument named &lt;code&gt;location&lt;/code&gt;. All it does for now is log the string you pass to the method. In the next installment, we will be loading the model here instead.&lt;/p&gt;

&lt;p&gt;Now click the play button in the upper left side and the app should be installed to your phone / simulator. Or you run into all the fun Apple specific stuff like selecting a Deveolpment Team, assigning provisioning profiles or certificates, creating an apple id ... 🤮&lt;/p&gt;

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

&lt;p&gt;As we wrap up this part of our journey into iOS native modules with React Native, we have laid a solid foundation for integrating more complex functionalities into our app. In our next installment, we will dive deeper, moving from merely logging a file location to actually loading and manipulating models in our AR environment.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>ios</category>
      <category>objectivec</category>
      <category>arkit</category>
    </item>
    <item>
      <title>Navigating the AR Landscape in React Native with Kotlin</title>
      <dc:creator>Pascal C</dc:creator>
      <pubDate>Fri, 15 Dec 2023 16:26:31 +0000</pubDate>
      <link>https://dev.to/9bytes/navigating-the-ar-landscape-in-react-native-with-kotlin-2caj</link>
      <guid>https://dev.to/9bytes/navigating-the-ar-landscape-in-react-native-with-kotlin-2caj</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In the &lt;a href="https://dev.to/9bytes/building-ar-vr-experiences-with-react-native-part-1-bridging-the-gap-with-kotlin-1dii"&gt;first part&lt;/a&gt; of this series, we laid the groundwork by setting up &lt;em&gt;Kotlin&lt;/em&gt; within our &lt;em&gt;React Native&lt;/em&gt; environment, a crucial step in bringing augmented reality (AR) to our applications. This segment is designed for developers who are ready to take the next step in their AR journey, willing to learn how to integrate ARCore into their hybrid apps.&lt;/p&gt;

&lt;p&gt;This is part two of a multi part article series about the integration of AR services via native modules into a &lt;em&gt;React Native&lt;/em&gt; app. You will learn how to integrate &lt;a href="https://developers.google.com/ar/develop"&gt;ARCore&lt;/a&gt; and how to display a 3D-model in this article.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Part one: &lt;a href="https://dev.to/9bytes/building-ar-vr-experiences-with-react-native-part-1-bridging-the-gap-with-kotlin-1dii"&gt;Setting up a native module via Kotlin&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Part Three: &lt;a href="https://dev.to/9bytes/seamlessly-integrating-native-modules-in-ios-for-react-native-ar-apps-5alp"&gt;Setting up a native module via Objective-C&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Part Four: &lt;a href="https://dev.to/9bytes/managing-ios-augmented-reality-views-with-objective-c-in-react-native-apps-7ko"&gt;Integrating ARKit&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The full code for this part is &lt;a href="https://github.com/Gh05d/RN3DWorldExplorer/tree/part-2"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is ARCore
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://developers.google.com/ar/develop"&gt;ARCore&lt;/a&gt; is Google's platform for building augmented reality (AR) experiences. It enables phones to understand and interact with the real world. Using three key capabilities – motion tracking, environmental understanding, and light estimation – ARCore makes it possible for apps to merge virtual content with the real world in a seamless and realistic way.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Add dependencies to the project
&lt;/h3&gt;

&lt;p&gt;First we need to add the necessary dependencies to our project. Go into your &lt;em&gt;android/app/build.gradle&lt;/em&gt; and add the following implementations to your &lt;code&gt;dependencies&lt;/code&gt; section:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight gradle"&gt;&lt;code&gt;&lt;span class="c1"&gt;// AR&lt;/span&gt;
&lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s1"&gt;'com.google.ar:core:1.40.0'&lt;/span&gt;
&lt;span class="n"&gt;implementation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"io.github.sceneview:arsceneview:0.10.0"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XNCX4jp2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3xwm0fxx96l0ui59yl2i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XNCX4jp2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3xwm0fxx96l0ui59yl2i.png" alt="app level build.gradle file" width="800" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then we have to bump our &lt;code&gt;minSdkVersion&lt;/code&gt; to 24 in our &lt;em&gt;android/build.gradle&lt;/em&gt;. Afterwards sync the project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Download a model
&lt;/h3&gt;

&lt;p&gt;Now we need a 3D model to display. Download one from &lt;a href="https://ar-code.com/blog/ar-portals-3d-models-in-glb-and-usdz-formats"&gt;here&lt;/a&gt; for example. Make sure to select the &lt;em&gt;GLB&lt;/em&gt; version!&lt;/p&gt;

&lt;h3&gt;
  
  
  Add file to Android
&lt;/h3&gt;

&lt;p&gt;To add a GLB model to your Android project in Android Studio, you should create an &lt;em&gt;assets&lt;/em&gt; folder and place your GLB file there. Here's how to do it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create the &lt;em&gt;assets&lt;/em&gt; Folder:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Right-click on the &lt;em&gt;app&lt;/em&gt; folder in the Android Studio project view.&lt;/li&gt;
&lt;li&gt;Go to &lt;em&gt;New&lt;/em&gt; &amp;gt; &lt;em&gt;Folder&lt;/em&gt; &amp;gt; &lt;em&gt;Assets Folder&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;em&gt;Finish&lt;/em&gt; in the dialog that appears to create the folder.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Add Your GLB File:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Copy your GLB model file.&lt;/li&gt;
&lt;li&gt;Paste it into the &lt;em&gt;assets&lt;/em&gt; folder you just created.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Create an Activity XML file
&lt;/h3&gt;

&lt;p&gt;Now we need to create the layout file where our model will be displayed:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Locate the &lt;em&gt;res&lt;/em&gt; (Resources) Folder: In your project hierarchy in Android Studio, it is typically found under &lt;em&gt;app&lt;/em&gt; &amp;gt; &lt;em&gt;src&lt;/em&gt; &amp;gt; &lt;em&gt;main&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create the &lt;em&gt;layout&lt;/em&gt; Folder:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Right-click on the &lt;em&gt;res&lt;/em&gt; folder.&lt;/li&gt;
&lt;li&gt;Choose &lt;em&gt;New&lt;/em&gt; &amp;gt; &lt;em&gt;Directory&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Name the directory &lt;em&gt;layout&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Add Your XML File:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Right-click on the newly created &lt;em&gt;layout&lt;/em&gt; folder.&lt;/li&gt;
&lt;li&gt;Choose &lt;em&gt;New&lt;/em&gt; &amp;gt; &lt;em&gt;Layout resource file&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Name the file &lt;em&gt;ar_activity.xml&lt;/em&gt; and click 'OK'.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Android Studio will open the file in Design mode, but we will need to change into Code mode. In order to do this, click on the Code button (should be in the upper right and looks like 5 vertical lines). Copy the following code into the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;androidx.constraintlayout.widget.ConstraintLayout&lt;/span&gt; &lt;span class="na"&gt;xmlns:android=&lt;/span&gt;&lt;span class="s"&gt;"http://schemas.android.com/apk/res/android"&lt;/span&gt;
    &lt;span class="na"&gt;android:layout_width=&lt;/span&gt;&lt;span class="s"&gt;"match_parent"&lt;/span&gt;
    &lt;span class="na"&gt;android:layout_height=&lt;/span&gt;&lt;span class="s"&gt;"match_parent"&lt;/span&gt;
    &lt;span class="na"&gt;tools:context=&lt;/span&gt;&lt;span class="s"&gt;".MainActivity"&lt;/span&gt;
    &lt;span class="na"&gt;xmlns:app=&lt;/span&gt;&lt;span class="s"&gt;"http://schemas.android.com/apk/res-auto"&lt;/span&gt;
    &lt;span class="na"&gt;xmlns:tools=&lt;/span&gt;&lt;span class="s"&gt;"http://schemas.android.com/tools"&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;io.github.sceneview.ar.ArSceneView&lt;/span&gt;
        &lt;span class="na"&gt;android:id=&lt;/span&gt;&lt;span class="s"&gt;"@+id/sceneView"&lt;/span&gt;
        &lt;span class="na"&gt;android:layout_width=&lt;/span&gt;&lt;span class="s"&gt;"match_parent"&lt;/span&gt;
        &lt;span class="na"&gt;android:layout_height=&lt;/span&gt;&lt;span class="s"&gt;"match_parent"&lt;/span&gt;
        &lt;span class="na"&gt;tools:layout_editor_absoluteX=&lt;/span&gt;&lt;span class="s"&gt;"25dp"&lt;/span&gt;
        &lt;span class="na"&gt;tools:layout_editor_absoluteY=&lt;/span&gt;&lt;span class="s"&gt;"16dp"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;ProgressBar&lt;/span&gt;
        &lt;span class="na"&gt;android:id=&lt;/span&gt;&lt;span class="s"&gt;"@+id/progressBar"&lt;/span&gt;
        &lt;span class="na"&gt;android:layout_width=&lt;/span&gt;&lt;span class="s"&gt;"wrap_content"&lt;/span&gt;
        &lt;span class="na"&gt;android:layout_height=&lt;/span&gt;&lt;span class="s"&gt;"wrap_content"&lt;/span&gt;
        &lt;span class="na"&gt;android:layout_centerInParent=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
        &lt;span class="na"&gt;app:layout_constraintBottom_toBottomOf=&lt;/span&gt;&lt;span class="s"&gt;"parent"&lt;/span&gt;
        &lt;span class="na"&gt;app:layout_constraintEnd_toEndOf=&lt;/span&gt;&lt;span class="s"&gt;"parent"&lt;/span&gt;
        &lt;span class="na"&gt;app:layout_constraintStart_toStartOf=&lt;/span&gt;&lt;span class="s"&gt;"@+id/sceneView"&lt;/span&gt;
        &lt;span class="na"&gt;app:layout_constraintTop_toTopOf=&lt;/span&gt;&lt;span class="s"&gt;"@+id/sceneView"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;Button&lt;/span&gt;
        &lt;span class="na"&gt;android:id=&lt;/span&gt;&lt;span class="s"&gt;"@+id/closeButton"&lt;/span&gt;
        &lt;span class="na"&gt;android:layout_width=&lt;/span&gt;&lt;span class="s"&gt;"48dp"&lt;/span&gt;
        &lt;span class="na"&gt;android:layout_height=&lt;/span&gt;&lt;span class="s"&gt;"48dp"&lt;/span&gt;
        &lt;span class="na"&gt;android:layout_alignParentTop=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
        &lt;span class="na"&gt;android:layout_alignParentEnd=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
        &lt;span class="na"&gt;android:layout_marginTop=&lt;/span&gt;&lt;span class="s"&gt;"30dp"&lt;/span&gt;
        &lt;span class="na"&gt;android:layout_marginEnd=&lt;/span&gt;&lt;span class="s"&gt;"30dp"&lt;/span&gt;
        &lt;span class="na"&gt;android:text=&lt;/span&gt;&lt;span class="s"&gt;"X"&lt;/span&gt;
        &lt;span class="na"&gt;android:textColor=&lt;/span&gt;&lt;span class="s"&gt;"#fff"&lt;/span&gt;
        &lt;span class="na"&gt;app:layout_constraintEnd_toEndOf=&lt;/span&gt;&lt;span class="s"&gt;"parent"&lt;/span&gt;
        &lt;span class="na"&gt;app:layout_constraintTop_toTopOf=&lt;/span&gt;&lt;span class="s"&gt;"parent"&lt;/span&gt;
        &lt;span class="na"&gt;tools:layout_editor_absoluteX=&lt;/span&gt;&lt;span class="s"&gt;"365dp"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/androidx.constraintlayout.widget.ConstraintLayout&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If there is a warning / error about a missing package `androidx.constraintlayout.widget.ConstraintLayout´ right click on it, select &lt;em&gt;Show Context Actions&lt;/em&gt; and select &lt;em&gt;Add dependency&lt;/em&gt;. Android Studio will then add an import and sync the project.&lt;/p&gt;

&lt;p&gt;The button at the end is so that we can close the screen, when we want to return to the non-ar part of our app. In order for this button to be displayed correctly, we need to&lt;/p&gt;

&lt;h3&gt;
  
  
  Update the ARModule file
&lt;/h3&gt;

&lt;p&gt;Now we can reference the created layout file in our module. Open the file &lt;em&gt;ARModule.kt&lt;/em&gt; and replace the &lt;code&gt;showAR&lt;/code&gt; method with the following:&lt;br&gt;
`&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@ReactMethod
  fun showAR(fileName: String) {
      val assetPath = "file:///android_asset/$fileName"
      val intent = Intent(reactContext, ModelDisplayActivity::class.java)
        intent.putExtra("MODEL_PATH", assetPath)

        // If starting the activity from a non-activity context, set this flag
      intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

      reactContext.startActivity(intent)
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will pass the filename of our model to our native code, which will in turn load it from the assets folder and start a custom &lt;a href="https://developer.android.com/reference/android/app/Activity"&gt;Activity&lt;/a&gt; to display the model. In simple terms, an activity represents a single screen with a user interface.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create the Activity file
&lt;/h3&gt;

&lt;p&gt;Right click on the &lt;em&gt;com.rn3dworldexplorer&lt;/em&gt; folder and select &lt;em&gt;New&lt;/em&gt; &amp;gt; &lt;em&gt;Kotlin Class&lt;/em&gt;. Name the file &lt;em&gt;ModelDisplayActivity.kt&lt;/em&gt;. Copy the following code into it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.rn3dworldexplorer&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.os.Bundle&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.util.Log&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.view.View&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.widget.Button&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.widget.ProgressBar&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.widget.Toast&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;androidx.appcompat.app.AppCompatActivity&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.google.ar.core.Config&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.github.sceneview.ar.ArSceneView&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.github.sceneview.ar.node.ArModelNode&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.github.sceneview.ar.node.PlacementMode&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.github.sceneview.math.Position&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.CoroutineScope&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.Dispatchers&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.launch&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ModelDisplayActivity&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;AppCompatActivity&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;lateinit&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;progressBar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ProgressBar&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;lateinit&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;closeButton&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Button&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;lateinit&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;sceneView&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ArSceneView&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;lateinit&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;modelNode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ArModelNode&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Bundle&lt;/span&gt;&lt;span class="p"&gt;?)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;setContentView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ar_activity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;// Initialize views&lt;/span&gt;
        &lt;span class="n"&gt;closeButton&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;findViewById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;closeButton&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;progressBar&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;findViewById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;progressBar&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;sceneView&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;findViewById&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ArSceneView&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="nc"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sceneView&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lightEstimationMode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;LightEstimationMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DISABLED&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;sceneView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;onArSessionFailed&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="nc"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;e&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ARModule"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"${exception.message}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="c1"&gt;// If AR is not available, we add the model directly to the scene for a 3D only usage&lt;/span&gt;
            &lt;span class="n"&gt;sceneView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;modelNode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Set close button listener&lt;/span&gt;
        &lt;span class="n"&gt;closeButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setOnClickListener&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;finish&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Load model if path is provided&lt;/span&gt;
        &lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getStringExtra&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"MODEL_PATH"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;modelPath&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="nf"&gt;loadModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;modelPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;?:&lt;/span&gt; &lt;span class="nf"&gt;showMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Model path is null"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;loadModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;glbFileLocation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;d&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ARModule"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"loadModel path: $glbFileLocation"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;progressBar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;visibility&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;VISIBLE&lt;/span&gt;

        &lt;span class="nc"&gt;CoroutineScope&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Dispatchers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;launch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;modelNode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ArModelNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sceneView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;PlacementMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;INSTANT&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nf"&gt;loadModelGlbAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                        &lt;span class="n"&gt;glbFileLocation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;glbFileLocation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="n"&gt;scaleToUnits&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;1f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="n"&gt;centerOrigin&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Position&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.0f&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="n"&gt;sceneView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;planeRenderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isVisible&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;
                        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;materialInstance&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;materialInstances&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&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="n"&gt;sceneView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;modelNode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;modelNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;anchor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="n"&gt;sceneView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;planeRenderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isVisible&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nf"&gt;showMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error loading model: ${e.message}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="nc"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;e&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ARModule"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Error occurred: ${e.message}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;progressBar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;visibility&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;GONE&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="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;showMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;makeText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;LENGTH_LONG&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;show&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is a brief overview of the file:&lt;/p&gt;

&lt;h4&gt;
  
  
  Properties
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;UI Elements: The class defines UI elements like a ProgressBar, a Button (closeButton), and an ArSceneView (for AR content display).&lt;/li&gt;
&lt;li&gt;Model Node: modelNode of type ArModelNode is used to represent the 3D model in AR.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  onCreate Method
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;UI Setup: In the onCreate method (called when the activity is starting), it sets up the user interface from a layout resource (R.layout.ar_activity).&lt;/li&gt;
&lt;li&gt;Initializing Views: Finds and initializes views like the close button, progress bar, and AR scene view.&lt;/li&gt;
&lt;li&gt;AR Session Failure Handling: Sets an error handling mechanism for the AR session. If AR is not available, it directly adds the model to the scene for non-AR 3D viewing.&lt;/li&gt;
&lt;li&gt;Close Button Listener: Implements an action for the close button - when clicked, it finishes (closes) the activity.&lt;/li&gt;
&lt;li&gt;Model Loading: Checks if a model path is provided via the intent; if so, it calls loadModel to load the model.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  loadModel Method
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Functionality: This method loads the 3D model (GLB format) for display in the AR scene.&lt;/li&gt;
&lt;li&gt;Coroutine: Uses a coroutine for asynchronous execution to avoid blocking the UI thread.&lt;/li&gt;
&lt;li&gt;Model Node Setup: Configures the modelNode with the model path, scale, and origin. Once the model is loaded, it is anchored to a position in the AR scene.&lt;/li&gt;
&lt;li&gt;Visibility Settings: Manages the visibility of the plane renderer and progress bar based on the model loading status.&lt;/li&gt;
&lt;li&gt;Error Handling: Catches exceptions, logs errors, and shows error messages if model loading fails.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  showMessage Method
&lt;/h4&gt;

&lt;p&gt;Functionality: A utility method to show a toast message on the screen. It's used to provide feedback to the user (like successful model loading or error messages).&lt;/p&gt;

&lt;h3&gt;
  
  
  Added the necessary permissions to the Androidmanifest.xml file
&lt;/h3&gt;

&lt;p&gt;Replace the contents of your &lt;em&gt;AndroidManifest.xml&lt;/em&gt; with this one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;manifest&lt;/span&gt; &lt;span class="na"&gt;xmlns:android=&lt;/span&gt;&lt;span class="s"&gt;"http://schemas.android.com/apk/res/android"&lt;/span&gt; &lt;span class="na"&gt;xmlns:tools=&lt;/span&gt;&lt;span class="s"&gt;"http://schemas.android.com/tools"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;uses-permission&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.permission.INTERNET"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;uses-permission&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.permission.CAMERA"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- You may need these if doing any screen recording from within the app --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;uses-feature&lt;/span&gt;
        &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.hardware.vr.headtracking"&lt;/span&gt;
        &lt;span class="na"&gt;android:required=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
        &lt;span class="na"&gt;android:version=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;uses-permission&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.permission.NFC"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;uses-permission&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.permission.WAKE_LOCK"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- Other camera related features --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;uses-feature&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.hardware.camera"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;uses-feature&lt;/span&gt;
        &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.hardware.camera.autofocus"&lt;/span&gt;
        &lt;span class="na"&gt;android:required=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;
        &lt;span class="na"&gt;tools:replace=&lt;/span&gt;&lt;span class="s"&gt;"required"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;uses-feature&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.hardware.camera.ar"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- Specifying OpenGL version or requirements --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;uses-feature&lt;/span&gt;
        &lt;span class="na"&gt;android:glEsVersion=&lt;/span&gt;&lt;span class="s"&gt;"0x00030000"&lt;/span&gt;
        &lt;span class="na"&gt;android:required=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;
        &lt;span class="na"&gt;tools:node=&lt;/span&gt;&lt;span class="s"&gt;"remove"&lt;/span&gt;
        &lt;span class="na"&gt;tools:replace=&lt;/span&gt;&lt;span class="s"&gt;"required"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- Usage of accelerometer and gyroscope --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;uses-feature&lt;/span&gt;
        &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.hardware.sensor.accelerometer"&lt;/span&gt;
        &lt;span class="na"&gt;android:required=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;
        &lt;span class="na"&gt;tools:replace=&lt;/span&gt;&lt;span class="s"&gt;"required"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;uses-feature&lt;/span&gt;
        &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.hardware.sensor.gyroscope"&lt;/span&gt;
        &lt;span class="na"&gt;android:required=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;
        &lt;span class="na"&gt;tools:replace=&lt;/span&gt;&lt;span class="s"&gt;"required"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;application&lt;/span&gt;
      &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;".MainApplication"&lt;/span&gt;
      &lt;span class="na"&gt;android:label=&lt;/span&gt;&lt;span class="s"&gt;"@string/app_name"&lt;/span&gt;
      &lt;span class="na"&gt;android:icon=&lt;/span&gt;&lt;span class="s"&gt;"@mipmap/ic_launcher"&lt;/span&gt;
      &lt;span class="na"&gt;android:roundIcon=&lt;/span&gt;&lt;span class="s"&gt;"@mipmap/ic_launcher_round"&lt;/span&gt;
      &lt;span class="na"&gt;android:allowBackup=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;
      &lt;span class="na"&gt;android:theme=&lt;/span&gt;&lt;span class="s"&gt;"@style/AppTheme"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;activity&lt;/span&gt;
        &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;".MainActivity"&lt;/span&gt;
        &lt;span class="na"&gt;android:label=&lt;/span&gt;&lt;span class="s"&gt;"@string/app_name"&lt;/span&gt;
        &lt;span class="na"&gt;android:configChanges=&lt;/span&gt;&lt;span class="s"&gt;"keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"&lt;/span&gt;
        &lt;span class="na"&gt;android:launchMode=&lt;/span&gt;&lt;span class="s"&gt;"singleTask"&lt;/span&gt;
        &lt;span class="na"&gt;android:windowSoftInputMode=&lt;/span&gt;&lt;span class="s"&gt;"adjustResize"&lt;/span&gt;
        &lt;span class="na"&gt;android:exported=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;intent-filter&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;action&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.intent.action.MAIN"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;category&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.intent.category.LAUNCHER"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/intent-filter&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/activity&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;activity&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;".ModelDisplayActivity"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;meta-data&lt;/span&gt;
            &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"com.google.ar.core"&lt;/span&gt;
            &lt;span class="na"&gt;android:value=&lt;/span&gt;&lt;span class="s"&gt;"optional"&lt;/span&gt;
            &lt;span class="na"&gt;tools:replace=&lt;/span&gt;&lt;span class="s"&gt;"android:value"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/application&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/manifest&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We request several device features needed for &lt;em&gt;AR&lt;/em&gt; like the gyroscope as well as register our custom activity via this line: &lt;code&gt;&amp;lt;activity android:name=".ModelDisplayActivity" /&amp;gt;&lt;/code&gt;. Not all of them may be used in the end, so it is your responsibility to choose carefully. This list just aims to be as comprehensive as possible out of convenience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adjust our JavaScript React code
&lt;/h3&gt;

&lt;p&gt;We are finally back in the cozy surroundings of your &lt;em&gt;JavaScript&lt;/em&gt; code. All that is left is to adjust our &lt;em&gt;ARModule.tsx&lt;/em&gt; and our &lt;em&gt;App.tsx&lt;/em&gt;. For the &lt;em&gt;ARModule&lt;/em&gt; file, adjust your &lt;code&gt;showAR&lt;/code&gt; function to this &lt;code&gt;showAR(path: string): Promise&amp;lt;void&amp;gt;;&lt;/code&gt; to reflect the new type signature. After that, in the &lt;em&gt;App.tsx&lt;/em&gt; you can adjust the onPress function of the button to pass the name of your chosen model. For me it is like this:&lt;br&gt;
&lt;code&gt;onPress={async () =&amp;gt; await ARModule.showAR("AR-model.glb")}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now just press the button and it should look similar to this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lnyHKlml--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lj60nxxp4ey45g1twukm.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lnyHKlml--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lj60nxxp4ey45g1twukm.jpg" alt="3D Sphere displayed on mobile phone" width="800" height="1778"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;As we conclude this second part of our series, we have navigated through the integration of &lt;em&gt;ARCore&lt;/em&gt; in a &lt;em&gt;React Native&lt;/em&gt; environment via &lt;em&gt;Kotlin&lt;/em&gt;. It can be pretty overwhelming if you haven't delved too deep into native code integration, but hopefully, it was manageable. From here on out, you can expand on the basic functionality and create your own features.&lt;/p&gt;

&lt;p&gt;Moving forward, we will be doing the setup for native modules using &lt;em&gt;Objective C&lt;/em&gt; in &lt;em&gt;iOS&lt;/em&gt; in the next entry. &lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>kotlin</category>
      <category>arcore</category>
      <category>android</category>
    </item>
    <item>
      <title>Building AR Experiences with React Native: Bridging the Gap with Kotlin</title>
      <dc:creator>Pascal C</dc:creator>
      <pubDate>Sun, 10 Dec 2023 18:56:04 +0000</pubDate>
      <link>https://dev.to/9bytes/building-ar-vr-experiences-with-react-native-part-1-bridging-the-gap-with-kotlin-1dii</link>
      <guid>https://dev.to/9bytes/building-ar-vr-experiences-with-react-native-part-1-bridging-the-gap-with-kotlin-1dii</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Recently I got assigned an interesting project which required having AR capabilities in a &lt;em&gt;React Native&lt;/em&gt; app for cross platform purposes. The initial idea was integrating &lt;a href="https://github.com/ViroCommunity/viro" rel="noopener noreferrer"&gt;ViroReact&lt;/a&gt;, but this very quickly turned out to be a bad idea. Missing features for the 3D-Models (model animations, ...) and it's general incompatibility with the newest &lt;a href="https://reactnative.dev" rel="noopener noreferrer"&gt;React Native&lt;/a&gt; Version (0.72) made it unsufficient for our use case. So the decision was made to implement the functionality via native modules. And so began my descent into dependency hell 💾🔥...&lt;/p&gt;

&lt;p&gt;This is part one of a multi part article series about the integration of AR services via native modules into a &lt;em&gt;React Native&lt;/em&gt; app. The first half of this series will be about the integration into an Android app, using &lt;a href="https://developers.google.com/ar/develop" rel="noopener noreferrer"&gt;ARCore&lt;/a&gt; and &lt;a href="https://github.com/SceneView/sceneview-android" rel="noopener noreferrer"&gt;SceneView&lt;/a&gt;. In this part, you will learn how to set up Kotlin to write native modules.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Part Two: &lt;a href="https://dev.to/9bytes/navigating-the-ar-landscape-in-react-native-with-kotlin-2caj"&gt;Integrating ARCore&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Part Three: &lt;a href="https://dev.to/9bytes/seamlessly-integrating-native-modules-in-ios-for-react-native-ar-apps-5alp"&gt;Setting up iOS with Objective-C&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Part Four: &lt;a href="https://dev.to/9bytes/seamlessly-integrating-native-modules-in-ios-for-react-native-ar-apps-5alp"&gt;Integrating ARKit&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can follow along or download the full code of part one &lt;a href="https://github.com/Gh05d/RN3DWorldExplorer/tree/part-1" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coding
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;I am using the &lt;em&gt;React Native&lt;/em&gt; CLI for this project on a real device (simulators don't work well with AR APIs). Make sure to have finished the &lt;a href="https://reactnative.dev/docs/environment-setup" rel="noopener noreferrer"&gt;setup&lt;/a&gt; for new &lt;em&gt;React Native&lt;/em&gt; apps on Android. Also download &lt;a href="https://developer.android.com/studio" rel="noopener noreferrer"&gt;Android Studio&lt;/a&gt;. You will need it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting up a new React Native project
&lt;/h3&gt;

&lt;p&gt;Open up your favorite terminal on the OS of your choice (I am on &lt;em&gt;Ubuntu 22.04.3 LTS&lt;/em&gt;) and use the following command to setup a &lt;a href="https://reactnative.dev/docs/environment-setup" rel="noopener noreferrer"&gt;new React Native project&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx react-native init RN3DWorldExplorer&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then add the folder to the workspace of your favorite editor and change into the directory via &lt;code&gt;cd RN3DWorldExplorer&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Kotlin
&lt;/h3&gt;

&lt;p&gt;When writing native modules, you have the choice to use &lt;a href="https://kotlinlang.org/" rel="noopener noreferrer"&gt;Kotlin&lt;/a&gt; or &lt;a href="https://www.java.com" rel="noopener noreferrer"&gt;Java&lt;/a&gt;. We will be using Kotlin for this tutorial.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Kotlin is a modern but already mature programming language. It's concise, safe, interoperable with Java and other languages, and provides many ways to reuse code between multiple platforms for productive programming.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Unfortunately, it does not work out of the box (This may change in future &lt;a href="https://reactnative.dev/docs/native-modules-intro" rel="noopener noreferrer"&gt;React Native versions&lt;/a&gt;). We have to do the following steps to make it work with &lt;em&gt;React Native&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Add &lt;code&gt;kotlinVersion = "1.8.0"&lt;/code&gt; to the &lt;code&gt;buildscript { ext&lt;/code&gt; section of your &lt;em&gt;android/build.gradle&lt;/em&gt; nad &lt;code&gt;classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")&lt;/code&gt; to the &lt;code&gt;dependencies&lt;/code&gt; section. It should look like this:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/image.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/image.png" alt="Project wide build.gradle file"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add &lt;code&gt;apply plugin: 'kotlin-android'&lt;/code&gt; to the top of your &lt;em&gt;android/app/build.gradle&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add &lt;code&gt;implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"&lt;/code&gt; to the &lt;code&gt;dependencies&lt;/code&gt;` section of the same file&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sync the project with &lt;a href="https://gradle.org/install/" rel="noopener noreferrer"&gt;Gradle&lt;/a&gt; via the elephant button in the upper right&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now try running the app via &lt;code&gt;npm run start&lt;/code&gt; and type &lt;em&gt;a&lt;/em&gt; for Android. The app should build and run now.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bridging native modules to React Native
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Creating a native module
&lt;/h4&gt;

&lt;p&gt;Following the steps outlined from the &lt;a href="https://reactnative.dev/docs/native-modules-android" rel="noopener noreferrer"&gt;docs&lt;/a&gt;, we will be creating our AR module.&lt;/p&gt;

&lt;p&gt;For this, open up Android Studio, navigate via the project pane (upper left) to the &lt;em&gt;app/java/com.rn3dworldexplorer&lt;/em&gt; folder, right click on it, select new -&amp;gt; Kotlin Class and name it ARModule.kt. Then add the following code to the file:&lt;br&gt;
`&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.rn3dworldexplorer&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.content.Intent&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.facebook.react.bridge.ReactApplicationContext&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.facebook.react.bridge.ReactContextBaseJavaModule&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.facebook.react.bridge.ReactMethod&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ARModule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;reactContext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ReactApplicationContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ReactContextBaseJavaModule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reactContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"ARModule"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@ReactMethod&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;showAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="n"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello ARWorld"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;With the &lt;code&gt;getName()&lt;/code&gt; function, we will be able to &lt;a href="https://reactnative.dev/docs/native-modules-android?android-language=kotlin#module-name" rel="noopener noreferrer"&gt;access&lt;/a&gt; our module in our React Native code.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;showAR()&lt;/code&gt; function takes a &lt;a href="https://reactnative.dev/docs/native-modules-android?android-language=kotlin#promises" rel="noopener noreferrer"&gt;Promise&lt;/a&gt; as a parameter for now. The reason is that these methods can't return values directly to JavaScript due to the asynchronous nature of the bridge between native code and JavaScript. In part 2, we will integrate a custom activity to display a 3D-model instead.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Registering the native module
&lt;/h4&gt;

&lt;p&gt;Now we need to &lt;a href="https://reactnative.dev/docs/native-modules-android?android-language=kotlin#register-the-module-android-specific" rel="noopener noreferrer"&gt;register the module&lt;/a&gt; with React Native:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In order to do so, you need to add your native module to a ReactPackage and register the ReactPackage with React Native. During initialization, React Native will loop over all packages, and for each ReactPackage, register each native module within.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Create a new Kotlin file called &lt;em&gt;ArPackage.kt&lt;/em&gt; and copy this code into it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.rn3dworldexplorer&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.view.View&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.facebook.react.ReactPackage&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.facebook.react.bridge.NativeModule&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.facebook.react.bridge.ReactApplicationContext&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.facebook.react.uimanager.ReactShadowNode&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.facebook.react.uimanager.ViewManager&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GLBPackage&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ReactPackage&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;createViewManagers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;reactContext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ReactApplicationContext&lt;/span&gt;
    &lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;MutableList&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ViewManager&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ReactShadowNode&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;*&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;mutableListOf&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;createNativeModules&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;reactContext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ReactApplicationContext&lt;/span&gt;
    &lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;MutableList&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NativeModule&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;GLBModule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reactContext&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toMutableList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This file imports the created native AR - module and instantiates it via the &lt;code&gt;createNativeModules&lt;/code&gt; function and returns it as a list of &lt;em&gt;NativeModules&lt;/em&gt; to register.&lt;/p&gt;

&lt;p&gt;Now we just must add the &lt;em&gt;ARPackage.kt&lt;/em&gt; to ReactNativeHost's &lt;code&gt;getPackages()&lt;/code&gt; method. Open up &lt;em&gt;MainApplication.java&lt;/em&gt; and add this inside the method: &lt;code&gt;packages.add(new ARPackage());&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqv3toy80jj15ahphloik.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqv3toy80jj15ahphloik.png" alt="MainApplication.java file"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This bridges our native module with the &lt;em&gt;JavaScript&lt;/em&gt; part of our application. Sync the project one last time.&lt;/p&gt;

&lt;h4&gt;
  
  
  Add the native module to the app
&lt;/h4&gt;

&lt;p&gt;It is &lt;a href="https://reactnative.dev/docs/native-modules-android?android-language=kotlin#better-native-module-export" rel="noopener noreferrer"&gt;best practice&lt;/a&gt; to create a file for every native module in your code. So in the root of your project, create a new folder &lt;em&gt;modules&lt;/em&gt; and inside it a file named &lt;em&gt;ARModule.tsx&lt;/em&gt;. Copy this code inside it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NativeModules&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ARModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;NativeModules&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ARModuleInterface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;showAR&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;ARModule&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;ARModuleInterface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Doing it this way allows us to properly &lt;a href="https://www.typescriptlang.org/" rel="noopener noreferrer"&gt;type&lt;/a&gt; our module and be able to import it anywhere simply via &lt;code&gt;import ARModule from "./modules/ARModule";&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Update App.tsx
&lt;/h4&gt;

&lt;p&gt;Right now we have the boilerplate setup for new &lt;em&gt;React Native&lt;/em&gt; projects in our &lt;em&gt;App.tsx&lt;/em&gt;. Update the file with this code instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;PropsWithChildren&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;SafeAreaView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;ScrollView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;StatusBar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;View&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ARModule&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./modules/ARModule&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;SectionProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;PropsWithChildren&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Section&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FC&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SectionProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sectionContainer&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sectionTitle&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sectionDescription&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FC&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SafeAreaView&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;StatusBar&lt;/span&gt; &lt;span class="na"&gt;barStyle&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"light-content"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ScrollView&lt;/span&gt; &lt;span class="na"&gt;contentInsetAdjustmentBehavior&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"automatic"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Section&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"AR"&lt;/span&gt; &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Render the native AR module"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;
            &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Show AR"&lt;/span&gt;
            &lt;span class="na"&gt;onPress&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ARModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;showAR&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
              &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ScrollView&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;SafeAreaView&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;sectionContainer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;marginTop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;paddingHorizontal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;sectionTitle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;fontWeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;600&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;sectionDescription&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;marginTop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;marginBottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;fontWeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;400&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the app now, press the "Show AR" button and you should see a &lt;code&gt;console.log&lt;/code&gt; "Hello ARWorld" in your terminal.&lt;/p&gt;

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

&lt;p&gt;This concludes the first part of this series on integrating AR services into &lt;em&gt;React Native&lt;/em&gt;. This part focused on setting up a Kotlin environment to write native modules, a crucial step in bridging the gap between the high-level &lt;em&gt;React Native&lt;/em&gt; framework and the low-level efficiency of native Android development. Looking ahead, the established groundwork here will allow us to dive into the world of AR development in &lt;em&gt;Android&lt;/em&gt;. The next part of this series will explore the integration of &lt;em&gt;ARCore&lt;/em&gt; and &lt;em&gt;SceneView&lt;/em&gt;.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>android</category>
      <category>arcore</category>
      <category>kotlin</category>
    </item>
  </channel>
</rss>
