<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Rupesh Chaudhari on Medium]]></title>
        <description><![CDATA[Stories by Rupesh Chaudhari on Medium]]></description>
        <link>https://medium.com/@hrupesh?source=rss-9f74c62cc277------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*p79hYV-PDpBPZhVsqaQfzQ.jpeg</url>
            <title>Stories by Rupesh Chaudhari on Medium</title>
            <link>https://medium.com/@hrupesh?source=rss-9f74c62cc277------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Wed, 27 May 2026 02:50:57 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@hrupesh/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Creating a Chatbot and Translation app with Nextjs and React Native using ChatGPT]]></title>
            <link>https://medium.com/@hrupesh/creating-a-chatbot-and-translation-app-with-nextjs-and-react-native-using-chatgpt-e4cc6c986106?source=rss-9f74c62cc277------2</link>
            <guid isPermaLink="false">https://medium.com/p/e4cc6c986106</guid>
            <category><![CDATA[openai]]></category>
            <category><![CDATA[nextjs]]></category>
            <category><![CDATA[react-native]]></category>
            <category><![CDATA[chatgpt]]></category>
            <category><![CDATA[chatbots]]></category>
            <dc:creator><![CDATA[Rupesh Chaudhari]]></dc:creator>
            <pubDate>Sat, 24 Dec 2022 14:59:44 GMT</pubDate>
            <atom:updated>2022-12-24T14:59:44.494Z</atom:updated>
            <content:encoded><![CDATA[<h3>Creating a Chatbot and Translation app with Nextjs and React Native using ChatGPT (OpenAI)</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*oJOrW5F-idSElzhn0wpAIw.png" /></figure><h3>What is ChatGPT?</h3><p>I asked the same question on <a href="https://chat.openai.com/chat">Chat-GPT</a> , and here’s what it said. 🤯</p><blockquote>ChatGPT is a chatbot model developed by OpenAI that is based on the GPT (Generative Pre-trained Transformer) language model. It is designed to generate human-like responses to text input in a conversational context. ChatGPT uses a combination of machine learning and natural language processing techniques to generate appropriate responses to user input in a way that resembles human conversation.</blockquote><blockquote>The ChatGPT model is trained on a large dataset of human conversations, and it is able to generate responses that are coherent, contextually relevant, and often quite similar to those that a human might provide in a similar conversational context. ChatGPT is able to maintain a consistent persona or “character” throughout a conversation, and it can also generate responses to a wide range of topics and content types.</blockquote><blockquote>ChatGPT can be used to build chatbots or conversational agents that can engage with users in a variety of settings, including customer service, e-commerce, social media, and more. It is also a useful tool for researchers and developers working on natural language processing and chatbot technology. — From <a href="https://chat.openai.com/chat">ChatGPT</a></blockquote><p>As you can see, it is very accurate in answering.</p><p>In this article, we will see how we can use <a href="https://openai.com/">OpenAI’s</a> API to incorporate ChatGPT into a React Native application to create a Chatbot and text translation app.</p><p>For your reference:</p><ol><li><a href="https://github.com/hrupesh/nextjs-chatgpt-BE"><em>https://github.com/hrupesh/nextjs-chatgpt-BE</em></a></li><li><a href="https://github.com/hrupesh/RNChatGPTApp"><em>https://github.com/hrupesh/RNChatGPTApp</em></a></li></ol><h3>Creating the ServerSide with Nextjs</h3><p>To utilize ChatGPT in react native, which will be our client side we first need to create a server. The server will have two REST API endpoints ask-a-question and translate . The first endpoint will take in a param called question in the request body and return an answer to question which we will query from the OpenAI’s createCompletion method. The second endpoint will be translate which will take two params query and language . The first param query will store the text which user wants to translate and the second is language which is the desired language user needs to translate into.</p><p>Okay, enough talk; Now let’s start to code.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/480/1*inq28kKegUQrdZkYkVRpHg.gif" /></figure><p>You can find the code in this <a href="https://github.com/hrupesh/nextjs-chatgpt-BE">repository</a>.</p><p>To create a new Nextjs project head to your terminal and type the following command.</p><pre>npx create-next-app@latest<br><br>OR Add a typescript flag to create in typescipt<br><br>npx create-next-app@latest --typescript</pre><p>You will be prompted with what name you want to give to your project, enter what you want, and proceed.</p><p>After your project is created open the project folder in your preferred Code Editor.</p><p>To test run the app, execute the following:</p><pre>yarn dev <br><br>OR<br><br>npm run dev<br><br>OR <br><br>next dev</pre><p>Once your app is running you can view it on <a href="http://localhost:3000/">http://localhost:3000/</a></p><p>We need to create two API endpoints so we will not touch anything else in the pages folder other than the api folder.</p><p>Nextjs treats files under this folder as API endpoints, let’s create our first endpoint.</p><p>Create a new file name ask-a-question.ts inside pages/api .</p><p>Before we write code in this file, we first need to install openai into our project.</p><p>Run the below command to install openai dependency into your project using any package manager.</p><pre>yarn add openai<br><br>OR<br><br>npm i openai</pre><p>Now let’s use it.</p><p>We will create a common file that will configure the OpenAiApi</p><p>Create a new folder at the root of the project and add a file name config.ts inside it.</p><pre>mkdir src &amp;&amp; touch config.ts</pre><p>Now add the following code inside this file:</p><pre>import { Configuration, OpenAIApi } from &quot;openai&quot;;<br><br>const config = new Configuration({<br>    apiKey: process.env.OPEN_AI_KEY<br>});<br><br>const openAI = new OpenAIApi(config);<br><br>export default openAI;</pre><p>Also, we need to add the OPEN_AI_KEY in .env file.</p><pre>touch .env</pre><p>Now you need to create an API Key for using Open AI’s API, follow this <a href="https://beta.openai.com/account/api-keys">link</a> to do so.</p><p>Log in to their website and create your API-KEY.</p><blockquote>NOTE: You cannot use Open AI API without apiKey</blockquote><p>We will now add the code to handle ask-a-question endpoint, add the below code in ask-a-question.ts file.</p><pre>import type { NextApiRequest, NextApiResponse } from &quot;next&quot;;<br>import openAI from &quot;../../src/config&quot;;<br><br>type Data = {<br>  result?: string | undefined;<br>  error?: string;<br>};<br><br>export default async function handler(<br>  req: NextApiRequest,<br>  res: NextApiResponse&lt;Data&gt;<br>) {<br>  if (!req?.body?.question){<br>    res.status(400).json({ error: &#39;Invalid params&#39; })<br>  }<br><br>  const completion = await openAI.createCompletion({<br>    model: &#39;text-davinci-003&#39;,<br>    prompt: req?.body?.question,<br>    temperature: 0.8,<br>    max_tokens: 2048,<br>  });<br>  res.status(200).json({ result: completion.data?.choices?.[0]?.text });<br>}</pre><p>In the above code first, we are checking if request has a valid question parameter value, if not then returning 400 with error message Invalid params . If we get the params correctly then are calling openAI.createCompletion the method which calls the openai API under the hood with the given prompt and specified model and other options.</p><p>We are passing the question which we receive in the request body to the API then weawait until it returns. Then we simply return the answer in the response .</p><p>The output will be as below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1015/1*zj_oXRhM7pnRjS9orbOnMQ.png" /></figure><p>Now let’s create the second endpoint i.e. for translation.</p><p>Create another file in pages/api and name it translate.ts , then add the following code inside.</p><pre>import type { NextApiRequest, NextApiResponse } from &quot;next&quot;;<br>import openAI from &quot;../../src/config&quot;;<br><br>type Data = {<br>  result?: string | undefined;<br>  error?: string;<br>};<br><br>export default async function handler(<br>  req: NextApiRequest,<br>  res: NextApiResponse&lt;Data&gt;<br>) {<br>  if (!req?.body?.query || !req?.body?.language) {<br>    res.status(400).json({ error: &quot;Invalid params&quot; });<br>  }<br><br>  const { query = &quot;&quot;, language = &quot;English&quot; } = req?.body;<br>  const completion = await openAI.createCompletion({<br>    model: &quot;text-davinci-003&quot;,<br>    // We are prompting the API in the below format<br>    // The ?? after `query` is just a HACK<br>    prompt: `translate ${query}?? in ${language}`,<br>    temperature: 0.8,<br>    max_tokens: 2048,<br>  });<br>  res.status(200).json({ result: completion.data?.choices?.[0]?.text });<br>}</pre><p>That’s it, we have created two endpoints using Chat-GPT to answer anything.</p><p>The output of the above will be:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1013/1*6X56fu6MDaXDR4Hwhg-IBg.png" /></figure><p>Yay 🔥 we have completed our application’s Backend.</p><p>You can deploy this using <a href="http://vercel.com">Vercel</a>, it is very easy and fast.</p><h3>Creating Application with React Native</h3><p>Now let’s create an mobile app to utilize this back end we just created.</p><p>If you want to skip the code, here is the repository <a href="https://github.com/hrupesh/RNChatGPTApp">URL</a>. You also need to download the assets folder from the repo.</p><p>We will use React Native to create the mobile app for iOS and Android. Get started by creating a new react native project.</p><pre>npx react-native init &lt;your-project-name&gt; --template react-native-template-typescript</pre><p>once project is created, run it on iOS simulator and Android emulator using the below commands</p><pre>yarn ios<br>yarn android<br>  OR<br>react-native run-android<br>react-native run-ios</pre><p>Now you should have a React Native app running on your simulators.</p><p>Before we start to write our code, let’s remove the starter code App.tsx file and add the following.</p><pre>import React, {useState} from &#39;react&#39;;<br>import {View, Text, StyleSheet, Image, Pressable, TextInput} from &#39;react-native&#39;;<br><br>const App: React.FC = () =&gt; (<br>  &lt;View style={styles.container}&gt;<br>    &lt;Text&gt;Hello React Native!&lt;/Text&gt;<br>  &lt;/View&gt;<br>);<br><br>const styles = StyleSheet.create({<br>  container: {<br>    flex: 1,<br>    justifyContent: &#39;center&#39;,<br>    alignItems: &#39;center&#39;,<br>  },<br>});<br><br>export default App;</pre><p>Now you must see a white screen with text Hello React Native! at the center.</p><p>We will now write the code to display a tab bar on app screen, the tab bar will have two options, first will be for Chat (were user can type anything to get appropriate results) second will be translation section.</p><p>Add the following code to App.tsx</p><pre>import React, {useState} from &#39;react&#39;;<br>import {View, Text, StyleSheet, Image, Pressable, TextInput} from &#39;react-native&#39;;<br>import {Conversation as ConversationIcon, Translate} from &#39;./assets&#39;;<br>import { Conversation, Translation } from &#39;./src/components&#39;;<br><br>interface ContentProps {<br>  selectedIndex: number;<br>}<br><br>const Content: React.FC&lt;ContentProps&gt; = ({ selectedIndex }) =&gt; {<br>  switch (selectedIndex) {<br>    case 0: <br>      return &lt;Conversation /&gt;<br>    case 1:<br>      return &lt;Translation /&gt;<br>    default: return &lt;&gt;&lt;/&gt;;<br>  }<br>}<br><br>const App: React.FC = () =&gt; {<br>  const [selectedIndex, setSelectedIndex] = useState&lt;number&gt;(0);<br>  const changeSelection = (selection: number) =&gt; () =&gt; setSelectedIndex(selection);<br>  return (<br>    &lt;View style={styles.container}&gt;<br>      &lt;Content {...{selectedIndex}} /&gt;<br>      &lt;View style={styles.tabBar}&gt;<br>        &lt;Pressable onPress={changeSelection(0)}&gt;<br>          &lt;Image style={styles.tabIcon} source={ConversationIcon} /&gt;<br>        &lt;/Pressable&gt;<br>        &lt;Pressable onPress={changeSelection(1)}&gt;<br>          &lt;Image style={styles.tabIcon} source={Translate} /&gt;<br>        &lt;/Pressable&gt;<br>      &lt;/View&gt;<br>    &lt;/View&gt;<br>  );<br>};<br><br>const styles = StyleSheet.create({<br>  container: {<br>    flex: 1,<br>    justifyContent: &#39;flex-end&#39;,<br>    alignItems: &#39;center&#39;,<br>  },<br>  tabBar: {<br>    flexDirection: &#39;row&#39;,<br>    justifyContent: &#39;space-around&#39;,<br>    alignItems: &#39;center&#39;,<br>    paddingBottom: 30,<br>    paddingTop: 20,<br>    backgroundColor: &#39;#82AAE3&#39;,<br>    width: &#39;100%&#39;,<br>    shadowColor: &quot;#000&quot;,<br>    shadowOffset: {<br>      height: -6,<br>      width: 0<br>    },<br>    shadowOpacity: 0.2,<br>    shadowRadius: 10,<br>  },<br>  tabIcon: {<br>    width: 24,<br>    height: 24,<br>  },<br>});<br><br>export default App;</pre><p>As you would have noticed we have not yet created Conversation and Translation components. Let’s go ahead and create these, starting with the Conversation component.</p><p>Create a new folder at the root of project named src and another folder named components inside it.</p><pre>mkdir src &amp;&amp; cd src &amp;&amp; mkdir components &amp;&amp; cd components &amp;&amp; touch index.ts<br>mkdir Conversation &amp;&amp; cd Conversation &amp;&amp; touch index.tsx &amp;&amp; touch styles.ts</pre><p>Now paste the following code inside index.tsx file of Conversation folder.</p><pre>import React, {useCallback, useRef, useState} from &#39;react&#39;;<br>import {<br>  Image,<br>  KeyboardAvoidingView,<br>  Platform,<br>  ScrollView,<br>  Text,<br>  TextInput,<br>  View,<br>} from &#39;react-native&#39;;<br>import {Typing} from &#39;../../../assets&#39;;<br>import {getAnswer} from &#39;../../services/api&#39;;<br>import styles from &#39;./styles&#39;;<br><br>export const Conversation: React.FC = () =&gt; {<br>  const [text, setText] = useState&lt;string&gt;(&#39;&#39;);<br>  const [loading, setLoading] = useState&lt;boolean&gt;(false);<br>  const [conversation, setConversation] = useState&lt;Record&lt;string, string&gt;&gt;({});<br>  const scrollRef = useRef&lt;ScrollView&gt;(null);<br><br>  const handleSubmit = useCallback(async () =&gt; {<br>    setTimeout(() =&gt; scrollRef?.current?.scrollToEnd({animated: true}), 200);<br>    setConversation(prev =&gt; ({<br>      ...prev,<br>      ...{[`sent${Object.keys(prev)?.length}`]: text},<br>    }));<br>    setText(&#39;&#39;);<br>    setLoading(true);<br>    const answer = await getAnswer(text);<br>    setLoading(false);<br>    setConversation(prev =&gt; ({<br>      ...prev,<br>      ...{[`received${Object.keys(prev)?.length}`]: answer},<br>    }));<br>    setTimeout(() =&gt; scrollRef?.current?.scrollToEnd({animated: true}), 200);<br>  }, [text]);<br><br>  return (<br>    &lt;&gt;<br>      &lt;ScrollView<br>        ref={scrollRef}<br>        keyboardDismissMode=&quot;interactive&quot;<br>        showsVerticalScrollIndicator={false}<br>        keyboardShouldPersistTaps={&#39;always&#39;}<br>        contentContainerStyle={styles.scrollView}&gt;<br>        {Object?.keys(conversation)?.map(keyName =&gt; {<br>          if (keyName?.includes(&#39;sent&#39;)) {<br>            return (<br>              &lt;View<br>                key={`sent${keyName}`}<br>                style={[styles.sent, styles.chatBubble]}&gt;<br>                &lt;Text<br>                  selectable<br>                  selectionColor={&#39;purple&#39;}<br>                  style={styles.msgText}&gt;<br>                  {conversation?.[keyName]}<br>                &lt;/Text&gt;<br>              &lt;/View&gt;<br>            );<br>          }<br>          return (<br>            &lt;View key={keyName} style={[styles.received, styles.chatBubble]}&gt;<br>              &lt;Text selectable selectionColor={&#39;yellow&#39;} style={styles.msgText}&gt;<br>                {conversation?.[keyName]?.replace(&#39;\n&#39;, &#39;&#39;)?.replace(&#39;\n&#39;, &#39;&#39;)}<br>              &lt;/Text&gt;<br>            &lt;/View&gt;<br>          );<br>        })}<br>        {loading &amp;&amp; (<br>          &lt;View<br>            key={&#39;typingLoader&#39;}<br>            style={[styles.received, styles.chatBubble]}&gt;<br>            &lt;Image<br>              resizeMode=&quot;contain&quot;<br>              source={Typing}<br>              style={styles.typingLoader}<br>            /&gt;<br>          &lt;/View&gt;<br>        )}<br>      &lt;/ScrollView&gt;<br>      &lt;KeyboardAvoidingView<br>        style={styles.container}<br>        behavior={Platform.OS === &#39;ios&#39; ? &#39;padding&#39; : &#39;height&#39;}&gt;<br>        &lt;TextInput<br>          blurOnSubmit<br>          autoCapitalize=&quot;none&quot;<br>          autoComplete=&quot;off&quot;<br>          autoCorrect={false}<br>          keyboardAppearance={&#39;dark&#39;}<br>          keyboardType={&#39;web-search&#39;}<br>          style={styles.input}<br>          placeholder=&quot;Ask me anything....&quot;<br>          value={text}<br>          onChangeText={setText}<br>          onSubmitEditing={handleSubmit}<br>          placeholderTextColor={&#39;#1116&#39;}<br>        /&gt;<br>      &lt;/KeyboardAvoidingView&gt;<br>    &lt;/&gt;<br>  );<br>};</pre><p>Before we get into the above code, paste the below code in styles.ts file in same folder.</p><pre>import {Dimensions, StyleSheet} from &#39;react-native&#39;;<br><br>export const WIDTH = Dimensions.get(&#39;window&#39;).width;<br><br>export default StyleSheet.create({<br>  container: {<br>    flex: 1,<br>    justifyContent: &#39;flex-end&#39;,<br>    alignItems: &#39;center&#39;,<br>  },<br>  input: {<br>    borderWidth: 2,<br>    borderColor: &#39;#91D8E4&#39;,<br>    width: WIDTH - 40,<br>    height: 60,<br>    borderRadius: 12,<br>    backgroundColor: &#39;#EAFDFC&#39;,<br>    paddingHorizontal: 14,<br>    fontWeight: &#39;700&#39;,<br>    color: &#39;#000&#39;,<br>    marginBottom: 20,<br>    shadowColor: &#39;#82AAE3&#39;,<br>    shadowOffset: {<br>      height: 0,<br>      width: 0,<br>    },<br>    shadowOpacity: 0.4,<br>    shadowRadius: 4,<br>  },<br>  loader: {<br>    position: &#39;absolute&#39;,<br>    width: &#39;100%&#39;,<br>    height: &#39;100%&#39;,<br>    zIndex: 999,<br>    backgroundColor: &#39;#fffc&#39;,<br>    justifyContent: &#39;center&#39;,<br>    alignItems: &#39;center&#39;,<br>  },<br>  scrollView: {<br>    paddingHorizontal: 20,<br>    paddingTop: 60,<br>    paddingBottom: 140,<br>    width: WIDTH,<br>  },<br>  sent: {<br>    backgroundColor: &#39;#04DE71&#39;,<br>    alignSelf: &#39;flex-end&#39;,<br>  },<br>  received: {<br>    backgroundColor: &#39;#2094FA&#39;,<br>    alignSelf: &#39;flex-start&#39;,<br>  },<br>  chatBubble: {<br>    borderRadius: 20,<br>    paddingVertical: 12,<br>    marginBottom: 8,<br>    maxWidth: WIDTH / 2 + 80,<br>    paddingHorizontal: 16,<br>  },<br>  msgText: {<br>    fontWeight: &#39;500&#39;,<br>    color: &#39;#FFF&#39;,<br>    letterSpacing: 0.2,<br>  },<br>  typingLoader: {<br>    width: 80,<br>    height: 20<br>  }<br>});</pre><p>Now let’s discuss what does the code in Conversation component do.</p><p>We have done the following in code:</p><ol><li>We have created three state variable for storing and updating the text , loading state, and conversation . We also created a ref object named scrollRef which we will use to scroll to the bottom of our chat scrollview.</li><li>Then we have declared a handleSubmit method, this method is responsible for setting the user end of text into conversation and then calling the getAnswer method which calls our backend API and returns the answer from API (<em>We will create this method in next step</em>). Then we are appending the answer we get from API into our conversation state var.</li><li>Scrollview is used to render all the data in converation variable. We are mapping over it to render all the texts we sent and got from the api.</li><li>Lastly we have our TextInput wrapped in a KeyBoardAvoidingView so that it doesn’t hide behind device keyboard. This TextInput is responsible for getting input from the user and calling the handleSubmit method when user submits into the TextInput .</li></ol><p>This will not work yet as we have not create the getAnswer method yet.</p><p>To do so, create a new folder name services in src and inside the folder create another folder named api , then a file name index.ts .</p><pre>cd src &amp;&amp; mkdir services &amp;&amp; cd services<br>mkdir api &amp;&amp; cd api<br>touch index.ts</pre><p>For calling API’s in our application we will use axios , so lets install it.</p><pre>yarn add axios<br>   OR<br>npm i axios</pre><p>After the dependency is installed, paste the below code inside index.ts file.</p><pre>import axios from &#39;axios&#39;;<br>const BASE_URL = &#39;http://nextjs-chatgpt-be.vercel.app/api/&#39;;<br><br>export const getAnswer = async (question: string) =&gt; {<br>  try {<br>    const res = await axios.post(<br>      `${BASE_URL}ask-a-question`,<br>      {question},<br>    );<br>    return res?.data?.result;<br>  } catch (e) {<br>    console.error(e);<br>    return &#39;Something went wrong!! ☹️&#39;;<br>  }<br>};<br><br>export const getTranslatedText = async (query: string, language: string) =&gt; {<br>  try {<br>    const res = await axios.post(`${BASE_URL}translate`, {query, language});<br>    return res?.data?.result;<br>  } catch (e) {<br>    console.error(e);<br>    return &#39;Something went wrong!! ☹️&#39;;<br>  }<br>};</pre><p>In the above code we have declared two methods:</p><ul><li>getAnswer for calling the ask-a-question endpoint</li><li>getTranslatedText for calling the translate endpoint (<em>We will use this method in later steps</em>).</li></ul><p>After writing all this code our app will look like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*MvY1Rirr7Qtvco0w8BYAkg.gif" /><figcaption>Chatbot using Chat-GPT (OpenAI)</figcaption></figure><p>Isn’t this cool 😎 , we just created a full chatbot in React Native using minimal code.</p><p>Let’s move onto the final part, creating the text translation app.</p><p>Create a folder named Translation in components folder.</p><pre>cd components &amp;&amp; mkdir Translation &amp;&amp; cd Translation<br>touch index.tsx &amp;&amp; touch styles.ts</pre><p>Add the below code in styles.ts</p><pre>import {StyleSheet} from &#39;react-native&#39;;<br>import {WIDTH} from &#39;../Conversation/styles&#39;;<br><br>export default StyleSheet.create({<br>  container: {<br>    flex: 1,<br>    justifyContent: &#39;flex-start&#39;,<br>    alignItems: &#39;center&#39;,<br>    paddingTop: 80,<br>  },<br>  input: {<br>    borderWidth: 2,<br>    borderColor: &#39;#91D8E4&#39;,<br>    width: WIDTH - 40,<br>    height: 60,<br>    borderRadius: 12,<br>    backgroundColor: &#39;#EAFDFC&#39;,<br>    paddingHorizontal: 14,<br>    fontWeight: &#39;700&#39;,<br>    color: &#39;#000&#39;,<br>    marginBottom: 20,<br>    shadowColor: &#39;#82AAE3&#39;,<br>    shadowOffset: {<br>      height: 0,<br>      width: 0,<br>    },<br>    shadowOpacity: 0.4,<br>    shadowRadius: 4,<br>  },<br>  translatedText: {<br>    fontWeight: &#39;700&#39;,<br>    fontSize: 24,<br>    color: &#39;#000&#39;,<br>    textAlign: &#39;left&#39;,<br>    alignSelf: &#39;flex-start&#39;,<br>    letterSpacing: 0.4,<br>  }<br>});</pre><p>Add the following code in index.tsx</p><pre>import {View, Text, TextInput, Button, ActivityIndicator} from &#39;react-native&#39;;<br>import React, {useCallback, useState} from &#39;react&#39;;<br>import styles from &#39;./styles&#39;;<br>import {getTranslatedText} from &#39;../../services/api&#39;;<br><br>export const Translation: React.FC = () =&gt; {<br>  const [text, setText] = useState&lt;string&gt;(&#39;&#39;);<br>  const [language, setLanguage] = useState&lt;string&gt;(&#39;English&#39;);<br>  const [translatedText, setTranslatedText] = useState&lt;string&gt;(&#39;&#39;);<br>  const [loading, setLoading] = useState&lt;boolean&gt;(false);<br>  const translateText = useCallback(async () =&gt; {<br>    setLoading(true);<br>    const result = await getTranslatedText(text, language);<br>    setTranslatedText(result);<br>    setLoading(false);<br>  }, [text, language]);<br>  return (<br>    &lt;View style={styles.container}&gt;<br>      &lt;TextInput<br>        placeholder=&quot;Enter text to translate&quot;<br>        style={styles.input}<br>        value={text}<br>        onChangeText={setText}<br>        placeholderTextColor={&#39;#1116&#39;}<br>      /&gt;<br>      &lt;TextInput<br>        placeholder=&quot;Enter Language to translate in&quot;<br>        style={styles.input}<br>        value={language}<br>        onChangeText={setLanguage}<br>        placeholderTextColor={&#39;#1116&#39;}<br>      /&gt;<br>      {loading ? (<br>        &lt;ActivityIndicator size={&#39;large&#39;} color={&#39;#2094FA&#39;} /&gt;<br>      ) : (<br>        &lt;Button title={`Translate to ${language}`} onPress={translateText} /&gt;<br>      )}<br>      &lt;Text style={styles.translatedText}&gt;{translatedText}&lt;/Text&gt;<br>    &lt;/View&gt;<br>  );<br>};</pre><p>This is a very simple component which has two TextInputs to handle two state variables text and language . text is the actual string which user wants to translate and language is the desired language which user wants to translate into.</p><p>Then we have a Button which when pressed calls the translateText method. This method calls the getTranslatedText method which fetches the translated text from our API.</p><p>Output of above code will similar to below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*04d9shZSKfY_pvgvhWur9Q.gif" /><figcaption>Translation using Chat-GPT (OpenAI)</figcaption></figure><p>Congratulations 🎉 , you just made a ChatBot and Transaltion App using React Native and Nextjs.</p><h3>Conclusion</h3><p>As i was getting lazy i used ChatGPT to write the conclusion for this article. 😆</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EOb_8Y7Nx2Mc7NTSHlOZJQ.png" /><figcaption>Conclusion of ChatGPT 😆</figcaption></figure><blockquote>ChatGPT is a powerful chatbot technology that has revolutionized how chatbots interact with people. With its natural language processing capabilities, it can understand the user’s intent and provide relevant responses. As AI technologies continue to evolve, so will ChatGPT. In the future, it can be expected to provide even more intelligent interactions, making it an invaluable tool in the chatbot landscape. — From <a href="https://chat.openai.com/chat">ChatGPT</a></blockquote><p>Thank you for reading, Cheers 🥃</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e4cc6c986106" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Build Layout Animations Using React Native Reanimated]]></title>
            <link>https://medium.com/better-programming/layout-animations-with-react-native-reanimated-2-3-0-52da4bdc347e?source=rss-9f74c62cc277------2</link>
            <guid isPermaLink="false">https://medium.com/p/52da4bdc347e</guid>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[react-native]]></category>
            <category><![CDATA[react]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Rupesh Chaudhari]]></dc:creator>
            <pubDate>Sat, 22 Jan 2022 23:08:53 GMT</pubDate>
            <atom:updated>2022-02-03T15:35:15.950Z</atom:updated>
            <content:encoded><![CDATA[<h4>with react-native-reanimated 2.3.0 library</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*cf-SKznUipa5Wx6G" /><figcaption>Photo by <a href="https://unsplash.com/@lautaroandreani?utm_source=medium&amp;utm_medium=referral">Lautaro Andreani</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>In this article, we will see how we can implement Layout Animations in React Native using the <a href="https://docs.swmansion.com/react-native-reanimated/">react-native-reanimated</a> library.</p><p>React Native Reanimated is an animation library that runs the animations that we declare on the Javascript thread directly onto the Native / UI thread.</p><p>In React Native the components render or appear instantly on the UI which is not as pleasing to the User as compared to something which slowly fades in or with some other animation. Now animating your components while they enter or exit in the UI is very easy thanks to the new version <a href="https://docs.swmansion.com/react-native-reanimated/docs/">2.3.0</a> of reanimated. They have introduced something called <a href="https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/layout_animations">Layout Animation</a> which does exactly the same as it sounds. Using this we can now specify which type of animation should happen when a component Mounts / Enters or Demounts / Exits the Screen. There are a lot of predefined animations we can use for <a href="https://docs.swmansion.com/react-native-reanimated/docs/api/LayoutAnimations/entryAnimations#predefined-animations">Entering</a> and <a href="https://docs.swmansion.com/react-native-reanimated/docs/api/LayoutAnimations/exitAnimations#predefined-animations">Exiting</a> animations.</p><p>We will see how we can implement Layout Animations in our React Native application by creating two animations:</p><ul><li>Animated Flip Counter</li><li>Animated Todo List</li></ul><p>Below are the prerequisites you need before starting to code:</p><ul><li>React-Native Version =&gt; 0.62+</li><li>React-Native-Reanimated =&gt; 2.3.0 or above (As Layout Animations are introduced recently with 2.3.0)</li></ul><p>We will start by creating a new react-native project, to create a new react-native project type the below command into your terminal.</p><p><strong>You can check out the code in this </strong><a href="https://github.com/hrupesh/LayoutAnimationsDemo"><strong>repository</strong></a></p><blockquote>As of the time I am writing this, the latest react-native version is 0.67</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/302/1*uH1dkq0yBZdq9_9gm0MDLg.png" /></figure><p>Then change your current working directory into the App we just created</p><pre>cd &lt;App-Name&gt;</pre><p>Type the below into terminal to install pods and run the iOS project:</p><pre>cd ios<br>pod install<br>cd ..<br>yarn ios </pre><pre>``` <br>Use Yarn if you have it installed and if <br>not run [ npm run ios ]</pre><pre>```</pre><p>Run the android project using the below command:</p><pre>yarn android</pre><p>Now that our iOS and Android apps are up and running now we will install react-native-reanimated. As this library uses <a href="https://github.com/react-native-community/discussions-and-proposals/issues/40">TurboModules</a> we need to do some extra steps to make it work.</p><blockquote>Turbo Modules offer a new architecture for initializing native modules. At the runtime of the application, the TurboModules open a bridge that will later allow the js code to initialize any module at its first use.</blockquote><p>The setup in iOS is pretty straightforward now as they are not using Turbomodules anymore to register their module.</p><p>Run the below command in your terminal window to install reanimated package.</p><blockquote>As of the time I am writing this the latest reanimated version is 2.3.1</blockquote><pre>yarn add react-native-reanimated</pre><pre>```<br>Once installed cd into ios folder and install pods for RNReanimated<br>```<br>cd ios<br>pod install</pre><pre>```<br>Now we just need to build the iOS app again<br>To do that either build from XCode or using below command<br>```<br>yarn ios</pre><p>That’s it we have installed reanimated into our iOS project.</p><p>For android, there are some extra steps we need to take:</p><p>First, we need to enable Hermes; to do that go to app-level build.gradle file and toggle the enableHermes flag to true.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*R_1klMUGa3SbM851ljTZ_g.png" /></figure><p>Then we need to return the Reanimated JSI Module in getJSIModulePackage method, to do that add the below to your MainApplication.java</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*nIf8XscEG_zXBIK6MSoZBw.png" /></figure><p>And now we need to rebuild our Android app for the native changes to reflect</p><pre>```<br>Either run the android app from android studio or type the command below </pre><pre>```<br>yarn android</pre><p>Now that reanimated is correctly installed into our project, we can utilize it to create awesome animations.</p><p>We will start by creating a simple counter which flips every time as its value is changed.</p><p>To utilize the Layout Animations we have these two props which take predefined or <a href="https://docs.swmansion.com/react-native-reanimated/docs/api/LayoutAnimations/customAnimations"><em>Custom created</em></a> animations as inputs:</p><ul><li>entering : The animation that should take place when a component is Mounted onto the screen.</li><li>exiting : The animation that should take place when a component is demounted from the screen.</li></ul><p>In this example, we will create a counter with two buttons [add and subtract] and they do exactly the same as they sound and count is wrapped inside an Animated View which flips every time as the value changes.</p><p>This is possible because of the key property in React , so we just need to assign the count value which is a React state to the key prop and rest will be handled by React and Reanimated . We’ll look at how this actually works when we write the code for it.</p><p>Paste the below code to your App.js file</p><pre>import {<br>  Text,<br>  SafeAreaView,<br>  Button,<br>  View,<br>  StyleSheet,<br>  TouchableOpacity,<br>} from &quot;react-native&quot;;<br>import React, { useState } from &quot;react&quot;;<br>import Animated, {<br>  FlipInXUp,<br>  FlipOutXDown,<br>  SlideInDown,<br>  SlideOutUp,<br>} from &quot;react-native-reanimated&quot;;</pre><pre>const App = () =&gt; {<br>  const [count, setCount] = useState(0);<br>  return (<br>    &lt;SafeAreaView style={styles.container}&gt;<br>      &lt;View style={styles.counterContainer}&gt;<br>        &lt;Animated.View<br>          key={count}<br>          style={styles.counterFlip}<br>          entering={FlipInXUp.springify()}<br>          exiting={FlipOutXDown.springify()}<br>        &gt;<br>          &lt;Text style={styles.counterText}&gt;{count}&lt;/Text&gt;<br>        &lt;/Animated.View&gt;<br>        &lt;TouchableOpacity<br>          style={[styles.button, styles.subBtn]}<br>          onPress={() =&gt; setCount(count - 1)}<br>        &gt;<br>          &lt;Text style={styles.btnText}&gt;{&quot;-&quot;}&lt;/Text&gt;<br>        &lt;/TouchableOpacity&gt;<br>        &lt;TouchableOpacity<br>          style={[styles.button, styles.addBtn]}<br>          onPress={() =&gt; setCount(count + 1)}<br>        &gt;<br>          &lt;Text style={styles.btnText}&gt;{&quot;+&quot;}&lt;/Text&gt;<br>        &lt;/TouchableOpacity&gt;<br>      &lt;/View&gt;<br>    &lt;/SafeAreaView&gt;<br>  );<br>};</pre><pre>export default App;</pre><pre>const styles = StyleSheet.create({<br>  container: {<br>    flex: 1,<br>    justifyContent: &quot;center&quot;,<br>    alignItems: &quot;center&quot;,<br>    backgroundColor: &quot;#000&quot;,<br>  },<br>  counterContainer: {<br>    height: 100,<br>    backgroundColor: &quot;#EEE&quot;,<br>    width: &quot;90%&quot;,<br>    justifyContent: &quot;center&quot;,<br>    alignItems: &quot;center&quot;,<br>    borderRadius: 100,<br>    marginBottom: 8,<br>    overflow: &quot;hidden&quot;,<br>    paddingVertical: 8,<br>  },<br>  counterText: {<br>    color: &quot;#FFF&quot;,<br>    fontWeight: &quot;bold&quot;,<br>    fontSize: 54,<br>    letterSpacing: 2,<br>    lineHeight: 64,<br>  },<br>  button: {<br>    position: &quot;absolute&quot;,<br>    backgroundColor: &quot;#111&quot;,<br>    borderRadius: 40,<br>    height: 80,<br>    width: 80,<br>    justifyContent: &quot;center&quot;,<br>    alignItems: &quot;center&quot;,<br>  },<br>  subBtn: { left: 6 },<br>  addBtn: { right: 6 },<br>  btnText: {<br>    color: &quot;#FFF&quot;,<br>    fontWeight: &quot;400&quot;,<br>    fontSize: 54,<br>    lineHeight: 56,<br>  },<br>  counterFlip: {<br>    backgroundColor: &quot;#000&quot;,<br>    paddingHorizontal: 24,<br>    justifyContent: &quot;center&quot;,<br>    alignItems: &quot;center&quot;,<br>    height: 90,<br>    borderRadius: 6,<br>  },<br>});</pre><p>Once you have pasted the code you will see we have Animated.View a component that has Text a component that displays the count value. The major code is here:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vqcGledN8urXx8MLZomW4A.png" /></figure><p>We have used count as key for our View , so what happens is when we increment or decrement the count value the key for the component is also changed and that results in demounting of the component and mounts another component with the new key value.</p><p>We have used FlipInXUp as entering animation and FlipOutXDown as exiting animation and also we have used springify method on them so that we get a springy animation for our counter view.</p><p>Our final output will be:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/476/1*531pWbMqlUqmxVCqI1heTg.gif" /></figure><p>Now that the counter is complete we can move onto the Animated Todo List component.</p><p>This will be a pretty straightforward ToDo List with Delete and Add Todo functions only. If you want you can add more features according to you.</p><p>The UI that we will design will look like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/400/1*6GOV1mOzO9AIuHJXj0mqNQ.png" /></figure><p>Let’s start by creating a Component for the Todo’s, create a Todos.tsx or Todos.js file according to your accessibility. And also remove all the code (move the counter component to separate file) that we wrote for Counter in App.js and paste the following code inside it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*I0MVW7ImAi-1MmfqgcOsGw.png" /></figure><blockquote>We have not yet created Todos component</blockquote><p>Paste the following code into your Todos.tsx file</p><pre>import React, { useState } from &quot;react&quot;;<br>import { ScrollView, StyleSheet, Text, TextInput, View } from &quot;react-native&quot;;<br>import Animated, {<br>  Easing,<br>  FadeInDown,<br>  Layout,<br>  SlideOutLeft,<br>} from &quot;react-native-reanimated&quot;;</pre><pre>type Todo = {<br>  id: number,<br>  text: string,<br>};</pre><pre>export const Todos: React.FC = () =&gt; {<br>  const [todos, setTodos] = useState&lt;Todo[]&gt;([<br>    { id: 1, text: &quot;Initial Todo 1&quot; },<br>    { id: 2, text: &quot;Initial Todo 2&quot; },<br>  ]);<br>  const [text, setText] = useState &lt; string &gt; &quot;&quot;;</pre><pre>  const removeTodo = (id: number) =&gt; {<br>    setTodos(todos.filter((todo) =&gt; todo.id !== id));<br>  };</pre><pre>  const addTodo = () =&gt; {<br>    if (text?.trim()) {<br>      setTodos([...todos, { id: todos?.length + 1, text }]);<br>      setText(&quot;&quot;);<br>    }<br>  };</pre><pre>  return (<br>    &lt;ScrollView<br>      contentContainerStyle={styles.container}<br>      keyboardDismissMode=&quot;on-drag&quot;<br>      keyboardShouldPersistTaps={&quot;always&quot;}<br>    &gt;<br>      &lt;Text style={styles.header}&gt;Your To Do&#39;s&lt;/Text&gt;<br>      &lt;View style={styles.separator} /&gt;<br>      &lt;TextInput<br>        style={styles.todoInput}<br>        blurOnSubmit={false}<br>        placeholder={&quot;Add ToDo&quot;}<br>        placeholderTextColor={&quot;#444&quot;}<br>        value={text}<br>        onChangeText={setText}<br>        onSubmitEditing={addTodo}<br>      /&gt;<br>      &lt;View style={styles.separator} /&gt;<br>      {todos.map((todo, index) =&gt; (<br>        &lt;Animated.View<br>          key={todo.id}<br>          style={styles.todo}<br>          entering={FadeInDown}<br>          layout={Layout.easing(Easing.bounce).delay(index * 100)}<br>          exiting={SlideOutLeft}<br>        &gt;<br>          &lt;Text style={styles.todoText}&gt;{todo.text}&lt;/Text&gt;<br>          &lt;Text onPress={() =&gt; removeTodo(todo?.id)}&gt;{&quot;✅&quot;}&lt;/Text&gt;<br>        &lt;/Animated.View&gt;<br>      ))}<br>    &lt;/ScrollView&gt;<br>  );<br>};</pre><pre>const styles = StyleSheet.create({<br>  container: {<br>    paddingVertical: 14,<br>    paddingHorizontal: 18,<br>  },<br>  header: {<br>    fontSize: 32,<br>    fontWeight: &quot;800&quot;,<br>    color: &quot;#fff&quot;,<br>    letterSpacing: 1.2,<br>  },<br>  separator: {<br>    height: StyleSheet.hairlineWidth,<br>    backgroundColor: &quot;#444&quot;,<br>    marginTop: 10,<br>  },<br>  todo: {<br>    paddingVertical: 10,<br>    paddingHorizontal: 18,<br>    borderWidth: StyleSheet.hairlineWidth,<br>    borderColor: &quot;#444&quot;,<br>    borderRadius: 4,<br>    marginTop: 12,<br>    flexDirection: &quot;row&quot;,<br>    justifyContent: &quot;space-between&quot;,<br>    alignItems: &quot;center&quot;,<br>  },<br>  todoText: {<br>    fontSize: 18,<br>    fontWeight: &quot;400&quot;,<br>    color: &quot;#ccc&quot;,<br>  },<br>  todoInput: {<br>    paddingVertical: 10,<br>    paddingHorizontal: 18,<br>    borderWidth: StyleSheet.hairlineWidth,<br>    borderColor: &quot;#bbb&quot;,<br>    backgroundColor: &quot;#111b&quot;,<br>    borderRadius: 4,<br>    marginTop: 10,<br>    color: &quot;#fff&quot;,<br>    fontSize: 20,<br>    fontWeight: &quot;600&quot;,<br>    letterSpacing: 1.4,<br>  },<br>});</pre><p>Now let’s see what have we actually done here:</p><ul><li>We have wrapped the component with a ScrollView to list all the Todo’s here</li><li>Then we have TextInput which modifies our state value text which is used to add a new Todo, and when a user submits from that input then we add that Todo object to our todos array.</li><li>We have mapped over todos array to list the todos in our ScrollView and then we are Rendering the Todo in an Animated.View component.</li><li>Animated.View component is the one where all the magic happens, you must have noticed we have introduced a new prop named layout this prop is responsible to trigger any animation if there is any change in layout, like in our case if any Todo is deleted then all the remaining Todo’s, specifically the ones below it will change their layout, and then we are animating it with Easing bounce function and we have delay for each item of index * 100 this is to achieve the ripple effect so that each component is animated 100ms after the other.</li></ul><blockquote>NOTE: Don’t use the delay of index * 100 in large lists as there, it may result into many seconds of delay</blockquote><ul><li>Also, we have “ ✅ “ text, which upon pressed deletes the specified Todo object</li></ul><p>And that’s it we have created an Animated Todo List without any other animation-specific code.</p><p>The Output will be something like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/476/1*-DiwUQvqOv9fFwjt36MwZA.gif" /></figure><p>So now we have a working understanding of how Layout Animations in React Native Reanimated works, and how can we easily implement them without writing much code. This is a powerful feature that will change the way we animate in React Native.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=52da4bdc347e" width="1" height="1" alt=""><hr><p><a href="https://medium.com/better-programming/layout-animations-with-react-native-reanimated-2-3-0-52da4bdc347e">Build Layout Animations Using React Native Reanimated</a> was originally published in <a href="https://betterprogramming.pub">Better Programming</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Bridging for iOS and Android in react-native]]></title>
            <link>https://medium.com/simform-engineering/bridging-for-ios-and-android-in-react-native-64b8ce60a8c2?source=rss-9f74c62cc277------2</link>
            <guid isPermaLink="false">https://medium.com/p/64b8ce60a8c2</guid>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[react-native]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[react-native-bridge]]></category>
            <category><![CDATA[android]]></category>
            <dc:creator><![CDATA[Rupesh Chaudhari]]></dc:creator>
            <pubDate>Mon, 21 Jun 2021 11:49:45 GMT</pubDate>
            <atom:updated>2021-06-21T11:49:45.700Z</atom:updated>
            <content:encoded><![CDATA[<h3>Native Bridging for iOS and Android in React Native</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DlpTvHL00QDoyvo2DJkPTw.png" /></figure><p>For those who are not familiar with React Native, it is a cross-platform development framework allowing you to create native apps for iOS and Android. Using React Native, you can maintain two platforms using the same codebase, allowing faster development, iteration, and knowledge-sharing.</p><p>With this framework, we have two sides, JavaScript and Native. Between the two is a bridge, allowing bidirectional and asynchronous communication. This is the power of React Native, on top of a multitude of other benefits.</p><p>In 2020, we’ve seen the likes of Facebook, Bloomberg, and Shopify using React Native to develop their mobile applications, amongst others in the Fortune 500. With over 11 million JavaScript developers and more companies switching to React Native, releasing your technology for React Native could bring more growth.</p><h3><strong>What is React Native bridging?</strong></h3><p>React Native Bridging is a concept that was developed by the React team to help the mobile app developers build their own custom modules, if not provided by the default Components given by React.</p><p>React Native provides developers with a variety of modules that developers can use to create functionality in the application. For example, React Native provides its own “Net Info” module to check for Internet Connectivity in applications. However, sometimes an app needs access to a platform API for which React doesn’t have a module yet. Or maybe the app needs a custom functionality that cannot be achieved using default React Native modules.</p><p>Hence, React Native allows us to write Native Code (Android and iOS) and communicate between native code and React Native JavaScript code to achieve custom-developed functionality.</p><p>According to the documentation, React Native team believes that if React Native doesn’t support a native feature that you need, you should be able to build it yourself by using Bridging.</p><p>There are two ways to bridge native code to JavaScript:</p><ol><li>Native Modules</li><li>Native UI Components</li></ol><p>But in this article, we are only going to discuss about native modules.</p><p>Native Modules can be used to access native iOS and Android features.</p><p>We will see how to create Native modules for both iOS and android separately by creating a demo application.</p><p>An overview of steps to create a native android module:</p><ol><li>Create a java class file that will contain all the native logic you want to execute and variables and callbacks you want to export to JavaScript.</li><li>Create a java package for the java class you just created in the previous step and register the module in this package.</li><li>Now the last step is to make the package available in the JavaScript code. To do so add your package in the return array of <strong><em>getPackages()</em></strong> method in the <strong><em>MainApplication.java</em></strong> file.</li><li>That’s it you have now exported your native module to javascript, to access it we will use <strong><em>NativeModules</em></strong> from React Native.</li></ol><p>We’ll understand this process in more detail by practically implementing a native module.</p><p>So now let’s directly jump into some code and practical implementation.</p><p>For this example, we will be creating a native module in android that alters with sound to reproduce a funny one. For example, we can make a person sound like an alien or a kid.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/333/1*HgIyy90zhZUdgr1uupBqaQ.gif" /><figcaption>Let’s dive right in….</figcaption></figure><ul><li>Let’s start by first creating a new React Native project:</li></ul><p>Type the below command into your terminal window to create a new React Native Project from scratch</p><pre>react-native init VoiceChanger</pre><p>Here I have named the project “<strong><em>VoiceChanger</em></strong>” you are free to name it whatever you like.</p><ul><li>Change your current working directory to the new project we just created</li></ul><p>Type below command in your terminal window</p><pre>cd VoiceChanger</pre><p>For the sake of simplicity of this article, I will use a static mp3 file that we are going to modify in our native code, but you can also record the audio through the phone’s microphone and alter that.</p><p>Our UI is going to be straightforward and looking something like this on iOS and Android devices:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/838/1*zbgZ_cMT0uvUbIjsbVFdSw.png" /><figcaption>UI on iOS and Android</figcaption></figure><p>When the user taps any effect button then that type of voice will be played.</p><p>For example, if a user taps on the alien icon, then an alien-type voice will be played, and likewise for the child icon.</p><p>We will also cover how we can change the speed of audio, that is, we will be playing audio at 2x speed and 0.5x speed.</p><ul><li>Modify your App.js to look something like this:</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/bb882f10013bef3aa7ac97a1f187d1a4/href">https://medium.com/media/bb882f10013bef3aa7ac97a1f187d1a4/href</a></iframe><blockquote>We have commented ,</blockquote><blockquote>const { VoiceChangingModule } = NativeModules;</blockquote><blockquote>because we have not created a native module yet. Once we have created NativeModule named “<strong><em>VoiceChangingModule</em></strong>” we will uncomment that line</blockquote><p>Now we will be creating a Native Android Module, for that follow the below steps</p><ul><li>Open Android studio in your project’s android directory</li><li>If you have opened the project correctly you will see something like this in your project files on the left side in android studio.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/257/1*8IU3yrdhEwT8KIAKv5SjUA.png" /></figure><ul><li>Navigate to the folder containing MainApplication.java</li><li>Right-click the folder name &gt; Go to New Option &gt; Select Java Class</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/525/1*0yIojBHwpcqC-SE68brs7Q.png" /></figure><ul><li>Enter Java Class File Name</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/604/1*_uaXr5oN8yHYAhzKDLZkEA.png" /></figure><p>I have named the file as VoiceChangingModule, this is a module file that will contain all of our native android logic.</p><ul><li>Paste this code in your VoiceChangingModule Class:</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d0ef48065011eae7396543a103abe07b/href">https://medium.com/media/d0ef48065011eae7396543a103abe07b/href</a></iframe><blockquote>As you can notice we have a getName() method which returns a String, this is a name with which we can access our module in JavaScript code</blockquote><ul><li>Now we need to wrap our module in a package that will be exported to javascript for that we will create a new java class file</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/488/1*h7aoJBs2NRXB7Y8FOKxdNQ.png" /></figure><p>I am going to name this File “<strong><em>VoiceChangingPackage</em></strong>”</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/599/1*of5RMkeuD60iJQEEWKMwPA.png" /></figure><ul><li>Edit the package <strong><em>VoiceChangingPackage</em></strong> file to create and return the module we just created</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/90b3398779f6a80612a43ce0eca84d05/href">https://medium.com/media/90b3398779f6a80612a43ce0eca84d05/href</a></iframe><ul><li>Add the package in PackageList of <strong><em>getPackages()</em></strong> method of MainApplication.java</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3c68950ec12c17f8ace465ca90db46c2/href">https://medium.com/media/3c68950ec12c17f8ace465ca90db46c2/href</a></iframe><p>Yayyy!! That’s it we have successfully exported our Native Android module to Javascript.</p><p>Now let’s access the module from javascript, but before doing so let’s just add 4 methods to our <strong><em>VoiceChangingModule.java</em></strong> file</p><ul><li>changeVoiceToAlien</li><li>changeVoiceToChild</li><li>speedUpVoice</li><li>slowDownVoice</li></ul><p>After adding these methods our final <strong><em>VoiceChangingModule.java </em></strong>will look something like this.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/21fb72479c1a1c887a2542c838562260/href">https://medium.com/media/21fb72479c1a1c887a2542c838562260/href</a></iframe><p>As you can see, we have just tweaked a little bit of Pitch and speed of voice playback to achieve these kinds of voice effects.</p><p>Now let’s access these methods in javascript.</p><ul><li>Get the Module in Javascript from NativeModules provided by react-native</li></ul><pre>const { VoiceChangingModule } = NativeModules;</pre><p>Uncomment the above line in our <strong><em>App.js</em></strong> which we commented earlier.</p><ul><li>Now add these functions in <strong><em>App.js</em></strong> which will be called on each voice effect icon’s press</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5c27374c3863262936ce95d9822a1e50/href">https://medium.com/media/5c27374c3863262936ce95d9822a1e50/href</a></iframe><blockquote>Note: As we have only created this native module in android only so we can access this module in android platform only.</blockquote><p>That’s it we have made a native android module and utilized it in javascript.</p><p>Now let’s run this example, in your command line type:</p><pre>npx react-native run-android</pre><blockquote>Note: If you have done changes in native side and those are not reflecting you need to rebuild the project because you have changed native code.</blockquote><p>Now that we have created a native android module, let’s take a look at how we can create a native iOS module?</p><p>An Overview of Steps to create a native iOS module:</p><ol><li>Create a swift class which will contain all the native logic and variable and callbacks you want to export to the javascript</li><li>Create a bridging header file that will help communicate between swift and objective C, now import <strong><em>RCTBridgeModule</em></strong> in this file while providing an interface to register the bridge module.</li><li>Create an objective C file and export module we created in the first step by using <strong><em>RCT_EXTERN_METHOD</em></strong></li><li>Now we can access the native module we just created in our javascript code</li></ol><p>Like in the previous section of creating a native android module we’ll now similarly understand this process by creating a native iOS module.</p><p>So, we will now create an iOS native module for the same functionality that we achieved in android, i.e., adding voice effects to a sound.</p><ul><li>We do not need to create a new project as we are going to add a native module in iOS in the same project that we created above in the native android module part.</li></ul><blockquote>If you have not followed (Native Android Module) then please refer above and set up a bare react native project</blockquote><ul><li>Open the project folder then navigate to the iOS folder and find VoiceChanger.xcodeworkspace and open it</li></ul><pre>VoiceChanger -&gt; iOS -&gt; VoiceChanger.xcodeworkspace</pre><ul><li>After opening the XCode project you will see something like this</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vJaiaP8WpDoC6m5dz4Q_EQ.png" /></figure><blockquote>NOTE: Appearance may vary based upon the version of XCode you are using.</blockquote><ul><li>The next step is to create a new swift file in the project, which will contain our native swift logic</li></ul><pre>File -&gt; New -&gt; File</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/863/1*mjgfNBvnz4qUbDIe_rqlqw.png" /></figure><ul><li>After clicking the new file option a popup will appear asking us to select which type of file we want to create. As we want to create a swift file, select swift and click next</li></ul><pre>Swift -&gt; Next</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/904/1*ygU94VenrXaXFOZVdCBLFQ.png" /></figure><ul><li>After clicking next, we will be asked for the name of the file we want to create, enter the name of the swift file, in my case, it is “VoiceChangerModule”. And select where do you want to create this file, select your projects folder, typically this folder contains all the native iOS logic and also AppDelegate file.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/720/1*kFsQCFBDxwAZZW-9CWipCg.png" /></figure><ul><li>Click create, you will be prompted to if you want to create a bridging header file. Select Yes.</li></ul><blockquote>Bridging header file basically acts as a communicator between swift code and objective C code.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/736/1*CgG1jUptaVcq3aF7wCj-rQ.png" /></figure><ul><li>If you have clicked on creating a bridging header, you will have a “<strong><em>VoiceChanger-Bridging-Header.h”</em></strong> file. Paste the following code into that file.</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a57aa5be6c3d3114e2e0d46165331f76/href">https://medium.com/media/a57aa5be6c3d3114e2e0d46165331f76/href</a></iframe><blockquote>RCTBridgeModule provides us an interface to register our bridge module</blockquote><ul><li>Download any mp3 or any audio file and place it in our project folder. Here I have named my sound file “<strong><em>sound_sample.mp3</em></strong>” so it would be better if you follow that.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/321/1*XNlLMYbvX36uvzIf7mXKAw.png" /></figure><ul><li>Edit your “<strong><em>VoiceChangingModule.swift”</em></strong> file to write voice changing logic in it</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2bc3c7b743e39236c1505619184271ab/href">https://medium.com/media/2bc3c7b743e39236c1505619184271ab/href</a></iframe><ul><li>As you can see, we have four functions:</li></ul><p>1. changeVoiceToAlien()</p><p>2. changeVoiceToChild()</p><p>3. speedUpVoice()</p><p>4. slowDownVoice()</p><ul><li>These four functions use a helper function <strong><em>playModifiedSound()</em></strong> which takes two parameters:</li></ul><ol><li><strong><em>value</em></strong> — Takes Float value — Describes how much value to be used, in this case, rate or pitch</li><li><strong><em>rateOrPitch</em></strong> — Takes String value — is used to just know whether to change rate of Audio or Pitch</li></ol><p>We can also see we have <strong><em>requiresMainQueueSetup()</em></strong> function which returns true. This function is used to tell native code that we want to run our module on <strong><em>mainQueue</em></strong> Thread.</p><ul><li>Now that we have written our native logic in our functions, it is time to export them to javascript. For that, we will create a new Objective-C file.</li></ul><pre>Go To File -&gt; New -&gt; File -&gt; Select Objective-C type of file -&gt; Enter File Name -&gt; Click Next</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/863/1*mjgfNBvnz4qUbDIe_rqlqw.png" /><figcaption>Create New File</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/734/1*ergdFMsuS8alMcfH4q500w.png" /><figcaption>Select Objective-C and then Next</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/742/1*ZlnJ4CTk-LOTledoTXzRVA.png" /><figcaption>Enter File Name and then Next</figcaption></figure><ul><li>Now that we have created an Objective-C file, let’s edit it to export our module and its functions to javascript</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/928fe903ee6421c656403e8971e3f89c/href">https://medium.com/media/928fe903ee6421c656403e8971e3f89c/href</a></iframe><p>That’s it! We have now created and exported a native iOS module to javascript. Let’s see how will we access it in javascript.</p><p>But before that, we need to enable audio service for our iOS app.</p><p>For that Go To:</p><pre>Add Capability Button in Signing and Capabilities tab in project details -&gt; select Background Modes -&gt; then check these two options</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1010/1*Q6BhJpyu_zD1lBR8J6JPzA.png" /><figcaption>Enable Audio and Background Processing</figcaption></figure><blockquote>Do not forget to build the project from XCode after doing changes.</blockquote><ul><li>After you have built the application from XCode go to your App.js file and edit it to call the native module methods that we just created on each button press.</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/99215d0239ab9d64e0ae458c70030710/href">https://medium.com/media/99215d0239ab9d64e0ae458c70030710/href</a></iframe><p>Notice that we are calling differently for each platform with just one change, i.e., in android, we call the native module method with a parameter and in iOS without any parameter.</p><p>Yay!!, That’s it, we have made Native Android and iOS modules in React Native to use native code and achieve similar behavior in both platforms.</p><p>Thus, this is how we can create a bridge between React Native JavaScript code and native android/iOS Code.</p><p>If you want to skip the code and want to see the code in action, then feel free to download the demo of this project from below repository</p><p><a href="https://github.com/mobile-simformsolutions/react-native-bridging">https://github.com/mobile-simformsolutions/react-native-bridging</a></p><blockquote><strong>Conclusion</strong>: As we saw react-native bridging is a quite powerful feature for accessing native features that are not available in react native environment and it provides developers an option to develop their features natively if they want.</blockquote><p>Hope you found this article helpful, if so then please don’t forget to give some claps 👏🏻 and share it with your other fellow developer friends.</p><p>Thank You!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=64b8ce60a8c2" width="1" height="1" alt=""><hr><p><a href="https://medium.com/simform-engineering/bridging-for-ios-and-android-in-react-native-64b8ce60a8c2">Bridging for iOS and Android in react-native</a> was originally published in <a href="https://medium.com/simform-engineering">Simform Engineering</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>