<?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: Ankush Lokhande</title>
    <description>The latest articles on DEV Community by Ankush Lokhande (@ankushppie).</description>
    <link>https://dev.to/ankushppie</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%2F996981%2F147ee08c-19aa-4b74-839a-bc78bfeb52c0.png</url>
      <title>DEV Community: Ankush Lokhande</title>
      <link>https://dev.to/ankushppie</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ankushppie"/>
    <language>en</language>
    <item>
      <title>How to Set Up SSH &amp; GPG Signed Commits on GitHub to Block Force-Push Attacks</title>
      <dc:creator>Ankush Lokhande</dc:creator>
      <pubDate>Mon, 01 Jun 2026 07:13:18 +0000</pubDate>
      <link>https://dev.to/ankushppie/how-to-set-up-ssh-gpg-signed-commits-on-github-to-block-force-push-attacks-5g56</link>
      <guid>https://dev.to/ankushppie/how-to-set-up-ssh-gpg-signed-commits-on-github-to-block-force-push-attacks-5g56</guid>
      <description>&lt;p&gt;👋 Hey all,&lt;br&gt;
Welcome back to our blog!&lt;/p&gt;

&lt;p&gt;Here's a scary thought:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Someone force-pushes to main.&lt;br&gt;
Git history gets rewritten.&lt;br&gt;
A malicious commit appears in the branch.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nobody notices that the commit wasn't created by the developer it claims to be from.&lt;/p&gt;

&lt;p&gt;This isn't just a theoretical risk. Misconfigured repositories, compromised accounts, and unverified commits can make it difficult to trust the history of your codebase.&lt;/p&gt;

&lt;p&gt;Today, we're setting up two important layers of Git security that many developers overlook: &lt;strong&gt;SSH authentication&lt;/strong&gt; and &lt;strong&gt;GPG commit signing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Together, they help ensure:&lt;/p&gt;

&lt;p&gt;✅ Only authorized machines can authenticate with GitHub using your SSH key&lt;br&gt;
✅ Every commit is cryptographically signed and can be verified&lt;br&gt;
✅ Rewritten history and suspicious commits become much easier to detect&lt;br&gt;
✅ GitHub displays a &lt;strong&gt;Verified&lt;/strong&gt; badge for authentic signed commits&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%2Fbesf4fdiltoalseymtcl.gif" 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%2Fbesf4fdiltoalseymtcl.gif" alt="Let's Begin" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this guide, we'll walk through the complete setup on macOS — from installing GitHub CLI and configuring SSH access to generating a GPG key and signing every commit you create.&lt;/p&gt;

&lt;p&gt;Let's lock down our Git workflow. 🔐&lt;/p&gt;
&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Mac with Homebrew installed&lt;/li&gt;
&lt;li&gt;GitHub account&lt;/li&gt;
&lt;li&gt;Terminal access&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%2Flkhb5ofx3h8ok7e0vl9p.gif" 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%2Flkhb5ofx3h8ok7e0vl9p.gif" alt="Setup Prerequisites" width="480" height="258"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Configure SSH Authentication &amp;amp; GPG Signed Commits on GitHub
&lt;/h2&gt;

&lt;p&gt;SSH authentication secures access to your GitHub repositories, while GPG signing verifies the authenticity of every commit you create. Together, they help protect your codebase and build trust in your Git history.&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%2Fnyunl56acsuy684o2uv4.gif" 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%2Fnyunl56acsuy684o2uv4.gif" alt="Start Coding" width="498" height="277"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 1 — Install GitHub CLI
&lt;/h3&gt;

&lt;p&gt;Run command to download gh:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;gh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;gh&lt;/code&gt; is GitHub's official command-line tool. It allows you to authenticate with GitHub, generate SSH keys, and manage repositories directly from your terminal.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 2 — SSH Setup
&lt;/h3&gt;

&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh auth login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Answer the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;? Where do you use GitHub?
  GitHub.com
? What is your preferred protocol for Git operations on this host?
  SSH
? Generate a new SSH key to add to your GitHub account?
  Yes
? Enter a passphrase for your new SSH key (Optional)
  ********
? Title for your SSH key
  title_for_ssh_key // eg. organization_name
? How would you like to authenticate GitHub CLI?
  Login with a web browser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GitHub CLI will then display a one-time code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;! First copy your one-time code: XXXX-XXXX
Press Enter to open https://github.com/login/device in your browser...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Press Enter, open the provided URL, sign in to your GitHub account, and enter the one-time code when prompted.&lt;/p&gt;

&lt;p&gt;After successful authentication, you'll see output similar to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✓ Authentication complete.
✓ Configured git protocol
✓ Uploaded the SSH key to your GitHub account
✓ Logged in as your-username
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This step automatically generates a new SSH key, uploads it to your GitHub account, and configures Git to use SSH for repository operations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3 — Install GnuPG
&lt;/h3&gt;

&lt;p&gt;Run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;gnupg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the installation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpg &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;GnuPG (GPG) is used to generate cryptographic keys that digitally sign your commits. GitHub uses these signatures to verify that a commit was created by you and has not been modified since it was signed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 4 — Generate a GPG Key
&lt;/h3&gt;

&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpg &lt;span class="nt"&gt;--full-generate-key&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Select the following options:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Please select what kind of key you want:
(1) RSA and RSA

RSA keys may be between 1024 and 4096 bits long.
What keysize do you want?
4096

Please specify how long the key should be valid.
0 = key does not expire

Real name:
Your Name

Email address:
your-email@example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Review the information and confirm the key creation.&lt;/p&gt;

&lt;p&gt;You'll then be prompted to create a passphrase for your key.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Choose a strong passphrase and store it securely. This passphrase protects your private GPG key and will be required when signing commits.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 5 — Find Your GPG Key ID
&lt;/h3&gt;

&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpg &lt;span class="nt"&gt;--list-secret-keys&lt;/span&gt; &lt;span class="nt"&gt;--keyid-format&lt;/span&gt; LONG
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sec   rsa4096/ABC123DEF4567890 2026-06-01 [SC]
      1234567890ABCDEF1234567890ABCDEF12345678
uid                 [ultimate] Your Name &amp;lt;your-email@example.com&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the value after &lt;code&gt;rsa4096/&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;ABC123DEF4567890
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;This is your &lt;strong&gt;GPG Key ID&lt;/strong&gt;. You'll use it to export your public key and configure Git commit signing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 6 — Export Your Public GPG Key
&lt;/h3&gt;

&lt;p&gt;Replace &lt;code&gt;&amp;lt;KEY_ID&amp;gt;&lt;/code&gt; with the key ID copied in the previous step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpg &lt;span class="nt"&gt;--armor&lt;/span&gt; &lt;span class="nt"&gt;--export&lt;/span&gt; &amp;lt;KEY_ID&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpg &lt;span class="nt"&gt;--armor&lt;/span&gt; &lt;span class="nt"&gt;--export&lt;/span&gt; ABC123DEF4567890
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll see output similar to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-----BEGIN PGP PUBLIC KEY BLOCK-----
...
-----END PGP PUBLIC KEY BLOCK-----
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the entire block, including the &lt;code&gt;BEGIN&lt;/code&gt; and &lt;code&gt;END&lt;/code&gt; lines.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is your &lt;strong&gt;public GPG key&lt;/strong&gt;. GitHub uses it to verify commits signed with your private key.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 7 — Add Your GPG Key to GitHub
&lt;/h3&gt;

&lt;p&gt;Open GitHub and navigate to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Profile Picture → Settings → SSH and GPG Keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Click:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New GPG Key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Paste the public key copied in the previous step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-----BEGIN PGP PUBLIC KEY BLOCK-----
...
-----END PGP PUBLIC KEY BLOCK-----
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then click &lt;strong&gt;Add GPG Key&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Once added, GitHub can verify commits signed with your private GPG key and display the &lt;strong&gt;Verified&lt;/strong&gt; badge on your commits.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 8 — Configure Git to Sign Commits
&lt;/h3&gt;

&lt;p&gt;Replace &lt;code&gt;&amp;lt;KEY_ID&amp;gt;&lt;/code&gt; with your GPG Key ID and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.signingkey &amp;lt;KEY_ID&amp;gt;
git config &lt;span class="nt"&gt;--global&lt;/span&gt; commit.gpgsign &lt;span class="nb"&gt;true
&lt;/span&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; gpg.program gpg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.signingkey ABC123DEF4567890
git config &lt;span class="nt"&gt;--global&lt;/span&gt; commit.gpgsign &lt;span class="nb"&gt;true
&lt;/span&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; gpg.program gpg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;These settings tell Git which GPG key to use and automatically sign every commit you create.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 9 — Configure GPG Terminal Support
&lt;/h3&gt;

&lt;p&gt;Run:&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="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'export GPG_TTY=$(tty)'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.zshrc
&lt;span class="nb"&gt;source&lt;/span&gt; ~/.zshrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;This allows GPG to interact correctly with your terminal when requesting your passphrase during commit signing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 10 — Verify Commit Signing
&lt;/h3&gt;

&lt;p&gt;Create a signed commit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git commit &lt;span class="nt"&gt;-S&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Test signed commit"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If prompted, enter the passphrase you created when generating your GPG key.&lt;/p&gt;

&lt;p&gt;Push the commit to GitHub:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the commit on GitHub. You should see a &lt;strong&gt;Verified&lt;/strong&gt; badge next to the commit.&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%2Fx0w44j5e75oxj5d9lg9t.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%2Fx0w44j5e75oxj5d9lg9t.png" alt="Verified Commit Example" width="800" height="185"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Verified badge confirms that GitHub successfully validated the GPG signature attached to your commit.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 11 — Protect Your Main Branch
&lt;/h3&gt;

&lt;p&gt;For maximum security, enable branch protection rules on your repository.&lt;/p&gt;

&lt;p&gt;Navigate to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Repository → Settings → Branches
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Edit your branch protection rule and enable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✓ Require signed commits
✓ Block force pushes
✓ Require pull request reviews
✓ Require status checks before merging
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;These protections help ensure that only verified, reviewed, and trusted code can be merged into your main branch.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Let's Wrap!
&lt;/h2&gt;

&lt;p&gt;SSH authentication protects repository access, while GPG signing verifies commit authenticity. Together, they provide a stronger security foundation for your Git workflow and make suspicious or rewritten commits much easier to identify. 🔐&lt;/p&gt;

&lt;p&gt;One correction: GitHub doesn't literally have a setting called "Block force pushes" everywhere. Depending on the repository type, you'll typically see "Allow force pushes" (leave disabled) or "Restrict who can force push". So for accuracy, you may want to write:&lt;/p&gt;

&lt;p&gt;✓ Require signed commits&lt;br&gt;
✓ Disable force pushes&lt;br&gt;
✓ Require pull request reviews&lt;br&gt;
✓ Require status checks before merging&lt;/p&gt;

&lt;p&gt;which is easier for readers to understand.&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%2Fcqku8zfdzb1ipz0ionn2.jpg" 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%2Fcqku8zfdzb1ipz0ionn2.jpg" alt="Thanks for reading" width="400" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you found this blog helpful or have any further questions, we would love to hear from you. Feel &lt;strong&gt;free to reach out&lt;/strong&gt; and &lt;strong&gt;&lt;a href="https://dev.to/ankushppie"&gt;follow us&lt;/a&gt;&lt;/strong&gt; on our social media platforms for more tips and tutorials on tech-oriented posts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Happy coding!👨‍💻
&lt;/h3&gt;

</description>
      <category>github</category>
      <category>development</category>
      <category>developer</category>
      <category>learning</category>
    </item>
    <item>
      <title>Flutter Deep Linking: Complete Guide for Android App Links &amp; iOS Universal Links</title>
      <dc:creator>Ankush Lokhande</dc:creator>
      <pubDate>Wed, 27 May 2026 12:40:55 +0000</pubDate>
      <link>https://dev.to/ankushppie/flutter-deep-linking-complete-guide-for-android-app-links-ios-universal-links-4kde</link>
      <guid>https://dev.to/ankushppie/flutter-deep-linking-complete-guide-for-android-app-links-ios-universal-links-4kde</guid>
      <description>&lt;p&gt;👋 Hey all,&lt;br&gt;
Welcome back to the mobile development blog!&lt;/p&gt;

&lt;p&gt;Ever tapped a link in WhatsApp or an email and landed directly on a specific screen inside an app? That’s deep linking in action.&lt;/p&gt;

&lt;p&gt;For Flutter developers, deep linking sounds simple — open a URL and navigate to a screen. But in reality, it involves Android App Links, iOS Universal Links, server-side verification files, app configuration, and platform-specific setup, where even a small mistake can break the entire flow.&lt;/p&gt;

&lt;p&gt;In this guide, we’ll implement deep linking in Flutter for both Android and iOS, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Android App Links setup&lt;/li&gt;
&lt;li&gt;iOS Universal Links setup&lt;/li&gt;
&lt;li&gt;Domain verification&lt;/li&gt;
&lt;li&gt;Flutter route handling&lt;/li&gt;
&lt;li&gt;Deep link testing&lt;/li&gt;
&lt;li&gt;Common issues and fixes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;using real-world examples and production-ready implementation.&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%2Fbesf4fdiltoalseymtcl.gif" 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%2Fbesf4fdiltoalseymtcl.gif" alt="Let's Begin" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Table Of Contents&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
Flutter Deep Linking Implementation

&lt;ul&gt;
&lt;li&gt;Step 1: Add Required Package&lt;/li&gt;
&lt;li&gt;Step 2: Domain Verification Setup&lt;/li&gt;
&lt;li&gt;Step 3: Configure Deep Linking&lt;/li&gt;
&lt;li&gt;Step 4: Handle Deep Link Redirection in Flutter&lt;/li&gt;
&lt;li&gt;Step 5: Testing Deep Links&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  # Flutter Deep Linking Implementation
&lt;/h2&gt;

&lt;p&gt;In this section, we’ll configure deep linking for both Android and iOS so that URLs can open specific screens directly in the Flutter app.&lt;/p&gt;

&lt;p&gt;This setup includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adding deep linking support in Flutter&lt;/li&gt;
&lt;li&gt;Configuring Android App Links&lt;/li&gt;
&lt;li&gt;Configuring iOS Universal Links&lt;/li&gt;
&lt;li&gt;Verifying domain ownership&lt;/li&gt;
&lt;li&gt;Handling incoming URLs inside the app&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By the end, your app will be able to open directly from supported web links and navigate users to the correct screen automatically.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  # Step 1: Add Required Package
&lt;/h3&gt;

&lt;p&gt;To handle incoming deep links inside the Flutter application, we’ll use the &lt;a href="https://pub.dev/packages/app_links" rel="noopener noreferrer"&gt;app_links&lt;/a&gt; package.&lt;br&gt;
Install the latest version using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flutter pub add app_links
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command automatically adds the latest compatible version to your &lt;code&gt;pubspec.yaml&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  # Step 2: Domain Verification Setup
&lt;/h3&gt;

&lt;p&gt;To allow your app to open links directly from your domain, both Android and iOS require domain verification files hosted on your server.&lt;/p&gt;

&lt;h4&gt;
  
  
  A). Android App Links Verification
&lt;/h4&gt;

&lt;p&gt;Android uses an &lt;code&gt;assetlinks.json&lt;/code&gt; file to verify that your domain belongs to your application.&lt;br&gt;
Create this file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://yourdomain.com/.well-known/assetlinks.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  {
    "relation": [
      "delegate_permission/common.handle_all_urls",
      "delegate_permission/common.get_login_creds"
    ],
    "target": {
      "namespace": "android_app",
      "package_name": "com.example.app",
      "sha256_cert_fingerprints": [
        "DEBUG_SHA256",
        "RELEASE_SHA256",
        "PLAY_CONSOLE_SHA256"
      ]
    }
  }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;handle_all_urls&lt;/code&gt; → Opens app directly from supported links.&lt;br&gt;
&lt;code&gt;get_login_creds&lt;/code&gt; → Recommended for Play Store builds and Google credential sharing support.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;SHA256 Fingerprints&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You should add all possible SHA256 fingerprints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Debug &amp;amp; Release SHA256:&lt;/strong&gt; Run the following command to get both Debug and Release SHA256 fingerprints:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;android &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; ./gradlew signingReport
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Play Console SHA256:&lt;/strong&gt; Navigate to:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Protected with Play → Play Store protection → Protect app signing key → App signing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the: &lt;strong&gt;App signing certificate SHA-256 fingerprint&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is extremely important because production apps downloaded from Play Store are signed by Google Play, not your local keystore.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  B). iOS Universal Links Verification
&lt;/h4&gt;

&lt;p&gt;iOS uses an &lt;code&gt;apple-app-site-association&lt;/code&gt; file for verification.&lt;/p&gt;

&lt;p&gt;Create this file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://yourdomain.com/.well-known/apple-app-site-association
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "applinks": {
    "details": [
      {
        "appIDs": [
          "TEAM_ID.com.example.app"
        ],
        "components": [
          {
            "/": "*"
          }
        ]
      }
    ]
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Handle All URLs:&lt;br&gt;
&lt;code&gt;"/": "*"&lt;/code&gt; → Opens all supported URLs inside the app.&lt;br&gt;
Handle Specific URLs Only:&lt;br&gt;
&lt;code&gt;"/product/*"&lt;/code&gt; → Opens only matching URLs inside the app.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Replace&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;TEAM_ID&lt;/code&gt; → Apple Developer Team ID&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;com.example.app&lt;/code&gt; → iOS Bundle Identifier&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Verify Domain Association&lt;/strong&gt;&lt;br&gt;
Once the verification files are hosted, you can verify them using the following methods.&lt;/p&gt;

&lt;p&gt;Android Verification:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://yourdomain.com&amp;amp;relation=delegate_permission/common.handle_all_urls
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;If everything is configured correctly, you should see your app’s package name in the response.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;iOS Verification:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://yourdomain.com/.well-known/apple-app-site-association
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;The browser should directly return the JSON response without downloading the file or showing HTML.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  # Step 3: Configure Deep Linking
&lt;/h3&gt;

&lt;p&gt;Now configure deep linking for both Android and iOS applications.&lt;/p&gt;

&lt;h4&gt;
  
  
  A). Android Deep Linking Configuration
&lt;/h4&gt;

&lt;p&gt;Android allows you to configure deep linking in two ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open only specific URLs&lt;/li&gt;
&lt;li&gt;Open all links from your domain&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Open your &lt;code&gt;AndroidManifest.xml&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;android/app/src/main/AndroidManifest.xml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside your &lt;code&gt;MainActivity&lt;/code&gt;, add one of the following &lt;code&gt;intent-filter&lt;/code&gt; configurations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 1: Handle Specific URLs Only&lt;/strong&gt;&lt;br&gt;
Use this when you want to open only selected paths inside the app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;intent-filter android:autoVerify="true"&amp;gt;
    &amp;lt;action android:name="android.intent.action.VIEW" /&amp;gt;

    &amp;lt;category android:name="android.intent.category.DEFAULT" /&amp;gt;
    &amp;lt;category android:name="android.intent.category.BROWSABLE" /&amp;gt;

    &amp;lt;data
        android:scheme="https"
        android:host="yourdomain.com"
        android:pathPrefix="/product" /&amp;gt;
&amp;lt;/intent-filter&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://yourdomain.com/product/12
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only URLs starting with &lt;code&gt;/product&lt;/code&gt; will open the app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 2: Handle All Links from Domain&lt;/strong&gt;&lt;br&gt;
Use this when all URLs from your domain should open inside the app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;intent-filter android:autoVerify="true"&amp;gt;
    &amp;lt;action android:name="android.intent.action.VIEW" /&amp;gt;

    &amp;lt;category android:name="android.intent.category.DEFAULT" /&amp;gt;
    &amp;lt;category android:name="android.intent.category.BROWSABLE" /&amp;gt;

    &amp;lt;data
        android:scheme="https"
        android:host="yourdomain.com" /&amp;gt;
&amp;lt;/intent-filter&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://yourdomain.com/anything
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Any valid URL from the domain can open the application.&lt;/p&gt;

&lt;h4&gt;
  
  
  B). iOS Universal Links Configuration
&lt;/h4&gt;

&lt;p&gt;Now let’s configure Universal Links for iOS so supported URLs can directly open your Flutter application instead of opening in Safari.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Associated Domains Setup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open your iOS project in Xcode &amp;amp; navigate to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Runner → Signing &amp;amp; Capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the Associated Domains capability and include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;applinks:yourdomain.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For subdomains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;applinks:*.yourdomain.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Add Associated Domains in &lt;code&gt;Info.plist&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;key&amp;gt;com.apple.developer.associated-domains&amp;lt;/key&amp;gt;
&amp;lt;array&amp;gt;
    &amp;lt;string&amp;gt;applinks:yourdomain.com&amp;lt;/string&amp;gt;
&amp;lt;/array&amp;gt;
&amp;lt;key&amp;gt;LSApplicationQueriesSchemes&amp;lt;/key&amp;gt;
&amp;lt;array&amp;gt;
    &amp;lt;string&amp;gt;https&amp;lt;/string&amp;gt;
&amp;lt;/array&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  # Step 4: Handle Deep Link Redirection in Flutter
&lt;/h3&gt;

&lt;p&gt;Now that platform configuration is complete, let’s handle incoming deep links inside the Flutter application.&lt;/p&gt;

&lt;p&gt;This implementation supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cold start links (app killed state)&lt;/li&gt;
&lt;li&gt;Foreground links&lt;/li&gt;
&lt;li&gt;Background links&lt;/li&gt;
&lt;li&gt;Specific route handling&lt;/li&gt;
&lt;li&gt;Dynamic route parsing for multiple URLs&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Create &lt;code&gt;deep_link_service.dart&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Create a reusable deep link service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'dart:async';
import 'package:app_links/app_links.dart';
import 'package:flutter/foundation.dart';

class DeepLinkService {
  static final AppLinks _appLinks = AppLinks();
  static StreamSubscription? _subscription;

  static String? pendingRoute;

  /// Call before runApp()
  static Future&amp;lt;void&amp;gt; init() async {
    try {
      final Uri? initialUri = await _appLinks.getInitialLink();

      if (initialUri != null) {
        if (kDebugMode) {
          print('DeepLink cold start: $initialUri');
        }

        pendingRoute = initialUri.toString();
      }
    } catch (e) {
      if (kDebugMode) {
        print('DeepLink init error: $e');
      }
    }
  }

  /// Listen for foreground/background links
  static void startListening(Function(Uri uri) onLinkReceived) {
    _subscription?.cancel();

    _subscription = _appLinks.uriLinkStream.listen(
      (Uri uri) {
        if (kDebugMode) {
          print('DeepLink foreground: $uri');
        }

        onLinkReceived(uri);
      },
      onError: (e) {
        if (kDebugMode) {
          print('DeepLink stream error: $e');
        }
      },
    );
  }

  static void dispose() {
    _subscription?.cancel();
    _subscription = null;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Initialize Before &lt;code&gt;runApp()&lt;/code&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await DeepLinkService.init();

  runApp(const MyApp());
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Start Listening Inside Controller
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@override
void onInit() {
  super.onInit();

  initDeepLinkListener();

  /// Handle cold start deep link
  final String? pendingRoute = DeepLinkService.pendingRoute;

  DeepLinkService.pendingRoute = null;

  if (pendingRoute != null) {
    handleDeepLink(Uri.parse(pendingRoute));
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Listen for Incoming Links
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void initDeepLinkListener() {
  DeepLinkService.startListening((Uri uri) {
    handleDeepLink(uri);
  });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Handle Route Redirection
&lt;/h4&gt;

&lt;p&gt;This is the main navigation handler where you can support:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Single URL pattern&lt;/li&gt;
&lt;li&gt;Multiple URLs&lt;/li&gt;
&lt;li&gt;Dynamic IDs&lt;/li&gt;
&lt;li&gt;Full app routing
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void handleDeepLink(Uri uri) {
  final segments = uri.pathSegments;

  /// Example:
  /// https://yourdomain.com/product/12
  if (segments.length &amp;gt;= 2 &amp;amp;&amp;amp; segments[0] == 'product') {
    final productId = segments[1];

    Get.to(
      () =&amp;gt; ProductDetailsScreen(
        productId: productId,
      ),
    );

    return;
  }

  /// Example:
  /// https://yourdomain.com/profile/45
  if (segments.length &amp;gt;= 2 &amp;amp;&amp;amp; segments[0] == 'profile') {
    final userId = segments[1];

    Get.to(
      () =&amp;gt; ProfileScreen(
        userId: userId,
      ),
    );

    return;
  }

  /// Default fallback
  Get.to(() =&amp;gt; const HomeScreen());
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Handle Single Link vs All Links&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Case 1: Handle Only One Specific URL
Example:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://yourdomain.com/product/12
if (segments[0] == 'product') {
  // Navigate to product screen
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Case 2: Handle Multiple Dynamic URLs
Examples:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://yourdomain.com/product/12
https://yourdomain.com/profile/45
https://yourdomain.com/booking/88
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Manage like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;switch (segments[0]) {
  case 'product':
    break;

  case 'profile':
    break;

  case 'booking':
    break;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach makes the deep linking flow scalable and easy to maintain for large Flutter applications.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  # Step 5: Testing Deep Links
&lt;/h3&gt;

&lt;p&gt;This is very important because most developers struggle during testing.&lt;/p&gt;

&lt;p&gt;Include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Android testing command&lt;/li&gt;
&lt;li&gt;iOS testing command&lt;/li&gt;
&lt;li&gt;Real device testing&lt;/li&gt;
&lt;li&gt;Browser / WhatsApp / Email testing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Android&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;adb shell am start \
-a android.intent.action.VIEW \
-d "https://yourdomain.com/product/12"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;iOS&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;xcrun simctl openurl booted "https://yourdomain.com/product/12"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Let's Wrap!
&lt;/h2&gt;

&lt;p&gt;Deep linking is an essential feature for modern mobile applications. It allows users to open specific screens directly from URLs, creating a faster and smoother user experience.&lt;/p&gt;

&lt;p&gt;Although the setup involves platform-specific configuration for Android and iOS, once everything is configured correctly, deep linking becomes a powerful and scalable navigation system for your Flutter application.&lt;/p&gt;

&lt;p&gt;With Android App Links, iOS Universal Links, proper domain verification, and Flutter route handling, your app is now ready to support production-ready deep linking across both platforms.&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%2Fcqku8zfdzb1ipz0ionn2.jpg" 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%2Fcqku8zfdzb1ipz0ionn2.jpg" alt="Thanks for reading" width="400" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you found this blog helpful or have any further questions, we would love to hear from you. Feel &lt;strong&gt;free to reach out&lt;/strong&gt; and &lt;strong&gt;&lt;a href="https://dev.to/ankushppie"&gt;follow us&lt;/a&gt;&lt;/strong&gt; on our social media platforms for more tips and tutorials on tech-oriented posts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Happy coding!👨‍💻
&lt;/h3&gt;

</description>
      <category>deeplink</category>
      <category>android</category>
      <category>ios</category>
      <category>mobile</category>
    </item>
    <item>
      <title>VPN Fundamentals for Mobile Developers: Everything You Need to Know Before Integrating WireGuard</title>
      <dc:creator>Ankush Lokhande</dc:creator>
      <pubDate>Wed, 02 Apr 2025 05:12:31 +0000</pubDate>
      <link>https://dev.to/ankushppie/vpn-fundamentals-for-mobile-developers-everything-you-need-to-know-before-integrating-wireguard-5b4g</link>
      <guid>https://dev.to/ankushppie/vpn-fundamentals-for-mobile-developers-everything-you-need-to-know-before-integrating-wireguard-5b4g</guid>
      <description>&lt;p&gt;👋 Hey all,&lt;/p&gt;

&lt;p&gt;Welcome back to the mobile development blog! Today, we understand the fundamentals of VPN technology. This guide covers essential concepts, key protocols, and security aspects you need to understand before integrating WireGuard into your Android and iOS apps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table Of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;What is VPN&lt;/li&gt;
&lt;li&gt;What is an IP Address&lt;/li&gt;
&lt;li&gt;Types of VPN Protocols&lt;/li&gt;
&lt;li&gt;
Key Components of a VPN

&lt;ul&gt;
&lt;li&gt;VPN Client&lt;/li&gt;
&lt;li&gt;VPN Server&lt;/li&gt;
&lt;li&gt;VPN Tunnel&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;How Does a VPN Work&lt;/li&gt;

&lt;li&gt;

Development-Oriented Terms in VPNs

&lt;ul&gt;
&lt;li&gt;Interface&lt;/li&gt;
&lt;li&gt;Peer&lt;/li&gt;
&lt;li&gt;Encryption&lt;/li&gt;
&lt;li&gt;Tunneling&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Conclusion&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  # What is VPN
&lt;/h2&gt;

&lt;p&gt;A virtual private network (VPN) creates a secure, encrypted connection over a public network, providing additional privacy and security. It masks your IP address and encrypts your data for enhanced privacy and security.&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%2Fa0e7e0orqdj9mnabxw44.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%2Fa0e7e0orqdj9mnabxw44.png" alt="VPN overview" width="682" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features of a VPN:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Encryption:&lt;/strong&gt; Secures data transmission to prevent unauthorized access.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anonymity:&lt;/strong&gt; Hides your IP address to protect your online identity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secure Access:&lt;/strong&gt; Allows safe connection to private networks from anywhere.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bypass Restrictions:&lt;/strong&gt; Helps access geo-blocked content and restricted services.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  # What is an IP Address
&lt;/h2&gt;

&lt;p&gt;An IP (Internet Protocol) address is the unique identifying number assigned to every device connected to the Internet or a local network. It allows devices to communicate with each other over the internet or local network.&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%2F6d117nern97il6xh8c1w.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%2F6d117nern97il6xh8c1w.png" alt="Types of IP Addresses" width="800" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Types of IP Addresses
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Public IP address: It is unique across the internet, assigned by your Internet Service Provider (&lt;a href="https://en.wikipedia.org/wiki/Internet_service_provider" rel="noopener noreferrer"&gt;ISP&lt;/a&gt;) and used for devices (such as mobiles, PCs, hardware, etc.) to communicate on the public internet.&lt;/li&gt;
&lt;li&gt;Private IP address: It is Used within a local or private network (like a home or office network) and is not visible from the internet.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  # Types of VPN Protocols
&lt;/h2&gt;

&lt;p&gt;A VPN protocol defines how data is securely transmitted between your device and the VPN server.&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%2F0luvdsgr2x8qm61fpepq.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%2F0luvdsgr2x8qm61fpepq.png" alt="VPN Protocols" width="512" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is a wide range of VPN Protocols available across the market &amp;amp; different protocols offer varying levels of security, speed, and compatibility.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;OpenVPN&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Security:&lt;/strong&gt; Strong encryption (AES-256)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speed:&lt;/strong&gt; Moderate&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compatibility:&lt;/strong&gt; Works on Windows, macOS, Linux, Android, iOS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best For:&lt;/strong&gt; General use, privacy-focused applications&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;WireGuard&lt;/strong&gt; (Modern &amp;amp; Lightweight)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Security:&lt;/strong&gt; State-of-the-art cryptography (ChaCha20)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speed:&lt;/strong&gt; Very fast (lightweight &amp;amp; efficient)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compatibility:&lt;/strong&gt; Android, iOS, Windows, Linux, macOS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best For:&lt;/strong&gt; Mobile VPNs, gaming, and high-speed connections&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;IPsec&lt;/strong&gt; (IKEv2/IPsec, L2TP/IPsec)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Security:&lt;/strong&gt; Strong encryption (AES-256)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speed:&lt;/strong&gt; Fast but depends on the implementation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compatibility:&lt;/strong&gt; Supported on most operating systems&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best For:&lt;/strong&gt; Mobile users (IKEv2 handles network changes well)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;PPTP&lt;/strong&gt; (Point-to-Point Tunneling Protocol) – Outdated&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Security:&lt;/strong&gt; Weak (easily broken)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speed:&lt;/strong&gt; Very fast&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compatibility:&lt;/strong&gt; Built into most OS but insecure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best For:&lt;/strong&gt; Not recommended due to security risks&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;SSTP&lt;/strong&gt; (Secure Socket Tunneling Protocol)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Security:&lt;/strong&gt; Strong (AES encryption, SSL/TLS-based)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speed:&lt;/strong&gt; Decent&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compatibility:&lt;/strong&gt; Mainly Windows-based&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best For:&lt;/strong&gt; Windows users who need built-in VPN support&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Which VPN Protocol Should You Use?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;For security &amp;amp; privacy: OpenVPN or WireGuard&lt;/li&gt;
&lt;li&gt;For speed &amp;amp; efficiency: WireGuard&lt;/li&gt;
&lt;li&gt;For mobile reliability: IKEv2/IPsec&lt;/li&gt;
&lt;li&gt;For Windows-only users: SSTP&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  # Key Components of a VPN: Client, Server, and Tunnel
&lt;/h2&gt;

&lt;p&gt;A VPN (Virtual Private Network) consists of three main components that work together to create a secure and private connection over the Internet. Understanding these elements is essential before integrating a VPN into your mobile application.&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%2Fo4rwtmug4ontk712g1c5.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%2Fo4rwtmug4ontk712g1c5.png" alt="Key Components of a VPN" width="800" height="346"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  # VPN Client – The User’s Gateway to Privacy
&lt;/h3&gt;

&lt;p&gt;A VPN client is an application or software installed on a user's device (mobile, computer, etc.) that initiates and manages the VPN connection. It encrypts outgoing data before sending it through the VPN tunnel and decrypts incoming data from the server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; WireGuard, OpenVPN, or built-in VPN clients on Android &amp;amp; iOS.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  # VPN Server – The Secure Middleman
&lt;/h3&gt;

&lt;p&gt;A VPN server is a remote server that acts as an intermediary between the VPN client and the internet. It receives encrypted data from the client, decrypts it, forwards it to the intended destination (websites, services, etc.), and then encrypts responses before sending them back.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; A WireGuard or OpenVPN server hosted on a cloud provider or private network.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  # VPN Tunnel – The Encrypted Pathway
&lt;/h3&gt;

&lt;p&gt;A VPN tunnel is a secure, encrypted connection between the VPN client and server. It prevents third parties, such as ISPs, hackers, advertizement agencies, or government agencies, from intercepting or accessing transmitted data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; When a user connects to a VPN, their internet traffic is routed through an encrypted tunnel, making online activities private and secure.&lt;/p&gt;




&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  # How Does a VPN Work
&lt;/h2&gt;

&lt;p&gt;A Virtual Private Network (VPN) creates a secure, encrypted connection between a user's device and a remote server, allowing private and safe internet access.&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%2Fspb5keuwnk876hs3i8vx.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%2Fspb5keuwnk876hs3i8vx.png" alt="How Does a VPN Work" width="800" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here’s how it works step by step:&lt;/strong&gt;  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The request is sent from a remote location.&lt;/li&gt;
&lt;li&gt;The request travels over the internet.&lt;/li&gt;
&lt;li&gt;The request reaches the VPN.&lt;/li&gt;
&lt;li&gt;The VPN authenticates the user.&lt;/li&gt;
&lt;li&gt;The VPN establishes a secure connection.&lt;/li&gt;
&lt;li&gt;The VPN server forwards the data.&lt;/li&gt;
&lt;li&gt;The Network Access Server receives it.&lt;/li&gt;
&lt;li&gt;The server routes the data to its destination.&lt;/li&gt;
&lt;li&gt;The resources are sent back.&lt;/li&gt;
&lt;li&gt;The resources reach the original location.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  # Development-Oriented Terms in VPNs
&lt;/h2&gt;

&lt;p&gt;As we dine into the basics of VPN &amp;amp; the protocols, the popular VPN protocol is WireGuard. To integrate a VPN like &lt;strong&gt;WireGuard&lt;/strong&gt; into your mobile app (Android &amp;amp; iOS), understanding these key development terms is essential.&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;&lt;a href="https://www.wireguard.com/" rel="noopener noreferrer"&gt;WireGuard VPN&lt;/a&gt;&lt;/strong&gt;, the connection is defined using two key components: &lt;strong&gt;Interface&lt;/strong&gt; and &lt;strong&gt;Peer&lt;/strong&gt;. These terms describe how devices communicate securely within a VPN network. The Interface is the local device’s configuration &amp;amp; The Peer is the remote party it connects to securely. And both ends (client &amp;amp; server) must have each other's public keys to authenticate.&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%2Fhqeccwftvmzgw435ruak.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%2Fhqeccwftvmzgw435ruak.png" alt="WireGuard Tunnel" width="540" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  # Interface (VPN Configuration on a Device)
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Interface&lt;/strong&gt; refers to the VPN configuration on a local device (VPN client or server). It defines the details needed to establish a connection, such as the IP address, private key, and listening port.&lt;/p&gt;

&lt;h4&gt;
  
  
  Key Parameters in an Interface:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;PrivateKey&lt;/code&gt;: A unique private key for authentication.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Address&lt;/code&gt;: The internal VPN IP address assigned to the device (e.g., 10.0.0.2/24).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ListenPort&lt;/code&gt;: The port the WireGuard server or client listens on (e.g., 51820).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DNS&lt;/code&gt;: (Optional) The DNS server to use while connected to the VPN.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example (Client Configuration - wg_client.conf):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;Interface&lt;/span&gt;]
&lt;span class="n"&gt;PrivateKey&lt;/span&gt; = &lt;span class="n"&gt;CLIENT_PRIVATE_KEY&lt;/span&gt;
&lt;span class="n"&gt;Address&lt;/span&gt; = &lt;span class="m"&gt;10&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;2&lt;/span&gt;/&lt;span class="m"&gt;24&lt;/span&gt;
&lt;span class="n"&gt;DNS&lt;/span&gt; = &lt;span class="m"&gt;1&lt;/span&gt;.&lt;span class="m"&gt;1&lt;/span&gt;.&lt;span class="m"&gt;1&lt;/span&gt;.&lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  # Peer (Remote VPN Connection)
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;Peer&lt;/strong&gt; represents a remote device in the WireGuard VPN network. It contains the public key of the other party (server or client) and defines information related to allowed IPs and endpoints.&lt;/p&gt;

&lt;h4&gt;
  
  
  Key Parameters in a Peer:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;PublicKey&lt;/code&gt;: The public key of the remote peer (server or another client).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;AllowedIPs&lt;/code&gt;: Specifies which IPs can communicate through this peer.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Endpoint&lt;/code&gt;: The IP/hostname of the remote peer (needed for clients connecting to a server).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PersistentKeepalive&lt;/code&gt;: (Optional) Keeps the connection alive for NAT traversal (useful for mobile clients).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example (Client Configuration - wg_client.conf):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Peer]
PublicKey = SERVER_PUBLIC_KEY
AllowedIPs = 0.0.0.0/0
Endpoint = vpn.example.com:51820
PersistentKeepalive = 25
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  # Encryption (Securing VPN Data)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Encryption&lt;/strong&gt; is the process of encoding data so only authorized devices can read it and in case of WireGuard, it uses &lt;strong&gt;ChaCha20 encryption&lt;/strong&gt;, which is fast, secure, and efficient for mobile devices. The encrypted data securely travels through the VPN tunnel to ensure privacy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
🔒 &lt;strong&gt;Without VPN:&lt;/strong&gt; Your ISP sees all your browsing activity.&lt;br&gt;
🔐 &lt;strong&gt;With VPN (Encrypted):&lt;/strong&gt; Data appears scrambled, unreadable to outsiders.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  # Tunneling (Creating a Secure Data Pathway)
&lt;/h3&gt;

&lt;p&gt;Tunneling is the process of encapsulating network traffic inside a secure VPN tunnel. This tunnel prevents third parties such as ISPs, hackers, governments &amp;amp; other agencies from intercepting your data. VPN tunnels may use different protocols like WireGuard, OpenVPN, or IPSec.&lt;/p&gt;




&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  # Let's Wrap!
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.wireguard.com/" rel="noopener noreferrer"&gt;WireGuard&lt;/a&gt; is the most popular PVN protocol to use nowadays. WireGuard simplifies VPN implementation with &lt;strong&gt;modern cryptography&lt;/strong&gt;, &lt;strong&gt;high performance&lt;/strong&gt;, and &lt;strong&gt;ease of use&lt;/strong&gt;, making it an excellent choice for both Android and iOS applications.&lt;/p&gt;

&lt;p&gt;📢 Next, read our detailed guide:&lt;br&gt;
&lt;strong&gt;&lt;a href="https://dev.to/ankushppie/vpn-fundamentals-for-mobile-developers-everything-you-need-to-know-before-integrating-wireguard-177d-temp-slug-5986139?preview=a744039924ec8fb42f9163919c40de2731515dbfe41212d42a364eef04a06d436638883d01b0f321d5a44c231c2c82cfe3e47097354eb7ec745a5704"&gt;VPN Fundamentals for Android &amp;amp; iOS Developers: Everything You Need to Know Before Integrating WireGuard&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As you move forward with VPN integration, having a solid grasp of concepts like Interface, Peer, encryption, and tunneling will help you build a secure and efficient VPN solution.&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%2Fcqku8zfdzb1ipz0ionn2.jpg" 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%2Fcqku8zfdzb1ipz0ionn2.jpg" alt="Thanks for reading" width="400" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you found this blog helpful or have any further questions, we would love to hear from you. Feel &lt;strong&gt;free to reach out&lt;/strong&gt; and &lt;strong&gt;&lt;a href="https://dev.to/ankushppie"&gt;follow us&lt;/a&gt;&lt;/strong&gt; on our social media platforms for more tips and tutorials on tech-oriented posts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Happy coding!👨‍💻
&lt;/h3&gt;

</description>
      <category>vpn</category>
      <category>wireguard</category>
      <category>mobile</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Building a Secure VPN in Android with WireGuard: A Complete Guide</title>
      <dc:creator>Ankush Lokhande</dc:creator>
      <pubDate>Wed, 02 Apr 2025 05:12:14 +0000</pubDate>
      <link>https://dev.to/ankushppie/building-a-secure-vpn-in-android-with-wireguard-a-complete-guide-n1</link>
      <guid>https://dev.to/ankushppie/building-a-secure-vpn-in-android-with-wireguard-a-complete-guide-n1</guid>
      <description>&lt;p&gt;👋 Hey all,&lt;/p&gt;

&lt;p&gt;In this guide, we’ll learn how to integrate &lt;strong&gt;WireGuard&lt;/strong&gt; into your &lt;strong&gt;Android&lt;/strong&gt; app using &lt;strong&gt;Jetpack Compose&lt;/strong&gt; and &lt;strong&gt;Kotlin&lt;/strong&gt;. There is a wide range of VPN protocols available in the market to integrate with Android, and we selected &lt;strong&gt;WireGuard&lt;/strong&gt; (a modern VPN protocol) known for its simplicity, speed, and strong security features. By the end of this tutorial, you’ll have a working WireGuard VPN implementation that you can integrate into your application.&lt;/p&gt;

&lt;p&gt;If you are new to VPNs or unfamiliar with related terms, please read this blog before proceeding:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/ankushppie/vpn-fundamentals-for-mobile-developers-everything-you-need-to-know-before-integrating-wireguard-5b4g" class="crayons-story__hidden-navigation-link"&gt;VPN Fundamentals for Mobile Developers: Everything You Need to Know Before Integrating WireGuard&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/ankushppie" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F996981%2F147ee08c-19aa-4b74-839a-bc78bfeb52c0.png" alt="ankushppie profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/ankushppie" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Ankush Lokhande
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Ankush Lokhande
                
              
              &lt;div id="story-author-preview-content-2336923" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/ankushppie" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F996981%2F147ee08c-19aa-4b74-839a-bc78bfeb52c0.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Ankush Lokhande&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/ankushppie/vpn-fundamentals-for-mobile-developers-everything-you-need-to-know-before-integrating-wireguard-5b4g" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Apr 2 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/ankushppie/vpn-fundamentals-for-mobile-developers-everything-you-need-to-know-before-integrating-wireguard-5b4g" id="article-link-2336923"&gt;
          VPN Fundamentals for Mobile Developers: Everything You Need to Know Before Integrating WireGuard
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/vpn"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;vpn&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/wireguard"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;wireguard&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/mobile"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;mobile&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/tutorial"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;tutorial&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/ankushppie/vpn-fundamentals-for-mobile-developers-everything-you-need-to-know-before-integrating-wireguard-5b4g" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;13&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/ankushppie/vpn-fundamentals-for-mobile-developers-everything-you-need-to-know-before-integrating-wireguard-5b4g#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              1&lt;span class="hidden s:inline"&gt;&amp;nbsp;comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            6 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


&lt;p&gt;If you're already familiar with VPNs or have already read the blog, let's get started!!!&lt;/p&gt;

&lt;h2&gt;
  
  
  Table Of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Essential Prerequisites for Setting up your project&lt;/li&gt;
&lt;li&gt;Test how VPN works on devices&lt;/li&gt;
&lt;li&gt;Setting up the project&lt;/li&gt;
&lt;li&gt;Let's Wrap&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;br&gt;
Before implementing the VPN, I explored various VPN protocols and found &lt;a href="https://www.wireguard.com/" rel="noopener noreferrer"&gt;WireGuard&lt;/a&gt; the most suitable choice for mobile development. Its simplicity, speed, and strong security features stand out from traditional protocols like OpenVPN and IPSec. WireGuard is even better because many people support it, and there are lots of free code examples online. This makes it easier to add WireGuard to an Android app.&lt;/p&gt;



&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  # Essential Prerequisites for Setting up your project
&lt;/h2&gt;

&lt;p&gt;Before beginning development, it is essential to ensure that you have all the necessary tools installed and that they are up to date.&lt;/p&gt;

&lt;p&gt;Make sure you have the following ready before starting:&lt;br&gt;
&lt;strong&gt;Android Studio&lt;/strong&gt; – Install the latest stable version.&lt;br&gt;
&lt;strong&gt;VPN Server&lt;/strong&gt; – You need a server to generate the &lt;code&gt;wg.conf&lt;/code&gt; file for WireGuard.&lt;/p&gt;



&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  # Test how VPN works on devices
&lt;/h2&gt;

&lt;p&gt;To test how the VPN is working on your device (laptop, mobile, etc.), you can download available apps from the Store. Here are some of the best apps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;For Android: &lt;a href="https://play.google.com/store/apps/details?id=com.wireguard.android&amp;amp;pcampaignid=web_share" rel="noopener noreferrer"&gt;WireGuard&lt;/a&gt;, &lt;a href="https://play.google.com/store/apps/details?id=com.zaneschepke.wireguardautotunnel&amp;amp;pcampaignid=web_share" rel="noopener noreferrer"&gt;WG Tunnel&lt;/a&gt;, &lt;a href="https://play.google.com/store/apps/details?id=net.openvpn.openvpn&amp;amp;pcampaignid=web_share" rel="noopener noreferrer"&gt;OpenVPN Connect&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For Mac: &lt;a href="https://apps.apple.com/in/app/wireguard/id1451685025?mt=12" rel="noopener noreferrer"&gt;WireGuard&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can also download the platform-specific app from the official website of WireGuard: &lt;a href="https://www.wireguard.com/install/" rel="noopener noreferrer"&gt;Download it from here&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You need a config file (eg. &lt;code&gt;client.conf&lt;/code&gt;) to run the VPN on the device. Contact your server provider guy or create by own.&lt;/p&gt;

&lt;p&gt;Here are some sample files to show how &lt;strong&gt;config&lt;/strong&gt; file look like: &lt;strong&gt;&lt;a href="https://github.com/WireGuard/wireguard-android/tree/master/tunnel/src/test/resources" rel="noopener noreferrer"&gt;client.conf&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;



&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  # Setting up the project
&lt;/h2&gt;

&lt;p&gt;Are you ready to dive into the coding part? Let's get started!&lt;/p&gt;
&lt;h3&gt;
  
  
  Add dependency to the project
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dependencies {
    // Add WireGuard dependency  
    implementation("com.wireguard.android:tunnel:1.0.20210211") 

    // Add desugaring library for Java 8+ API support
    implementation("com.android.tools:desugar_jdk_libs:2.1.5")  
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Check the latest tunnel library for WireGuard for Android: &lt;a href="https://central.sonatype.com/artifact/com.wireguard.android/tunnel" rel="noopener noreferrer"&gt;Maven repository&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Check the latest desugaring library: &lt;a href="https://mvnrepository.com/artifact/com.android.tools/desugar_jdk_libs" rel="noopener noreferrer"&gt;Maven repository&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Configuring VPN Service in &lt;code&gt;AndroidManifest.xml&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Before using the WireGuard module, update your &lt;code&gt;AndroidManifest.xml&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Add Required Permissions:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
These permissions allow the app to access the internet and check network status:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;uses-permission android:name="android.permission.INTERNET" /&amp;gt;
&amp;lt;uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Register VPN Service:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Add the following inside the &lt;code&gt;&amp;lt;application&amp;gt;&lt;/code&gt; tag to enable the WireGuard VPN service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;application&amp;gt;
    &amp;lt;service
        android:name="com.wireguard.android.backend.GoBackend$VpnService"
        android:exported="false"
        android:permission="android.permission.BIND_VPN_SERVICE"&amp;gt;

        &amp;lt;intent-filter&amp;gt;
            &amp;lt;action android:name="android.net.VpnService" /&amp;gt;
        &amp;lt;/intent-filter&amp;gt;

    &amp;lt;/service&amp;gt;
&amp;lt;/application&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Dive into the coding logic
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create a class &lt;code&gt;WireGuardTunnel.kt&lt;/code&gt; in your project. This class acts as a wrapper for a WireGuard tunnel, allowing you to track and manage its state efficiently.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import com.wireguard.android.backend.Tunnel

typealias StateChangeCallback = (Tunnel.State) -&amp;gt; Unit

class WireGuardTunnel(
    private var name: String,
    private val onStateChanged: StateChangeCallback? = null
) : Tunnel {
    private var state: Tunnel.State = Tunnel.State.DOWN

    override fun getName() = name

    override fun onStateChange(newState: Tunnel.State) {
        state = newState
        onStateChanged?.invoke(newState)
    }

    fun getState(): Tunnel.State = state
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To manage VPN server details, add the following &lt;code&gt;ServerInfo&lt;/code&gt; data class to your project:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import com.google.gson.annotations.SerializedName

data class ServerInfo(
    // Interface details
    @SerializedName("address") val interfaceAddress: String?,
    @SerializedName("dns") val interfaceDns: String?,
    @SerializedName("private_key") val interfacePrivateKey: String?,

    // Peer details
    @SerializedName("public_key") val peerPublicKey: String?,
    @SerializedName("preshared_key") val peerPresharedKey: String?,
    @SerializedName("allowed_ips") val peerAllowedIPs: String?,
    @SerializedName("endpoint") val peerEndpoint: String?,
    @SerializedName("persistent_keep_alive") val peerPersistentKeepalive: String?
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To track different states of the VPN connection, add the following VPNStatus enum class:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;enum class VPNStatus {
    PREPARE,        // VPN is getting ready  
    CONNECTING,     // Establishing a connection  
    CONNECTED,      // VPN is active and running  
    DISCONNECTING,  // Disconnecting from the VPN  
    DISCONNECTED,   // VPN is not connected  
    NO_CONNECTION,  // No available VPN connection  
    REFRESHING      // Refreshing VPN status  
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To handle VPN operations, add the following &lt;code&gt;WireguardManager&lt;/code&gt; class. We'll expand it with more methods later.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import android.app.Activity
import android.content.Context
import com.wireguard.android.backend.Backend
import kotlinx.coroutines.*

class WireguardManager(private val context: Context, private val activity: Activity?) {
    private val scope = CoroutineScope(Job() + Dispatchers.Main.immediate)
    private var backend: Backend? = null
    private var tunnelName: String = "wg_default"
    private var config: Config? = null
    private var tunnel: WireGuardTunnel? = null
    private val futureBackend = CompletableDeferred&amp;lt;Backend&amp;gt;()
    private val TAG = "WireguardManager"

    companion object {
        private var state: VPNStatus = VPNStatus.NO_CONNECTION
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Implement the initialize method in the &lt;code&gt;WireguardManager&lt;/code&gt; class:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class WireguardManager(private val context: Context, private val activity: Activity?) {

    // Remaining code

    init {
        scope.launch(Dispatchers.IO) {
            try {
                cachedTunnelData = SharedPreferenceHelper.getVpnData()
                backend = GoBackend(context)
                futureBackend.complete(backend!!)
                activity?.let { GoBackend.VpnService.prepare(it) }
            } catch (e: Throwable) {
                Log.e(TAG, "ERROR: Exception during WireguardManager initialization: ${e.localizedMessage}")
                Log.e(TAG, Log.getStackTraceString(e))
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Add support methods:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class WireguardManager(private val context: Context, private val activity: Activity?) {

    // Remaining code

    /**
     * Generates WireGuard configuration from the provided ServerInfo.
     * This creates a wg-quick compatible configuration for the VPN tunnel.
     */
    private fun getConfigData(tunnelData: ServerInfo): Config {
        val wgQuickConfig = """
            [Interface]
            Address = ${tunnelData.interfaceAddress ?: ""}
            DNS = ${tunnelData.interfaceDns ?: ""}
            PrivateKey = ${tunnelData.interfacePrivateKey ?: ""}

            [Peer]
            PublicKey = ${tunnelData.peerPublicKey ?: ""}
            PresharedKey = ${tunnelData.peerPresharedKey ?: ""}
            AllowedIPs = ${tunnelData.peerAllowedIPs ?: ""}
            Endpoint = ${tunnelData.peerEndpoint ?: ""}
            PersistentKeepalive = ${tunnelData.peerPersistentKeepalive ?: ""}
        """.trimIndent()

        val inputStream = ByteArrayInputStream(wgQuickConfig.toByteArray())
        return Config.parse(inputStream)
    }

    /**
     * Checks if any VPN connection is currently active on the device.
     * Returns `true` if a VPN connection is detected, otherwise `false`.
     */
    val isVpnActive: Boolean
        get() {
            return try {
                val connectivityManager =
                    context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

                val activeNetwork = if (Build.VERSION.SDK_INT &amp;gt;= Build.VERSION_CODES.M) {
                    connectivityManager.activeNetwork ?: return false
                } else {
                    // For Android &amp;lt; 6.0, use the old method
                    val networkInfo = connectivityManager.activeNetworkInfo
                    return networkInfo != null &amp;amp;&amp;amp; networkInfo.type == ConnectivityManager.TYPE_VPN
                }

                val networkCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork)

                // Check if any VPN is active
                networkCapabilities?.hasTransport(NetworkCapabilities.TRANSPORT_VPN) == true
            } catch (e: Exception) {
                Log.e(TAG, "isVpnActive - ERROR - ${e.localizedMessage}", e)
                false
            }
        }

    /**
     * Retrieves an existing WireGuard tunnel or creates a new one if none exists.
     * The `callback` function listens for state changes in the tunnel.
     */
    private fun getTunnel(name: String, callback: StateChangeCallback? = null): WireGuardTunnel {
        if (tunnel == null) {
            tunnel = WireGuardTunnel(name, callback)
        }
        return tunnel as WireGuardTunnel
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Add methods to update the status:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class WireguardManager(private val context: Context, private val activity: Activity?) {

    // Remaining code

    /**
     * Updates the VPN status based on the tunnel's state.
     * Runs on the main thread to ensure UI updates happen smoothly.
     */
    private fun updateStageFromState(state: Tunnel.State) {
        scope.launch(Dispatchers.Main) {
            when (state) {
                Tunnel.State.UP -&amp;gt; updateStage(VPNStatus.CONNECTED)      // VPN is active
                Tunnel.State.DOWN -&amp;gt; updateStage(VPNStatus.DISCONNECTED) // VPN is disconnected
                else -&amp;gt; updateStage(VPNStatus.NO_CONNECTION)             // No active VPN connection
            }
        }
    }

    /**
     * Sets the VPN status and saves it in shared preferences.
     * Ensures status updates run on the main thread.
     */
    private fun updateStage(stage: VPNStatus?) {
        scope.launch(Dispatchers.Main) {
            val updatedStage = stage ?: VPNStatus.NO_CONNECTION
            state = updatedStage
            // Store VPN status in SharedPreferences if required
        }
    }

     /**
     * Returns the VPN status based on the tunnel's state.
     */
    fun getStatus(): VPNStatus {
        return state
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Add methods to start the VPN service:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class WireguardManager(private val context: Context, private val activity: Activity?) {

    // Remaining code

    /**
     * Starts the VPN connection process.
     * Initializes the tunnel and attempts to connect.
     */
    fun start(tunnelData: ServerInfo) {
        initialize(tunnelName)
        connect(tunnelData)
    }

    /**
     * Initializes the tunnel with a given name.
     * Ensures the tunnel name is valid before proceeding.
     */
    private fun initialize(localizedDescription: String) {
        if (Tunnel.isNameInvalid(localizedDescription)) {
            Log.e(TAG, "Invalid Tunnel Name: $localizedDescription")
            return
        }
        tunnelName = localizedDescription
    }

    /**
     * Connects to the VPN using the provided tunnel configuration.
     * Updates VPN status at different stages of the connection process.
     */
    private fun connect(tunnelData: ServerInfo) {
        scope.launch(Dispatchers.IO) {
            try {
                updateStage(VPNStatus.PREPARE) // Preparing VPN connection

                // Generate WireGuard configuration
                config = getConfigData(tunnelData)
                updateStage(VPNStatus.CONNECTING) // Attempting to connect

                // Retrieve or create the WireGuard tunnel
                val tunnel = getTunnel(tunnelName) { state -&amp;gt;
                    scope.launch {
                        Log.i(TAG, "onStateChange - $state")
                        updateStageFromState(state)
                    }
                }

                // Activate the VPN connection
                futureBackend.await().setState(tunnel, Tunnel.State.UP, config)

                scope.launch(Dispatchers.Main) {
                    updateStage(VPNStatus.CONNECTED) // VPN is successfully connected
                    // Store VPN status in SharedPreferences if required
                }

                Log.i(TAG, "Connect - success!")
            } catch (e: Throwable) {
                updateStage(VPNStatus.NO_CONNECTION) // Failed to establish a connection
                Log.e(TAG, "Connect - ERROR - ${e.message}")
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Add methods to disconnect the VPN service:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class WireguardManager(private val context: Context, private val activity: Activity?) {
    // Remaining code

    /**
     * Stops the VPN connection by calling the disconnect method.
     */
    fun stop() {
        disconnect()
    }

    /**
     * Disconnects the active VPN tunnel.
     * - If no tunnel is running, logs an error.
     * - Updates VPN status before and after disconnection.
     * - Handles reconnection if cached tunnel data exists.
     */
    private fun disconnect() {
        scope.launch(Dispatchers.IO) {
            try {
                // Check if any tunnel is currently running
                if (futureBackend.await().runningTunnelNames.isEmpty()) {
                    throw Exception("Tunnel is not running")
                }

                updateStage(VPNStatus.DISCONNECTING)

                // Retrieve the active tunnel and monitor state changes
                val tunnel = getTunnel(tunnelName) { state -&amp;gt;
                    scope.launch {
                        Log.i(TAG, "onStateChange - $state")
                        updateStageFromState(state)
                    }
                }

                // Set the tunnel state to DOWN to disconnect
                futureBackend.await().setState(tunnel, Tunnel.State.DOWN, config)

                // Update VPN status and shared preferences on the main thread
                scope.launch(Dispatchers.Main) {
                    updateStage(VPNStatus.DISCONNECTED)
                    // Store VPN status in SharedPreferences if required
                }
                Log.i(TAG, "Disconnect - success!")
            } catch (e: Throwable) {
                Log.e(TAG, "Disconnect - ERROR - ${e.message}")
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now create a View Model class &lt;code&gt;VPNViewModel&lt;/code&gt;, responsible for handling the VPN state, starting/stopping the connection, and monitoring the VPN status efficiently.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class VPNViewModel(application: Application) : AndroidViewModel(application) {
    private val context by lazy { application.applicationContext }
    private var wireguardManager: WireguardManager? = null

    // VPN connection status as a StateFlow
    private val _vpnState = MutableStateFlow(VPNStatus.NO_CONNECTION)
    val vpnState: StateFlow&amp;lt;VPNStatus&amp;gt; = _vpnState.asStateFlow()

    // Whether VPN is currently active
    private val _isVpnActive = MutableStateFlow(false)
    val isVpnActive: StateFlow&amp;lt;Boolean&amp;gt; = _isVpnActive.asStateFlow()

    /**
     * Initializes the WireGuard manager and starts monitoring VPN state changes.
     * This method should be called when the ViewModel is created.
     */
    fun initVPN(activity: Activity) {
        wireguardManager = WireguardManager(context, activity)

        // Observe VPN state changes in a coroutine
        viewModelScope.launch {
            while (isActive) {
                delay(500) // Check every 500ms (half a second)

                // Restore last known VPN state from SharedPreferences if needed and assign in fallback
                _vpnState.value = wireguardManager?.getStatus()
                    ?: VPNStatus.NO_CONNECTION

                _isVpnActive.value = wireguardManager?.isVpnActive ?: false
            }
        }
    }

    /**
     * Starts the VPN connection with the given tunnel data.
     */
    fun startVPN(tunnelData: ServerInfo) {
        viewModelScope.launch {
            wireguardManager?.start(tunnelData)
        }
    }

    /**
     * Stops the active VPN connection.
     */
    fun stopVPN() {
        viewModelScope.launch {
            wireguardManager?.stop()
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Managing the VPN Connections with ViewModel in Jetpack Compose
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Handling VPN Permission Request
val vpnPermissionLauncher = rememberLauncherForActivityResult(
    contract = ActivityResultContracts.StartActivityForResult()
) { result -&amp;gt;
    if (result.resultCode == Activity.RESULT_OK) {
        // Permission granted, now connect
        viewModel.startVPN(tunnelData)
    } else {
        // Permission denied, show an error or update UI
    }
}

// Starting a VPN Connection
coroutineScope.launch(Dispatchers.IO) {
    val intent = GoBackend.VpnService.prepare(activity)
    delay(100) // Small delay to prevent UI lag
    if (intent != null) {
        vpnPermissionLauncher.launch(intent) // Request permission if needed
    } else {
        viewModel.startVPN(tunnelData) // No permission needed, start directly
    }
}

// Stopping a VPN Connection
coroutineScope.launch(Dispatchers.IO) {
    delay(100) // Simulate network request
    withContext(Dispatchers.Main) {
        viewModel.stopVPN() // Stop the VPN connection
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  # Let's Wrap
&lt;/h2&gt;

&lt;p&gt;Managing VPN connections in an Android app requires handling permissions, starting connections, and managing disconnections efficiently. Using Jetpack Compose and a ViewModel, we can make the app easy to use while keeping the code organized and easy to manage.&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%2Fcqku8zfdzb1ipz0ionn2.jpg" 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%2Fcqku8zfdzb1ipz0ionn2.jpg" alt="Thanks for reading"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you found this blog helpful or have any further questions, we would love to hear from you. Feel &lt;strong&gt;free to reach out&lt;/strong&gt; and &lt;strong&gt;&lt;a href="https://dev.to/ankushppie"&gt;follow us&lt;/a&gt;&lt;/strong&gt; on our social media platforms for more tips and tutorials on tech-oriented posts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Happy coding!👨‍💻
&lt;/h3&gt;

</description>
      <category>android</category>
      <category>wireguard</category>
      <category>jetcompose</category>
      <category>vpn</category>
    </item>
    <item>
      <title>Images Vanish: My Experience with the dev.to Image Outage</title>
      <dc:creator>Ankush Lokhande</dc:creator>
      <pubDate>Tue, 01 Apr 2025 10:46:28 +0000</pubDate>
      <link>https://dev.to/ankushppie/images-vanish-my-experience-with-the-devto-image-outage-f0g</link>
      <guid>https://dev.to/ankushppie/images-vanish-my-experience-with-the-devto-image-outage-f0g</guid>
      <description>&lt;p&gt;Recently, I noticed that all the images in my dev.to blogs are missing! 😟 At first, I thought it was just a small glitch, but now I’m wondering—has this happened to anyone else?&lt;br&gt;
But the platform's image hosting had an issue—possibly a server crash or temporary outage.&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%2Fpnn3d0iv0kfmkbi6p8j3.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%2Fpnn3d0iv0kfmkbi6p8j3.png" alt="Image no longer exist - devto" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Is it a platform-wide issue, or just my account? Could it be a server crash? I have no idea! If you’re also facing this, let me know.&lt;/p&gt;

&lt;p&gt;I trust this platform, but what is happening??? 😟&lt;/p&gt;

&lt;p&gt;Also, does anyone know how to reach out to the &lt;a href="https://dev.to/"&gt;dev.to&lt;/a&gt; team for help? If you have any suggestions, please share. Let’s figure this out together! 🚀&lt;/p&gt;

</description>
      <category>devto</category>
      <category>help</category>
      <category>webdev</category>
      <category>discuss</category>
    </item>
    <item>
      <title>15 Best VSCode Extensions to Improve Your Productivity in 2023 (PART-1)</title>
      <dc:creator>Ankush Lokhande</dc:creator>
      <pubDate>Fri, 27 Oct 2023 04:30:00 +0000</pubDate>
      <link>https://dev.to/ankushppie/best-vs-code-extensions-boost-your-productivity-part-1-2hlf</link>
      <guid>https://dev.to/ankushppie/best-vs-code-extensions-boost-your-productivity-part-1-2hlf</guid>
      <description>&lt;p&gt;👋 Hey all,&lt;/p&gt;

&lt;p&gt;Boosting our productivity as a developer plays an important role in daily planning and work. Whenever you're working on the complex structure of code, complex coding tasks, debugging, or working on new features, the ability to efficiently manage your time and workflow can make a significant difference in your overall performance.&lt;/p&gt;

&lt;p&gt;As you prepare for interviews and work as a developer, the right tools and strategies boost your productivity and directly impact on workload, progress, and growth.&lt;/p&gt;

&lt;p&gt;As a mobile developer, I've been using &lt;strong&gt;Visual Studio Code&lt;/strong&gt; &lt;em&gt;(VS-code)&lt;/em&gt; since the beginning of my coding journey, and I am excited to share my experience using this blog.&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%2Fdc3rk3opjznfcije5ipo.gif" 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%2Fdc3rk3opjznfcije5ipo.gif" alt="Excited to share my experience"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  # Best and Useful VS-Code Extensions
&lt;/h2&gt;

&lt;p&gt;In this blog, we'll explore productivity-boosting VS Code extensions and see how they can help you become an excellent coder.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Better Comments
&lt;/h3&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%2Fb25ra01lb25otq7z5ecr.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%2Fb25ra01lb25otq7z5ecr.png" alt="Better Comments Extension"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Better Comments&lt;/strong&gt; extension will help you to create more human-friendly comments in your code and also provide customization for custom comments and edit the color schema.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How to use:&lt;/em&gt;&lt;br&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%2Fx063i1xt933fav66zj62.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%2Fx063i1xt933fav66zj62.png" alt="Example for Better Comments"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Extension Link: &lt;a href="https://marketplace.visualstudio.com/items?itemName=aaron-bond.better-comments" rel="noopener noreferrer"&gt;Visual Studio Code Market Place: Better Comments&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Prettier - Code formatter
&lt;/h3&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%2Fr89k2nrgkuuaxazh2moh.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%2Fr89k2nrgkuuaxazh2moh.png" alt="Prettier - Code formatter Extension"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Prettier - Code formatter&lt;/strong&gt; is the best tool to format your code in a better way. You can format your JSON, HTML, JavaScript, Dart &amp;amp; whatever you want.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How to use:&lt;/em&gt;&lt;br&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%2Fy0vum45aegg6nrfdhs6s.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%2Fy0vum45aegg6nrfdhs6s.png" alt="Example for Prettier - Code formatter"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Extension Link: &lt;a href="https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode" rel="noopener noreferrer"&gt;Visual Studio Code Market Place: Prettier - Code formatter&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Back and Forward buttons
&lt;/h3&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%2F1g5qz48vd5avlck2t9sh.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%2F1g5qz48vd5avlck2t9sh.png" alt="Back and Forward buttons Extension"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Show &lt;strong&gt;back and forward buttons&lt;/strong&gt; on the status bar, as you can see in other IDEs. The buttons are also located towards the bottom left of the screen. It helps to trace activities and indicate where you've previously clicked and which file visited previously.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How to use:&lt;/em&gt; &lt;br&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%2Fhwm33wnvm8m4ozudwjyg.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%2Fhwm33wnvm8m4ozudwjyg.png" alt="Example for Back and Forward buttons"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Extension Link: &lt;a href="https://marketplace.visualstudio.com/items?itemName=grimmer.vscode-back-forward-button" rel="noopener noreferrer"&gt;Visual Studio Code Market Place: Back and Forward buttons&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Turbo Console Log
&lt;/h3&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%2Fmedd7wunw1tdhgi8j0b8.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%2Fmedd7wunw1tdhgi8j0b8.png" alt="Turbo Console Log Extension"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Turbo Console Log&lt;/strong&gt; is a powerful tool for automating the process of writing meaningful log messages. This tool offers vast combinations of log methods.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How to use:&lt;/em&gt;&lt;br&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%2Fi734eelxbya29xepmh3w.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%2Fi734eelxbya29xepmh3w.png" alt="Example for Turbo Console Log"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Extension Link: &lt;a href="https://marketplace.visualstudio.com/items?itemName=ChakrounAnas.turbo-console-log" rel="noopener noreferrer"&gt;Visual Studio Code Market Place: Turbo Console Log&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Android iOS Emulator
&lt;/h3&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%2Fvt3uz9iieqvhmoqt3qk6.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%2Fvt3uz9iieqvhmoqt3qk6.png" alt="Android iOS Emulator Extension"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A small Visual Studio Code extension to run Android and iOS Simulators in a click. It provides support to run the emulator/simulator from the VS-Code&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How to use:&lt;/em&gt;&lt;br&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%2Fr9yruv0bpzgnsxxvfl5x.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%2Fr9yruv0bpzgnsxxvfl5x.png" alt="Example for Android iOS Emulator"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Extension Link: &lt;a href="https://marketplace.visualstudio.com/items?itemName=DiemasMichiels.emulate" rel="noopener noreferrer"&gt;Visual Studio Code Market Place: Android iOS Emulator&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Import Cost
&lt;/h3&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%2F5957m3m0jiok6gse2x2w.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%2F5957m3m0jiok6gse2x2w.png" alt="Import Cost Extension"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Import Cost&lt;/strong&gt; extension displays the size of the imported package inline in the editor. The extension utilizes webpack in order to detect the imported size.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How to use:&lt;/em&gt;&lt;br&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%2F5tmw02e3h00zv1pqho63.jpeg" 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%2F5tmw02e3h00zv1pqho63.jpeg" alt="Example for Import Cost"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Extension Link: &lt;a href="https://marketplace.visualstudio.com/items?itemName=wix.vscode-import-cost" rel="noopener noreferrer"&gt;Visual Studio Code Market Place: Import Cost&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  7. indent-rainbow
&lt;/h3&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%2F1jq7ucveb4qsekgi20g9.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%2F1jq7ucveb4qsekgi20g9.png" alt="indent-rainbow Extension"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;indent-rainbow&lt;/strong&gt; is a straightforward extension that makes your code indentation more readable. It adds colors to the spaces or tabs before your text, using different colors in a repeating pattern. This can be useful when writing code in languages like Python, Nim, Yaml, and even for file types that don't rely on indentation.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How to use:&lt;/em&gt;&lt;br&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%2F9fxk7d56kwqhd8w0k62j.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%2F9fxk7d56kwqhd8w0k62j.png" alt="Example for indent-rainbow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Extension Link: &lt;a href="https://marketplace.visualstudio.com/items?itemName=oderwat.indent-rainbow" rel="noopener noreferrer"&gt;Visual Studio Code Market Place: indent-rainbow&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Code Spell Checker
&lt;/h3&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%2F2vbudi3pvf1r1tv1fm89.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%2F2vbudi3pvf1r1tv1fm89.png" alt="Code Spell Checker Extension"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Spell Checker&lt;/strong&gt; is the best one to minimize minor mistakes during development. The goal of this extension is to help catch common spelling errors while coding. It suggests the spelling mistakes runtime.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How to use:&lt;/em&gt;&lt;br&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%2Fy8xzfok0codqjj3y2fnx.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%2Fy8xzfok0codqjj3y2fnx.png" alt="Example for Code Spell Checker"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Extension Link: &lt;a href="https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker" rel="noopener noreferrer"&gt;Visual Studio Code Market Place: Code Spell Checker&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  9. Image preview
&lt;/h3&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%2Fccesxgkjynvhdsqjikv9.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%2Fccesxgkjynvhdsqjikv9.png" alt="Image preview Extension"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Image preview&lt;/strong&gt; enhances the preview functionality for images. It shows an image preview in the gutter and on hover.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How to use:&lt;/em&gt;&lt;br&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%2Fw9hi8uh9y3f4thcg6obo.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%2Fw9hi8uh9y3f4thcg6obo.png" alt="Example for Image preview"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Extension Link: &lt;a href="https://marketplace.visualstudio.com/items?itemName=kisstkondoros.vscode-gutter-preview" rel="noopener noreferrer"&gt;Visual Studio Code Market Place: Image preview&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  10. VSCode Icons
&lt;/h3&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%2Fs957sb70up4gdi7j9ks0.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%2Fs957sb70up4gdi7j9ks0.png" alt="VSCode Icons Extension"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;VSCode Icons&lt;/strong&gt; organizes your folder icons and displays file icons based on their file extensions. This extension enhances the visual organization of your project in Visual Studio Code, making it easier to identify and work with files and folders.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How to use:&lt;/em&gt;&lt;br&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%2Fe8kwaggdez044p10wux3.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%2Fe8kwaggdez044p10wux3.png" alt="Example for VSCode Icons"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Extension Link: &lt;a href="https://marketplace.visualstudio.com/items?itemName=vscode-icons-team.vscode-icons" rel="noopener noreferrer"&gt;Visual Studio Code Market Place: VSCode Icons&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  11. Polacode
&lt;/h3&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%2Fdm0zxl2azkz4eppvqiky.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%2Fdm0zxl2azkz4eppvqiky.png" alt="Polacode Extension"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create an awesome snippet screenshot with &lt;strong&gt;Polacode&lt;/strong&gt;. This extension makes beautiful screenshots for your code with in a click.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How to use:&lt;/em&gt;&lt;br&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%2Fcyq0taqdmw11smy1if2t.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%2Fcyq0taqdmw11smy1if2t.png" alt="Example for Polacode"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Extension Link: &lt;a href="https://marketplace.visualstudio.com/items?itemName=pnp.polacode" rel="noopener noreferrer"&gt;Visual Studio Code Market Place: Polacode&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  12. Code Runner
&lt;/h3&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%2Fay0fbte2ih02z58ooa3z.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%2Fay0fbte2ih02z58ooa3z.png" alt="Code Runner Extension"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Run code&lt;/strong&gt; extension is a versatile tool designed to streamline the process of running code snippets or entire code files in multiple programming languages. It's a valuable resource for developers, programmers, and tech enthusiasts looking to quickly test and execute code.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How to use:&lt;/em&gt;&lt;br&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%2Fqm36iek8lc4gzrd7vott.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%2Fqm36iek8lc4gzrd7vott.png" alt="Example for Code Runner"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Extension Link: &lt;a href="https://marketplace.visualstudio.com/items?itemName=formulahendry.code-runner" rel="noopener noreferrer"&gt;Visual Studio Code Market Place: Code Runner&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  13. Colorize
&lt;/h3&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%2Fpj0ia5stwrs41qztvwsq.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%2Fpj0ia5stwrs41qztvwsq.png" alt="Colorize Extension"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Instantly visualize CSS colors in your files with &lt;strong&gt;Colorize&lt;/strong&gt;. This extension creates style files looking for colors and generates a colored background (using the color) for each of them.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How to use:&lt;/em&gt;&lt;br&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%2Fymsvnq82lehapn60wok9.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%2Fymsvnq82lehapn60wok9.png" alt="Example for Colorize"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Extension Link: &lt;a href="https://marketplace.visualstudio.com/items?itemName=kamikillerto.vscode-colorize" rel="noopener noreferrer"&gt;Visual Studio Code Market Place: Colorize&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  14. Path Intellisense
&lt;/h3&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%2Fqpekozm8py3sg1u77wnl.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%2Fqpekozm8py3sg1u77wnl.png" alt="Path Intellisense Extension"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Path Intellisense&lt;/strong&gt; plugin offers filename autocompletion and provides file and folder previews as hints.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How to use:&lt;/em&gt;&lt;br&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%2Fp28106kgrvq3yfjn9zp0.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%2Fp28106kgrvq3yfjn9zp0.png" alt="Example for Path Intellisense"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Extension Link: &lt;a href="https://marketplace.visualstudio.com/items?itemName=christian-kohler.path-intellisense" rel="noopener noreferrer"&gt;Visual Studio Code Market Place: Path Intellisense&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  15. Pubspec Assist
&lt;/h3&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%2Fml7714id8wgwexu09keq.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%2Fml7714id8wgwexu09keq.png" alt="Pubspec Assist Extension"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pubspec Assist&lt;/strong&gt; extension allows you to easily add and modify dependencies for your Dart and Flutter project's pubspec.yaml, all without leaving your editor, and formats the file automatically.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How to use:&lt;/em&gt;&lt;br&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%2Fnwvb6d7sclct1t2emn64.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%2Fnwvb6d7sclct1t2emn64.png" alt="Example for Pubspec Assist"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Extension Link: &lt;a href="https://marketplace.visualstudio.com/items?itemName=jeroen-meijer.pubspec-assist" rel="noopener noreferrer"&gt;Visual Studio Code Market Place: Pubspec Assist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These extensions are designed to streamline your workflow, offer useful features, and help you become a more efficient developer. This is just the beginning! We have more amazing VS Code extensions to share with you.&lt;br&gt;
&lt;em&gt;Stay tuned for Part 2.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you found this blog helpful or have any further questions, we would love to hear from you. Feel &lt;strong&gt;free to reach out&lt;/strong&gt; and &lt;strong&gt;&lt;a href="https://dev.to/ankushppie"&gt;follow us&lt;/a&gt;&lt;/strong&gt; on our social media platforms for more tips and tutorials on productivity.&lt;/p&gt;

&lt;h3&gt;
  
  
  Happy coding!👨‍💻
&lt;/h3&gt;

</description>
      <category>vscode</category>
      <category>extensions</category>
      <category>productivity</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Effective techniques to use Comments in Swift iOS</title>
      <dc:creator>Ankush Lokhande</dc:creator>
      <pubDate>Sun, 29 Jan 2023 04:30:00 +0000</pubDate>
      <link>https://dev.to/ankushppie/effective-techniques-to-use-comments-in-swift-ios-hje</link>
      <guid>https://dev.to/ankushppie/effective-techniques-to-use-comments-in-swift-ios-hje</guid>
      <description>&lt;p&gt;👋 Hey all,&lt;/p&gt;

&lt;p&gt;In this blog, we will explore the different types of comments and techniques that can be used in the Swift programming language.&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%2Fg5ebt2o7pxcix59xziba.gif" 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%2Fg5ebt2o7pxcix59xziba.gif" alt="Let's Start" width="300" height="166"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Table Of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Types of comments&lt;/li&gt;
&lt;li&gt;Ways to use comments&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;br&gt;
Comments are an essential part of any codebase, allowing developers to convey important information about the code to other developers who may be reading it. We will discuss the types of comments and also discuss the best use cases for each one. Whether you are a beginner or an experienced developer, this post will give you a deeper understanding of how to use comments effectively in your Swift code.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  # Types of comments
&lt;/h2&gt;

&lt;p&gt;In most programming languages, comments are typically written in two ways: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Single-Line comment&lt;/strong&gt; :
Single line comments start with &lt;em&gt;"//"&lt;/em&gt; and continue until the end of the line.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// This is a single line comment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multi-Line comment&lt;/strong&gt; :
Multi-line comments start with &lt;em&gt;"/*"&lt;/em&gt; and end with &lt;em&gt;"*/"&lt;/em&gt;. They can span multiple lines.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* This is a
multi-line comment */

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

&lt;/div&gt;


&lt;p&gt;It is also possible to nest multi-line comments by starting a new multi-line comment inside an existing one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/*
This is a
multi-line comment
/*
 nested multi-line comment
*/
*/

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

&lt;/div&gt;



&lt;p&gt;In addition to the traditional comments, Swift also has a unique type of comment known as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Documentation comment&lt;/strong&gt; :
It is used to provide information about the code and is typically used to document the purpose, usage, and behavior of classes, methods, and properties. It is placed immediately before the code it describes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Swift documentation comments can be written in two formats:&lt;br&gt;
&lt;em&gt;A. Each line is preceded by a triple slash (///):&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;/// This is a documentation comment
/// 
/// Here is the description
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;B. Javadoc-style block comments (/** … */):&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;/**
 This is a documentation comment

 Here is the description
*/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  # Ways to use comments
&lt;/h2&gt;

&lt;p&gt;There are several ways to use comments based on their purpose:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Informative Comment:&lt;/strong&gt;&lt;br&gt;
These provide a brief explanation of what the code is doing or what a specific function or variable is used for.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// This function calculates the average of two numbers
func average(a:Int, b:Int) {
    // code
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Inline Comment:&lt;/strong&gt;&lt;br&gt;
These comments provide explanations or clarifications for specific lines of code and are placed on the same line as the code they describe.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let x = 5 // This is an inline comment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Debugging Comment:&lt;/strong&gt;&lt;br&gt;
These functions are used as a comment for understanding what's happening in the app and for finding and fixing errors during the development process. The most common functions are: &lt;br&gt;
&lt;em&gt;print()&lt;/em&gt;, &lt;em&gt;dump()&lt;/em&gt;, &lt;em&gt;debugPrint()&lt;/em&gt;, &lt;em&gt;NSLog()&lt;/em&gt; and &lt;em&gt;os_log()&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;func average(a: Int, b: Int) -&amp;gt; Float {
    let avg = (a + b) / 2;
    debugPrint(avg);
    return avg;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;debugPrint(avg)&lt;/code&gt; is used as a comment during the development process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Organizational Comment:&lt;/strong&gt;&lt;br&gt;
These are comments that are used to organize the code and leave reminders for yourself or other developers.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;MARK:&lt;/code&gt; syntax is used to create a clear visual separation in the source code, often used to organize code by functionality or feature.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// MARK: - View Life Cycle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;TODO:&lt;/code&gt; syntax is used to indicate that a specific task or issue needs to be addressed in the future.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// TODO: Add error handling
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;FIXME:&lt;/code&gt; syntax is similar to TODO comments, but they indicate that there is an issue with the code that needs to be fixed as soon as possible.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// FIXME: Memory leak
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Here is a screenshot of an example:&lt;br&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%2Flhfgvffny7y26tkw9rd5.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%2Flhfgvffny7y26tkw9rd5.png" alt="Example of MARK, TODO and FIXME" width="800" height="662"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;&lt;code&gt;MARK:-&lt;/code&gt; separates a section of code from the previous one, while &lt;code&gt;MARK:&lt;/code&gt; groups sections together with the previous one.&lt;/em&gt;&lt;br&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%2Fa66039w3c5hmar1pzng9.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%2Fa66039w3c5hmar1pzng9.png" alt="MARK:- vs MARK:" width="362" height="267"&gt;&lt;/a&gt;&lt;br&gt;
Other organizational tags also perform similar behavior.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Deprecation Comment:&lt;/strong&gt;&lt;br&gt;
These are comments that are used to indicate that a function or class is deprecated and should no longer be used.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@available(*, deprecated, message: "Use 'newFunction()' instead", renamed: "newFunction")
func oldFunction() {
    // code
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fesvyzdhi8c96nf2e3le5.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%2Fesvyzdhi8c96nf2e3le5.png" alt="Example of Deprecation comment" width="407" height="55"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Preprocessor Directives Comment:&lt;/strong&gt;&lt;br&gt;
These are the directives tag can be used as a comment to include custom warning and error messages in your code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;#warning&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#warning("This is a warning message.")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Ffvos196hsqtw518ykt18.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%2Ffvos196hsqtw518ykt18.png" alt="Warning tag" width="228" height="27"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;#error&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#error("This is a error message.")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fl6ljrtdguo2u49axce72.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%2Fl6ljrtdguo2u49axce72.png" alt="Error tag" width="210" height="27"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Documentation Comment:&lt;/strong&gt;&lt;br&gt;
These are comments that are used to document the purpose, usage, and parameters of a function or class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
Call alert to handle the crashes and errors.

Use this method to to call alert at any instance

- Note: This method not required any instance of object, It calls globally.

`` `
GNMAlertController().showError(message: "Key not found")
`` `

- Parameters:
    - message: - Error message `(String)`
- Returns: null
*/
internal func showError(message: String) {
    // code
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the preview of documenation:&lt;br&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%2Frb6pipd9m39nwcaitx1g.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%2Frb6pipd9m39nwcaitx1g.png" alt="Example of Documentation Comment" width="487" height="376"&gt;&lt;/a&gt;&lt;br&gt;
Here is the callouts list, You can also use as needed:&lt;br&gt;
&lt;em&gt;Attention&lt;/em&gt;, &lt;em&gt;Author&lt;/em&gt;, &lt;em&gt;Authors&lt;/em&gt;, &lt;em&gt;Bug&lt;/em&gt;, &lt;em&gt;Complexity&lt;/em&gt;, &lt;em&gt;Copyright&lt;/em&gt;, &lt;em&gt;Date&lt;/em&gt;, &lt;em&gt;Experiment&lt;/em&gt;, &lt;em&gt;Important&lt;/em&gt;, &lt;em&gt;Invariant&lt;/em&gt;, &lt;em&gt;Note&lt;/em&gt;, &lt;em&gt;Parameters&lt;/em&gt;, &lt;em&gt;Postcondition&lt;/em&gt;, &lt;em&gt;Precondition&lt;/em&gt;, &lt;em&gt;Remark&lt;/em&gt;, &lt;em&gt;Requires&lt;/em&gt;, &lt;em&gt;Returns&lt;/em&gt;, &lt;em&gt;Since&lt;/em&gt;, &lt;em&gt;Todo&lt;/em&gt;, &lt;em&gt;Version&lt;/em&gt; and &lt;em&gt;Warning&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  # Let's Wrap!
&lt;/h2&gt;

&lt;p&gt;Commenting your code is an efficient way to improve readability, understandability, and maintainability for scalable projects. However, for small projects, clear and effective code alone may be sufficient.&lt;br&gt;
Here is a link that provides tips on how to code effectively: &lt;a href="https://dev.to/ankushppie/unlock-the-power-of-debugging-utilizing-clear-code-as-a-tool-for-documentation-161f"&gt;Utilizing Clear Code as a Tool for Documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By following the above-mentioned techniques, you can ensure that your code is easy to understand, navigate, and maintain.&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%2Fgnf7m5vwb9rnf1t6r1wg.gif" 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%2Fgnf7m5vwb9rnf1t6r1wg.gif" alt="Thanks for reading" width="1024" height="1024"&gt;&lt;/a&gt;&lt;br&gt;
If you found this blog helpful or have any further questions, we would love to hear from you. Feel &lt;strong&gt;free to reach out&lt;/strong&gt; and &lt;strong&gt;&lt;a href="https://dev.to/ankushppie"&gt;follow us&lt;/a&gt;&lt;/strong&gt; on our social media platforms for more tips and tutorials on iOS development.&lt;/p&gt;

&lt;h3&gt;
  
  
  Happy coding!👨‍💻
&lt;/h3&gt;

</description>
      <category>career</category>
      <category>gratitude</category>
      <category>productivity</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Code Documentation: Best Practices and Strategies</title>
      <dc:creator>Ankush Lokhande</dc:creator>
      <pubDate>Mon, 23 Jan 2023 04:30:00 +0000</pubDate>
      <link>https://dev.to/ankushppie/unlock-the-power-of-debugging-utilizing-clear-code-as-a-tool-for-documentation-161f</link>
      <guid>https://dev.to/ankushppie/unlock-the-power-of-debugging-utilizing-clear-code-as-a-tool-for-documentation-161f</guid>
      <description>&lt;p&gt;👋 Hey all,&lt;/p&gt;

&lt;p&gt;In this blog post, we will explore how to effectively use code as a form of documentation in development.&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%2Fr2imisgpixqg7q51g041.gif" 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%2Fr2imisgpixqg7q51g041.gif" alt="You're Welcome"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Table Of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Reasons why code documentation are important in code&lt;/li&gt;
&lt;li&gt;Approach to documentation code&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;br&gt;
As developers, we are not only responsible for writing efficient and optimized code, but we are also responsible for documenting that code. Code documentation, helps to make the code more readable and understandable for others, as well as for future reference.&lt;/p&gt;

&lt;p&gt;It also enables easy collaboration, better maintenance and debugging. Clear, well-written code can make it much easier for other developers to understand the code and make changes to it, which can save time and reduce the risk of errors.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  # Reasons why code documentation are important in code
&lt;/h2&gt;

&lt;p&gt;There are several reasons why code documentation are important in code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Clarity:&lt;/strong&gt; Using the descriptive naming of &lt;code&gt;class&lt;/code&gt;, &lt;code&gt;variable&lt;/code&gt; &amp;amp; &lt;code&gt;method&lt;/code&gt; can be used to explain the purpose of a particular piece of code or to provide context for how it works. This can make it easier for other developers to understand the code and make changes to it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintenance:&lt;/strong&gt; While debugging, descriptive naming can also be used to understand the behaviour of process, which can help other developers to quickly identify and fix the problems.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Organization:&lt;/strong&gt; It can be used to group related code together, making it easier to navigate and understand large or complex codebases.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collaboration:&lt;/strong&gt; Code documentation can be used to communicate with other developers and to coordinate work on a project.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Future reference:&lt;/strong&gt; It can also be used for future reference for the developer or other members in the team who wants to understand the code after a long time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Overall, focus on code documentation to make it clear and descriptive makes code more readable, understandable and maintainable.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  # Approach to documentation code
&lt;/h2&gt;

&lt;p&gt;Using clear and descriptive &lt;code&gt;class&lt;/code&gt;, &lt;code&gt;variable&lt;/code&gt;, and &lt;code&gt;method&lt;/code&gt; names can greatly enhance the understandability and maintainability of code. By providing context and purpose through the names, it becomes easier for others to understand the intended functionality of the code and make changes or additions as needed.&lt;/p&gt;

&lt;p&gt;For example, instead of using a class name like &lt;em&gt;"Cust"&lt;/em&gt; or &lt;em&gt;"MainClass"&lt;/em&gt;, a more descriptive name like &lt;strong&gt;"Customer"&lt;/strong&gt; would provide context and make it clear that the class is related to customer information. Similarly, a variable named &lt;em&gt;"i"&lt;/em&gt; or &lt;em&gt;"a"&lt;/em&gt; doesn't convey any information about its purpose, whereas a variable named &lt;strong&gt;"customerName"&lt;/strong&gt; makes it clear that it stores a customer's name. Lastly, a method named &lt;em&gt;"doSomething"&lt;/em&gt; doesn't explain what the method does, but a method named &lt;strong&gt;"calculateDiscount"&lt;/strong&gt; makes it clear that the method is used to calculate a discount.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Here's an example in Java:&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;class Customer {
    private String customerName;
    private int customerAge;
    private String customerAddress;

    public void setCustomerName(String customerName) {
        this.customerName = customerName;
    }

    public String getCustomerName() {
        return customerName;
    }

    public int calculateDiscount(double purchaseAmount) {
        int discount = 0;
        if (customerAge &amp;gt; 60) {
            discount = (int)(purchaseAmount * 0.1);
        }
        return discount;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;In this example, the class name &lt;em&gt;"Customer"&lt;/em&gt; gives context about what the &lt;u&gt;class represents&lt;/u&gt;. The variable names "customerName", "customerAge" and "customerAddress" makes it clear that they are &lt;u&gt;related to a customer&lt;/u&gt;. The method "calculateDiscount" tells us that the method is used to &lt;u&gt;calculate a discount&lt;/u&gt;, and the parameter "purchaseAmount" tells us that it required the &lt;u&gt;purchase amount as input&lt;/u&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Therefore, writing optimized code and documenting it properly is a vital responsibility for any developer. It ensures that the code is not only functional but also maintainable and understandable for a long run.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  # Let's Wrap
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Experience is not about how many years of experience you have, It is about the quality of your years of experience.&lt;/strong&gt; So always try to learn from the mistakes and apply those lessons to future tasks or projects.&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%2F3wq59kjp1zo3h514l3w4.gif" 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%2F3wq59kjp1zo3h514l3w4.gif" alt="Any Questions?"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you have any insights or knowledge gained from your experience regarding code documentation, please feel free to share it with us in the comments section.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you found this blog helpful or have any further questions, we would love to hear from you. Feel &lt;strong&gt;free to reach out&lt;/strong&gt; and &lt;strong&gt;&lt;a href="https://dev.to/ankushppie"&gt;follow us&lt;/a&gt;&lt;/strong&gt; on our social media platforms for more tips and tutorials.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>codequality</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Create your own CocoaPods library in Swift: A Step-by-Step Guide</title>
      <dc:creator>Ankush Lokhande</dc:creator>
      <pubDate>Sun, 15 Jan 2023 12:59:24 +0000</pubDate>
      <link>https://dev.to/ankushppie/creating-custom-pods-in-swift-for-ios-a-step-by-step-guide-1p6g</link>
      <guid>https://dev.to/ankushppie/creating-custom-pods-in-swift-for-ios-a-step-by-step-guide-1p6g</guid>
      <description>&lt;p&gt;👋 Hey all,&lt;/p&gt;

&lt;p&gt;During my tenure as a developer, I have come across various challenges and have had to find solutions to those challenges. One such challenge was to build a library that could be reused across multiple projects &amp;amp; publish it on the CocoaPods to be reusable by any of the developer. And that's where the concept of creating custom pods came into play.&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%2Fbesf4fdiltoalseymtcl.gif" 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%2Fbesf4fdiltoalseymtcl.gif" alt="Let's Begin" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Table Of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Essential Prerequisites for Setting up your project&lt;/li&gt;
&lt;li&gt;Setting up the Pod Structure&lt;/li&gt;
&lt;li&gt;Publish Pod on CocoaPods&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;br&gt;
In iOS development, &lt;strong&gt;CocoaPods&lt;/strong&gt; is a widely used dependency manager that allows developer to easily integrate third-party libraries and frameworks into the projects. However, sometimes you may need to create your own custom libraries to be used across multiple projects.&lt;/p&gt;

&lt;p&gt;In this blog, we will learn how to build a custom pod using step-by-step approach in Swift for iOS development. We will cover everything from the setting up the pod structure to publishing it on the CocoaPods. By the end of this guide, you will have a solid understanding of how to create and maintain your own custom pods.&lt;/p&gt;

&lt;p&gt;Before we dive into the guide, let's briefly talk about what custom pods are and why you might want to create one. Custom pods are the libraries that you create by yourself. These libraries can be used across multiple projects and allowing you to easily share. This can save your time and effort when working on the new projects, and it can also help you to write more efficient code.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  # Essential Prerequisites for Setting up your project
&lt;/h2&gt;

&lt;p&gt;Before beginning development, it is essential to ensure that you have all the necessary tools installed and that they are up to date.&lt;br&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%2Flkhb5ofx3h8ok7e0vl9p.gif" 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%2Flkhb5ofx3h8ok7e0vl9p.gif" alt="Setup Prerequisites" width="1024" height="1024"&gt;&lt;/a&gt;&lt;br&gt;
Ensure that the Prerequisites are up to date:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A laptop running macOS, as CocoaPods are designed to work with macOS and iOS development.&lt;/li&gt;
&lt;li&gt;The latest version of Xcode, you can be download it from the Mac App Store.&lt;/li&gt;
&lt;li&gt;Ruby, the programming language that CocoaPods is built on. This should be pre-installed on macOS and you can also check by running command:
&lt;code&gt;ruby -v&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The CocoaPods gem, which can be installed by running command in the terminal:
&lt;code&gt;sudo gem install cocoapods&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  # Setting up the Pod Structure
&lt;/h2&gt;

&lt;p&gt;Are you ready to dive into the coding part? Let's get started!&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%2Fnyunl56acsuy684o2uv4.gif" 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%2Fnyunl56acsuy684o2uv4.gif" alt="Start Coding" width="498" height="277"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 1: Initiate Project
&lt;/h3&gt;

&lt;p&gt;First, navigate to the desired directory where you want to create your custom Pod. Once you have selected the folder, open the terminal within that directory.&lt;br&gt;
To create a new project for Pod creation, run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pod lib create [POD_NAME]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, proceed with configuring your Pod as necessary.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Configure a template for your Unique Pod
&lt;/h3&gt;

&lt;p&gt;Please respond to the following prompts (capitalization does not matter):&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A.&lt;/strong&gt; What platform do you want to use?? [ iOS / macOS ]&lt;br&gt;
&lt;code&gt;iOS&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;B.&lt;/strong&gt; What language do you want to use?? [ Swift / ObjC ]&lt;br&gt;
&lt;code&gt;Swift&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;C.&lt;/strong&gt; Would you like to include a demo application with your library? [ Yes / No ]&lt;br&gt;
&lt;code&gt;Yes&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;D.&lt;/strong&gt; Which testing frameworks will you use? [ Quick / None ]&lt;br&gt;
&lt;code&gt;None&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;E.&lt;/strong&gt; Would you like to do view based testing? [ Yes / No ]&lt;br&gt;
&lt;code&gt;No&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Once the setup is complete, it redirect to the project within XCode. If the directory is not already open, open it manually: &lt;br&gt;
&lt;code&gt;[PROJECT_DIRECTORY]/../[POD_NAME]/Example/[POD_NAME.xcworkspace]&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 3: Setup Codebase on GitHub
&lt;/h3&gt;

&lt;p&gt;Create a new repository on GitHub and link it to your existing codebase. &lt;br&gt;
This will set up a GitHub repository with your existing code and allow you to continue to push and pull updates from the repository for future development.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 4: Revise the template version
&lt;/h3&gt;

&lt;p&gt;Set the default pod template setting to the minimum version:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;iOS deployment target: &lt;code&gt;12.0&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Swift version: &lt;code&gt;Swift5&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Project Format: &lt;code&gt;Xcode 12-compatible&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In addition, reflect this updated configuration in both Xcode and the relevant files.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 5: Revise Podspec Metadata file
&lt;/h3&gt;

&lt;p&gt;Revise the &lt;code&gt;.podspec&lt;/code&gt; file within the Podspec Metadata section.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;s.name = &amp;lt;POD_NAME&amp;gt;
s.version = &amp;lt;POD_VERSION&amp;gt; (example: 0.1.0)

# This short description is used to provide a brief summary of the functionality of the pod.
#   * The name of the pod and the purpose it serves.
#   * The main features and functionality provided by the pod.
#   * The main platform(s) or technology(s) that the pod is intended to be used with.
#   * Any dependencies or prerequisites that are required for the pod to function properly.
#   * Any notable or unique features or capabilities of the pod that set it apart from similar libraries or frameworks.
s.summary = &amp;lt;SHORT_DESCRIPTION_OF_POD&amp;gt;

# This description is used to generate tags and improve search results.
#   * Think: What does it do? Why did you write it? What is the focus?
#   * Try to keep it short, snappy and to the point.
#   * Write the description between the DESC delimiters below.
#   * Finally, don't worry about the indent, CocoaPods strips it!
s.description = &amp;lt;&amp;lt;-DESC
&amp;lt;LONG_DESCRIPTION_OF_POD&amp;gt;
DESC
s.homepage = &amp;lt;GITHUB_REPO_LINK&amp;gt;
# s.screenshots = &amp;lt;EXAMPLE_IMAGE&amp;gt;, &amp;lt;EXAMPLE_VIDEO&amp;gt;, &amp;lt;EXAMPLE_GIF&amp;gt;
s.license = { :type =&amp;gt; 'MIT', :file =&amp;gt; 'LICENSE' }
s.author = { &amp;lt;AUTHOR_NAME&amp;gt; =&amp;gt; &amp;lt;AUTHOR_EMAIL_ADDRESS&amp;gt; }
s.source = { :git =&amp;gt; &amp;lt;GITHUB_REPO_URL&amp;gt;, :tag =&amp;gt; s.version.to_s }
s.social_media_url = &amp;lt;SOCIAL_MEDIA_LINK&amp;gt;, &amp;lt;OTHER_LINK&amp;gt;
s.ios.deployment_target = '12.0'
s.source_files = 'Classes/**/*.swift'
s.swift_version = '5.0'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We specified a custom path for source files:&lt;br&gt;
&lt;code&gt;s.source_files = 'Classes/**/*'&lt;/code&gt; thus, we must create &lt;code&gt;Classes&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;Locate the &lt;code&gt;.podspec&lt;/code&gt; file in the Podspec Metadata group, as shown in the screenshot:&lt;br&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%2Faf0o61r2ftqjyy3576tz.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%2Faf0o61r2ftqjyy3576tz.png" alt="Metadata Group" width="800" height="478"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 6: Creating a Codebase Directory
&lt;/h3&gt;

&lt;p&gt;Delete the &lt;code&gt;ReplaceMe.swift&lt;/code&gt; file and Create &lt;code&gt;Classes&lt;/code&gt; folder in the directory:&lt;br&gt;
&lt;code&gt;Pods project &amp;gt; Development Pods group &amp;gt; [POD_NAME] group&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Create a file with the same name as the Pod within the Classes folder and use it to write custom code for the Pod.&lt;br&gt;
example: &lt;code&gt;&amp;lt;POD_NAME&amp;gt;.swift&lt;/code&gt;&lt;br&gt;
You can also create multiple folders and files in order to write personalize code.&lt;/p&gt;

&lt;p&gt;Refer to the screenshot for clarification:&lt;br&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%2Fdkjbmo4c5f01pryq8pei.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%2Fdkjbmo4c5f01pryq8pei.png" alt="Codebase folder structure" width="800" height="562"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 7: Create an example using Pod
&lt;/h3&gt;

&lt;p&gt;To test the code of Pod, create an example by following the instructions in the folder reference:&lt;br&gt;
&lt;code&gt;[POD_NAME] project &amp;gt; Examples for [POD_NAME] group &amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Please refer to the attached screenshot for further clarification:&lt;br&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%2Fvsy7dlrx6ehxw9gj4rhs.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%2Fvsy7dlrx6ehxw9gj4rhs.png" alt="Test code" width="800" height="341"&gt;&lt;/a&gt;&lt;br&gt;
Implement personalize Pod in example folder to help everyone to understand how to use it.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 8: Push changes to the Git Repository
&lt;/h3&gt;

&lt;p&gt;Commit the changes to the local Git repository and push them to the remote repository.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Your personalized pod can be reused across multiple projects, and can also be shared as open-source with the community.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  # Publish Pod on CocoaPods
&lt;/h2&gt;

&lt;p&gt;Now, We are at the stage where you can easily share your iOS development work with community by publishing personalize Pod to CocoaPods.&lt;br&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%2Fnx6d7wbjewoc03rax3ea.gif" 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%2Fnx6d7wbjewoc03rax3ea.gif" alt="Not done yet" width="1024" height="1024"&gt;&lt;/a&gt;&lt;br&gt;
Publishing your own CocoaPod is fairly straight forward. Let's get started!&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 1: Getting setup with Trunk
&lt;/h3&gt;

&lt;p&gt;To publish new or update Pod(libraries) to CocoaPods for public release you need a valid Trunk session on your current device. You can also publish your private library as well on the CocoaPods.&lt;/p&gt;

&lt;p&gt;First sign up with email address to begins a valid session on your current device. We are using terminal to access the Trunk account. To register, please follow these instructions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run command in the terminal by navigating to the project's directory.
Here is the example:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pod trunk register ankush@example.org 'Ankush Lokhande' --description='Macbook Air'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;email and author name is the required parameter to run this command. CocoaPods personally recommend including a description with your session to give some context when you list your sessions later.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Shortly you will get an email by Trunk to verify the connection between your Trunk account and the current computer. With the email open on your computer device, you are now able to access your Trunk account through the terminal. You can list your sessions by running the command:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pod trunk me
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Trunk accounts do not have passwords, only per-computer session tokens.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 2: Validate Pod using lint
&lt;/h3&gt;

&lt;p&gt;You can validate a pod using lint by running the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pod lib lint &amp;lt;POD_NAME.podspec&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will check the podspec file of the specified pod against the CocoaPods specs guideline and provide feedback on any error or issues that it finds on your pod. You can also skip the warnings and it only fails in the errors case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pod lib lint &amp;lt;POD_NAME.podspec&amp;gt; --allow-warnings
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you have fixed issues or errors that are detected, you can then submit the pod for review.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Create Release
&lt;/h3&gt;

&lt;p&gt;You can create release by the multiple ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using terminal:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cd ~/code/Pods/NAME
$ edit NAME.podspec
# set the new version to 0.0.1
# set the new tag to 0.0.1
$ pod lib lint

$ git add -A &amp;amp;&amp;amp; git commit -m "Release 0.0.1."
$ git tag '0.0.1'
$ git push --tags
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Using GitHub web interface:
Here are the steps:

&lt;ul&gt;
&lt;li&gt;Go to the GitHub repository for your project.&lt;/li&gt;
&lt;li&gt;Click the "Releases" tab near the top of the page.&lt;/li&gt;
&lt;li&gt;Click the "Create a new release" button.&lt;/li&gt;
&lt;li&gt;In the "Tag version" field, enter a version number for your release (e.g. 1.0.0).&lt;/li&gt;
&lt;li&gt;In the "Release title" field, enter a name for your release (e.g. "Initial Release").&lt;/li&gt;
&lt;li&gt;Optionally, you can write a description of the release in the "Description" field.&lt;/li&gt;
&lt;li&gt;Click the "Publish release" button.&lt;/li&gt;
&lt;/ul&gt;


&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%2Fskrj6ha18eep9dsy76zv.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%2Fskrj6ha18eep9dsy76zv.png" alt="Create Git Release" width="517" height="227"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Deploying a Library
&lt;/h3&gt;

&lt;p&gt;You must have a valid Trunk session to deploy a specific library. We have already discussed how to use Trunk.&lt;br&gt;
Run the command to deploy library:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pod trunk push [POD_NAME.podspec]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will deploy your Podspec to Trunk and make it publicly available to everyone. You can also deploy Podspecs to your own private specs repo with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pod repo push REPO [NAME.podspec]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After deploying specific pod, it generate a dedicated URL for your pod. &lt;br&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%2Fr0hyi5jp1jbi3bu6k79y.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%2Fr0hyi5jp1jbi3bu6k79y.png" alt="Deploy pod" width="632" height="230"&gt;&lt;/a&gt;&lt;br&gt;
Now, The URL provided in the terminal can now be used by anyone to access your pod.&lt;/p&gt;

&lt;h2&gt;
  
  
  Congrats! 🎉
&lt;/h2&gt;

&lt;p&gt;Your pod is published on the CocoaPods. &lt;br&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%2Fk3svu15uxq6elh1w68mn.gif" 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%2Fk3svu15uxq6elh1w68mn.gif" alt="Work done" width="498" height="280"&gt;&lt;/a&gt;&lt;br&gt;
You can access your pod on CocoaPods using the provided link by Trunk. Anyone with link can add the pod to an existing Xcode project and use the feature across multiple projects.&lt;br&gt;
&lt;strong&gt;Note:&lt;/strong&gt; May be it take time up to a  week or a month to appear your pod in the CocoaPods search results.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  # Let's Wrap!
&lt;/h2&gt;

&lt;p&gt;With a little bit of effort, you can create a pod that becomes a valuable asset to the iOS developer community. By following the step-by-step guide outlined in this blog post, you should now have a solid understanding of how to create, test, and distribute your own custom pods. With this knowledge, you can easily create reusable components that can save you time and effort when developing iOS apps. You can also extend the functionality of your pod with the time and make it more reusable and functional.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Resources for in-depth exploration:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://cocoapods.org/" rel="noopener noreferrer"&gt;CocoaPods Website&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://guides.cocoapods.org/" rel="noopener noreferrer"&gt;CocoaPods Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://guides.cocoapods.org/making/making-a-cocoapod.html" rel="noopener noreferrer"&gt;Making a CocoaPod&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://guides.cocoapods.org/making/getting-setup-with-trunk.html" rel="noopener noreferrer"&gt;Getting setup with Trunk&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/CocoaPods/CocoaPods" rel="noopener noreferrer"&gt;GitHub Repo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Here are a few additional tips to keep in mind when creating and maintaining your custom pod:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make sure to include clear and comprehensive examples of how to use the pod in your documentation.&lt;/li&gt;
&lt;li&gt;Regularly test the pod in different environments to ensure compatibility and fix any bugs.&lt;/li&gt;
&lt;li&gt;Always include versioning and release notes to keep track of the updates and changes made to the pod.&lt;/li&gt;
&lt;li&gt;Consider open-sourcing the pod to allow other developers to contribute and improve the code.&lt;/li&gt;
&lt;li&gt;Be responsive to issues and pull requests, and maintain an active presence in the community around your pod.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By following these tips, you can ensure that your custom pod is well-maintained and widely adopted by other developers.&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%2Fwdqzgpkzz1wpb1df77w7.gif" 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%2Fwdqzgpkzz1wpb1df77w7.gif" alt="Happy coding" width="480" height="320"&gt;&lt;/a&gt;&lt;br&gt;
If you found this blog helpful or have any further questions, we would love to hear from you. Feel &lt;strong&gt;free to reach out&lt;/strong&gt; and &lt;strong&gt;&lt;a href="https://dev.to/ankushppie"&gt;follow us&lt;/a&gt;&lt;/strong&gt; on our social media platforms for more tips and tutorials on iOS development.&lt;/p&gt;

&lt;h3&gt;
  
  
  Happy coding!👨‍💻
&lt;/h3&gt;

</description>
      <category>c</category>
      <category>programming</category>
      <category>performance</category>
      <category>discuss</category>
    </item>
  </channel>
</rss>
