<?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: Arogya Kharel</title>
    <description>The latest articles on DEV Community by Arogya Kharel (@gurkhaman).</description>
    <link>https://dev.to/gurkhaman</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%2F792807%2Fb3a1cf83-7f52-4cec-ac78-910745e44120.jpg</url>
      <title>DEV Community: Arogya Kharel</title>
      <link>https://dev.to/gurkhaman</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gurkhaman"/>
    <language>en</language>
    <item>
      <title>Using shell script to automate API calls</title>
      <dc:creator>Arogya Kharel</dc:creator>
      <pubDate>Thu, 20 Jan 2022 03:21:36 +0000</pubDate>
      <link>https://dev.to/gurkhaman/using-shell-script-to-automate-api-calls-d3c</link>
      <guid>https://dev.to/gurkhaman/using-shell-script-to-automate-api-calls-d3c</guid>
      <description>&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Quick Summary&lt;/li&gt;
&lt;li&gt;Before Starting&lt;/li&gt;
&lt;li&gt;Objective&lt;/li&gt;
&lt;li&gt;Why Shell Scripts?&lt;/li&gt;
&lt;li&gt;What to automate?&lt;/li&gt;
&lt;li&gt;
Copy-Paste to a &lt;code&gt;.sh&lt;/code&gt; File

&lt;ul&gt;
&lt;li&gt;Going further&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Quick Summary
&lt;/h2&gt;

&lt;p&gt;Here are the steps we will be taking:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Changing API requests to &lt;code&gt;cURL&lt;/code&gt; commands.&lt;/li&gt;
&lt;li&gt;Pasting &lt;code&gt;cURL&lt;/code&gt; commands to a &lt;code&gt;.sh&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;Profit.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Before Starting
&lt;/h2&gt;

&lt;p&gt;I am assuming you have some familiarity with the following concepts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API, API requests and responses&lt;/li&gt;
&lt;li&gt;Postman or a similar API testing tool&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cURL&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It shouldn't be difficult to follow either way. Let's go. &lt;/p&gt;

&lt;h2&gt;
  
  
  Objective
&lt;/h2&gt;

&lt;p&gt;Why automate API calls at all? Well, testing of course and benchmarking if you are into that. It's a pretty good idea to see if your API server responds properly to continuous requests, and find out if the API dependencies are in the right order. &lt;/p&gt;

&lt;p&gt;Most students like myself tend to do a few API calls here and there and call it a day. To be honest, most assignments or personal projects don't really need much testing since they are generally tiny in scope. But maybe you will need to find the average server response time for a million requests, or make some graphs on server reliability. Automation will be extremely valuable then.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Shell Scripts?
&lt;/h2&gt;

&lt;p&gt;Because they are everywhere. Bash for example is like the glue holding Linux systems together. Most icon you click, startup, configuration and so many more elements of the Linux system is handled through shell scripts.  &lt;/p&gt;

&lt;p&gt;There is also Python. It is definitely easier to work with and has extensive IDE and library support (there is also this whole thing with floating points and what not). However, there is a bit of an overhead and python is generally slower than bash. But if one is to consider developer efficiency, python is miles ahead (imo). But we use bash here because the actual automation is very simple (it's just &lt;code&gt;cURL&lt;/code&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  What to Automate?
&lt;/h2&gt;

&lt;p&gt;I have a few API request formats prepared. Here is one using the &lt;code&gt;GET&lt;/code&gt; method:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fakbyxv1q1pm35cizbfju.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fakbyxv1q1pm35cizbfju.png" alt="Query Approved CC" width="377" height="431"&gt;&lt;/a&gt;&lt;/p&gt;
This one sends the server some data in json format. The server will then use some CLI command to complete the operation.



&lt;p&gt;and here is one that sends a data through parameter instead of the body:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5dlu20769umnpdfflghj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5dlu20769umnpdfflghj.png" alt="Install CC" width="378" height="252"&gt;&lt;/a&gt;&lt;/p&gt;
Here the &lt;b&gt;:package_name&lt;/b&gt; at the end of the URL is the parameter. The server is accepting the name of a tarball that needs to be installed. The HTTP method to be used is &lt;b&gt;POST&lt;/b&gt;.



&lt;p&gt;The next step is to transform these calls into &lt;code&gt;cURL&lt;/code&gt; commands. Tools like Postman generate code snippets that you can use (which is what I did, but it is easy to figure out the &lt;code&gt;cURL&lt;/code&gt; format by reading their documentation). I will assume you have a few ones prepared as well. The ones from earlier are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="nt"&gt;--request&lt;/span&gt; GET &lt;span class="s1"&gt;'127.0.0.1:8080/fabric/lifecycle/approve'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--data-raw&lt;/span&gt; &lt;span class="s1"&gt;'{
  "cc_name": "basic",
  "channel_name": "mychannel"
}'&lt;/span&gt;


curl &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="nt"&gt;--request&lt;/span&gt; POST &lt;span class="s1"&gt;'127.0.0.1:8080/fabric/lifecycle/install/basic.tar.gz'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Copy-Paste to a &lt;code&gt;.sh&lt;/code&gt; File &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Now all that is left is to paste all your &lt;code&gt;cURL&lt;/code&gt; commands to a file. Add a &lt;code&gt;#!/bin/bash&lt;/code&gt; at the very top of your file and that's it! Remember to put them in the correct order.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

curl &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="nt"&gt;--request&lt;/span&gt; GET &lt;span class="s1"&gt;'127.0.0.1:8080/fabric/lifecycle/approve'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--data-raw&lt;/span&gt; &lt;span class="s1"&gt;'{
  "cc_name": "basic",
  "channel_name": "mychannel"
}'&lt;/span&gt;

curl &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="nt"&gt;--request&lt;/span&gt; POST &lt;span class="s1"&gt;'127.0.0.1:8080/fabric/lifecycle/install/basic.tar.gz'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You might also need to give execution access to the script with &lt;code&gt;chmod +x script.sh&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Going Further
&lt;/h3&gt;

&lt;p&gt;Copy-pasting while simple can result in a file full of URLs and a script with extremely limited functionality. &lt;/p&gt;

&lt;h4&gt;
  
  
  1. Printing the response from your server.
&lt;/h4&gt;

&lt;p&gt;Knowing the server response to your requests is vital. One way to print the API response is to substitute (&lt;code&gt;$()&lt;/code&gt;) the &lt;code&gt;cURL&lt;/code&gt; command into a variable and then &lt;code&gt;echo&lt;/code&gt; it, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;MYVAR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="nt"&gt;--request&lt;/span&gt; GET ......&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$MYVAR&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will print whatever response &lt;code&gt;cURL&lt;/code&gt; got from the server.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Save the IP address as a variable.
&lt;/h4&gt;

&lt;p&gt;Since your IP address is most likely going to be repeated, why not save it as a variable. This can also be useful when you need to change the IP address (happens a lot when using services like AWS). Simply store your IP address in a variable and then call it later, like below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;IPADDR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'127.0.0.1'&lt;/span&gt;
&lt;span class="nv"&gt;ADMIN1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="nt"&gt;--request&lt;/span&gt; POST &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$IPADDR&lt;/span&gt;&lt;span class="s2"&gt;:8080/fabric/lifecycle/admin/Org1"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$ADMIN1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Functions!
&lt;/h4&gt;

&lt;p&gt;What if you need to repeat certain requests? Naively copy-pasting &lt;code&gt;cURL&lt;/code&gt; commands will result in a long and illegible code. Use functions and simply call them for better clarity!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Define your functions&lt;/span&gt;
admin1&lt;span class="o"&gt;(){&lt;/span&gt;
  &lt;span class="nv"&gt;ADMIN1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="nt"&gt;--request&lt;/span&gt; POST &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$IPADDR&lt;/span&gt;&lt;span class="s2"&gt;:8080/fabric/lifecycle/admin/Org1"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$ADMIN1&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

packageCC&lt;span class="o"&gt;(){&lt;/span&gt;
  &lt;span class="nv"&gt;PACKAGE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="nt"&gt;--request&lt;/span&gt; POST &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$IPADDR&lt;/span&gt;&lt;span class="s2"&gt;:8080/fabric/lifecycle/package"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data-raw&lt;/span&gt; &lt;span class="s1"&gt;'{
      "cc_source_name": "asset-transfer-basic",
      "label": "basic_1.0",
      "language": "go",
      "package_name": "basic.tar.gz"
  }'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$PACKAGE&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# Then call them&lt;/span&gt;
admin1
packageCC
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
Imagine multiple packageCC calls without using the function. We have reduced 9 lines of code into 1!





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

&lt;p&gt;You can find the source for the script and all the &lt;code&gt;cURL&lt;/code&gt; commands &lt;a href="https://github.com/arogyaGurkha/GurkhaFabricAPI/blob/master/automation.sh" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;This was only the first part of automation. You now might want to loop this file multiple times and calculate some metrics or draw a graph. While certainly possible using bash, it could be interesting (and definitely easier) implementing such tests with python (hint hint). &lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>api</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Compiling Textual IRC Client</title>
      <dc:creator>Arogya Kharel</dc:creator>
      <pubDate>Thu, 13 Jan 2022 13:31:19 +0000</pubDate>
      <link>https://dev.to/gurkhaman/building-textual-irc-client-4317</link>
      <guid>https://dev.to/gurkhaman/building-textual-irc-client-4317</guid>
      <description>&lt;p&gt;&lt;a href="https://www.codeux.com/textual/" rel="noopener noreferrer"&gt;Textual&lt;/a&gt; is often the most recommended IRC client for macOS. You can buy it for $7.99 or you can simply build it from source. Let us look at how to do exactly that.&lt;/p&gt;

&lt;h1&gt;
  
  
  Prerequisites
&lt;/h1&gt;

&lt;p&gt;Your mac needs to have Xcode 10.0 or newer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cloning the source
&lt;/h2&gt;

&lt;p&gt;Clone the source from &lt;a href="https://github.com/Codeux-Software/Textual" rel="noopener noreferrer"&gt;here&lt;/a&gt; wherever you desire. Don't forget to download the submodules used by Textual. If submodules aren't downloaded, Xcode will give &lt;code&gt;the directory &amp;lt;directory&amp;gt; does not contain a xcode project&lt;/code&gt; build error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git clone https://github.com/Codeux-Software/Textual.git
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;Textual
&lt;span class="nv"&gt;$ &lt;/span&gt;git submodule update &lt;span class="nt"&gt;--init&lt;/span&gt; &lt;span class="nt"&gt;--recursive&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setup code signing certificates
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Launch Keychain Access.app and use Certificate Assistance to Create a Certificate.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Enter your name, set Identity Type to "Self Signed Root" and set Certificate Type to "Code Signing" and create the certificate.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Your certificate should be visible in the "My Certificates" section of "login" Keychain&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Changing config files
&lt;/h1&gt;

&lt;p&gt;You will need to change two files: &lt;code&gt;Code Signing Identity.xcconfig&lt;/code&gt; and &lt;/p&gt;

&lt;p&gt;&lt;code&gt;Enabled Features.xcconfig&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Signing Identity configuration
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Open &lt;code&gt;Code Signing Identity.xcconfig&lt;/code&gt; with a text editor of choice. It should be located at &lt;code&gt;Textual/Configurations/Build/&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;For &lt;code&gt;CODE_SIGN_IDENTITY&lt;/code&gt;, type the name that was used to create the Certificate above.&lt;/li&gt;
&lt;li&gt;Leave &lt;code&gt;DEVELOPMENT_TEAM&lt;/code&gt;, &lt;code&gt;PROVISIONING_PROFILE_SPECIFIER&lt;/code&gt; empty.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h2&gt;
  
  
  Enabled Features configuration
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Open &lt;code&gt;Enabled Features.xcconfig&lt;/code&gt; with a text editor of choice. It should be located at &lt;code&gt;Textual/Configurations/Build/Standard Release/&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Set &lt;code&gt;TEXTUAL_BUILT_WITH_LICENSE_MANAGER&lt;/code&gt; to 0. This prevents the trial period countdown.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h1&gt;
  
  
  Building Textual
&lt;/h1&gt;

&lt;p&gt;Open Textual in Xcode by launching &lt;code&gt;Textual.xcworkspace&lt;/code&gt; file in Textual root. Xcode will start indexing and processes source files. Once that is complete, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;On your Xcode menu bar, click Product &amp;gt; Scheme and select &lt;strong&gt;Textual (Standard Release).&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Similarly, click on Product &amp;gt; Build to start building the app. This should start the build process.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnjmhlwp88lifskvafq2j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnjmhlwp88lifskvafq2j.png" alt="Building in progress" width="800" height="76"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to &lt;code&gt;Textual/Build Results/Release&lt;/code&gt; and you should see a shiny new Textual.app. Drag this to your Applications folder.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You should now have a working Textual app (with no trial countdown) that you built yourself!&lt;/p&gt;

</description>
      <category>installation</category>
      <category>software</category>
      <category>xcode</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
