<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Kotlin - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Kotlin - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sat, 23 May 2026 08:50:46 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/kotlin/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Master Kotlin & Android 60-Hour Course ]]>
                </title>
                <description>
                    <![CDATA[ Do you want to create the next groundbreaking mobile app? Kotlin, a modern and powerful language officially backed by Google, not only makes Android development more efficient and enjoyable but also opens doors to diverse programming opportunities be... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/master-kotlin-and-android-60-hour-course/</link>
                <guid isPermaLink="false">6824aba7be2c002301d59188</guid>
                
                    <category>
                        <![CDATA[ Kotlin ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Android ]]>
                    </category>
                
                    <category>
                        <![CDATA[ youtube ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Beau Carnes ]]>
                </dc:creator>
                <pubDate>Wed, 14 May 2025 14:41:43 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1747233684976/019ffd11-b74c-437d-815f-857ab3465317.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Do you want to create the next groundbreaking mobile app? Kotlin, a modern and powerful language officially backed by Google, not only makes Android development more efficient and enjoyable but also opens doors to diverse programming opportunities beyond mobile. Whether you're looking to build innovative applications, solve real-world problems, or join a thriving global community of developers, learning Kotlin and Android is a great investment in your future.</p>
<p>We just posted a massive 60-hour Kotlin and Android Development course on the freeCodeCamp.org YouTube channel. This course will help you master modern Android practices. Alexandru Cristian developed this course. It’s packed with hands-on practice, ensuring you not only learn the theory but also apply it by building multiple real-world applications.</p>
<p>This is a thorough exploration of the Kotlin programming language and the Android development ecosystem. Here’s a glimpse of what you’ll learn:</p>
<h3 id="heading-kotlin-from-the-ground-up"><strong>Kotlin from the ground up</strong></h3>
<ul>
<li><p>Solidify your understanding of Kotlin syntax, variables, operators, control flow (loops, conditionals), and null safety.</p>
<ul>
<li><p>Dive deep into Object-Oriented Programming (OOP) with Kotlin, covering classes, inheritance, interfaces, abstract classes, and data classes.</p>
</li>
<li><p>Master Kotlin Collections (lists, sets, maps) and powerful functions to manipulate them.</p>
</li>
<li><p>Explore advanced concepts like Generics, Lambda functions, and Kotlin Coroutines for efficient asynchronous programming.</p>
</li>
<li><p>Even touch upon SQL basics to understand data persistence.</p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-comprehensive-android-development"><strong>Comprehensive android development</strong></h3>
<ul>
<li><p>Get started with Android Studio and understand the Android project structure.</p>
<ul>
<li><p>Learn traditional UI development with XML, including various layouts (LinearLayout, RelativeLayout, ConstraintLayout) and UI widgets.</p>
</li>
<li><p>Master Android Activities and Fragments, their lifecycles, and how to navigate between screens using Intents and the modern Navigation Component.</p>
</li>
<li><p>Build dynamic lists with RecyclerView.</p>
</li>
<li><p>Understand and implement Material Design principles.</p>
</li>
<li><p>Work with data persistence using Room Database and connect to the cloud with Firebase Firestore.</p>
</li>
<li><p>Make network requests and handle APIs using Retrofit and parse JSON data.</p>
</li>
<li><p>Implement robust app architecture using MVVM (Model-View-ViewModel), LiveData, and potentially Dependency Injection.</p>
</li>
<li><p>Get an introduction to the future of Android UI with Jetpack Compose.</p>
</li>
</ul>
</li>
</ul>
<p>Theory is important, but practice is what makes a developer. Throughout this 60-hour course, you'll be building a portfolio of applications. The final project is an Uber clone that will have you implementing features like maps integration, user authentication, real-time location tracking, and more, demonstrating truly professional-grade development techniques.</p>
<h3 id="heading-start-learning-today">Start learning today</h3>
<p>Learning Kotlin and Android development opens doors to an exciting career in mobile technology. Android powers billions of devices worldwide, and skilled developers are in constant demand. Kotlin is a modern, concise, and powerful language officially supported by Google for Android development, making it an essential skill for today's app creators.</p>
<p>Watch the full course on <a target="_blank" href="https://youtu.be/blKkRoZPxLc">the freeCodeCamp.org YouTube channel</a> (60-hour watch).</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/blKkRoZPxLc" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Concurrency in Kotlin Server-Side Development ]]>
                </title>
                <description>
                    <![CDATA[ By Faith Oyama Imagine you're running a bustling restaurant. Orders fly in, dishes need cooking, tables require clearing, and happy customers demand attention. How can you handle all this chaos without everything turning into a total disaster? This i... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/concurrency-in-kotlin-server-side-development/</link>
                <guid isPermaLink="false">66d45edb230dff01669057f3</guid>
                
                    <category>
                        <![CDATA[ concurrency ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Kotlin ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 05 Jan 2024 23:59:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/01/concurrency.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Faith Oyama</p>
<p>Imagine you're running a bustling restaurant. Orders fly in, dishes need cooking, tables require clearing, and happy customers demand attention. How can you handle all this chaos without everything turning into a total disaster? This is where concurrency comes in.</p>
<p>In the world of server-side development, things can get just as hectic. Users fire off requests, databases need querying, calculations demand crunching, and all this needs to happen smoothly and efficiently. Without concurrency, it's like having one overworked chef trying to do everything.</p>
<p>But with concurrency, it's like adding a whole team of skilled multitaskers to your kitchen. You have specialized "coroutines" handling different tasks – one taking orders, another cooking, one washing dishes, and so on. Each works simultaneously, but in a coordinated way, ensuring your customers get their delicious meals fast and with a smile.</p>
<h2 id="heading-examples-of-concurrency">Examples of Concurrency</h2>
<p>Here are some real-world examples of how concurrency works in server-side development:</p>
<p><strong>Serving multiple users at once:</strong> Imagine your website gets slammed by eager shoppers during a flash sale. Without concurrency, each user request would have to wait its turn, leading to frustratingly slow loading times. </p>
<p>But with coroutines, multiple requests can be processed simultaneously, keeping everyone happy and shopping with ease.</p>
<p><strong>Processing data pipelines:</strong> Do you work with really large datasets? Concurrency can break them down and analyze them bit by bit.</p>
<p><strong>Handling asynchronous requests:</strong> Think of API calls, database queries, or file uploads. These often take time to complete. With concurrency, your main program doesn't have to sit and wait. It can launch separate coroutines to handle these requests and get back to other tasks, keeping everything running smoothly.</p>
<p>Concurrency isn't just some fancy buzzword – it's a powerful tool that lets you handle the ever-growing demands of server-side development with ease and efficiency. </p>
<p>Now, we'll dive deeper into the differences between threads and coroutines, the fundamental building blocks of concurrent programming in Kotlin.</p>
<h2 id="heading-threads-vs-coroutines">Threads vs. Coroutines</h2>
<p>Now, let's talk about the two main players on this team: threads and coroutines. </p>
<h3 id="heading-what-are-threads">What are Threads?</h3>
<p>Threads are powerful, and capable of handling complex tasks – but they're also a bit resource-hungry. Each thread requires its memory space and attention from the operating system. </p>
<p>This can be great for demanding tasks like breaking down big numbers or sending critical emails, but if you have too many threads running around, your server starts getting overwhelmed, leading to slowdowns and even crashes.</p>
<h3 id="heading-what-are-coroutines">What are Coroutines?</h3>
<p>Coroutines are lightweight, flexible, and able to switch between tasks in a flash. They don't need their dedicated tables, they share resources efficiently, and they can even pause their work gracefully if something else needs immediate attention. </p>
<p>Think of them as taking orders, checking on tables, and cleaning dishes – always contributing, but in a light and adaptable way.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/kotin.PNG" alt="Image" width="600" height="400" loading="lazy">
<em>Table showing differences bewteen threads and coroutines.</em></p>
<p>So, which of them should you choose? Well, it depends! For heavy lifting, threads are strong and reliable. But for the everyday hustle and bustle, coroutines are your agile friends. </p>
<p>Kotlin favours coroutines for concurrent programming because they're more efficient and easier to manage, especially when dealing with lots of asynchronous tasks.</p>
<h2 id="heading-how-to-launch-coroutines">How to Launch Coroutines</h2>
<p>In your server-side code, there are two main ways to launch coroutines.</p>
<h3 id="heading-launch-and-forget-using-the-launch-keyword">Launch and Forget: Using the <code>launch</code> Keyword</h3>
<p>This fires up a new coroutine and sends it off to its assigned task, but doesn't wait for it to finish. </p>
<p>Here's how it looks in code:</p>
<pre><code class="lang-kotlin"><span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">updateCustomerOrder</span><span class="hljs-params">(
  orderId: <span class="hljs-type">Int</span>,
  newDish: <span class="hljs-type">String</span>
)</span></span> {
  launch {
    updateOrderInDatabase(orderId, newDish)
  }
  sendConfirmationEmail(orderId)
}
</code></pre>
<p>This is ideal for tasks that don't need immediate feedback. You can launch multiple coroutines like this without overloading your server, as they work independently and share resources efficiently.</p>
<h3 id="heading-wait-and-receive-the-async-keyword">Wait and Receive: The <code>async</code> Keyword</h3>
<p>Now, let's say you need to know the total bill before you can settle up with the customer. This is where <code>async</code> comes in. It's like sending an assistant to calculate the bill and then patiently waiting for them to return with the answer.</p>
<p>Here's how it works:</p>
<pre><code class="lang-kotlin"><span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">calculateBill</span><span class="hljs-params">(orderId: <span class="hljs-type">Int</span>)</span></span>: <span class="hljs-built_in">Double</span> {
  <span class="hljs-keyword">val</span> billResult = async {
    calculateBillFromDatabase(orderId)
  }
  <span class="hljs-keyword">val</span> totalBill = billResult.await()
  <span class="hljs-keyword">return</span> totalBill
}
</code></pre>
<p>This is useful for tasks where you need the result before proceeding. The <code>async</code> keyword creates a coroutine that calculates the bill in the background (performs the task), but the main program pauses and waits until the result is ready.</p>
<h2 id="heading-channels-communication-lifelines">Channels: Communication Lifelines</h2>
<p>Channels allow coroutines to send and receive messages in a safe and organized way, even when things get crazy. Here's how they work:</p>
<h3 id="heading-one-way-streets-send-channels">One-Way Streets: Send Channels</h3>
<p>A send channel allows one coroutine to send a message that another coroutine can receive on the other end. Only one direction, just like a one-way street.</p>
<h3 id="heading-bi-directional-bridges-receive-channels">Bi-Directional Bridges: Receive Channels</h3>
<p>Receive channels allow a coroutine to wait for and receive a message that was sent on the corresponding send channel. Two-way communication, like a bridge in both directions.</p>
<h3 id="heading-putting-channels-to-work">Putting Channels to Work:</h3>
<p>Here's an example of using channels to update customer orders:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">val</span> orderUpdatesChannel = Channel&lt;Pair&lt;<span class="hljs-built_in">Int</span>, String&gt;&gt;()

<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">updateCustomerOrder</span><span class="hljs-params">(orderId: <span class="hljs-type">Int</span>, newDish: <span class="hljs-type">String</span>)</span></span> {
  launch {
    updateOrderInDatabase(orderId, newDish)
    orderUpdatesChannel.send(orderId to newDish)
  }
}

<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">sendOrderConfirmationEmails</span><span class="hljs-params">()</span></span> {
  <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) {
    <span class="hljs-keyword">val</span> orderUpdate = orderUpdatesChannel.receive()
    <span class="hljs-keyword">val</span> (updatedOrderId, newDish) = orderUpdate
    sendConfirmationEmail(updatedOrderId)
  }
}
</code></pre>
<p>In this case, the <code>updateCustomerOrder</code> coroutine sends the updated order details through the <code>orderUpdatesChannel</code>. The <code>sendOrderConfirmationEmails</code> coroutine constantly waits on the channel, receiving updates one by one and sending out confirmation emails.</p>
<h2 id="heading-structured-concurrency">Structured Concurrency</h2>
<p>Think of structured concurrency like assigning roles and responsibilities in your kitchen. It helps you:</p>
<ol>
<li><strong>Define the scope:</strong> You can create coroutine contexts that provide specific resources and boundaries for your coroutines to work within. This keeps things organized and prevents rogue coroutines from mucking up the system.</li>
<li><strong>Cancellation:</strong> Imagine a customer changing their order halfway through cooking. Structured concurrency allows you to easily cancel the wrong dish and start preparing the new one, without everything crumbling into a greasy mess.</li>
<li><strong>Supervision:</strong> Structured concurrency lets you set up supervisors who monitor their "child" coroutines, ensuring they finish their tasks properly or handle errors gracefully.</li>
</ol>
<h3 id="heading-key-tools-for-structured-concurrency">Key tools for structured concurrency:</h3>
<p><strong>Dispatchers:</strong> They control where and how your coroutines run, like assigning them to specific threads or pools.</p>
<p><strong>Jobs:</strong> Think of them as the tasks themselves, assigned to specific coroutines within a context. You can track their progress, cancel them if needed, and keep things organized.</p>
<p><strong>Supervisor Jobs:</strong> They supervise child jobs, handling failures and propagating them properly, preventing errors from cascading and ruining the whole meal.</p>
<p>Different types of tasks in your server-side code demand different environments. This is where the various dispatcher types come in:</p>
<ol>
<li><strong>The Main Dispatcher:</strong> Think of it as the front of the house, handling UI updates and interacting directly with the customer (user). It's a single thread, ensuring smooth and responsive interactions without any chaotic multitasking.</li>
<li><strong>The Default Dispatcher:</strong> This is the workhorse for general computation tasks. It uses a thread pool, assigning coroutines to available threads. Great for CPU-intensive calculations, database processing, and other heavy lifting.</li>
<li><strong>The IO Dispatcher:</strong> This dispatcher handles blocking I/O operations like network calls, file access, or database queries. </li>
<li><strong>Custom Dispatchers:</strong> You can create custom dispatchers with specific thread pools or even single threads, tailoring them to the needs of your unique tasks.</li>
</ol>
<p>Choosing the right dispatcher is very important for optimizing performance and avoiding congestion. Here are some tips:</p>
<ul>
<li>Use the main dispatcher only for UI updates and user interaction.</li>
<li>Default dispatcher for most CPU-intensive tasks.</li>
<li>IO dispatcher for any blocking I/O operations.</li>
<li>Consider custom dispatchers for specific high-volume or sensitive tasks.</li>
</ul>
<h2 id="heading-flows">Flows</h2>
<p>Imagine your restaurant is booming, orders flying in faster than the chefs can cook. How do you handle this data deluge without everything turning into a soggy mess?</p>
<p>Think of Flows as streams of data flowing through your server-side code, like the continuous stream of orders coming from the tables. Instead of dealing with each dish individually, Flows let you handle the data continuously, adapting to the pace and transforming it on the fly.</p>
<p>Here's why Flows are a game-changer:</p>
<ul>
<li>No more waiting around for data to arrive. Flows let you launch coroutines to handle the stream asynchronously, keeping your main program free to keep taking orders and managing the overall experience.</li>
<li>Flows allow you to extract insights, generate reports, or trigger actions in real-time.</li>
<li>Flows automatically adjust their pace based on downstream processing capabilities, preventing backlogs and ensuring smooth data flow through your system.</li>
<li>Errors are handled delicately with flows, which transmit them without bringing down the entire service.</li>
</ul>
<p>Here's an example of using Flows to process a stream of sensor readings:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">val</span> sensorReadingsFlow = sensorManager.readings()
    .filter { reading -&gt; reading.temperature &gt; <span class="hljs-number">80</span> } 
    .map { reading -&gt; <span class="hljs-string">"Alert! Sensor <span class="hljs-subst">${reading.id}</span> at <span class="hljs-subst">${reading.temperature}</span> degrees!"</span> }    
    .launchIn(Dispatchers.IO) 
    .onEach { message -&gt; logger.warn(message) } 
    .collectLatest { message -&gt; sendPushNotification(message) }
</code></pre>
<p>This Flow reads sensor readings continuously, filters for high temperatures, transforms them into alert messages, and sends them to users, all in a non-blocking, resilient way.</p>
<p>Flows are a powerful tool for modern server-side development. They let you embrace the world of asynchronous data processing with grace and efficiency, keeping your code responsive, scalable, and ready to handle whatever data banquet your users throw at you.</p>
<h2 id="heading-testing-your-concurrency-setup">Testing Your Concurrency Setup</h2>
<p>So, you've built your server-side kitchen with agile coroutines, smooth communication channels, and efficient dispatchers. Your data flows like a rushing stream, and your customers (users) are singing your praises. But before you hang the "Open" sign permanently, there's one more crucial step: testing your concurrency magic.</p>
<p>Testing helps you uncover edge cases, prevent crashes, and ensure everything runs smoothly even under heavy load.</p>
<p>Here are some key points for testing concurrent code:</p>
<ul>
<li><strong>Focus on isolation:</strong> Test individual coroutines and channels in isolation to identify problems in specific components. You can use libraries like kotlinx-coroutines-test to control time and simulate asynchronous behavior.</li>
<li><strong>Mock dependencies:</strong> External dependencies like databases or APIs can add complexity. Mocking these dependencies allows you to focus on coroutine behavior without introducing real-world uncertainties.</li>
<li><strong>Verify state changes:</strong> Ensure coroutines update data structures and flags correctly as they execute. Assert expected values at different points in the execution flow.</li>
<li><strong>Stress test performance:</strong> Push your code to its limits with high volume or complex scenarios. This helps you identify bottlenecks and ensure your system scales gracefully.</li>
</ul>
<p>Remember, testing concurrent code is not always straightforward. Be patient, experiment with different methods, and don't be afraid to seek help from experienced developers and testing frameworks.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>We've explored agile coroutines dancing across tasks, efficient channels keeping them in sync, and smart dispatchers directing the flow. We've seen how Flows seamlessly handle data streams, and we've learned the importance of robust testing to ensure everything runs smoothly.</p>
<p>Now, with this knowledge, you should understand the concept of concurrency in your Kotlin applications. Embrace it, use it wisely, and watch your applications soar to new heights of responsiveness, scalability, and efficiency.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Secure Kotlin Server Applications ]]>
                </title>
                <description>
                    <![CDATA[ By Faith Oyama In server-side application development using Kotlin, taking robust security measures is important. Developers encounter various threats and vulnerabilities that can compromise applications. This article delves into comprehensive securi... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/securing-kotlin-server-applications/</link>
                <guid isPermaLink="false">66d45eeed1ffc3d3eb89dde3</guid>
                
                    <category>
                        <![CDATA[ Kotlin ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Security ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 04 Jan 2024 22:33:33 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/01/Securing-Kotlin-Server-Applications-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Faith Oyama</p>
<p>In server-side application development using Kotlin, taking robust security measures is important. Developers encounter various threats and vulnerabilities that can compromise applications. This article delves into comprehensive security strategies tailored for Kotlin server applications, aiming to equip developers with the knowledge to fortify their systems against potential risks.</p>
<p>Security in Kotlin server applications isn't just about preventing unauthorized access. It's also about safeguarding against diverse threats such as injection attacks, cross-site scripting (XSS), and data breaches. </p>
<p>In this article, we'll explore fundamental security practices, authentication methods, access control, input validation, secure communication, and much more.</p>
<h2 id="heading-authentication-mechanisms">Authentication Mechanisms</h2>
<p>In Kotlin server applications, implementing robust authentication mechanisms is important in controlling access and ensuring data security. One popular method is token-based authentication, which employs tokens (like JSON Web Tokens - JWTs) for user verification. It offers scalability and flexibility, enabling stateless authentication.</p>
<p>Let's delve into a simple implementation of JWT-based authentication using the java-jwt library:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">import</span> com.auth0.jwt.JWT
<span class="hljs-keyword">import</span> com.auth0.jwt.algorithms.Algorithm
<span class="hljs-keyword">import</span> java.util.*

<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">generateToken</span><span class="hljs-params">(userId: <span class="hljs-type">String</span>)</span></span>: String {
    <span class="hljs-keyword">val</span> algorithm = Algorithm.HMAC256(<span class="hljs-string">"secret_key"</span>)
    <span class="hljs-keyword">return</span> JWT.create()
        .withIssuer(<span class="hljs-string">"your_issuer"</span>)
        .withSubject(userId)
        .withExpiresAt(Date(System.currentTimeMillis() + <span class="hljs-number">3600000</span>))
        .sign(algorithm)
}
</code></pre>
<p>This function generates a JWT token for a given user ID, signed using an HMAC algorithm. Ensure to securely manage the secret key.</p>
<h2 id="heading-authorization-and-access-control">Authorization and Access Control</h2>
<p>Authorization involves defining and managing user roles and permissions to regulate access to various parts of an application. In Kotlin, implementing RBAC (role-based access control) ensures proper access control within the server.</p>
<p>Let's create a simple RBAC setup using Ktor:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">enum</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UserRole</span> </span>{
ADMIN, USER, GUEST
}

<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">checkPermission</span><span class="hljs-params">(userRole: <span class="hljs-type">UserRole</span>, resource: <span class="hljs-type">String</span>, action: <span class="hljs-type">String</span>)</span></span>: <span class="hljs-built_in">Boolean</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">when</span> (userRole) {
        UserRole.ADMIN -&gt; <span class="hljs-literal">true</span>
        UserRole.USER -&gt; resource == <span class="hljs-string">"profile"</span> &amp;&amp; (action == <span class="hljs-string">"read"</span> || action == <span class="hljs-string">"write"</span>)
        UserRole.GUEST -&gt; resource == <span class="hljs-string">"public"</span> &amp;&amp; action == <span class="hljs-string">"read"</span>
    }
}
</code></pre>
<p>In this example, <code>checkPermission()</code> validates whether a user with a specific role has permission to perform a particular action on a resource.</p>
<h2 id="heading-input-validation-and-data-sanitization">Input Validation and Data Sanitization</h2>
<p>Input validation is crucial to prevent security vulnerabilities like SQL injection and XSS attacks. Kotlin, when used in server applications, should meticulously validate and sanitize user inputs before processing.</p>
<p>Let's consider an example of input validation using regular expressions in Kotlin:</p>
<pre><code class="lang-kotlin"><span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">isValidEmail</span><span class="hljs-params">(email: <span class="hljs-type">String</span>)</span></span>: <span class="hljs-built_in">Boolean</span> {
    <span class="hljs-keyword">val</span> emailRegex = <span class="hljs-string">"^[A-Za-z](.*)([@]{1})(.{1,})(\\.)(.{1,})"</span>
    <span class="hljs-keyword">return</span> email.matches(emailRegex.toRegex())
}

<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">sanitizeInput</span><span class="hljs-params">(input: <span class="hljs-type">String</span>)</span></span>: String {
    <span class="hljs-keyword">return</span> input.replace(<span class="hljs-string">"&lt;"</span>, <span class="hljs-string">"&amp;lt;"</span>).replace(<span class="hljs-string">"&gt;"</span>, <span class="hljs-string">"&amp;gt;"</span>)
}
</code></pre>
<p>The <code>isValidEmail()</code> function uses a regular expression to verify if an email address is in the correct format. Meanwhile, <code>sanitizeInput()</code> escapes HTML tags to prevent XSS attacks.</p>
<h2 id="heading-secure-communication-and-https">Secure Communication and HTTPS</h2>
<p>Securing communication between clients and servers is imperative to protect sensitive data. Enabling HTTPS (HTTP Secure) ensures encrypted data transmission over the network.</p>
<p>In Kotlin server applications, configuring HTTPS can be achieved using Ktor:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">import</span> io.ktor.server.engine.embeddedServer
<span class="hljs-keyword">import</span> io.ktor.server.netty.Netty
<span class="hljs-keyword">import</span> io.ktor.features.HSTS
<span class="hljs-keyword">import</span> io.ktor.features.HttpsRedirect

<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-keyword">val</span> server = embeddedServer(Netty, port = <span class="hljs-number">8080</span>) {
        install(HttpsRedirect) {
            sslPort = <span class="hljs-number">8443</span>
        }
        install(HSTS) {
            includeSubDomains = <span class="hljs-literal">true</span>
        }
    }
    server.start(wait = <span class="hljs-literal">true</span>)
}
</code></pre>
<p>In this example, Ktor's HttpsRedirect feature redirects HTTP requests to HTTPS, ensuring secure communication.</p>
<p>Make sure your project has the necessary Ktor dependencies and that you've imported the required features (HSTS and HttpsRedirect) to use these functionalities.</p>
<p>If you encounter errors with the code, make sure that you've included the appropriate Ktor dependencies in your project's build file (for example, <code>build.gradle.kts</code> or <code>pom.xml</code> for Gradle or Maven respectively) and have updated your project to resolve these dependencies.</p>
<h2 id="heading-handling-security-headers-and-csrf-protection">Handling Security Headers and CSRF Protection</h2>
<p>Security headers play a vital role in mitigating various web vulnerabilities. Configuring headers like Content Security Policy (CSP), X-Frame-Options, and others is essential in Kotlin server applications to enhance security.</p>
<p>Let's implement security headers using Ktor:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">import</span> io.ktor.application.*
<span class="hljs-keyword">import</span> io.ktor.features.*

<span class="hljs-function"><span class="hljs-keyword">fun</span> Application.<span class="hljs-title">installSecurityHeaders</span><span class="hljs-params">()</span></span> {
    install(DefaultHeaders)
    install(ContentNegotiation)
    install(Compression)
    install(CachingHeaders)
    install(XForwardedHeaderSupport)
    install(FrameOptions) {
        frameOptionsHeader = <span class="hljs-string">"DENY"</span>
    }
    install(ContentSecurityPolicy) {
        default {
            frameAncestors {
                self
            }
            script {
                unsafeInline = ContentSecurityPolicyHeader.UnsafeInlineSource
            }
        }
    }
}
</code></pre>
<p>Here, we use Ktor's ContentSecurityPolicy and FrameOptions features to define security headers like Content Security Policy and X-Frame-Options, mitigating potential risks like clickjacking attacks.</p>
<h2 id="heading-logging-and-monitoring-for-security">Logging and Monitoring for Security</h2>
<p>Comprehensive logging is crucial for detecting security incidents and analyzing application behaviour. Logging security-related events and suspicious activities helps you identify potential threats in Kotlin server applications.</p>
<p>Let's implement logging using the Logback logging framework in Kotlin:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">import</span> org.slf4j.LoggerFactory

<span class="hljs-keyword">val</span> logger = LoggerFactory.getLogger(<span class="hljs-string">"SecurityLogger"</span>)

<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">logSecurityEvent</span><span class="hljs-params">(event: <span class="hljs-type">String</span>)</span></span> {
    logger.info(<span class="hljs-string">"Security event: <span class="hljs-variable">$event</span>"</span>)
}
</code></pre>
<p>In this example, we've created a SecurityLogger instance using Logback to record security events such as authentication failures or access denied attempts.</p>
<h2 id="heading-securing-dependencies-and-patch-management">Securing Dependencies and Patch Management</h2>
<p>Maintaining the security of dependencies within Kotlin projects is fundamental to preempting vulnerabilities introduced by third-party libraries. Regularly updating and managing dependencies is critical to addressing potential security flaws that could compromise the application's integrity.</p>
<p>To ensure the security of dependencies, it's vital to employ best practices such as version pinning and utilizing tools like Gradle or Maven.</p>
<h3 id="heading-version-pinning">Version Pinning</h3>
<p>Defining specific versions of dependencies in project configuration files (like <code>build.gradle.kts</code> for Gradle or <code>pom.xml</code> for Maven) ensures that known vulnerabilities are patched. By explicitly specifying versions, developers can control which libraries and versions their project utilizes, minimizing exposure to security risks associated with outdated or vulnerable dependencies.</p>
<h3 id="heading-dependency-update-automation">Dependency Update Automation</h3>
<p>Leveraging automated tools or services that periodically scan for dependency updates and security vulnerabilities (for example Dependabot, Renovate) can significantly streamline the process of managing dependencies. These tools automatically identify outdated dependencies and suggest updated versions or patches, simplifying the task of keeping dependencies secure and up-to-date.</p>
<p>In Kotlin projects, managing dependencies securely involves explicitly declaring libraries and versions in build configuration files:</p>
<p>Gradle (build.gradle.kts):</p>
<pre><code class="lang-kotlin">dependencies {
    implementation(<span class="hljs-string">"org.jetbrains.kotlin:kotlin-stdlib:1.6.0"</span>)
}
</code></pre>
<p>Maven (pom.xml):</p>
<pre><code class="lang-kotlin">&lt;dependencies&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.jetbrains.kotlin&lt;/groupId&gt;
        &lt;artifactId&gt;kotlin-stdlib&lt;/artifactId&gt;
        &lt;version&gt;<span class="hljs-number">1.6</span><span class="hljs-number">.0</span>&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;!-- Add other dependencies securely and define versions --&gt;
&lt;/dependencies&gt;
</code></pre>
<p>By employing these practices and utilizing tools that aid in dependency analysis and updates, Kotlin projects can maintain a more robust and secure ecosystem, mitigating the risks associated with outdated or vulnerable dependencies.</p>
<h2 id="heading-testing-and-secure-development-practices">Testing and Secure Development Practices</h2>
<p>Security testing plays a pivotal role in identifying vulnerabilities within Kotlin server applications. Adopting various testing methodologies helps in detecting and rectifying security flaws early in the development lifecycle.</p>
<h3 id="heading-penetration-testing">Penetration Testing:</h3>
<p>Performing penetration tests involves simulating attacks to assess the system's security posture. Tools like OWASP ZAP or Burp Suite assist in identifying potential vulnerabilities like SQL injection, XSS, or CSRF.</p>
<h3 id="heading-vulnerability-scanning">Vulnerability Scanning:</h3>
<p>Automated vulnerability scanning tools, such as Nessus or OpenVAS, can help you identify security weaknesses within the application and its dependencies. These tools scan for known vulnerabilities, outdated libraries, or misconfigurations.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Throughout this guide, we've explored diverse security measures tailored for Kotlin server applications. From authentication mechanisms to securing communication, input validation, and compliance considerations, each aspect contributes significantly to fortifying the application against potential threats.</p>
<p>Ensuring the security of Kotlin server applications is an ongoing endeavour. It's crucial to emphasize the need for continuous vigilance, proactive monitoring, and a proactive approach to address evolving security challenges.</p>
<p>To create secure Kotlin applications, you must adopt a security-first mindset. Prioritizing security considerations at every stage of the development lifecycle helps in crafting robust and trustworthy server applications.</p>
<p>By implementing the best practices discussed in this guide and staying updated on emerging security trends, you can significantly enhance the security of your server applications.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Kotlin and Android Development – Build a Chat App ]]>
                </title>
                <description>
                    <![CDATA[ Are you ready to dive into the world of Android development using Kotlin? We just posted a 10-hour Android course on the freeCodeCamp.org YouTube channel. Alexandru Cristian created this course. I will help you understand how to develop with Kotlin a... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/kotlin-and-android-development-build-a-chat-app/</link>
                <guid isPermaLink="false">66b203db82069b4c678c98e7</guid>
                
                    <category>
                        <![CDATA[ Android ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Kotlin ]]>
                    </category>
                
                    <category>
                        <![CDATA[ youtube ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Beau Carnes ]]>
                </dc:creator>
                <pubDate>Mon, 30 Oct 2023 16:24:23 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/10/kotlinandroid.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Are you ready to dive into the world of Android development using Kotlin?</p>
<p>We just posted a 10-hour Android course on the freeCodeCamp.org YouTube channel. Alexandru Cristian created this course. I will help you understand how to develop with Kotlin and Android.</p>
<p>This course will take you on a journey through:</p>
<ul>
<li>Collections such as lists, sets, and maps</li>
<li>Generics and type parameters</li>
<li>Lambda functions and scope functions</li>
<li>Android Studio, its file structure, and XML design</li>
<li>Android widgets like buttons, TextView, EditText, and more</li>
<li>How to build a fully functional quiz application for Android devices.</li>
</ul>
<p>The course is divided into several chapters, each focused on a specific topic, to provide a structured learning experience. Here's a glimpse of the chapters included in the course:</p>
<ol>
<li>Introduction</li>
<li>List, Set, Map</li>
<li>Mapping</li>
<li>Zipping and Association</li>
<li>Flatten</li>
<li>String Representation</li>
<li>Filtering</li>
<li>Test predicates - any(), none(), all()</li>
<li>Plus and Minus Operators</li>
<li>Grouping</li>
<li>Retrieve Collections Parts</li>
<li>Retrieve Single Elements</li>
<li>Aggregate Operations - sum(), count(), average(), minOrNull(), maxOrNull()</li>
<li>Comparable and Comparator</li>
<li>Binary Search</li>
<li>Generics - Type Parameters and Casting</li>
<li>Generics - Upper Bounds</li>
<li>Generics - Covariance and Contravariance</li>
<li>Generics - Type Erasure and reified keyword</li>
<li>Generics - Where keyword; and 2 Upper Bounds</li>
<li>Access Modifiers</li>
<li>Packages and Imports</li>
<li>Exceptions - Try Catch, Finally</li>
<li>Lambda Functions</li>
<li>Lambdas - it modifier</li>
<li>Scope Functions</li>
<li>Download Android Studio</li>
<li>Android Studio Presentation</li>
<li>Android File Structure</li>
<li>Android XML and Design</li>
<li>Android XML properties</li>
<li>Android - what does findViewById() function do?</li>
<li>String XML</li>
<li>Android Manifest</li>
<li>Android Button and TextView</li>
<li>Android Button OnClickListener</li>
<li>Android EditText</li>
<li>Android App - Convert Inches</li>
<li>Android App - Convert Inches 2</li>
<li>Android App - Change Color</li>
<li>Android Radio Buttons 1</li>
<li>Android Radio Buttons 2</li>
<li>Android SeekBar</li>
<li>Android Toggle Button</li>
<li>Quiz App - UI Welcome Screen</li>
<li>Quiz App - Creating Question Model</li>
<li>Quiz App - Setting the QuizActivity</li>
<li>Quiz App - Connecting the UI with the model</li>
<li>Quiz App - Adding the Button functionality</li>
<li>Quiz App - Selecting the Right and Wrong answers</li>
<li>Quiz App - Setting up the UI for ResultActivity</li>
<li>Quiz App - Improve Code</li>
<li>Quiz App - Sending data to Result Activity</li>
<li>Quiz App - Solve score bug</li>
</ol>
<p>This course is designed to give you a holistic understanding of Kotlin and Android development, with hands-on examples and real-world applications.</p>
<p>Watch the full course on <a target="_blank" href="https://youtu.be/kNghEbknLs8">the freeCodeCamp.org YouTube channel</a> (10-hour watch).</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/kNghEbknLs8" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Kotlin VS Java – What's the Difference? ]]>
                </title>
                <description>
                    <![CDATA[ By Shittu Olumide Technology advances very quickly these days, and there's always a new programming language or tool to learn.  You may have heard developers discussing the merits of and differences between two popular programming languages – Java an... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/kotlin-vs-java/</link>
                <guid isPermaLink="false">66d461177df3a1f32ee7f89e</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Kotlin ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 08 May 2023 13:48:47 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/05/Shittu-Olumide-Kotlin-VS-Java---What-s-the-Difference.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Shittu Olumide</p>
<p>Technology advances very quickly these days, and there's always a new programming language or tool to learn. </p>
<p>You may have heard developers discussing the merits of and differences between two popular programming languages – Java and Kotlin. </p>
<p>So what's the difference between them? Which one should you learn? Well, you are in the right place, because that's what we'll talk about in this guide. I'll highlight the major differences between Java and Kotlin that you need to know in a very simple way.</p>
<h2 id="heading-overview-of-kotlin-and-java">Overview of Kotlin and Java</h2>
<p>Kotlin and Java are two popular programming languages used to build software applications for a variety of platforms. While Java has been a dominant language in the software industry for over two decades, Kotlin is a newer language that has gained popularity in recent years due to its modern features and seamless interoperability with Java.</p>
<p>Java was first released in 1995 by Sun Microsystems, and it quickly became a popular language for building enterprise software applications. It is an object-oriented language with a strong emphasis on readability, maintainability, and portability. </p>
<p>Java is platform-independent, which means that it can be compiled and run on any platform that has a Java Virtual Machine (JVM).</p>
<p>Kotlin, on the other hand, was created by JetBrains in 2011 as an alternative to Java. It is a modern, statically-typed programming language that runs on the JVM, Android, and can be compiled to JavaScript. </p>
<p>Kotlin is designed to be concise, safe, and interoperable with Java, making it easy to integrate into existing Java projects.</p>
<p>In recent years, Kotlin has gained significant traction in the developer community, with many companies and organizations adopting it as their primary language for building software applications. But Java still remains a popular choice for building enterprise software, and it is likely to continue to be used for many years to come.</p>
<h2 id="heading-differences-between-kotlin-and-java">Differences Between Kotlin and Java</h2>
<p>In this section, we will examine the key differences between these two programming languages.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Feature</strong></td><td><strong>Kotlin</strong></td><td><strong>Java</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Syntax</strong></td><td>More concise and expressive syntax</td><td>More verbose syntax</td></tr>
<tr>
<td><strong>Null safety</strong></td><td>Built-in null safety features</td><td>No built-in null safety features</td></tr>
<tr>
<td><strong>Interoperability</strong></td><td>Seamless interoperability with Java</td><td>Interoperable, but requires extra work</td></tr>
<tr>
<td><strong>Extension functions</strong></td><td>Supports extension functions</td><td>No support for extension functions</td></tr>
<tr>
<td><strong>Lambdas</strong></td><td>More concise and expressive syntax for lambdas</td><td>Lambdas are verbose and require more code</td></tr>
<tr>
<td><strong>IDE support</strong></td><td>Strong IDE support in IntelliJ IDEA    Strong</td><td>IDE support in multiple IDEs</td></tr>
<tr>
<td><strong>Performance</strong></td><td>Comparable performance to Java</td><td>High performance, especially for large-scale applications</td></tr>
<tr>
<td><strong>Learning curve</strong></td><td>Can have a steeper learning curve for those familiar with Java</td><td>Fairly intuitive to learn</td></tr>
<tr>
<td><strong>Community support</strong></td><td>Growing community with increasing resources</td><td>Large and established community with a wealth of resources</td></tr>
<tr>
<td><strong>Build tools</strong></td><td>Uses Gradle as the default build tool</td><td>Uses Maven as the default build tool</td></tr>
</tbody>
</table>
</div><p>It's important to note that this is not an exhaustive list, and there are other differences between Kotlin and Java depending on your specific use case. But this table provides some of the key differences between the two technologies.</p>
<h3 id="heading-code-examples-of-differences-between-kotlin-and-java">Code examples of differences between Kotlin and Java</h3>
<p>To write a Lambda Expression in Kotlin looks like this:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">val</span> list = listOf(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>)
<span class="hljs-keyword">val</span> evenNumbers = list.filter { it % <span class="hljs-number">2</span> == <span class="hljs-number">0</span> }
</code></pre>
<p>But in Java, it is much more verbose:</p>
<pre><code class="lang-java">List&lt;Integer&gt; list = Arrays.asList(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>);
List&lt;Integer&gt; evenNumbers = list.stream()
                                 .filter(n -&gt; n % <span class="hljs-number">2</span> == <span class="hljs-number">0</span>)
                                 .collect(Collectors.toList());
</code></pre>
<p>Another practical example is using Extension Functions.</p>
<p>Kotlin allows you to add new functions to existing classes using extension functions:</p>
<pre><code class="lang-kotlin"><span class="hljs-function"><span class="hljs-keyword">fun</span> String.<span class="hljs-title">isPalindrome</span><span class="hljs-params">()</span></span>: <span class="hljs-built_in">Boolean</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span> == <span class="hljs-keyword">this</span>.reversed()
}
</code></pre>
<p>In Java, you cannot define extension functions. Instead, you can create utility classes with static methods:</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">StringUtils</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">isPalindrome</span><span class="hljs-params">(String str)</span> </span>{
        <span class="hljs-keyword">return</span> str.equals(<span class="hljs-keyword">new</span> StringBuilder(str).reverse().toString());
    }
}
</code></pre>
<h2 id="heading-use-cases-for-kotlin-and-java">Use Cases for Kotlin and Java</h2>
<p>Both Kotlin and Java have their own unique use cases and when it is most suitable to use either of them.</p>
<h3 id="heading-when-to-use-kotlin">When to use Kotlin:</h3>
<ul>
<li><strong>Android app development</strong>: Kotlin is the recommended language for developing Android apps by Google. It offers features like null safety, concise code, and better readability, making it easier to build and maintain Android applications.</li>
<li><strong>Web development</strong>: you can also use Kotlin for server-side development, and it can run on the Java Virtual Machine (JVM). This makes it a great choice for building web applications, especially when you need interoperability with Java.</li>
<li><strong>Data science and machine learning</strong>: Kotlin has recently gained popularity in the field of data science and machine learning due to its ability to integrate well with Python libraries, such as TensorFlow and PyTorch.</li>
<li><strong>Cross-platform development</strong>: you can use Kotlin to build applications for multiple platforms, including desktop, mobile, and web. This makes it an attractive choice for developers who want to build applications that can run on multiple devices.</li>
</ul>
<h3 id="heading-when-to-use-java">When to use Java:</h3>
<ul>
<li><strong>Enterprise application development</strong>: Java has been the go-to language for enterprise application development for decades. It has a vast ecosystem of libraries and frameworks you can use to build complex enterprise applications.</li>
<li><strong>Legacy systems</strong>: Many legacy systems are built on Java, and migrating them to a new language may not be feasible or cost-effective. In these cases, Java is still the best choice for maintaining and updating these systems.</li>
<li><strong>High-performance applications</strong>: Java is known for its performance and scalability, and it is often used for building high-performance applications that require high throughput and low latency.</li>
<li><strong>Android app development</strong>: While Kotlin is now the recommended language for Android app development, Java is still a viable option. Many existing Android apps are built on Java, and you can still use it to build new applications for the platform.</li>
<li><strong>Large-scale projects</strong>: Java's strong type system and emphasis on maintainability and scalability make it an ideal choice for large-scale projects. Its modular architecture also makes it easier to manage and maintain large codebases.</li>
<li><strong>Desktop application development</strong>: you can use Java to build cross-platform desktop applications, making it a good choice for developers who want to build applications that can run on multiple operating systems.</li>
<li><strong>Financial applications</strong>: Java's security features and stability make it a popular choice for building financial applications that require high levels of security and reliability.</li>
<li><strong>Gaming</strong>: Java can also be used for game development, especially for browser-based games. It has a built-in 2D and 3D graphics engine that makes it easy to create games that run on multiple platforms.</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In conclusion, Kotlin and Java are both powerful programming languages with their own unique strengths and use cases. </p>
<p>Kotlin is a relatively new language that offers features like null safety, concise code, and better readability, making it a great choice for Android app development, web development, data science, and cross-platform development. </p>
<p>Java, on the other hand, has been around for decades and is the go-to language for enterprise application development, legacy systems, high-performance applications, desktop application development, financial applications, and gaming.</p>
<p>If you're building an Android app, Kotlin is the recommended language by Google. If you're working on a legacy system or an enterprise application, Java is likely the best choice. </p>
<p>Finally, it's worth noting that Kotlin and Java are not mutually exclusive, and in many cases, they can be used together to achieve the best of both worlds.</p>
<p>Let's connect on <a target="_blank" href="https://www.twitter.com/Shittu_Olumide_">Twitter</a> and on <a target="_blank" href="https://www.linkedin.com/in/olumide-shittu">LinkedIn</a>. You can also subscribe to my <a target="_blank" href="https://www.youtube.com/channel/UCNhFxpk6hGt5uMCKXq0Jl8A">YouTube</a> channel.</p>
<p>Happy Coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Kotlin VS Java – What's the Difference? ]]>
                </title>
                <description>
                    <![CDATA[ Java is a widely popular programming language that has been used for years in various domains, including web development, mobile app development, desktop applications, and game development.  On the other hand, Kotlin is a relatively new programming l... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/kotlin-vs-java-whats-the-difference/</link>
                <guid isPermaLink="false">66c8c870fe21816c4cb75d09</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Kotlin ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Israel Chidera ]]>
                </dc:creator>
                <pubDate>Fri, 31 Mar 2023 20:21:28 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/03/emile-perron-xrVDYZRGdw4-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Java is a widely popular programming language that has been used for years in various domains, including web development, mobile app development, desktop applications, and game development. </p>
<p>On the other hand, Kotlin is a relatively new programming language that has been gaining popularity in recent years. Both languages are used to build applications for the Java Virtual Machine (JVM), but they differ in terms of syntax, features, and performance. </p>
<p>Java has been around for quite some time and has a vast community and a plethora of libraries. On the other hand, Kotlin is a relatively new language that offers contemporary features and concise syntax, which makes it an appealing alternative for developers. </p>
<p>In this article, we will discuss the differences between Kotlin and Java.</p>
<h1 id="heading-differences-between-kotlin-and-java">Differences Between Kotlin and Java</h1>
<h2 id="heading-syntax">Syntax</h2>
<p>One of the most significant differences between Kotlin and Java is the syntax. Kotlin has a more concise syntax than Java, which means that it requires less code to perform the same operations. </p>
<p>For example, let's compare the syntax for creating a class in both languages:</p>
<pre><code class="lang-java"><span class="hljs-comment">//java</span>

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyClass</span> </span>{
   <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> myField;

   <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">MyClass</span><span class="hljs-params">(<span class="hljs-keyword">int</span> myField)</span> </span>{
      <span class="hljs-keyword">this</span>.myField = myField;
   }

   <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getMyField</span><span class="hljs-params">()</span> </span>{
      <span class="hljs-keyword">return</span> myField;
   }

   <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setMyField</span><span class="hljs-params">(<span class="hljs-keyword">int</span> myField)</span> </span>{
      <span class="hljs-keyword">this</span>.myField = myField;
   }
}
</code></pre>
<pre><code class="lang-kotlin"><span class="hljs-comment">//kotlin</span>

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyClass</span></span>(<span class="hljs-keyword">private</span> <span class="hljs-keyword">var</span> myField: <span class="hljs-built_in">Int</span>) {
   <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">getMyField</span><span class="hljs-params">()</span></span> = myField
   <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">setMyField</span><span class="hljs-params">(value: <span class="hljs-type">Int</span>)</span></span> { myField = value }
}
</code></pre>
<p>As you can see, the Kotlin version is much more concise and readable than the Java version. In Kotlin, we can define the class and its fields in a single line, and the getters and setters are replaced with property accessors.</p>
<p>Additionally, Kotlin supports type inference, which means that you do not have to specify the data type of a variable explicitly.</p>
<pre><code class="lang-kotlin"><span class="hljs-comment">//kotlin</span>

<span class="hljs-keyword">val</span> myString = <span class="hljs-string">"Hello, world!"</span>
</code></pre>
<p>As seen in the Kotlin code above, we can use type inference to declare a variable without explicitly specifying its data type. The compiler will automatically determine the data type based on the value that we assign to the variable. This can make our code more concise and easier to read.</p>
<pre><code class="lang-java"><span class="hljs-comment">//java</span>

String myString = <span class="hljs-string">"Hello, world!"</span>;
</code></pre>
<p>In the Java code above, you are required to specify the data type of the variable which can make your code more verbose.</p>
<p>Here is another example showing the difference between the verbose syntax of Java and a more concise Kotlin syntax.</p>
<pre><code class="lang-java"><span class="hljs-comment">//java</span>

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">HelloWorld</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
        System.out.println(<span class="hljs-string">"Hello, World!"</span>);
    }
}
</code></pre>
<p>The code above is a simple "Hello, World!" program in Java that prints “Hello, World!” to the console.</p>
<pre><code class="lang-kotlin"><span class="hljs-comment">//kotlin</span>

<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    println(<span class="hljs-string">"Hello, World!"</span>)
}
</code></pre>
<p>As you can see, the Kotlin version is much shorter and more expressive. Kotlin achieves this by eliminating unnecessary boilerplate code, such as type declarations and semicolons, and using more natural language constructs.</p>
<h2 id="heading-null-safety">Null Safety</h2>
<p>Both Kotlin and Java compile to bytecode that runs on the JVM, which means they have similar performance characteristics. </p>
<p>But Kotlin has some performance advantages over Java in certain cases. For example, Kotlin's <strong>null safety</strong> feature can help reduce the number of runtime exceptions and improve the overall performance of the application. And Kotlin's use of immutable data structures can also lead to improved performance.</p>
<p><strong>Null safety</strong> is another area where Kotlin differs from Java. In Java, it's possible to have null values assigned to a variable, which can lead to null pointer exceptions at runtime. Kotlin, on the other hand, requires you to explicitly define whether a variable can be null or not. This makes it easier to avoid null pointer exceptions during runtime. </p>
<p>For example, in Kotlin, all variables are non-null by default, meaning that they cannot hold a null value unless explicitly declared as nullable using the "?" operator. This helps to prevent null-related errors at compile-time, rather than waiting until runtime.</p>
<pre><code class="lang-kotlin"><span class="hljs-comment">//kotlin</span>

<span class="hljs-keyword">var</span> name: String = <span class="hljs-string">"John"</span> <span class="hljs-comment">// non-null variable</span>
<span class="hljs-keyword">var</span> age: <span class="hljs-built_in">Int</span>? = <span class="hljs-literal">null</span> <span class="hljs-comment">// nullable variable</span>
</code></pre>
<h2 id="heading-functional-programming">Functional Programming</h2>
<p>Another significant difference between Java and Kotlin is their support for functional programming. While Java has added some support for functional programming in recent years with the release of <strong>Java 8</strong>, Kotlin was designed from the ground up to support functional programming concepts.</p>
<p>For example, Kotlin supports lambda expressions, higher-order functions, and extension functions. These features make it easier to write code that is both concise and expressive and can help to improve code quality. Here is a code sample showing this:</p>
<pre><code class="lang-kotlin"><span class="hljs-comment">//kotlin</span>
<span class="hljs-comment">// lambda expression</span>
<span class="hljs-keyword">val</span> list = listOf(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>)
<span class="hljs-keyword">val</span> doubledList = list.map { it * <span class="hljs-number">2</span> }

<span class="hljs-comment">// higher-order function</span>
<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">higherOrderFunc</span><span class="hljs-params">(x: <span class="hljs-type">Int</span>, y: <span class="hljs-type">Int</span>, f: (<span class="hljs-type">Int</span>, <span class="hljs-type">Int</span>) -&gt; <span class="hljs-type">Int</span>)</span></span>: <span class="hljs-built_in">Int</span> {
    <span class="hljs-keyword">return</span> f(x, y)
}
<span class="hljs-keyword">val</span> result = higherOrderFunc(<span class="hljs-number">3</span>, <span class="hljs-number">4</span>) { x, y -&gt; x + y }

<span class="hljs-comment">// extension function</span>
<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-built_in">Int</span>.<span class="hljs-title">isEven</span><span class="hljs-params">()</span></span> = <span class="hljs-keyword">this</span> % <span class="hljs-number">2</span> == <span class="hljs-number">0</span>
<span class="hljs-keyword">val</span> isFourEven = <span class="hljs-number">4</span>.isEven()
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In summary, <strong>Kotlin</strong> and <strong>Java</strong> are both awesome programming languages that have some significant differences. While Java is a more established language with a large community and extensive libraries, Kotlin provides modern features and concise syntax, making it an attractive choice for many developers. </p>
<p>Kotlin's focus on null safety and support for functional programming make it well-suited for modern application development, while Java's performance and library ecosystem make it a good choice for enterprise applications. </p>
<p>Ultimately, the choice between Java and Kotlin will depend on the specific needs of your application and your development team's preferences and skills.  </p>
<p>I hope this article was informative.<br>Happy learning.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Serialize Your Data in Kotlin and Jetpack Compose ]]>
                </title>
                <description>
                    <![CDATA[ Serialization is the process of transforming data that's in one format into another format that can be stored.  If you have ever worked with a database or fetching data from a server, this should all be familiar to you. If not, you have come to the r... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/serializing-your-data-in-kotlin/</link>
                <guid isPermaLink="false">66ba503a158e6c6a8cb8c7a5</guid>
                
                    <category>
                        <![CDATA[ Jetpack Compose ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Kotlin ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Tomer ]]>
                </dc:creator>
                <pubDate>Wed, 01 Feb 2023 21:19:13 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/01/fineas-anton-cnoMG2034k8-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Serialization is the process of transforming data that's in one format into another format that can be stored. </p>
<p>If you have ever worked with a database or fetching data from a server, this should all be familiar to you. If not, you have come to the right place. </p>
<p>In this tutorial, we will go over:</p>
<ul>
<li>How to setup serialization in a Jetpack Compose project</li>
<li>How to serialize a data class</li>
<li>How to de-serialize a data class</li>
</ul>
<p>You might be asking yourself, what’s so special about serialization in Jetpack Compose? In essence, there isn’t a lot of difference than with a regular Kotlin Android project. The only difference is in the setup.</p>
<h2 id="heading-how-to-set-everything-up">How to Set Everything Up</h2>
<p>Each version of Jetpack Compose corresponds with a version of Kotiln that it is compatible with. Each version of the kotlin-serialization library is also compatible with a specific version of Kotlin. So you need to make sure that each of the three parts in this tripod are compatible with one another.</p>
<p>How can you that?</p>
<p>Your first resource you'll want to consult is the <a target="_blank" href="https://developer.android.com/jetpack/androidx/releases/compose-kotlin">Compose to Kotlin Compatibility Map</a>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/1_5brVwILW54aNaFFimDF87Q.jpeg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Here you can see which version of Jetpack Compose corresponds to which Kotlin version.</p>
<p>The second resource you will need is the <a target="_blank" href="https://github.com/Kotlin/kotlinx.serialization/releases">releases page</a> for the kotlin-serialization library. There you will find which library version is compatible with which Kotlin version.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/1_y6Ba1fROOcSSXXm-Nll4Ew.jpeg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Confused? 😕</p>
<p>Let’s illustrate this with an example:</p>
<ul>
<li>Your Jetpack Compose version is <strong>1.1.0</strong>.</li>
<li>Looking over the compatibility map, you see it is compatible with Kotlin version <strong>1.6.10</strong>.</li>
<li>Heading to the releases page of kotlin-serialization library, you see that the version of the kotlin-serialization library that you need to use is <strong>1.3.2</strong>.</li>
</ul>
<p>Head into your project level build.gradle file, and inside the buildscript object, in the dependencies section, put in classpath for the kotlin-serialization library with the version you need.</p>
<pre><code class="lang-kotlin">dependencies {
        ...
        classpath <span class="hljs-string">"org.jetbrains.kotlin:kotlin-serialization:X.Y.Z"</span>
 }
</code></pre>
<p>Then, head over to your application build.gradle file and do these two things:</p>
<ol>
<li>Add the <strong>id ‘org.jetbrains.kotlin.plugin.serialization’</strong> inside of the plugins at the top of the file:</li>
</ol>
<pre><code class="lang-kotlin">plugins {
   ...
   id <span class="hljs-string">'org.jetbrains.kotlin.plugin.serialization'</span>
}
</code></pre>
<ol start="2">
<li>At the bottom of the file, inside the dependencies section add <strong>implementation ‘org.jetbrains.kotlinx:kotlinx-serialization-json:X.Y.Z’</strong>:</li>
</ol>
<pre><code class="lang-kotlin">dependencies {
   ...
   implementation <span class="hljs-string">'org.jetbrains.kotlinx:kotlinx-serialization-json:X.Y.Z'</span>
}
</code></pre>
<p>Sync your project and you should be good to go.</p>
<p>Note that we are using the <strong>json</strong> format of the library, but there are other formats that are supported as well:</p>
<ul>
<li>Protocol Buffers</li>
<li>CBOR (Concise Binary Object Representation)</li>
<li>Properties</li>
<li>HOCON (Human Optimized Config Object Notation)</li>
</ul>
<blockquote>
<p>⚠️ If you encounter any errors, make sure the versions you put are correct</p>
</blockquote>
<h2 id="heading-how-to-build-your-data-class">How to Build Your Data Class</h2>
<p>In order to have something we can serialize and later de-serialize, we need to work with data classes. </p>
<p>Creating a data class is simple. If you are using Android Studio, just right click inside your project’s module and choose New Kotlin file. Enter your class name and then append the data keyword before it.</p>
<p>For the sake of this article, let's say we are working with an API that returns a list of users. Each user object has a range of attributes it can have (just to name a few):</p>
<ul>
<li>First name</li>
<li>Last name</li>
<li>Age</li>
<li>Birthdate</li>
<li>Id</li>
</ul>
<p>To make our data class serializable, all you need to do is add the <strong>@Serializable</strong> annotation above the class declaration.</p>
<pre><code class="lang-kotlin"><span class="hljs-meta">@Serializable</span>
<span class="hljs-keyword">data</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UserModel</span></span>(
   <span class="hljs-keyword">val</span> firstName: String,
   <span class="hljs-keyword">val</span> lastName: String,
   <span class="hljs-keyword">val</span> age: <span class="hljs-built_in">Int</span>,
   <span class="hljs-keyword">val</span> birthdate: Date,
   <span class="hljs-keyword">val</span> id: <span class="hljs-built_in">Long</span>
)
</code></pre>
<p>Pretty nifty, right?</p>
<p>Well, there’s more.</p>
<p>The variable that will hold the user’s first name is written as firstName. That means that in the response from our server, it needs to return in a field with the same name. </p>
<p>Sometimes, in API responses, the keys are not written in camelCase, but rather in kebab_case. That would mean that the key for first name, might be first_name. In that case, we would have to write it out like this:</p>
<pre><code class="lang-kotlin"><span class="hljs-meta">@Serializable</span>
<span class="hljs-keyword">data</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UserModel</span></span>(
   <span class="hljs-keyword">val</span> first_name: String,
   <span class="hljs-keyword">val</span> lastName: String,
   <span class="hljs-keyword">val</span> age: <span class="hljs-built_in">Int</span>,
   <span class="hljs-keyword">val</span> birthdate: Date,
   <span class="hljs-keyword">val</span> id: <span class="hljs-built_in">Long</span>
)
</code></pre>
<p>But that is not the <a target="_blank" href="https://kotlinlang.org/docs/coding-conventions.html">convention</a> for property names in Kotlin.</p>
<p>So what can we do?</p>
<p>We can use the <strong>@SerialName</strong> annotation. This allows us to mark what the name of the field will be from the response and then write anything as the property for it.</p>
<pre><code class="lang-kotlin"><span class="hljs-meta">@Serializable</span>
<span class="hljs-keyword">data</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UserModel</span></span>(
   <span class="hljs-meta">@SerialName(<span class="hljs-meta-string">"first_name"</span>)</span>
   <span class="hljs-keyword">val</span> firstName: String,
   <span class="hljs-keyword">val</span> lastName: String,
   <span class="hljs-keyword">val</span> age: <span class="hljs-built_in">Int</span>,
   <span class="hljs-keyword">val</span> birthdate: Date,
   <span class="hljs-keyword">val</span> id: <span class="hljs-built_in">Long</span>
)
</code></pre>
<h2 id="heading-how-to-serialize-and-de-serialize">How to Serialize and De-Serialize</h2>
<p>Now that our data class is set up, let’s enjoy the fruits of our labor. Whenever we need to serialize our data class, we will use the <a target="_blank" href="https://kotlinlang.org/api/kotlinx.serialization/kotlinx-serialization-core/kotlinx.serialization/encode-to-string.html">Json.encodeToString</a> method:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">val</span> dataAsString: String = Json.encodeToString(user)
</code></pre>
<p>When we run the above line of code, we will get our data class in string form.</p>
<p>De-serializing our data is as simple as serializing it. We will use the <a target="_blank" href="https://kotlinlang.org/api/kotlinx.serialization/kotlinx-serialization-core/kotlinx.serialization/decode-from-string.html">Json.decodeFromString</a> method:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">val</span> user: UserModel = Json.decodeFromString&lt;UserModel&gt;(dataAsString)
</code></pre>
<blockquote>
<p>✋ Notice that we specified which type of data we want to de-serialize to with the type parameter ().</p>
</blockquote>
<p><img src="https://images.unsplash.com/photo-1600176842064-635fe81d2441?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDMwfHxyZW1vdGUlMjBjb250cm9sfGVufDB8fHx8MTY3NTAxODM0NQ&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Image" width="2000" height="1325" loading="lazy">
_Photo by [Unsplash](https://unsplash.com/@macroman?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit"&gt;Immo Wegmann / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm<em>campaign=api-credit)</em></p>
<p>Time for some extra credit.</p>
<p>Let’s say that in your data class you have a field that you don’t want to serialize. If we take our UserModel class, imagine that we want to have a user’s actual picture (bitmap).</p>
<pre><code class="lang-kotlin"><span class="hljs-meta">@Serializable</span>
<span class="hljs-keyword">data</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UserModel</span></span>(
   <span class="hljs-meta">@SerialName(<span class="hljs-meta-string">"first-name"</span>)</span>
   <span class="hljs-keyword">val</span> firstName: String,
   <span class="hljs-keyword">val</span> lastName: String,
   <span class="hljs-keyword">val</span> age: <span class="hljs-built_in">Int</span>,
   <span class="hljs-keyword">val</span> birthdate: Date,
   <span class="hljs-keyword">val</span> id: <span class="hljs-built_in">Long</span>,
   <span class="hljs-keyword">var</span> photo: Bitmap?
)
</code></pre>
<p>This is not something we will get from our API call, so how can we exclude it? Because if we don’t, our serialization will fail.</p>
<p>Here to our rescue is the <a target="_blank" href="https://kotlinlang.org/api/kotlinx.serialization/kotlinx-serialization-core/kotlinx.serialization/-transient/"><strong>@Transient</strong> annotation</a>.</p>
<pre><code>@Serializable
data <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UserModel</span>(
   @<span class="hljs-title">SerialName</span>("<span class="hljs-title">first</span>-<span class="hljs-title">name</span>")
   <span class="hljs-title">val</span> <span class="hljs-title">firstName</span>: <span class="hljs-title">String</span>,
   <span class="hljs-title">val</span> <span class="hljs-title">lastName</span>: <span class="hljs-title">String</span>,
   <span class="hljs-title">val</span> <span class="hljs-title">age</span>: <span class="hljs-title">Int</span>,
   <span class="hljs-title">val</span> <span class="hljs-title">birthdate</span>: <span class="hljs-title">Date</span>,
   <span class="hljs-title">val</span> <span class="hljs-title">id</span>: <span class="hljs-title">Long</span>,
   @<span class="hljs-title">Transient</span>
   <span class="hljs-title">var</span> <span class="hljs-title">photo</span>: <span class="hljs-title">Bitmap</span>?
)</span>
</code></pre><p>This will exclude the marked field from being serialized and de-serialized.</p>
<ul>
<li>If you want to see a real life example of using serialization inside a project, you can check out a project I made <a target="_blank" href="https://medium.com/r?url=https%3A%2F%2Fgithub.com%2FTomerPacific%2Fmovies-presenter">here</a></li>
<li>And if you would like to read other articles I have written, you can go <a target="_blank" href="https://medium.com/r?url=https%3A%2F%2Fgithub.com%2FTomerPacific%2FMediumArticles">here</a></li>
<li>For more information about the kotlin-serialization library, you can go <a target="_blank" href="https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/basic-serialization.md#json-encoding">here</a></li>
</ul>
<p>Thank you for reading! Happy serializing.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is Abstraction in Programming? Explained for Beginners ]]>
                </title>
                <description>
                    <![CDATA[ This article will not be a dry and boring explanation of abstract classes, interfaces, protocols, or similar software entities. I will explain what they are in simple terms, but my main goal is to change how you think about abstractions in general. A... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-abstraction-in-programming-for-beginners/</link>
                <guid isPermaLink="false">66d460d3c7632f8bfbf1e49d</guid>
                
                    <category>
                        <![CDATA[ abstraction ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Kotlin ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ryan Michael Kay ]]>
                </dc:creator>
                <pubDate>Wed, 21 Dec 2022 18:08:21 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/12/smartphone-g7993a9917_1280-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>This article will not be a dry and boring explanation of abstract classes, interfaces, protocols, or similar software entities.</p>
<p>I will explain what they are in simple terms, but my main goal is to change how you think about abstractions in general. All of this is in service of helping you develop the art of programming.</p>
<p>These are the topics I will cover:</p>
<ul>
<li><p><a class="post-section-overview" href="#heading-what-is-an-abstraction">What is an abstraction?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-use-abstractions-in-your-programs">How to use abstractions in your programs</a><br>  – <a class="post-section-overview" href="#heading-how-to-use-interfaces-and-protocols">How to use interfaces and protocols</a><br>  – <a class="post-section-overview" href="#heading-how-to-use-function-types-and-lambda-expressions">How to use function types and lambda expressions</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-is-abstraction-the-most-important-idea-in-programming">Is abstraction the most important idea in programming?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-much-abstraction-do-i-need">How much abstraction do I need?</a></p>
</li>
</ul>
<p>The code samples will be in Kotlin, but I have written the article assuming you only have basic programming knowledge in any industry standard language.</p>
<p>I also use a variety of approaches to cover both object-oriented and functional styles of code.</p>
<h2 id="heading-what-is-an-abstraction">What Is An Abstraction?</h2>
<p>To begin with, we will discuss what this term means in the most general sense. Here is a simplified definition I have come up with for an abstraction:</p>
<blockquote>
<p>“A <strong>less detailed representation</strong> of an object or concept in nature.”</p>
</blockquote>
<p>I know my definition sounds very vague, but we will discuss some clear examples shortly. First, we must understand what <strong>detail</strong> is.</p>
<h3 id="heading-what-is-detail">What Is Detail?</h3>
<p>Detail refers to the quantity, or density perhaps, of information. Here are two examples of data models which are more and less detailed:</p>
<pre><code class="lang-pgsql"><span class="hljs-keyword">User</span> {
  <span class="hljs-type">name</span>,
  id
}
</code></pre>
<pre><code class="lang-pgsql"><span class="hljs-keyword">User</span> {
  <span class="hljs-type">name</span>: String,
  id: <span class="hljs-type">Integer</span>,
  phone: <span class="hljs-type">Integer</span>,
  email: String
}
</code></pre>
<p>There is no need to overthink this point! More details is another way of saying more information or more complexity.</p>
<p>The only other key point is to understand what a <strong>representation</strong> is.</p>
<h3 id="heading-how-to-represent-something">How to Represent Something</h3>
<p>Suppose you are going to travel somewhere which has a particularly deadly kind of venomous snake. In order to gain information about this snake, you have a few different options:</p>
<ul>
<li><p>Read a verbal description of the snake and its behaviour</p>
</li>
<li><p>Look at a drawing or picture of the snake</p>
</li>
<li><p>Listen to audio of what it sounds like when behaving aggressively</p>
</li>
</ul>
<p>All of the above points are examples of different kinds of representations, or abstractions, of the venomous snake.</p>
<p>In each case, some pieces of information, which accurately represent properties of the real snake, are conveyed. However, neither a verbal description, nor an image, nor a recording can bite you!</p>
<p>Here we see the main utility of abstractions: <strong>Conveying important information</strong> (also known as details or properties) of an object or concept, <strong>while leaving out the unnecessary information</strong>.</p>
<h2 id="heading-how-to-use-abstractions-in-your-programs">How to Use Abstractions In Your Programs</h2>
<p>Before we discuss some specifics, it is worth mentioning that everything in a computer program is technically an abstraction.</p>
<p>In fact, <strong>programming languages, as well as all forms of mathematics, are systems of abstractions</strong>.</p>
<p>However, programmers tend to think of abstractions as a narrow band of software entities usually referred to as:</p>
<ul>
<li><p>Interfaces or Protocols</p>
</li>
<li><p>Abstract Classes</p>
</li>
<li><p>Function Types/References/Signatures</p>
</li>
<li><p>Super/Parent-Classes</p>
</li>
</ul>
<p>Unfortunately, the names and mechanics of the above software entities can vary substantially in different programming languages.</p>
<p>For this reason, I will take two examples which may be more or less appropriate to your preferred languages:</p>
<ol>
<li><p>An interface or protocol (which will also cover abstract classes)</p>
</li>
<li><p>A function type or method reference</p>
</li>
</ol>
<p>In any case, don't worry so much about the names or any minor differences in how these things work across languages. Instead, I invite you to focus on the general ideas.</p>
<h2 id="heading-how-to-use-interfaces-and-protocols">How to Use Interfaces and Protocols</h2>
<p>I will use the term interface from here on, but this term is synonymous with protocol. I will also use the term function synonymously with method.</p>
<p>Interfaces allow you to define behaviour of functions, classes, or objects, without defining their implementation.</p>
<p>Don't worry, I am not like some teachers who throw out some jargon and pretend like I am teaching you something.</p>
<p>Let's look at exactly what I mean by behaviour and implementation.</p>
<p><strong>Behaviour</strong> literally means a function declaration:</p>
<pre><code class="lang-kotlin"><span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">UserDataSource</span> </span>{
<span class="hljs-comment">//this line below has a function declaration but no function "body"</span>
  <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">getUserById</span><span class="hljs-params">(id: <span class="hljs-type">String</span>)</span></span>: User?
}

<span class="hljs-keyword">data</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span></span>(
  <span class="hljs-keyword">val</span> id: String,
  <span class="hljs-keyword">val</span> someData: Any
)
</code></pre>
<p>You can see the footnotes below regarding my usage of the term “function declaration.”</p>
<p>To translate this into English, this function declaration says the we are defining a function which:</p>
<ul>
<li><p>Is named “getUserById”</p>
</li>
<li><p>Accepts a String type called “id” as an argument when called</p>
</li>
<li><p>Returns a “User” or a null value if no user exists (this is because we have a “?” after the “User” type)</p>
</li>
</ul>
<p><strong>Implementation</strong> refers to the function body:</p>
<pre><code class="lang-kotlin"><span class="hljs-comment">//Note that ":" is short for extends/implements in Kotlin for the class</span>
<span class="hljs-comment">//declaration</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UserDatabase</span></span>(): UserDataSource {
<span class="hljs-comment">//the curly braces, and everything between them, is the implementation</span>
  <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">getUserById</span><span class="hljs-params">(id: <span class="hljs-type">String</span>)</span></span>: User? {
    <span class="hljs-keyword">var</span> user: User? = <span class="hljs-literal">null</span>
    <span class="hljs-comment">//… not important for this example</span>
    <span class="hljs-keyword">return</span> user
  }
}
</code></pre>
<p>Another name for the function inside of the interface is an <em>abstract function</em>. Hopefully, our discussion on abstract meaning “<em>less detail</em>” is starting to make more sense here!</p>
<p><strong>Some notes for accuracy:</strong></p>
<ol>
<li><p>Some languages have features to define properties, variables, and even implementations (that is, function declarations + function bodies) within interfaces. This does not change the primary purpose of interfaces, though.</p>
</li>
<li><p>The term function declaration will be defined differently depending on the language. Instead of worrying about verbal definitions, please consider my code examples to follow what I mean.</p>
</li>
</ol>
<h3 id="heading-what-about-abstract-classes">What About Abstract Classes?</h3>
<p>Apart from in Python (and perhaps other languages I am not aware of), abstract classes are very similar to interfaces except for one key difference: a <strong>class may only inherit from a single abstract class.</strong></p>
<p>In my opinion, before languages started to include ways for interfaces to define their own implementations, the use of abstract classes versus interfaces was clear:</p>
<ul>
<li><p>If you only want to share behaviour across a set of software entities, use an interface</p>
</li>
<li><p>If you want to share implementation <strong>and</strong> behaviour, use an abstract class instead</p>
</li>
</ul>
<p>Unfortunately, this distinction is very blurry since many languages now have features to add implementation to interfaces (like Java’s Default Methods).</p>
<p>The only general recommendation I can make which does not account for the specific details of any particular programming language is this: Use the simplest construct to get the job done.</p>
<h2 id="heading-how-to-use-function-types-and-lambda-expressions">How to Use Function Types and Lambda Expressions</h2>
<p>There are different ways to achieve abstraction without defining interfaces or classes. But the amount of structure these language features require is still subject to language specifics.</p>
<p>Kotlin provides enough of these features that you will hopefully be able to make some connections with your preferred languages.</p>
<h3 id="heading-how-to-use-function-types-instead-of-an-interface">How to Use Function Types Instead Of An Interface</h3>
<p>We will start with a practical example and then explain the finer details part by part.</p>
<p>Suppose we want to set up an abstract function (recall that this means a function with no implementation) to handle a click event.</p>
<p>Using something like an interface, we could do the following:</p>
<pre><code class="lang-kotlin"><span class="hljs-comment">//assume this is an platform/OS component that tells you when</span>
<span class="hljs-comment">//a user clicks something on screen</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PlatformComponent</span></span>(
  <span class="hljs-keyword">var</span> clickListener: ClickListener? = <span class="hljs-literal">null</span>
) {
  <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">userClickedScreen</span><span class="hljs-params">()</span></span> {
    <span class="hljs-comment">//Note: the "?" means handleClick() is only</span>
    <span class="hljs-comment">//called when clickListener is NOT NULL</span>
    clickListener?.handleClick()
  }
}
<span class="hljs-comment">//This interfaces hides (abstracts) the concrete class/type</span>
<span class="hljs-comment">//which handles the click</span>
<span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">ClickListener</span> </span>{
  <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">handleClick</span><span class="hljs-params">()</span></span>
}
<span class="hljs-comment">//This concrete class/type handles the click</span>
<span class="hljs-comment">//by extending the interface</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ScreenController</span></span>() : ClickListener {
  <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">handleClick</span><span class="hljs-params">()</span></span> {
    println(<span class="hljs-string">"Click handled."</span>)
  }
}

<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
  PlatformComponent(
    ScreenController()
  ).userClickedScreen()
}
</code></pre>
<p>An alternative approach is to use a function type instead of an interface:</p>
<pre><code class="lang-kotlin"><span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
  <span class="hljs-keyword">val</span> controller = ScreenController()
  <span class="hljs-keyword">val</span> component = PlatformComponent(
    <span class="hljs-comment">//The double colon tells the compiler that we are referring to</span>
    <span class="hljs-comment">//the function handleClick defined in ScreenController</span>
    controller::handleClick
  )
  component.userClickedScreen()
}

<span class="hljs-comment">//assume this is an platform/OS component that tells</span>
<span class="hljs-comment">//you when a user clicks something on screen</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PlatformComponent</span></span>(
  <span class="hljs-keyword">var</span> clickListener: () -&gt; <span class="hljs-built_in">Unit</span>
) {
  <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">userClickedScreen</span><span class="hljs-params">()</span></span> {
    <span class="hljs-comment">//This is equivalent to calling ScreenController.handleClick(),</span>
    <span class="hljs-comment">//but PlatformComponent does not know that. Abstraction!</span>
    clickListener()
  }
}
<span class="hljs-comment">//This concrete class/type handles the click</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ScreenController</span></span>() {
  <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">handleClick</span><span class="hljs-params">()</span></span> {
    println(<span class="hljs-string">"Click handled."</span>)
  }
}
</code></pre>
<p>In this example, we can see how there is even less structure required to achieve the same result. But keep in mind that having less structure does not immediately imply better code. Really, <strong>it depends</strong>.</p>
<p>In any case, with a practical example in mind, we can break down how this code actually works in more detail.</p>
<h3 id="heading-how-to-use-function-references">How to Use Function References</h3>
<p>If you are unfamiliar with how function types, method references (or whatever else they are called) work, this section explains them in Kotlin. Feel free to jump to the next section if you are already familiar.</p>
<p>Similar to most modern programming languages, we can create a reference variable to a particular function in Kotlin:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">var</span> clickListener: () -&gt; <span class="hljs-built_in">Unit</span>
</code></pre>
<p>In Kotlin, function types have the following syntax:</p>
<pre><code class="lang-kotlin">(optional list of parameter types) -&gt; <span class="hljs-keyword">return</span> type
</code></pre>
<p>For example:</p>
<ul>
<li><p><code>(Int, Int) -&gt; Int</code> means that the associated function must take in two Int parameters, and return a single Int</p>
</li>
<li><p><code>() -&gt; Unit</code> means that a function has no parameters and executes without returning a meaningful value</p>
</li>
</ul>
<p>Unit is roughly equivalent to Java’s void return type or Python’s None type – at least in principle.</p>
<p>When it comes time to call (invoke) a function reference, we have two options:</p>
<ul>
<li><p><code>clickListener()</code> for short</p>
</li>
<li><p><code>clickListener.invoke()</code> is the full syntax, which is necessary when making null-safe calls like <code>clickListener?.invoke()</code>, for example</p>
</li>
</ul>
<h3 id="heading-how-to-use-lambda-expressions">How to Use Lambda Expressions</h3>
<p>In the previous example, it is worth noting that ScreenController does not care what the actual function it is invoking happens to be named.</p>
<p>We can take this level of abstraction even further, by not even defining a ScreenController:</p>
<pre><code class="lang-kotlin"><span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
  <span class="hljs-comment">//note that the outer parenthesis are optional in Kotlin,</span>
  <span class="hljs-comment">//but may make this easier to understand</span>
  <span class="hljs-keyword">val</span> component = PlatformComponent(
    { println(<span class="hljs-string">"Click handled."</span>) }
  )
  component.userClickedScreen()
}
<span class="hljs-comment">//assume this is an platform/OS component that tells</span>
<span class="hljs-comment">//you when a user clicks something on screen</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PlatformComponent</span></span>(
  <span class="hljs-keyword">var</span> clickListener: () -&gt; <span class="hljs-built_in">Unit</span>
) {
  <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">userClickedScreen</span><span class="hljs-params">()</span></span> {
    clickListener()
  }
}
</code></pre>
<p>Unlike the previous examples, this one is <strong>not intended to resemble a practical scenario</strong> – just to demonstrate a lambda expression.</p>
<p>The actual lambda expression is this:</p>
<p><code>{ println(“Click handled.”) }</code></p>
<p>As you can see, it does not get much more abstract than a lambda expression.</p>
<p>On the surface, it's almost like defining only the implementation but not the behaviour. But at least in Kotlin, the lambda expression must conform to the type we are assigning it to.</p>
<p>In this case, <code>{ println(“Click handled.”) }</code> has no parameters and does not return a meaningful value. So it conforms to <code>() -&gt; Unit</code>.</p>
<h3 id="heading-which-approach-should-i-use">Which Approach Should I Use?</h3>
<p>You may wonder which approach you should be using – assuming your language allows for multiple approaches.</p>
<p>The most accurate answer I can give you is that there is no general rule.</p>
<p>Plenty of teachers these days will say “<em>x</em> is worse than y” or simply “<em>x</em> is bad,” because it works great for clickbait and search engine optimization.</p>
<p>But a language, platform, code construct, architecture, and just about anything else can only be judged good, bad, better, or worse relative to your requirements.</p>
<p>In fact, different requirements are the reason we have languages as different as Python and Java which are both extremely popular.</p>
<p>So instead, try different approaches and be skeptical of anyone who makes absolute statements without discussing requirements.</p>
<h2 id="heading-is-abstraction-the-most-important-idea-in-programming">Is Abstraction the Most Important Idea in Programming?</h2>
<p>The point of this article was never to say: <em>“Using interfaces and abstract classes everywhere will make you a better programmer.”</em></p>
<p>In fairness, as many developers do, I went through a phase around 2016–2018 where I did actually think that statement was pretty accurate.</p>
<p>Instead, the point of this article is to explain two things:</p>
<ul>
<li><p>Abstraction in programming, in my opinion, <strong>should</strong> <strong>not specifically mean abstract classes, or any particular code construct</strong></p>
</li>
<li><p>Abstraction in programming is a <strong>process</strong> by which we design our software entities according to <strong>how much detail</strong> they internally (privately) contain and externally (publicly) provide</p>
</li>
</ul>
<p>In a sense, every decision we make about the structure of our code, regardless of the language, comes down to this process of abstraction.</p>
<p>With that being said, how do we know when making some aspect of our program more abstract is beneficial, useless, or detrimental?</p>
<h2 id="heading-how-much-abstraction-do-i-need">How Much Abstraction Do I Need?</h2>
<p>I can only think of one kind of situation where you should strongly consider using something like an interface or function type.</p>
<p>Recall that these software entities provide variability of implementation but consistent behaviour. Further, that implementation typically refers to the body of a function.</p>
<p>Two things follow from that observation:</p>
<ul>
<li><p>If no variability of implementation is required, there is not likely to be a benefit of using a more abstract software entity.</p>
</li>
<li><p>If variability of implementation is required, using a more abstract software entity is likely beneficial.</p>
</li>
</ul>
<p>We will now discuss two situations I have encountered where variability is a requirement.</p>
<h3 id="heading-how-to-make-your-code-easier-to-test">How to Make Your Code Easier to Test</h3>
<p>Suppose that we have some kind of software entity, which must request some user data from a database or network adapter:</p>
<pre><code class="lang-kotlin"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PresentationLogic</span></span>(
 <span class="hljs-keyword">val</span> datasource: Datasource
) {
    <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">start</span><span class="hljs-params">()</span></span> {
        <span class="hljs-keyword">val</span> someData = datasource.getData()
        presentData(someData)
    }

    <span class="hljs-comment">//...</span>
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Datasource</span></span>() {
    <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">getData</span><span class="hljs-params">()</span></span>: Data {
        <span class="hljs-keyword">var</span> someData = getLocalOrRemoteData()
        <span class="hljs-comment">//... error handling and so on</span>

        <span class="hljs-keyword">return</span> someData
    }
}
</code></pre>
<p>Also suppose that we want to test <code>PresentationLogic</code> without needing a real datasource to supply the data.</p>
<p>There are a few different ways to solve this problem (see the note below), but a simple solution is to make the datasource more abstract:</p>
<pre><code class="lang-kotlin"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PresentationLogic</span></span>(
 <span class="hljs-keyword">val</span> datasource: DatasourceInterface
) {
    <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">start</span><span class="hljs-params">()</span></span> {
        <span class="hljs-keyword">val</span> someData = datasource.getData()
        presentData(someData)
    }

    <span class="hljs-comment">//...</span>
}

<span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">DatasourceInterface</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">getData</span><span class="hljs-params">()</span></span>: Data
}
</code></pre>
<p>From there, we can create a fake implementation of the datasource in a test environment:</p>
<pre><code class="lang-kotlin"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FakeDatasource</span></span>(): DatasourceInterface {
        <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">getData</span><span class="hljs-params">()</span></span>: Data {
            <span class="hljs-keyword">return</span> Data()
        }
}

<span class="hljs-meta">@Test</span>
<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">testLogic</span><span class="hljs-params">()</span></span> {
    <span class="hljs-keyword">val</span> logic = PresentationLogic(
       <span class="hljs-comment">//here we provide the fake version</span>
       FakeDatasource()
    )
}
</code></pre>
<p>Using abstraction, PresentationLogic does not know or care whether it is talking to a fake or real datasource. By extension, it does not need to change to work with either of them. Variability of implementation!</p>
<p>Note that there are other way to achieve this variability apart from using an interface. You could use a mocking library, or configure a build tool to swap out implementations.</p>
<p>There is no clear answer to which approach is better outside of discussing specific requirements.</p>
<p>Also, note that this approach would not actually work unless the details of how the datasource is created are kept separate from <code>PresentationLogic</code>.</p>
<p>This is commonly referred to as Dependency Injection, which I will discuss in a separate article.</p>
<h3 id="heading-how-to-work-with-different-versions-and-vendors-of-a-service">How to Work With Different Versions and Vendors of a Service</h3>
<p>Suppose that for some reason, you must work with different versions or vendors of the same service depending on different requirements.</p>
<p>An example could be supporting both AWS and Firebase to store the same data. Another example could be supporting a legacy version of a service along with a newer version of that same service.</p>
<p>In any case, it is another situation where variability of implementation is expected.</p>
<p>The code examples we will discuss have the following requirements:</p>
<ul>
<li><p>A client program must use three services, all from different vendors, to perform the same behaviour</p>
</li>
<li><p>The decision to choose a particular service is determined at runtime based on the environment (platform, OS, hardware, and so on) of the client program</p>
</li>
</ul>
<p>For those wondering, “client” in this context is a generic word for some program or software entity which uses other programs or software entities.</p>
<p>For example, YouTube’s website and mobile apps are “client apps” of YouTube’s backend servers.</p>
<p>Without applying any abstraction, our client program will need to know about every possible service and be told which service to choose:</p>
<pre><code class="lang-kotlin"><span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">clientProgram</span><span class="hljs-params">(
    request: <span class="hljs-type">Request</span>, 
    awsService: <span class="hljs-type">AwsService</span>,
    firebaseService: <span class="hljs-type">FirebaseService</span>,
    parseService: <span class="hljs-type">ParseService</span>
)</span></span>: Result {
    <span class="hljs-keyword">val</span> use: USE_SERVICE = determineBestService()

    <span class="hljs-keyword">val</span> result = <span class="hljs-keyword">when</span> (use) {
        USE_SERVICE.AWS -&gt; awsService.executeRequest(request)
        USE_SERVICE.FIREBASE -&gt; firebaseService.executeRequest(request)
        USE_SERVICE.PARSE -&gt; parseService.executeRequest(request)
    }

    <span class="hljs-comment">//assume additional work is done before returning the result</span>
    <span class="hljs-keyword">return</span> result
}

<span class="hljs-keyword">enum</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">USE_SERVICE</span> </span>{
    AWS,
    FIREBASE,
    PARSE
}
</code></pre>
<p>Notice that clientProgram has a parameter which refers to specific vendors of the service:</p>
<ul>
<li><p>Amazon Web Services (AWS)</p>
</li>
<li><p>Firebase</p>
</li>
<li><p>The now defunct Parse service from Facebook</p>
</li>
</ul>
<p>It follows that any changes to our services will require <code>clientProgram</code> to be refactored (rewritten) appropriately.</p>
<p>The reason I chose Parse as one of the example services is specifically because it was shut down, despite being widely used. There are various reasons why a particular service may no longer fit requirements, but not working any more is a good one.</p>
<p>An alternative approach would be to hide all the details about the service being used from clientProgram. You could use an interface, but for variety’s sake I have used a function type instead:</p>
<pre><code class="lang-kotlin"><span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-comment">//Creating the services</span>
    <span class="hljs-keyword">val</span> awsService = AwsService()
    <span class="hljs-keyword">val</span> firebaseService = FirebaseService()

    <span class="hljs-comment">//determining which service to use must </span>
    <span class="hljs-comment">//not be included in clientProgram</span>
    <span class="hljs-keyword">val</span> use: USE_SERVICE = determineBestService()

    <span class="hljs-comment">//Assign serviceToUse to the appropriate function</span>
    <span class="hljs-keyword">val</span> serviceToUse: (Request) -&gt; Result = <span class="hljs-keyword">when</span> (use) {
        USE_SERVICE.AWS -&gt; awsService::executeRequest
        USE_SERVICE.FIREBASE -&gt; firebaseService::executeRequest
    }

    <span class="hljs-keyword">val</span> request = getRequest()

    clientProgram(
       request,
       serviceToUse
    )
}


<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">clientProgram</span><span class="hljs-params">(
    request: <span class="hljs-type">Request</span>, 
    service: (<span class="hljs-type">Request</span>) -&gt; <span class="hljs-type">Result</span>
)</span></span>: Result {

    <span class="hljs-keyword">val</span> result = service.invoke(request)

    <span class="hljs-comment">//assume additional work is done before returning the result</span>

    <span class="hljs-keyword">return</span> result
}

<span class="hljs-keyword">enum</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">USE_SERVICE</span> </span>{
    AWS,
    FIREBASE
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AwsService</span></span>() {
    <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">executeRequest</span><span class="hljs-params">(request: <span class="hljs-type">Request</span>)</span></span>: Result = Result()
}
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FirebaseService</span></span>() {
    <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">executeRequest</span><span class="hljs-params">(request: <span class="hljs-type">Request</span>)</span></span>: Result = Result()
}
</code></pre>
<p>The end result of this abstraction is that we can change services without needing to change <code>clientProgram</code> – assuming our behaviour does not change.</p>
<p>I want to point out that I am not advocating that you hide every service behind some kind of abstraction. If no variability is required or expected, there may not be any benefit to extra abstraction.</p>
<h1 id="heading-closing-thoughts">Closing Thoughts</h1>
<p>I hope it is clear when reading this article that my intention is not to push dogmatic opinions about how abstract your code should be.</p>
<p>As a junior and intermediate developer, it took me a few years to realize that it really does depend on project requirements.</p>
<p>I also hope that this article gave you some new ideas and perspectives about what abstraction is and how it can be applied in your code. Good luck and happy coding!</p>
<h3 id="heading-before-you-go"><strong>Before you go...</strong></h3>
<p>If you liked this article and want more information on these principles and code constructs, check out my free, full length <a target="_blank" href="https://youtu.be/FL2SMZxNQlc">programming fundamentals course</a>. It includes professionally written English, Burmese, and Arabic subtitles.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn Kotlin in 14 Hours ]]>
                </title>
                <description>
                    <![CDATA[ Kotlin is the most popular programming language for building Android apps and it can also be can be used for any kind of development. We just published a full Kotlin course for beginners on the freeCodeCamp.org YouTube channel. Alex Cristian develope... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-kotlin-complete-course/</link>
                <guid isPermaLink="false">66b204a908bc664c3c097ed8</guid>
                
                    <category>
                        <![CDATA[ Kotlin ]]>
                    </category>
                
                    <category>
                        <![CDATA[ youtube ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Beau Carnes ]]>
                </dc:creator>
                <pubDate>Thu, 27 Oct 2022 14:21:20 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/10/kotlin.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Kotlin is the most popular programming language for building Android apps and it can also be can be used for any kind of development.</p>
<p>We just published a full Kotlin course for beginners on the freeCodeCamp.org YouTube channel.</p>
<p>Alex Cristian developed this course. Alex is an experienced developer who has created multiple Android apps.</p>
<p>This course will teach you Kotlin starting from the absolute beginning and going through advanced Kotlin concepts. The course uses intuitive and practical examples and at the end of each section there is a challenge to test your understanding.</p>
<p>Here are the sections covered in this course:</p>
<ul>
<li>Introduction</li>
<li>Install Intellij IDEA</li>
<li>Hello World</li>
<li>Variables</li>
<li>Window</li>
<li>Integer Type</li>
<li>DataType: Byte, Short and Long</li>
<li>Float and Double</li>
<li>Char and Boolean</li>
<li>Operators</li>
<li>Comments</li>
<li>IfThenElse: Statement-Expression</li>
<li>Less Than or Equal To Operator</li>
<li>logical AND operator</li>
<li>logical OR operator</li>
<li>When Statement-Expression</li>
<li>Null</li>
<li>Functions</li>
<li>Function: return and expressions</li>
<li>Functions Overloading</li>
<li>Functions Default Values</li>
<li>Functions vararg keyword</li>
<li>loops: FOR loop</li>
<li>loops: WHILE and DO WHILE loop, Labels and continue and break</li>
<li>loops Challenge</li>
<li>Arrays</li>
<li>Arrays Challenge</li>
<li>OOP: Classes</li>
<li>OOP: Primary Constructor</li>
<li>OOP: Initializer Blocks</li>
<li>OOP: Secondary Constructors</li>
<li>OOP: Constructor Parameters Default Values</li>
<li>OOP: Getters and Setters</li>
<li>OOP: lateinit keyword</li>
<li>OOP: Companion Object</li>
<li>OOP: Singleton</li>
<li>OOP: Lazy Initialization</li>
<li>OOP: Enum Classes</li>
<li>OOP: Inner Classes</li>
<li>OOP Challenge</li>
<li>OOP: Inheritance 1</li>
<li>OOP: Inheritance 2</li>
<li>OOP: Sealed Class</li>
<li>OOP: Abstract Classes</li>
<li>OOP: Data Class</li>
<li>OOP: Interfaces 1</li>
<li>OOP: Interfaces 2</li>
<li>OOP: Object Expression</li>
<li>OOP: Delegation</li>
<li>Lambda Functions and Lambda Expressions</li>
<li>it parameter in lambda</li>
<li>List, Set, Map</li>
<li>Mapping</li>
<li>Zipping</li>
<li>Flatten</li>
<li>String Representation</li>
<li>Filtering</li>
<li>Test predicates: any(), none(), all()  </li>
<li>Plus and Minus Operators</li>
<li>Grouping</li>
<li>Retrieve Collection parts</li>
<li>Retrieve Single Elements</li>
<li>Aggregate Operations: sum(), count(), average(), minOrNull(), maxOrNull()</li>
<li>Comparable and Comparator</li>
<li>Binary Search</li>
<li>Generics: Type Paramenters and Casting</li>
<li>Generics: Upper Bounds</li>
</ul>
<p>Watch the full course on <a target="_blank" href="https://youtu.be/EExSSotojVI">the freeCodeCamp.org YouTube channel</a> (13-hour watch).</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/EExSSotojVI" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Deploy a Kotlin Microservice to AWS with App Runner ]]>
                </title>
                <description>
                    <![CDATA[ By Piotr Wolak Hello, everyone. In this step-by-step tutorial, I would like to show you how to deploy a Kotlin Microservice using Docker and AWS App Runner.  Together, we will learn: what exactly is AWS App Runner?  how to configure AWS Command Line... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/kotlin-aws-app-runner/</link>
                <guid isPermaLink="false">66d4608bd1ffc3d3eb89de34</guid>
                
                    <category>
                        <![CDATA[ AWS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Kotlin ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ktor ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Microservices ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 15 Apr 2022 06:34:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/04/kotlin-aws-app-runner.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Piotr Wolak</p>
<p>Hello, everyone. In this step-by-step tutorial, I would like to show you how to deploy a Kotlin Microservice using Docker and AWS App Runner. </p>
<p>Together, we will learn:</p>
<ul>
<li>what exactly is AWS App Runner? </li>
<li>how to configure AWS Command Line Interface on your local machine </li>
<li>how to push Docker images to Amazon Elastic Container Registry (ECR)</li>
<li>and finally, how to deploy our containerized application with AWS App Runner</li>
</ul>
<p>I know, it might sound like a tremendous amount of work. But I am convinced that you will find out how simple it can be with the above tech stack.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before we start, make sure that you have <strong>Docker</strong> already installed on you local machine. We'll need to containerize our application. </p>
<p>If you don't have Docker, then the official <a target="_blank" href="https://docs.docker.com/engine/install/">Docker documentation</a> will help you set it up in a few minutes. </p>
<h2 id="heading-what-exactly-is-aws-app-runner">What Exactly is AWS App Runner?</h2>
<p>First, let's take minute to understand what exactly <strong>AWS App Runner</strong> is.</p>
<p>To put it simply, it is a fully managed service which allows you to build and deploy containerized web applications and APIs with ease. </p>
<p>It takes care of plenty of things, like traffic load balancing, or scaling, which helps developers like you and me focus on the code. </p>
<p><strong>AWS App Runner</strong> oftentimes is a great choice when creating a demo or proof of concept, but it's also worth considering for smaller teams without a dedicated person working on infrastructure. </p>
<h2 id="heading-how-to-create-asimple-kotlin-microservice">How to Create  aSimple Kotlin Microservice</h2>
<p>With that being said, let's prepare a simple REST API using Kotlin and Ktor. </p>
<p>If you are not interested in the Ktor implementation, then you can simply clone <a target="_blank" href="https://github.com/codersee-blog/ktor-app-runner-skeleton">this GitHub repository</a> and proceed to the <em>How to Build the Docker Image</em> step. </p>
<p>If you are using the IntelliJ IDEA Ultimate Edition, then you can create a Ktor project using the app. Otherwise, you can use the <a target="_blank" href="https://start.ktor.io/">Ktor Project Generator</a> tool and download project to your local machine.</p>
<p>Regardless of your choice, make sure to import the following plugins: </p>
<ul>
<li>ContentNegotiation</li>
<li>kotlinx.serialization</li>
<li>Routing</li>
</ul>
<h3 id="heading-how-to-configure-serialization">How to Configure Serialization</h3>
<p>After you've imported the project, create the <code>Serialization.kt</code> file and register <code>application/json</code> content type to the ContentNegotiation feature:</p>
<pre><code class="lang-kotlin"><span class="hljs-function"><span class="hljs-keyword">fun</span> Application.<span class="hljs-title">configureSerialization</span><span class="hljs-params">()</span></span> {
    install(ContentNegotiation) {
        json()
    }
}
</code></pre>
<p>In simple words, with this code snippet we will be able to serialize Kotlin objects into JSON (and deserialize the JSON into objects, as well). </p>
<h3 id="heading-how-to-create-a-dto">How to Create a DTO</h3>
<p>Now let's implement a <code>MessageDto</code> data class like this:</p>
<pre><code class="lang-kotlin"><span class="hljs-meta">@Serializable</span>
<span class="hljs-keyword">data</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MessageDto</span></span>(<span class="hljs-keyword">val</span> message: String)
</code></pre>
<p>Basically, we will use this generic class to provide messages for our API consumers. </p>
<h3 id="heading-how-to-expose-endpoints">How to Expose Endpoints</h3>
<p>As the next step, let's create a <code>Routing.kt</code> file and expose a new endpoint: </p>
<pre><code class="lang-kotlin"><span class="hljs-function"><span class="hljs-keyword">fun</span> Application.<span class="hljs-title">configureRouting</span><span class="hljs-params">()</span></span> {
    routing {
        helloWorldRoute()
    }
}

<span class="hljs-function"><span class="hljs-keyword">fun</span> Routing.<span class="hljs-title">helloWorldRoute</span><span class="hljs-params">()</span></span> {
    route(<span class="hljs-string">"/hello"</span>) {
        <span class="hljs-keyword">get</span> {
            call.respond(HttpStatusCode.OK, MessageDto(<span class="hljs-string">"Hello World!"</span>))
        }
    }
}
</code></pre>
<p>As you can see, our application will respond with a <strong>200 OK</strong> status code to each <code>GET</code> request to the <code>/hello</code> path.</p>
<h3 id="heading-how-to-configure-the-app">How to Configure the App</h3>
<p>Now, let's combine everything inside the <code>Application.kt</code> file: </p>
<pre><code class="lang-kotlin"><span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    embeddedServer(Netty, port = <span class="hljs-number">8080</span>, host = <span class="hljs-string">"0.0.0.0"</span>) {
        configureRouting()
        configureSerialization()
    }.start(wait = <span class="hljs-literal">true</span>)
}
</code></pre>
<p>As you can see, our Kotlin microservice will be a <strong>Netty embedded server</strong> running on <code>localhost:8080</code>. </p>
<p>I highly encourage you to run the application and verify that everything is working properly:</p>
<pre><code>GET localhost:<span class="hljs-number">8080</span>/hello

<span class="hljs-attr">Status</span>: <span class="hljs-number">200</span> OK
Response Body: 
{
    <span class="hljs-string">"message"</span>: <span class="hljs-string">"Hello World!"</span>
}
</code></pre><h3 id="heading-how-to-implement-the-dockerfile">How to Implement the Dockerfile</h3>
<p>Finally, let's add the <code>Dockerfile</code> to the root directory of our project:</p>
<pre><code>FROM openjdk:<span class="hljs-number">8</span>-jdk
EXPOSE <span class="hljs-number">8080</span>:<span class="hljs-number">8080</span>
RUN mkdir /app
COPY ./build/install/com.codersee.ktor-app-runner/ <span class="hljs-regexp">/app/</span>
WORKDIR /app/bin
CMD [<span class="hljs-string">"./com.codersee.ktor-app-runner"</span>]
</code></pre><p>Make sure that the directory specified for the <code>COPY</code> and <code>CMD</code> commands matches the value of <code>rootProject.name</code> inside the <code>settings.gradle.kts</code> file. If the project's name is <code>xyz</code> , then these commands should reflect that:</p>
<pre><code>...
COPY ./build/install/xyz/ <span class="hljs-regexp">/app/</span>
...
CMD [<span class="hljs-string">"./xyz"</span>]
</code></pre><h2 id="heading-how-to-build-the-docker-image">How to Build the Docker Image</h2>
<p>At this point, we have everything we need to build our <strong>Docker Image</strong>, which we will use later for the <strong>AWS App Runner</strong> deployment.</p>
<h3 id="heading-run-the-gradle-command">Run the Gradle Command</h3>
<p>As the first step, let's run the <code>installDist</code> command with Gradle Wrapper: </p>
<pre><code>./gradlew installDist
</code></pre><p>The above command is responsible for assembling the distribution content and installing it on the current machine. Although it might sound difficult, it will simply create necessary files inside the <code>./build/install/{project-name}/</code> directory. </p>
<h3 id="heading-build-the-docker-image">Build the Docker Image</h3>
<p>As the next step, let's build a Docker Image:</p>
<pre><code> docker build -t ktor-aws-runner .
</code></pre><p>As you can see, we named our desired image <code>ktor-aws-runner</code> with the <code>-t</code> option (a shortcut for <code>--tag</code>).</p>
<h3 id="heading-verify-docker-configuration">Verify Docker Configuration</h3>
<p>Finally, let's run our container to make sure that our Kotlin microservice is working properly:</p>
<pre><code>docker run -p <span class="hljs-number">8080</span>:<span class="hljs-number">8080</span> ktor-aws-runner
</code></pre><p>As a word of explanation, the <code>-p</code> flag (<code>--port</code>)  is responsible for publishing the container's <code>8080</code> port to the host <code>8080</code> port. </p>
<p>With that being done, after a few seconds we should see the following message in logs: </p>
<pre><code>Application started <span class="hljs-keyword">in</span> <span class="hljs-number">0.078</span> seconds
</code></pre><p>Similarly, we can perform a GET request to check if the exposed endpoint is responding correctly.</p>
<h2 id="heading-how-to-create-and-configure-an-aws-user">How to Create and Configure an AWS User</h2>
<p>With all of that being done, we can finally start working with AWS. But before we're able to push our Docker Image, we need to make sure that we have <strong>AWS CLI</strong> installed on our local machine. </p>
<p>We can do that easily with the below command: </p>
<pre><code> aws --version

 # Result:
 aws-cli/<span class="hljs-number">2.5</span><span class="hljs-number">.3</span> Python/<span class="hljs-number">3.9</span><span class="hljs-number">.11</span> Windows/<span class="hljs-number">10</span> exe/AMD64 prompt/off
</code></pre><p>The above result indicates that everything is setup correctly. Nevertheless, if we would like to install or update the CLI, then AWS ships with a really good article on that in their <a target="_blank" href="https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html">official documentation</a>. </p>
<p>Additionally, we have to have the access to AWS Cloud from our computer – and that's what we are going to set up in this step.</p>
<p>In order to set up the access, let's sign in to the <strong>AWS Management Console</strong> and navigate to the <strong>Users</strong> feature of the <strong>IAM Console</strong>. We can do that easily with the search bar at the top: </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/1-1.png" alt="Image shows search results for users query in AWS Management Console" width="600" height="400" loading="lazy"></p>
<p>On the next page, let's click the <strong>Add users</strong> button: </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/2-1.png" alt="Image shows empty list of Users in AWS IAM Console" width="600" height="400" loading="lazy"></p>
<p>Then we'll specify the preferred <strong>User name</strong> along with the <strong>Access key</strong> – <strong>Programmatic access</strong> credential type: </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/3-1.png" alt="Image shows user name and AWS access type options for new user" width="600" height="400" loading="lazy"></p>
<p>With these settings, we will be able to access AWS using a combination of access key and secret.</p>
<p>With that being done, let's hit the Next button. On this page, we have to select the group for our user. For the purpose of this tutorial, let's create a new one, using the button visible below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/4-2.png" alt="Image shows permissions and permissions boundary settings for new user" width="600" height="400" loading="lazy"></p>
<p>Nextly, let's specify a <strong>Group name</strong> ( <code>admin-group</code> in my case) in the modal and select the <strong>AdministratorAccess</strong>:</p>
<p>For simplicity, we are going to use the AdministratorAccess. But in real-life scenarios, we should always stick to The Principle of Least Privilege.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/5-2.png" alt="Image shows new group name with seleced policy- AdministratorAccess" width="600" height="400" loading="lazy"></p>
<p>After the group is created, let's hit the Next button once again: </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/6-2.png" alt="Image shows existing groups and selected admin-group" width="600" height="400" loading="lazy"></p>
<p>On the next page, we have the option of adding <strong>custom tags</strong> as key-value pairs. </p>
<p>But we won't need them today, so let's simply skip this page: </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/7-2.png" alt="Image shows add tags (optional) form" width="600" height="400" loading="lazy"></p>
<p>Finally, we will be redirected to the <strong>Review</strong> page, where we can validate our previous steps:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/8-1.png" alt="Image presents Review new user details" width="600" height="400" loading="lazy"></p>
<p>As you can see, everything looks good, so let's click <strong>Create user</strong>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/9-1.png" alt="Image shows created user " width="600" height="400" loading="lazy"></p>
<p>The user was created successfully, so we can finally import our access and secret keys. </p>
<p>Keep in mind that access and secret keys are highly confidential data and you should never share them with anyone!</p>
<p>Let's click the <strong>Download .csv</strong> button and fetch the file. Personally, I named it <code>some_user_credentials.csv</code> , but feel free to pick whatever name you like (and remember it :) ).</p>
<p>Next, let's navigate to the download directory and run the following command:</p>
<pre><code> aws configure <span class="hljs-keyword">import</span> --csv file:<span class="hljs-comment">//some_user_credentials.csv</span>

 # Result:
 Successfully imported <span class="hljs-number">1</span> profile(s)
</code></pre><p>Given the above message, we can expect that everything was set up correctly. Additionally, we can verify that a new file called <code>credentials</code> has been created (or updated) inside the <code>.aws</code> directory. </p>
<p>If you are using Windows then your path will be  <code>C:\Users\[your_user_name]\.aws</code>:</p>
<pre><code>[some-admin]
aws_access_key_id = [your access key id] 
aws_secret_access_key = [your secret]
</code></pre><h2 id="heading-how-to-push-the-docker-image-to-ecr">How to Push the Docker Image to ECR</h2>
<p>At this point, our CLI is properly prepared, so we can learn how to push our local Docker Image to the <strong>Elastic Container Registry</strong>.</p>
<p>As the first step, let's get back to the <strong>Management Console</strong> and type <strong>container registry</strong> in the search bar: </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/10-1.png" alt="Image shows search results for 'container reqistry' query" width="600" height="400" loading="lazy"></p>
<p>Let's click on the <strong>Elastic Container Registry</strong> and on the next page, the <strong>Create repository</strong> button. On the next page, let's select a Private repository and specify a name for it:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/11-1.png" alt="Image shows create repository general settings" width="600" height="400" loading="lazy"></p>
<p> For the rest of settings, let's leave the default values, just like below: </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/12.png" alt="Image shows Image scan and encryption settings" width="600" height="400" loading="lazy"></p>
<p>Finally, let's hit the <strong>Create repository</strong> button.</p>
<p>After that, we will be redirected to the Private repositories list, which now contains our newly created repository: </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/13.png" alt="Image presents private repositories with one item- my-ktor-registry on the list" width="600" height="400" loading="lazy"></p>
<p>Let's copy the URI and specify the following command in the terminal on our local machine: </p>
<pre><code>docker tag ktor-aws-runner:latest [your_registry_uri]:latest

# Example: docker tag ktor-aws-runner:latest <span class="hljs-number">111111111111.</span>dkr.ecr.us-east<span class="hljs-number">-1.</span>amazonaws.com/my-ktor-registry:latest
</code></pre><p>Why do we need that? Well, basically, when working with Docker <strong>we need to tag images with registry host and port</strong> (if necessary) in order to push them to any private repository. </p>
<p>With that being done, let's authenticate to the Amazon ECR registry:</p>
<pre><code>aws ecr get-login-password --profile some-admin --region us-east<span class="hljs-number">-1</span> | docker login --username AWS --password-stdin [your registry URI]

# Result:
Login Succeeded
</code></pre><p>After that, we can run the <code>git push</code> command in order to push the image to ECR: </p>
<pre><code>docker push [your_tagged_image] 

# Example: docker push <span class="hljs-number">111111111111.</span>dkr.ecr.us-east<span class="hljs-number">-1.</span>amazonaws.com/my-ktor-registry:latest
</code></pre><p>Depending on your connection it can take some time, but finally, we should see the update list in our repository: </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/14.png" alt="Image shows my-ktor-registry images with one item- latest on the list" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-deploy-the-application-to-aws-app-runner">How to Deploy the Application to AWS App Runner</h2>
<p>Now we have everything we need to share our Kotlin microservice with the world :) </p>
<p>Let's get back to the Management Console and search for app runner: </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/15.png" alt="Image presents search results for app runner query" width="600" height="400" loading="lazy"></p>
<p>On the next page, let's hit the <strong>Create service</strong> button.</p>
<p>For the Source configuration, let's choose the <strong>Container registry</strong> along with <strong>Amazon ECR</strong>: </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/16.png" alt="Image presents source  and deployment settings for new deployment" width="600" height="400" loading="lazy"></p>
<p>As you might have noticed, AWS App Runner can deploy services directly from a source code repository. If you are interested in such a configuration, just get in touch with me via email (contact[at]codersee[dot]com).</p>
<p>Next, let's click Browse and select <strong>previously created image</strong>: </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/17.png" alt="Image presents selected image reposiotory and image tag" width="600" height="400" loading="lazy"></p>
<p>Let's click continue and for the Deployment settings let's choose <strong>Manual</strong> and <strong>Create new service role:</strong> </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/18.png" alt="Image shows deployment trigger, ECR Access role and Service role name" width="600" height="400" loading="lazy"></p>
<p>The role name is not important in this tutorial, so we can specify any value. </p>
<p>As the next step, let's click Next and on the next page, let's provide a <strong>Service name</strong> along with <strong>CPU</strong>, <strong>Memory</strong> and <strong>Port</strong> information:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/19.png" alt="Image" width="600" height="400" loading="lazy">
<em>Image presents Service name, cpu, memory, environment variables, port and additional configuration settings</em></p>
<p>As you can see, we have chosen the minimum available combination (and that's what I suggest you do as well).</p>
<p>If we would like to specify some additional environment variables or a custom Start command, then this page allows us to do so. But we won't need any environment variables and we have already added a start command to our Docker Image, so let's leave it as it is.</p>
<p>On the Auto scaling page, select the <strong>Custom configuration</strong>: </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/20.png" alt="Image shows auto scaling settings with custom configuration set " width="600" height="400" loading="lazy"></p>
<p>Next, let's create a new configuration called <strong>my-configuration</strong>: </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/21.png" alt="Image shows add custom auto scaling configuration modal" width="600" height="400" loading="lazy"></p>
<p>As I have mentioned in the beginning, AWS App Runner takes care of plenty of things out of the box. One of them is auto scaling. Although it is a great feature, we have to limit it to our preferences and always remember that more resources means higher costs. </p>
<p>As you can see above, this example configuration <strong>will not scale our Kotlin Microservice</strong>. However, if we increase the Maximum size, then a new instance will be created each time the number of simultaneous request increases by 10. </p>
<p>Let's add the above config and leave the rest of items with their defaults. After we click Next, we will see the Review page with deployment summary. </p>
<p>On this page, let's click <code>Create and Deploy</code> button, which will start the deployment process: </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/22.png" alt="Image presents started AWS App Runner deployment process" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/23.png" alt="Image presents deployment logs event called Create service" width="600" height="400" loading="lazy"></p>
<p>And again, this process can take a few minutes. After it finishes, the status will change from <code>Operation in progress</code> to <code>Running</code> and we will be able to test our Ktor REST API.</p>
<p>Just like previously, let's test the <code>GET /hello</code> endpoint. But this time, as a host name of our microservice, we need to use the value from <code>Default domain</code>:</p>
<pre><code>#Example: 

GET https:<span class="hljs-comment">//aaaaaaaaaa.us-east-1.awsapprunner.com/hello</span>

Status: <span class="hljs-number">200</span> OK
Response Body: 
{
    <span class="hljs-string">"message"</span>: <span class="hljs-string">"Hello World!"</span>
}
</code></pre><h2 id="heading-important-notice">🛑 Important Notice</h2>
<p>Please remember to <strong>delete all the resources we've created today</strong>, so that you won't be charged for them. </p>
<p>It's really easy to forget about all the things we create when learning AWS Cloud and at some point, you may exceed your free quota. Thus, it is a good practice to remove all of that. </p>
<h2 id="heading-summary">Summary</h2>
<p>And that's all for this tutorial on how to deploy Kotlin Microservice to AWS Cloud with AWS App Runner. I really hope that after following along with this guide, you're able to easily deploy your applications to Amazon Cloud. </p>
<p>If you enjoyed this material, then you might want to check my <a target="_blank" href="https://codersee.com/articles/">other articles</a>. On my blog, I cover plenty of topics related to Kotlin, Ktor, and Spring Boot. </p>
<p>If you would like to ask me about anything, please reach out to me at <em>contact[at]codersee[dot]com</em>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Add Swipe Animations to a CardView in an Android App ]]>
                </title>
                <description>
                    <![CDATA[ By Gourav Khunger If you're building an Android app, you should consider adding animations. They can improve your app's user experience and increase retention.  These days, if you see an app that has no animation, it can feel odd and out-dated. And s... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/add-swipe-animations-to-a-card-view-in-android-app/</link>
                <guid isPermaLink="false">66d45edb052ad259f07e4ad2</guid>
                
                    <category>
                        <![CDATA[ android app development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ androiddev ]]>
                    </category>
                
                    <category>
                        <![CDATA[ animation ]]>
                    </category>
                
                    <category>
                        <![CDATA[ animations ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Kotlin ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 15 Nov 2021 16:09:53 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/11/Swiping-Animation-Android-Views.gif" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Gourav Khunger</p>
<p>If you're building an Android app, you should consider adding animations. They can improve your app's user experience and increase retention. </p>
<p>These days, if you see an app that has no animation, it can feel odd and out-dated. And since interactive experiences are kind of the new norm, you'll want to figure out ways to set your app apart.</p>
<h2 id="heading-what-well-build-here">What We'll Build Here</h2>
<p>Now, it might seem difficult to make your app stand out if you just have something basic like a quote sharing app (which is what we are going to work on here). It can be hard to hook the user and keep them interested.</p>
<p>Of course, you could just add two simple buttons to load the next/previous quote and call it a day. But that's pretty basic and any app could do that! Even if you're just building a simple side-project, there's no trade-off for good UX :)</p>
<p>So what we'll do in this tutorial is drop the buttons, and instead have logic where a user can swipe the card to the left. When they've swiped far enough, the app will load a new card with a new quote.</p>
<p>By the end of this post, you will learn how to make a really smooth animated card which a user can swipe that can perform whatever action you choose. Here's a demo of how it works:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/iHxFjvI4x.gif" alt="Animation showing smooth slide to refresh swiping animation on a android cardview." width="600" height="400" loading="lazy"></p>
<p>Amazing, right? Let's get into it!</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>For this tutorial, we will use Kotlin as the programming language for our app – but you can easily translate the code to Java and it would work the same.</p>
<p>For reference, this is the quote card that we wish to enable the swipe feature on.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/9CVHyoJfV.png" alt="Android card view with a quote." width="600" height="400" loading="lazy"></p>
<p>It is an androidX <code>CardView</code> with a bunch of <code>TextView</code>s and an <code>ImageView</code>. There's also a <code>ProgressBar</code> that gets shown while loading a new quote.</p>
<p>We won't be making the XML code for the user interface. You can <a target="_blank" href="https://github.com/gouravkhunger/QuotesApp/blob/main/app/src/main/res/layout/fragment_quote.xml">get the layout</a> I used here from the GitHub repository, or build your own.</p>
<p><a target="_blank" href="https://github.com/gouravkhunger/QuotesApp">Here's the complete code</a> for our Quotes app, if you wish to check it out. It uses the MVVM design pattern, but this article doesn't rely on what pattern you use for the business logic of your app, as we'll just be working on the UI part.</p>
<p>Now, we're ready to make that awesome swipe interface!</p>
<h2 id="heading-how-to-handle-swipes-in-our-app">How to Handle Swipes in Our App</h2>
<p>To handle swipes, we first need to set a touch listener on the card. Each time an action is performed on the card, the touch listener is called. Within the listener, we will add the logic to do the math and perform the animations.</p>
<p>Here is the blueprint of the touch listener we will be using:</p>
<pre><code class="lang-kotlin">quoteCard.setOnTouchListener(
    View.OnTouchListener { view, event -&gt;
        <span class="hljs-keyword">when</span> (event.action) {
            MotionEvent.ACTION_MOVE -&gt; {
                <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> Handle ACTION_MOVE</span>
            }
            MotionEvent.ACTION_UP -&gt; {
                <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> Handle ACTION_UP</span>
            }
        }

        <span class="hljs-comment">// required to by-pass lint warning</span>
        view.performClick()
        <span class="hljs-keyword">return</span><span class="hljs-symbol">@OnTouchListener</span> <span class="hljs-literal">true</span>
    }
)
</code></pre>
<p>Here, we are specifically listening for 2 actions on the card – the <code>ACTION_MOVE</code> and the <code>ACTION_UP</code>.</p>
<ul>
<li>The <code>ACTION_MOVE</code> event is called when a user starts swiping the card, that is, moving it.</li>
<li>The <code>ACTION_UP</code> is called when a user lifts their finger from the card, basically, when they release it.</li>
</ul>
<p>There are many other action events that we can override, such as <code>ACTION_DOWN</code> that's called when a person gets hold of the view, but we don't need them for this feature.</p>
<p>The basic setup for the card is done, so let's figure out the swiping logic.</p>
<h3 id="heading-the-math-behind-the-swipe-action">The math behind the swipe action</h3>
<p>First, let's re-think <strong>what we want to achieve</strong>. Implementing functionality is easier when you know exactly what you wish to have. Your code will also make more sense when your requirements are clear.</p>
<p>Here, we have a quote card. We want users to be able to swipe it only to the left, and if the minimum threshold to load a new quote is reached, it should move back to its original position and load a new quote.</p>
<p>Now, to achieve this, let's think of it in terms of the card. Let's define the mean position as the center of the card.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/dEnpWr7e4.png" alt="Mean Position of Quote Card" width="600" height="400" loading="lazy">
<em>Mean Position of the Card</em></p>
<p>We want the card to swipe if and only if the user swipes it to the left of the mean position.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/7epeWn53S.gif" alt="Animation illustrating user swipes to the left of the Quote Card" width="600" height="400" loading="lazy">
<em>Swipe only if moved towards the left of mean position</em></p>
<p>So how can we make this happen? </p>
<p>You guessed it – we will calculate the mean position and on the <code>ACTION_MOVE</code> event, we will check if the user swiped to the left and move the card accordingly.</p>
<h3 id="heading-how-to-implement-the-swipe-logic">How to implement the swipe logic</h3>
<p>To implement the logic, we first need to have the starting position of the card, which is fairly easy to calculate. We will just make sure that it is calculated with respect to the full-screen width, not just the card's width.</p>
<p>Place these lines of code before the <code>when(event.action)</code> statement:</p>
<pre><code class="lang-kotlin">quoteCard.setOnTouchListener(
    View.OnTouchListener { view, event -&gt;

        <span class="hljs-comment">// variables to store current configuration of quote card.</span>
        <span class="hljs-keyword">val</span> displayMetrics = resources.displayMetrics
        <span class="hljs-keyword">val</span> cardWidth = quoteCard.width
        <span class="hljs-keyword">val</span> cardStart = (displayMetrics.widthPixels.toFloat() / <span class="hljs-number">2</span>) - (cardWidth / <span class="hljs-number">2</span>)

        <span class="hljs-keyword">when</span> (event.action) {
            ...
        }
        ...
    }
)
</code></pre>
<p>First we get the <code>displayMetrics</code> from resources, which will give us the width of the screen using <code>displayMetrics.widthPixels.toFloat()</code>.</p>
<p>Then we get the <code>cardWidth</code> using the <code>width</code> property of the <code>quoteCard</code>.</p>
<p>Finally, we calculate the starting position of the card using the formula <code>(width of screen/2) - (cardWidth/2)</code>. Essentially, this gives us the x-coordinate of this position of the card:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/NiH3lsseM.gif" alt="Animation highlighting starting position of Quote Card" width="600" height="400" loading="lazy">
<em>Starting position of card.</em></p>
<p>Now, let's implement the code for the <code>ACTION_MOVE</code> event.</p>
<h3 id="heading-how-to-handle-the-actionmove-event">How to handle the <code>ACTION_MOVE</code> event</h3>
<p>Inside the <code>ACTION_MOVE</code> block, we first initialise the <code>newX</code> variable that holds the new x-coordinate that the card has been swiped to.</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">val</span> newX = event.rawX
</code></pre>
<p><code>event.rawX</code> gives us the absolute value of the new coordinate with respect to the screen width.</p>
<p><code>newX</code> will contain the x-coordinate where the user's finger is, at any given moment. The value <code>0.0</code> for <code>newX</code> means that the user swiped to the left-most part of the screen. And for my emulator, <code>1080.0</code> represents the right-most edge of the screen.</p>
<p>Since, we want the card to swipe only if <code>newX</code> is less than the mean position of the card, we will place an if-condition here to verify that this is the case.</p>
<p>Think of this with simple values. Let's suppose that the mean position of the card is at x-coordinate <code>540.0</code> (small x-coordinate) and the user swipes to <code>710.0</code> (bigger x-coordinate). But we don't want them to be able to swipe to the right. And if the user swipes to <code>320.0</code> (smaller x-coordinate), then we need to carry out the swipe and move the card to the new position.</p>
<p>Here's the code to implement the above logic:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">if</span> (newX - cardWidth &lt; cardStart) { <span class="hljs-comment">// or newX &lt; cardStart + cardWidth</span>
    quoteCard.animate().x(
        min(cardStart, newX - (cardWidth / <span class="hljs-number">2</span>))
    )
    .setDuration(<span class="hljs-number">0</span>)
    .start()
}
</code></pre>
<p>We subtract <code>cardWidth</code> from <code>newX</code> because <code>newX</code> is an absolute value which is not relative to the card. It has a higher value because <code>cardStart</code> is towards the start of the screen, and <code>newX</code> is initially somewhere in the middle (a user would generally swipe from the middle).</p>
<p>We want to compare the value of <strong>shift</strong> in the x-coordinate and median to the value of <code>cardStart</code>, not the value of <strong><code>newX</code></strong>, so we take this into account by subtracting <code>cardWidth</code>.</p>
<p>Then, we carry out the animation using <code>quoteCard.animate()</code> and we change its x coordinate using the <code>x()</code> function.</p>
<p>Now, why do we do <code>min(cardStart, newX - (cardWidth/2))</code>?</p>
<p>This is very interesting and intuitive to understand. From the beginning, we are emphasizing that the card should move only to the left and not to the right. </p>
<p><code>newX - (cardWidth/2))</code> is nothing but the swiped distance towards the left (so subtraction is involved – for the right side, it should be added).</p>
<p>The <code>min()</code> function here returns the minimum of the two values provided. If the swiped distance is less than the <code>cardStart</code>, it is returned, otherwise <code>cardStart</code> is used. This is the condition we want to meet and <code>min()</code> makes it really easy to handle.</p>
<p><code>setDuration(0)</code> ensures that the animation is carried instantaneously (which keeps swiping from feeling laggy). <code>start()</code> actually starts the animation with the given properties.</p>
<p>This animation will clear any doubt your have on how this works:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/other.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Visualisation of the aforementioned concept</em></p>
<p>(I don't have expertise on making animations, this was the best I could come up with.)</p>
<p>Here is the final code for the <code>ACTION_MOVE</code> event:</p>
<pre><code class="lang-kotlin">MotionEvent.ACTION_MOVE -&gt; {
    <span class="hljs-comment">// get the new coordinate of the event on X-axis</span>
    <span class="hljs-keyword">val</span> newX = event.rawX

    <span class="hljs-comment">// carry out swipe only if newX - cardWidth &lt; cardStart, that is</span>
    <span class="hljs-comment">// the card is swiped to the left side, not to the right</span>
    <span class="hljs-keyword">if</span> (newX - cardWidth &lt; cardStart) {
        quoteCard.animate()
            .x(
                min(cardStart, newX - (cardWidth / <span class="hljs-number">2</span>))
            )
        .setDuration(<span class="hljs-number">0</span>)
        .start()
    }
}
</code></pre>
<p>You can also include a <code>TextView</code> to the UI that reflects when the user should release the card. Place this code inside the above <code>if</code> statement too:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">if</span> (quoteCard.x &lt; MIN_SWIPE_DISTANCE) textView.text = getString(R.string.releaseCard)
<span class="hljs-keyword">else</span> textView.text = getString(R.string.infoText)
</code></pre>
<p>where <code>MIN_SWIPE_DISTANCE</code> is <code>-250</code>:</p>
<pre><code class="lang-kotlin"><span class="hljs-comment">// -250 produces best result, feel free to change to your liking</span>
<span class="hljs-keyword">const</span> <span class="hljs-keyword">val</span> MIN_SWIPE_DISTANCE = -<span class="hljs-number">250</span> <span class="hljs-comment">// User should move alteast -250 from mean position to load new quote</span>
</code></pre>
<p>Now, the <code>ACTION_MOVE</code> event is handled properly. Let's write the code to handle the <code>ACTION_UP</code> event, that is, when the card is released.</p>
<h3 id="heading-how-to-handle-the-actionup-event">How to handle the <code>ACTION_UP</code> event</h3>
<p>For the <code>ACTION_UP</code> event, we want the card to come back to its original position, wait for about <code>100</code> milliseconds, then load a new quote.</p>
<p>The logic to animate the card is similar, but this time we will make its animation duration about <code>150</code> millisecond to make it look smooth.</p>
<p>First, create a variable <code>currentX</code> that holds the current value of the x coordinate of the quote card. We'll use this variable later.</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">var</span> currentX = quoteCard.x
</code></pre>
<p>Then, start the animation on the card. Pass the <code>cardStart</code> variable to the <code>x()</code> function to make it return to its original position and set the duration to <code>150</code>.</p>
<pre><code class="lang-kotlin">quoteCard.animate()
    .x(cardStart)
    .setDuration(<span class="hljs-number">150</span>)
<span class="hljs-comment">// continued below</span>
</code></pre>
<p>This time, we set a listener on the animation. A listener is something that keeps an eye on the animation. By using it, we can perform actions on various animation events such as start, end, resume, and more.</p>
<pre><code class="lang-kotlin"><span class="hljs-comment">// continuation</span>
.setListener(
    <span class="hljs-keyword">object</span> : AnimatorListenerAdapter() {
        <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">onAnimationEnd</span><span class="hljs-params">(animation: <span class="hljs-type">Animator</span>)</span></span> {
            viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Default) {
                delay(<span class="hljs-number">100</span>)
                <span class="hljs-comment">// check if the swipe distance was more than</span>
                <span class="hljs-comment">// minimum swipe required to load a new quote</span>
                <span class="hljs-keyword">if</span> (currentX &lt; MIN_SWIPE_DISTANCE) {
                    <span class="hljs-comment">// Add logic to load a new quote if swiped adequately</span>
                    viewModel.getRandomQuote()
                    currentX = <span class="hljs-number">0f</span>
                }
            }
        }
    }
)
.start()
</code></pre>
<p>We set a listener to look for the ending of the animation by overriding the <code>onAnimationEnd()</code> function. </p>
<p>As soon as the animation ends, we launch a coroutine (similar to Threads in Java but much more efficient) with a delay of 100 milliseconds. It then checks if the user had swiped further than the <code>MIN_SWIPE_DISTANCE</code> needed to load a new quote. The variable <code>currentX</code> is used for the comparison here.</p>
<p>If the user actually swipes passing the minimum distance, the coroutine is delayed for <code>100</code> milliseconds. Then the view model loads a new random quote from the API, also resetting the <code>currentX</code> variable to <code>0f</code>.</p>
<p>The final code for the <code>ACTION_UP</code> event looks like this:</p>
<pre><code class="lang-kotlin">MotionEvent.ACTION_UP -&gt; {
    <span class="hljs-keyword">var</span> currentX = quoteCard.x
    quoteCard.animate()
        .x(cardStart)
        .setDuration(<span class="hljs-number">150</span>)
        .setListener(<span class="hljs-keyword">object</span> : AnimatorListenerAdapter() {
            <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">onAnimationEnd</span><span class="hljs-params">(animation: <span class="hljs-type">Animator</span>)</span></span> {
                viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Default) {
                    delay(<span class="hljs-number">100</span>)
                    <span class="hljs-comment">// check if the swipe distance was more than</span>
                    <span class="hljs-comment">// minimum swipe required to load a new quote</span>
                    <span class="hljs-keyword">if</span> (currentX &lt; MIN_SWIPE_DISTANCE) {
                        <span class="hljs-comment">// Add logic to load a new quote if swiped adequately</span>
                        viewModel.getRandomQuote()
                        currentX = <span class="hljs-number">0f</span>
                    }
                }
            }
        })
        .start()
    textView.text = getString(R.string.infoText)
}
</code></pre>
<h2 id="heading-final-code">Final Code</h2>
<p>This is the final code for the complete <code>onTouchListener()</code>:</p>
<pre><code class="lang-kotlin">quoteCard.setOnTouchListener(
    View.OnTouchListener { v, event -&gt;

        <span class="hljs-comment">// variables to store current configuration of quote card.</span>
        <span class="hljs-keyword">val</span> displayMetrics = resources.displayMetrics
        <span class="hljs-keyword">val</span> cardWidth = quoteCard.width
        <span class="hljs-keyword">val</span> cardStart = (displayMetrics.widthPixels.toFloat() / <span class="hljs-number">2</span>) - (cardWidth / <span class="hljs-number">2</span>)

        <span class="hljs-keyword">when</span> (event.action) {
            MotionEvent.ACTION_UP -&gt; {
                <span class="hljs-keyword">var</span> currentX = quoteCard.x
                quoteCard.animate()
                    .x(cardStart)
                    .setDuration(<span class="hljs-number">150</span>)
                    .setListener(
                        <span class="hljs-keyword">object</span> : AnimatorListenerAdapter() {
                            <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">onAnimationEnd</span><span class="hljs-params">(animation: <span class="hljs-type">Animator</span>)</span></span> {
                                viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Default) {
                                    delay(<span class="hljs-number">100</span>)

                                    <span class="hljs-comment">// check if the swipe distance was more than</span>
                                    <span class="hljs-comment">// minimum swipe required to load a new quote</span>
                                    <span class="hljs-keyword">if</span> (currentX &lt; MIN_SWIPE_DISTANCE) {
                                        <span class="hljs-comment">// Add logic to load a new quote if swiped adequately</span>
                                        viewModel.getRandomQuote()
                                        currentX = <span class="hljs-number">0f</span>
                                    }
                                }
                            }
                        }
                    )
                    .start()
                textView.text = getString(R.string.infoText)
            }
            MotionEvent.ACTION_MOVE -&gt; {
                <span class="hljs-comment">// get the new co-ordinate of X-axis</span>
                <span class="hljs-keyword">val</span> newX = event.rawX

                <span class="hljs-comment">// carry out swipe only if newX &lt; cardStart, that is,</span>
                <span class="hljs-comment">// the card is swiped to the left side, not to the right</span>
                <span class="hljs-keyword">if</span> (newX - cardWidth &lt; cardStart) {
                    quoteCard.animate()
                        .x(
                            min(cardStart, newX - (cardWidth / <span class="hljs-number">2</span>))
                        )
                        .setDuration(<span class="hljs-number">0</span>)
                        .start()
                    <span class="hljs-keyword">if</span> (quoteCard.x &lt; MIN_SWIPE_DISTANCE) 
                        textView.text = getString(R.string.releaseCard)
                    <span class="hljs-keyword">else</span> textView.text = getString(R.string.infoText)
                }
            }
        }

        <span class="hljs-comment">// required to by-pass lint warning</span>
        v.performClick()
        <span class="hljs-keyword">return</span><span class="hljs-symbol">@OnTouchListener</span> <span class="hljs-literal">true</span>
    }
}
</code></pre>
<p>Congrats! In this tutorial, we've implemented animation that lets a user swipe a card containing a quote to get a new quote.</p>
<p>Don't forget to download the app and test it out yourself. Stars and contributions on the <a target="_blank" href="https://github.com/gouravkhunger/QuotesApp">GitHub repository</a> are welcomed!</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Now you have learned how to animate a card and handle animation listeners on it. This helps create better UX that makes your app stand out.</p>
<p>Using the knowledge you gained in this post, you can now create most of the following animations for views in Android:</p>
<ul>
<li><strong>Programmatically create sliding animations for Android views.</strong></li>
</ul>
<p>Just as we did in this tutorial.</p>
<ul>
<li><strong>Left to right animation</strong></li>
</ul>
<p>This is fairly simple, just turn the subtraction in the variables to addition and <code>&lt;</code> signs in the <code>if</code> statements to <code>&gt;</code> signs. With these few tweaks here and there, the right to left animations in card view can be turned into left to right ones!</p>
<ul>
<li><strong>You can also show and hide views using animations.</strong></li>
</ul>
<p>For this, you have to keep track of the start position and end position then animate them with <code>alpha()</code> from <code>0</code> to <code>1</code>. For an example, you can refer to my library <a target="_blank" href="https://github.com/gouravkhunger/AccoLib">Accolib</a> to create animated FAQ accordions.</p>
<ul>
<li><strong>Basic animated layout changes can be achieved with view animations.</strong></li>
</ul>
<p>Thanks a lot for reading so far, I hope this post added some value. Subscribe to my newsletter at <a target="_blank" href="https://genicsblog.com">Genics Blog</a> to stay updated with my future articles!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Style and Theme an App With Jetpack Compose ]]>
                </title>
                <description>
                    <![CDATA[ In this article, we will learn how to style and theme an application in Jetpack Compose. Compose is a new UI framework for Android (though Desktop and Web support is being developed), which replaces the old XML-based View system. While still in beta ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-style-and-theme-an-app-with-jetpack-compose/</link>
                <guid isPermaLink="false">66d460cb47a8245f78752abd</guid>
                
                    <category>
                        <![CDATA[ Android ]]>
                    </category>
                
                    <category>
                        <![CDATA[ android app development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Kotlin ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UI Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ User Interface ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ryan Michael Kay ]]>
                </dc:creator>
                <pubDate>Mon, 22 Mar 2021 13:48:12 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/6054c45f687d62084bf67e41.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article, we will learn how to style and theme an application in Jetpack Compose.</p>
<p>Compose is a new UI framework for Android (though Desktop and Web support is being developed), which replaces the old XML-based View system.</p>
<p>While still in beta release as of writing this article, I do not expect this particular part of the library to change drastically for the stable release.</p>
<p>Topics include:</p>
<ul>
<li><p>A brief recap of the XML approach</p>
</li>
<li><p>How to migrate from the XML-based colors, themes, and typography (font) system</p>
</li>
<li><p>How to set up light and dark themes for your apps in only a few lines of code</p>
</li>
<li><p>How to use your new Kotlin-based style information in your composables</p>
</li>
<li><p>How to style Text Composables specifically</p>
</li>
</ul>
<p>Before proceeding, it is important that you understand what a composable is. I will not be stopping to explain that concept here, as I already have in <a target="_blank" href="https://www.freecodecamp.org/news/jetpack-compose-beginner-tutorial-composables-recomposition/">this article</a>.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/81r-vwPxlaw" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<h2 id="heading-how-we-used-to-style-android-apps-using-xml-resources">How We Used to Style Android Apps Using XML Resources</h2>
<p>As usual, I like to share with you the motivations behind, and a bit of history on, these topics. In case you do not care, feel free to skip to the next section where we get into the practical stuff.</p>
<h3 id="heading-android-resources">Android Resources</h3>
<p>The Android app resources system is something which the Android team deserves a high five for, at least in my opinion. But like every design decision, a feature in one situation becomes a flaw in another situation.</p>
<p>To be specific, one of the greatest challenges for both platform and application developers alike is to create what I will call <strong>localized resources</strong>. I am referring to the challenge of building apps which:</p>
<ul>
<li><p>Display text and graphics in a variety of different languages and alphabets</p>
</li>
<li><p>Look and feel proportionate to a wide variety of form factors (dimensions, densities, and so on.)</p>
</li>
</ul>
<p>Those are just two common examples – there are plenty more. The resource system gives us a place where app developers can provide localized resources which the platform can select for at compile time. This saves us having to write that boilerplate code ourselves.</p>
<h3 id="heading-feature-or-flaw">Feature or Flaw?</h3>
<p>While I would never want to manage the boilerplate code necessary for localized string resources myself, that does not mean I enjoy writing XML.</p>
<p>In fact, <strong>there are very few things I would prefer to do in XML</strong> over a modern, idiomatic, and elegant language such as Kotlin or Swift. Personal preference aside, there is a more technical reason why XML resources are not always ideal.</p>
<p>Please note that this is not meant as a criticism of the platform developers/engineers. It is merely an observation of how design decisions always have benefits and costs.</p>
<p>In order to integrate our XML-based resources into our JVM-based application code, we must necessarily have <strong>layers of translation</strong> (compilation) and <strong>platform bridges</strong> (APIs). This can present difficulties for both platform and application developers.</p>
<p>Two common problems I ran into were:</p>
<ul>
<li><p>I want access to a resource in a place where I do not want tight coupling to the platform APIs which provide the resource</p>
</li>
<li><p>I have to write some ridiculous boilerplate code just to change the look of a View (that is, override something defined within resource styles and themes)</p>
</li>
</ul>
<p>The <strong>root problem</strong> for everyone involved is <strong>tight coupling</strong> to the View system and the Android resource system (which are themselves tightly coupled together).</p>
<p>For the platform developers, this means they have to build on top of, or work around gigantic and old codebases. Add that they must also try to have new features work on older Android OS versions, and that becomes a very thankless job.</p>
<p>The result for us application developers is most often a lot of <strong>boilerplate code,</strong> some <strong>hacky workarounds</strong> for things which intuitively seem like they should be one-liners. Not to mention the main API for getting these resources is <code>Context</code>, which is a class you really do not want to leak in memory.</p>
<p><strong>Enter Jetpack Compose.</strong></p>
<h2 id="heading-how-to-set-up-themes-colors-and-fonts-with-jetpack-compose">How to Set Up Themes, Colors, and Fonts with Jetpack Compose</h2>
<p>With our review of the old system out of the way, let's explore a much prettier and simpler way to style and theme an Android application. I said I would keep this practical, but allow one point.</p>
<p>Since we will be doing that work in Kotlin, it means one very important thing: Both we and the platform developers are much less bound by translation (compilation) and API bridges (Android's <code>R</code> class and <code>Context</code>) between XML and the JVM.</p>
<p>In simple terms, this means <strong>much less boilerplate code</strong>, and <strong>much more control at runtime</strong>.</p>
<p>For the practical part of this article, my suggestion to you is to follow this process in the order I explain it. I have structured it in the order I follow when writing this code in a new App.</p>
<h3 id="heading-how-to-replace-colorsxml-resources-with-kotlin-compose">How to Replace Colors.xml Resources with Kotlin Compose</h3>
<p>If you have not already decided upon a color scheme for your application, I suggest that you use the various resources available on the official Material Design website. Try out:</p>
<ul>
<li><p>The <a target="_blank" href="https://material.io/design/color/the-color-system.html#tools-for-picking-colors">color palettes</a></p>
</li>
<li><p>The <a target="_blank" href="https://material.io/resources/color/">color tool</a></p>
</li>
</ul>
<p>If you plan to support light and dark app themes (explained shortly), try to select a color scheme which supports white text and a color scheme which supports black text.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/color_text_palettes.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Example of light and dark color schemes.</em></p>
<p>Create a file called something like <a target="_blank" href="https://github.com/BracketCove/GraphSudokuOpen/blob/master/app/src/main/java/com/bracketcove/graphsudoku/ui/Color.kt">Color.kt</a> (the name does not matter) and fill it with immutable <strong>val</strong>ues:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">import</span> androidx.compose.ui.graphics.Color

<span class="hljs-keyword">val</span> primaryGreen = Color(<span class="hljs-number">0XFF00bc00</span>)
<span class="hljs-keyword">val</span> primaryCharcoal = Color(<span class="hljs-number">0xFF2b2b2b</span>)
<span class="hljs-keyword">val</span> accentAmber = Color(<span class="hljs-number">0xFFffe400</span>)

<span class="hljs-keyword">val</span> textColorLight = Color(<span class="hljs-number">0xDCFFFFFF</span>)
<span class="hljs-keyword">val</span> textColorDark = Color(<span class="hljs-number">0xFFf3f3f3</span>)
<span class="hljs-keyword">val</span> gridLineColorLight = Color.Black
<span class="hljs-comment">//...</span>
</code></pre>
<p>You can either use a predefined value like <code>Color.Black</code> or supply your own ARGB Hex value.</p>
<p>Since ARGB Hex is just a bunch of jargon to describe what the heck "<code>0XFF00bc00</code>" means, let me translate:</p>
<ul>
<li><p>First two characters <code>0x</code> tell the compiler that this is a hexadecimal number</p>
</li>
<li><p>Second two characters , "<code>FF</code>" or "<code>DC</code>", represent Transparency/Opaqueness/<strong>A</strong>lpha in Hex</p>
</li>
<li><p>The remaining six character pairs represent <strong>R</strong>ed, <strong>G</strong>reen, and <strong>B</strong>lue</p>
</li>
</ul>
<h3 id="heading-how-to-add-fonts-and-replace-the-fontfamily-attribute">How to Add Fonts and Replace the <code>fontFamily</code> Attribute</h3>
<p>Typography (fonts) is also very easy to manage. This is the kind of thing where Kotlin's <a target="_blank" href="https://kotlinlang.org/docs/functions.html#default-arguments">default arguments</a> are very useful.</p>
<p>Create a file called something like <a target="_blank" href="https://github.com/BracketCove/GraphSudokuOpen/blob/master/app/src/main/java/com/bracketcove/graphsudoku/ui/Type.kt">Type.kt</a> (the name still does not matter) and create <code>Typography</code> class...:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">val</span> typography = Typography(
    body1 = TextStyle(
        fontFamily = FontFamily.Default,
        fontWeight = FontWeight.Normal,
        fontSize = <span class="hljs-number">16</span>.sp
    ),

    button = TextStyle(
        fontFamily = FontFamily.Default,
        fontWeight = FontWeight.Bold,
        fontSize = <span class="hljs-number">32</span>.sp
    ),

    caption = TextStyle(
        fontFamily = FontFamily.Default,
        fontWeight = FontWeight.Normal,
        fontSize = <span class="hljs-number">12</span>.sp
    )
)
<span class="hljs-comment">//...</span>
</code></pre>
<p>...and some <code>TextStyle</code> classes:</p>
<pre><code class="lang-kotlin"><span class="hljs-comment">//...</span>
<span class="hljs-keyword">val</span> mainTitle = TextStyle(
    fontFamily = FontFamily.Default,
    fontWeight = FontWeight.Light,
    fontSize = <span class="hljs-number">48</span>.sp,
    textAlign = TextAlign.Center
)

<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">dropdownText</span><span class="hljs-params">(color: <span class="hljs-type">Color</span>)</span></span> = TextStyle(
    fontFamily = FontFamily.Default,
    fontWeight = FontWeight.Normal,
    fontSize = <span class="hljs-number">32</span>.sp,
    textAlign = TextAlign.Center,
    color = color
)
<span class="hljs-comment">//...</span>
</code></pre>
<p>Whether you provide public functions or values (I advise against using <code>**var**</code> here) is up to your individual preference and current requirements.</p>
<h3 id="heading-how-to-create-an-app-theme-in-jetpack-compose">How to Create an App Theme in Jetpack Compose</h3>
<p>The last thing you need to configure before using your theme in your composables is a <code>MaterialTheme @Composable</code>. I have mine, and along with my light and dark color palettes in a file called <a target="_blank" href="https://github.com/BracketCove/GraphSudokuOpen/blob/master/app/src/main/java/com/bracketcove/graphsudoku/ui/GraphSudokuTheme.kt">GraphSudokuTheme</a>:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">import</span> androidx.compose.foundation.isSystemInDarkTheme
<span class="hljs-keyword">import</span> androidx.compose.material.MaterialTheme
<span class="hljs-keyword">import</span> androidx.compose.material.darkColors
<span class="hljs-keyword">import</span> androidx.compose.material.lightColors
<span class="hljs-keyword">import</span> androidx.compose.runtime.Composable
<span class="hljs-keyword">import</span> androidx.compose.ui.graphics.Color

<span class="hljs-keyword">private</span> <span class="hljs-keyword">val</span> LightColorPalette = lightColors(
    primary = primaryGreen,
    secondary = textColorLight,
    surface = lightGrey,
    primaryVariant = gridLineColorLight,
    onPrimary = accentAmber,
    onSurface = accentAmber
)

<span class="hljs-keyword">private</span> <span class="hljs-keyword">val</span> DarkColorPalette = darkColors(
    <span class="hljs-comment">//main background color</span>
    primary = primaryCharcoal,
    <span class="hljs-comment">//used for text color</span>
    secondary = textColorDark,
    <span class="hljs-comment">//background of sudoku board</span>
    surface = lightGreyAlpha,
    <span class="hljs-comment">//grid lines of sudoku board</span>
    primaryVariant = gridLineColorLight,
    onPrimary = accentAmber,

    onSurface = accentAmber

)

<span class="hljs-meta">@Composable</span>
<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">GraphSudokuTheme</span><span class="hljs-params">(
    darkTheme: <span class="hljs-type">Boolean</span> = isSystemInDarkTheme()</span></span>,
    content: <span class="hljs-meta">@Composable</span> () -&gt; <span class="hljs-built_in">Unit</span>
) {

    MaterialTheme(
        colors = <span class="hljs-keyword">if</span> (darkTheme) DarkColorPalette <span class="hljs-keyword">else</span> LightColorPalette,
        typography = typography,
        shapes = shapes,
        content = content
    )
}
</code></pre>
<p>Since you should already be familiar with what a composable is (I gave you fair warning), the only new thing here is <code>darkTheme: Boolean = isSystemInDarkTheme()</code>.</p>
<p>To give a simplified explanation, <code>isSystemInDarkTheme()</code> is a call which asks any compatible Android device for the user's preference of a light or dark theme.</p>
<p>It <strong>returns a boolean value</strong> which we can use in a Ternary (Conditional) Assignment expression such as <code>colors = if (darkTheme) DarkColorPalette else LightColorPalette</code>.</p>
<p>That is actually it. Colors, Fonts, and two Themes defined in a few minutes.</p>
<h2 id="heading-how-to-use-a-theme-in-compose">How to Use a Theme in Compose</h2>
<p>It is now time to use this Theme in your app. In this app, which only has two primary screens, I just use an <a target="_blank" href="https://github.com/BracketCove/GraphSudokuOpen/blob/master/app/src/main/java/com/bracketcove/graphsudoku/ui/activegame/ActiveGameActivity.kt">Activity</a> as a <strong>container</strong> for my composables:</p>
<pre><code class="lang-pgsql"><span class="hljs-keyword">class</span> NewGameActivity : AppCompatActivity(), NewGameContainer {
    //...
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //...

        setContent {
            GraphSudokuTheme {
                NewGameScreen(
                    onEventHandler = logic::onEvent,
                    viewModel
                )
            }
        }
        //...
    }
</code></pre>
<p>Wherever you find yourself calling <code>setContent {}</code>, my suggestion for beginners is to immediately place your Theme composable inside of it. Doing so will cause the style information to <strong>cascade/inherit to each nested composable</strong>.</p>
<p>You are done! Almost.</p>
<h2 id="heading-how-to-override-styles-and-themes">How to Override Styles and Themes</h2>
<p>If you can help it, try to include any colors you will want in your light and dark palettes. This way, when you call <code>MaterialTheme.colors.&lt;Color&gt;</code>, the system will handle the conditional logic necessary to pick the appropriate palette:</p>
<pre><code class="lang-pgsql">@Composable
fun NewGameContent(
    onEventHandler: (NewGameEvent) -&gt; Unit,
    viewModel: NewGameViewModel
) {
    Surface(
        Modifier
            .wrapContentHeight()
            .fillMaxWidth()
    ) {
        ConstraintLayout(Modifier.background(MaterialTheme.colors.<span class="hljs-keyword">primary</span>)) { 
            //...
        }
        //...
      }
}
</code></pre>
<p>However, sometimes it is more suitable to write your own conditional logic...or I just got lazy. Fortunately Compose makes many such configurations available as properties:</p>
<pre><code class="lang-pgsql">@Composable
fun DoneIcon(onEventHandler: (NewGameEvent) -&gt; Unit) {
    Icon(
        imageVector = Icons.Filled.Done,
        tint = <span class="hljs-keyword">if</span> (MaterialTheme.colors.isLight) textColorLight 
        <span class="hljs-keyword">else</span> textColorDark,
        contentDescription = <span class="hljs-keyword">null</span>,
        modifier = Modifier
            .clickable(
            //...
            )
    )
}
</code></pre>
<p><code>MaterialTheme.Colors.isLight</code> returns a boolean indicating what mode they are in, then we can use another Ternary Assignment from there.</p>
<h3 id="heading-how-to-style-a-text-composable">How to Style a Text Composable</h3>
<p>Just set the <code>style</code> argument equal to one of your text styles (whether it comes from <code>MaterialTheme</code> or one of the styles within <code>Type.kt</code>):</p>
<pre><code class="lang-kotlin">Text(
    text = stat.toTime(),
    style = statsLabel.copy(
        color = <span class="hljs-keyword">if</span> (isZero) Color.White
        <span class="hljs-keyword">else</span> MaterialTheme.colors.onPrimary,
    fontWeight = FontWeight.Normal
    ),
    modifier = Modifier
        .wrapContentSize()
        .padding(end = <span class="hljs-number">2</span>.dp, bottom = <span class="hljs-number">4</span>.dp),
        textAlign = TextAlign.End
)
</code></pre>
<p><code>TextStyle</code> has its own <code>copy</code> function ready to go should you need to overwrite anything.</p>
<p>And that's it! You now know how to style and theme an application using Jetpack Compose. Thanks for reading :)</p>
<h3 id="heading-social"><strong>Social</strong></h3>
<p>You can find me on <a target="_blank" href="https://www.instagram.com/rkay301/">Instagram here</a> and on <a target="_blank" href="https://twitter.com/wiseAss301">Twitter here</a>.</p>
<h3 id="heading-here-are-some-of-my-tutorials-amp-courses"><strong>Here are some of my tutorials &amp; courses</strong></h3>
<p><a target="_blank" href="https://www.youtube.com/channel/UCSwuCetC3YlO1Y7bqVW5GHg">https://youtube.com/wiseass</a> <a target="_blank" href="https://www.freecodecamp.org/news/author/ryan-michael-kay/">https://www.freecodecamp.org/news/author/ryan-michael-kay/</a> <a target="_blank" href="https://skl.sh/35IdKsj">https://skl.sh/35IdKsj</a> (introduction to Android with Android Studio)</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Handle UI Events in Jetpack Compose ]]>
                </title>
                <description>
                    <![CDATA[ In this short and practical article, we will talk about how to handle UI events in Jetpack Compose. In the old system, we used OnClickListeners and other interfaces. In Compose, we can take full advantage of Kotlin’s Sealed Classes, Function Types an... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-handle-ui-events-in-jetpack-compose/</link>
                <guid isPermaLink="false">66d460c99f2bec37e2da066a</guid>
                
                    <category>
                        <![CDATA[ Android ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Android Studio ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Jetpack Compose ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Kotlin ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ User Interface ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ryan Michael Kay ]]>
                </dc:creator>
                <pubDate>Tue, 16 Mar 2021 18:22:24 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/03/cat-4793068_1280-5.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this short and practical article, we will talk about how to handle UI events in Jetpack Compose.</p>
<p>In the old system, we used OnClickListeners and other interfaces. In Compose, we can take full advantage of Kotlin’s <strong>Sealed Classes</strong>, <strong>Function Types</strong> and <strong>Lambda Expressions</strong>.</p>
<p>If you do not know what a composable is, consider reading <a target="_blank" href="https://www.freecodecamp.org/news/jetpack-compose-beginner-tutorial-composables-recomposition/">this article which explains the fundamentals</a>.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/LrNPw1LQHEw" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<h2 id="heading-how-to-model-ui-events-with-a-sealed-class">How to Model UI Events with a Sealed Class</h2>
<p>First, we must learn what is meant by UI Events and how to model them with Sealed Classes.</p>
<p>I have described this same process for <a target="_blank" href="https://medium.com/swlh/simplify-your-ui-interactions-with-events-java-kotlin-any-language-5062c1b1e0e4">Java and Kotlin</a> (with the old view system) before, so I will keep this brief.</p>
<h3 id="heading-the-process">The Process</h3>
<p>For each screen or sub-screen of your UI, ask yourself this question: What are all the different ways which the user can interact with it?</p>
<p>Let's take an example from my first app built fully in compose, <a target="_blank" href="https://play.google.com/store/apps/details?id=com.bracketcove.graphsudoku">Graph Sudoku</a>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/graph_sudoku_small_screen.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Screenshot of a Sudoku Android App</em></p>
<p>The sealed class I use to represent the UI interactions of this screen looks like this:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">sealed</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ActiveGameEvent</span> </span>{
    <span class="hljs-keyword">data</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">OnInput</span></span>(<span class="hljs-keyword">val</span> input: <span class="hljs-built_in">Int</span>) : ActiveGameEvent()
    <span class="hljs-keyword">data</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">OnTileFocused</span></span>(<span class="hljs-keyword">val</span> x: <span class="hljs-built_in">Int</span>, 
    <span class="hljs-keyword">val</span> y: <span class="hljs-built_in">Int</span>) : ActiveGameEvent()
    <span class="hljs-keyword">object</span> OnNewGameClicked : ActiveGameEvent()
    <span class="hljs-keyword">object</span> OnStart : ActiveGameEvent()
    <span class="hljs-keyword">object</span> OnStop : ActiveGameEvent()
}
</code></pre>
<p>To explain briefly:</p>
<ul>
<li><p>OnInput represents a user touching an input button (like 0, 1, 2, 3, 4)</p>
</li>
<li><p>OnTileFocused represents a user selecting a tile (like the amber highlighted one)</p>
</li>
<li><p>OnNewGameClicked is self-explanatory</p>
</li>
<li><p>OnStart and OnStop are lifecycle events which my composables do not care about, but they are used in the Activity which acts as a Container for the composables</p>
</li>
</ul>
<p>Once you have your sealed class set up, you can now handle a wide variety of events using a single event handler function. Sometimes it might make more sense to have multiple event handler functions, so keep in mind that <strong>this approach must be adapted to your project's specific requirements</strong>.</p>
<h2 id="heading-how-to-connect-your-software-architecture">How to Connect Your Software Architecture</h2>
<p>What you have handling these events is totally up to you. Some people think that MVVM is the golden standard of software architectures, but it seems like more and more people are realizing that <strong>there is no single architecture which works best for every situation</strong>.</p>
<p>For Android with Compose, my current approach is to use a very 3rd party minimalist approach which typically has these things in each feature (screen):</p>
<ul>
<li><p>A (Presentation) Logic class <strong>as an event handler</strong></p>
</li>
<li><p>A ViewModel to store the data necessary to render the View (as the name implies)</p>
</li>
<li><p>An Activity which acts as a Container (not a god object)</p>
</li>
<li><p>Composables to form the View</p>
</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/model_view_whatever-3.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Model-View-Whatever</em></p>
<p>I do not care what you use as long as you are applying <a target="_blank" href="https://youtu.be/B_C41SF0KbI">separation of concerns</a>. This is how I arrived at this architecture, by simply asking what should and should not be put together in the same class.</p>
<p>Whether you want your ViewModel, a Fragment, or an Activity to be your event handler, all of them can be set up the same way: <strong>Function Types!</strong></p>
<p>Within your class of choice, set up an event handler function which accepts your sealed class as its argument:</p>
<pre><code class="lang-kotlin"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ActiveGameLogic</span></span>(
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">val</span> container: ActiveGameContainer?,
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">val</span> viewModel: ActiveGameViewModel,
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">val</span> gameRepo: IGameRepository,
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">val</span> statsRepo: IStatisticsRepository,
    dispatcher: DispatcherProvider
) : BaseLogic&lt;ActiveGameEvent&gt;(dispatcher),
    CoroutineScope {
    <span class="hljs-comment">//...</span>
    <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">onEvent</span><span class="hljs-params">(event: <span class="hljs-type">ActiveGameEvent</span>)</span></span> {
        <span class="hljs-keyword">when</span> (event) {
            <span class="hljs-keyword">is</span> ActiveGameEvent.OnInput -&gt; onInput(
                event.input,
                viewModel.timerState
            )
            ActiveGameEvent.OnNewGameClicked -&gt; onNewGameClicked()
            ActiveGameEvent.OnStart -&gt; onStart()
            ActiveGameEvent.OnStop -&gt; onStop()
            <span class="hljs-keyword">is</span> ActiveGameEvent.OnTileFocused -&gt; onTileFocused(event.x, event.y)
        }
    }
    <span class="hljs-comment">//...</span>
}
</code></pre>
<p>This approach is very organized and makes it easy to test every Unit in this 3rd party library free class through a single entry point.</p>
<p>However, we are not done yet. Naturally, we need a way to get a reference to this event handler function, <code>onEvent</code>, to our Composables. We can do this using a <strong>function reference</strong>:</p>
<pre><code class="lang-kotlin"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ActiveGameActivity</span> : <span class="hljs-type">AppCompatActivity</span></span>(), ActiveGameContainer {
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">lateinit</span> <span class="hljs-keyword">var</span> logic: ActiveGameLogic

    <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">onCreate</span><span class="hljs-params">(savedInstanceState: <span class="hljs-type">Bundle</span>?)</span></span> {
        <span class="hljs-keyword">super</span>.onCreate(savedInstanceState)

        <span class="hljs-keyword">val</span> viewModel = ActiveGameViewModel()

        setContent {
            ActiveGameScreen(
                onEventHandler = logic::onEvent,
                viewModel
            )
        }

        logic = buildActiveGameLogic(<span class="hljs-keyword">this</span>, viewModel, applicationContext)
    }

      <span class="hljs-comment">//...</span>
}
</code></pre>
<p>I am sure some of you are wondering why I am using an Activity. You can ask me during a <a target="_blank" href="https://youtu.be/-xV8k-4UW50">livestream Q&amp;A sometime for a detailed answer</a>.</p>
<p>In short, Fragments appear to be a bit pointless with Compose with my approach to architecture (I do not use Jetpack Navigation), and there is nothing wrong with using Activities as a feature specific container. <strong>Just avoid writing god activities, basically.</strong></p>
<p>To be specific, the way you make a reference to a function in Kotlin, is by providing the <strong>class/interface name</strong> (or <strong>skip that if it is a Top-Level function</strong>), followed by <strong>two colons</strong>, and the <strong>name of the function without any arguments or brackets</strong>:</p>
<pre><code class="lang-pgsql">onEventHandler = logic::onEvent
</code></pre>
<h2 id="heading-how-to-replace-onclicklistener-with-jetpack-compose-onclick-modifier">How to Replace onClickListener With Jetpack Compose onClick Modifier</h2>
<p>With that stuff ready, we can look at how this works within the composable. Naturally, your root composable will need the event handler function as a parameter:</p>
<pre><code class="lang-kotlin"><span class="hljs-meta">@Composable</span>
<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">ActiveGameScreen</span><span class="hljs-params">(
    onEventHandler: (<span class="hljs-type">ActiveGameEvent</span>) -&gt; <span class="hljs-type">Unit</span>,
    viewModel: <span class="hljs-type">ActiveGameViewModel</span>
)</span></span> {
<span class="hljs-comment">//...</span>
}
</code></pre>
<p>It can be a bit tricky to get function type syntax correctly, but understand that this <strong>really is a reference to a function,</strong> which is not so different from a reference to a class.</p>
<p>Just as you should not build god objects, you should not build giant composables:</p>
<ol>
<li><p>Break your UI down into the <strong>smallest reasonable parts</strong></p>
</li>
<li><p>Wrap them in a composable function</p>
</li>
<li><p>For each composable which has a UI interaction associated with it, <strong>it must be given a reference to your event handler function</strong></p>
</li>
</ol>
<p>Here is a composable which represents the input buttons of the Sudoku app, which is given the event handler by reference:</p>
<pre><code class="lang-kotlin"><span class="hljs-meta">@Composable</span>
<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">SudokuInputButton</span><span class="hljs-params">(
    onEventHandler: (<span class="hljs-type">ActiveGameEvent</span>) -&gt; <span class="hljs-type">Unit</span>,
    number: <span class="hljs-type">Int</span>
)</span></span> {
    Button(
        onClick = { onEventHandler.invoke(ActiveGameEvent.OnInput(number)) },
        modifier = Modifier
            .requiredSize(<span class="hljs-number">56</span>.dp)
            .padding(<span class="hljs-number">2</span>.dp)
    ) {
        Text(
            text = number.toString(),
            style = inputButton.copy(color = MaterialTheme.colors.onPrimary),
            modifier = Modifier.fillMaxSize()
        )
    }
}
</code></pre>
<p>To actually pass the event to the logic class, we must use the <code>invoke</code> function, which will accept arguments as per the function type definition (which accepts an <code>ActiveGameEvent</code> in this case).</p>
<p>At this point, you are ready to handle UI interaction events in Kotlin (compose or not) by taking full advantage of this beautiful and modern programming language.</p>
<p>If you liked this article, share it on social media and consider checking out the resources below to support an independent programmer and content creator.</p>
<h3 id="heading-social">Social</h3>
<p>You can find me on <a target="_blank" href="https://www.instagram.com/rkay301/">Instagram here</a> and on <a target="_blank" href="https://twitter.com/wiseAss301">Twitter here</a>.</p>
<h3 id="heading-here-are-some-of-my-tutorials-amp-courses">Here are some of my tutorials &amp; courses</h3>
<p><a target="_blank" href="https://www.youtube.com/channel/UCSwuCetC3YlO1Y7bqVW5GHg">https://youtube.com/wiseass</a> <a target="_blank" href="https://www.freecodecamp.org/news/author/ryan-michael-kay/">https://www.freecodecamp.org/news/author/ryan-michael-kay/</a> <a target="_blank" href="https://skl.sh/35IdKsj">https://skl.sh/35IdKsj</a> (introduction to Android with Android Studio)</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Kotlin Android App Tutorial – Build a Robinhood-Style App to Track COVID-19 Cases ]]>
                </title>
                <description>
                    <![CDATA[ The Robinhood stock trading app has some useful UI components that are applicable to many different types of apps that display data. Knowing how to implement those components is a very useful tool to have in your toolbox. We've released a course that... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-a-robinhood-style-android-app-to-track-covid-19-cases/</link>
                <guid isPermaLink="false">66b200e6cfbefba140e247f4</guid>
                
                    <category>
                        <![CDATA[ Kotlin ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Beau Carnes ]]>
                </dc:creator>
                <pubDate>Wed, 17 Feb 2021 17:37:07 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/02/andoidapp.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The Robinhood stock trading app has some useful UI components that are applicable to many different types of apps that display data. Knowing how to implement those components is a very useful tool to have in your toolbox.</p>
<p>We've released a course that will teach you how to develop an Android app with Kotlin that has a lot of similarities to Robinhood. But in this app, instead of charting stock prices, the app will chart COVID-19 cases.</p>
<p>You will learn how to display data in a way that can be used to display a wide variety of datasets in different contexts.</p>
<p>Rahul Pandey developed this course. He is an app developer and Facebook engineer. He has created many apps that are currently on the app store and has also created many app development tutorials.</p>
<p>Here are the different sections of this course:</p>
<ul>
<li>Retrieving data from the API</li>
<li>Building the layout</li>
<li>Render the spark line chart</li>
<li>Add chart interaction</li>
<li>Add colors and state spinner</li>
<li>Ticker view + radio button styling</li>
<li>Color update + conclusion</li>
</ul>
<p>Watch the full course on <a target="_blank" href="https://youtu.be/4gMDR69DB6A">the freeCodeCamp.org YouTube channel</a> (90 minute watch).</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Generate an Excel Report in a Spring Boot REST API with Apache POI and Kotlin ]]>
                </title>
                <description>
                    <![CDATA[ By Piotr Wolak In this article, I would like to show you how to generate Excel reports in the .xls and .xlsx formats (also known as Open XML) in a Spring Boot REST API with Apache POI and Kotlin. After finishing this guide, you will have a fundamenta... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/generate-excel-report-in-spring-rest-api/</link>
                <guid isPermaLink="false">66d46089677cb8c6c15f3167</guid>
                
                    <category>
                        <![CDATA[ excel ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Kotlin ]]>
                    </category>
                
                    <category>
                        <![CDATA[ REST API ]]>
                    </category>
                
                    <category>
                        <![CDATA[ spring-boot ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 08 Dec 2020 01:54:41 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/12/share-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Piotr Wolak</p>
<p>In this article, I would like to show you how to generate Excel reports in the <strong>.xls</strong> and <strong>.xlsx</strong> formats (also known as Open XML) in a <strong>Spring Boot REST API</strong> with <strong>Apache POI and Kotlin</strong>.</p>
<p>After finishing this guide, you will have a fundamental understanding of how to create custom cells formats, styles, and fonts. In the end, I will show you how to create Spring Boot REST endpoints so you can easily download generated files.</p>
<p>To better visualize what we'll learn, check out the preview of the resulting file:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/result_file_preview.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-step-1-add-the-necessary-imports">Step 1: Add the Necessary Imports</h2>
<p>As the first step, let's create a Spring Boot project (I highly recommend using the <a target="_blank" href="https://start.spring.io/">Spring Initializr</a> page) and add the following imports:</p>
<pre><code class="lang-groovy">implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.apache.poi:poi:4.1.2")
implementation("org.apache.poi:poi-ooxml:4.1.2")
</code></pre>
<p>Let me explain the purpose of each library: </p>
<ul>
<li>The <strong>Spring Boot Starter Web</strong> is necessary to create the REST API in our application.</li>
<li>The <strong>Apache POI</strong> is a complex Java library for working with Excel files. If we would like to work only with the .xls format, then the <em>poi</em> import would be enough. In our case, we would like to add the support for the <strong>.xlsx</strong> format, so the <em>poi-ooxml</em> component is necessary as well.</li>
</ul>
<h2 id="heading-step-2-create-the-models">Step 2: Create the Models</h2>
<p>As the next step, let's create an enum class called <strong>CustomCellStyle</strong> with 4 constants: </p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">enum</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CustomCellStyle</span> </span>{
    GREY_CENTERED_BOLD_ARIAL_WITH_BORDER,
    RIGHT_ALIGNED,
    RED_BOLD_ARIAL_WITH_BORDER,
    RIGHT_ALIGNED_DATE_FORMAT
}
</code></pre>
<p>Although the purpose of this enum class might seem a bit enigmatic at the moment, it will all become clear in the next sections.</p>
<h2 id="heading-step-3-prepare-cells-styles">Step 3: Prepare Cells Styles</h2>
<p>The Apache POI library comes with the <strong>CellStyle</strong> interface, which we can use to define custom styling and formatting within rows, columns, and cells.</p>
<p>Let's create a <strong>StylesGenerator</strong> component, which will be responsible for preparing a map containing our custom styles:</p>
<pre><code class="lang-kotlin"><span class="hljs-meta">@Component</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">StylesGenerator</span> </span>{

    <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">prepareStyles</span><span class="hljs-params">(wb: <span class="hljs-type">Workbook</span>)</span></span>: Map&lt;CustomCellStyle, CellStyle&gt; {
        <span class="hljs-keyword">val</span> boldArial = createBoldArialFont(wb)
        <span class="hljs-keyword">val</span> redBoldArial = createRedBoldArialFont(wb)

        <span class="hljs-keyword">val</span> rightAlignedStyle = createRightAlignedStyle(wb)
        <span class="hljs-keyword">val</span> greyCenteredBoldArialWithBorderStyle =
            createGreyCenteredBoldArialWithBorderStyle(wb, boldArial)
        <span class="hljs-keyword">val</span> redBoldArialWithBorderStyle =
            createRedBoldArialWithBorderStyle(wb, redBoldArial)
        <span class="hljs-keyword">val</span> rightAlignedDateFormatStyle =
            createRightAlignedDateFormatStyle(wb)

        <span class="hljs-keyword">return</span> mapOf(
            CustomCellStyle.RIGHT_ALIGNED to rightAlignedStyle,
            CustomCellStyle.GREY_CENTERED_BOLD_ARIAL_WITH_BORDER to greyCenteredBoldArialWithBorderStyle,
            CustomCellStyle.RED_BOLD_ARIAL_WITH_BORDER to redBoldArialWithBorderStyle,
            CustomCellStyle.RIGHT_ALIGNED_DATE_FORMAT to rightAlignedDateFormatStyle
        )
    }
}
</code></pre>
<p>As you can see, with this approach, we create each style once and put it inside a map so that we will be able to refer to it later. </p>
<p>There are plenty of design techniques which we could use here, but I believe using a map and enum constants is one of the best ways to keep the code cleaner and easier to modify.</p>
<p>With that being said, let's add some missing functions inside the generator class. Let's start with custom fonts first:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">createBoldArialFont</span><span class="hljs-params">(wb: <span class="hljs-type">Workbook</span>)</span></span>: Font {
    <span class="hljs-keyword">val</span> font = wb.createFont()
    font.fontName = <span class="hljs-string">"Arial"</span>
    font.bold = <span class="hljs-literal">true</span>
    <span class="hljs-keyword">return</span> font
}
</code></pre>
<p>The <strong>createBoldArialFont</strong> function creates a new bold Arial Font instance, which we will use later. </p>
<p>Similarly, let's implement a <strong>createRedBoldArialFont</strong> function and set the font color to red: </p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">createRedBoldArialFont</span><span class="hljs-params">(wb: <span class="hljs-type">Workbook</span>)</span></span>: Font {
    <span class="hljs-keyword">val</span> font = wb.createFont()
    font.fontName = <span class="hljs-string">"Arial"</span>
    font.bold = <span class="hljs-literal">true</span>
    font.color = IndexedColors.RED.index
    <span class="hljs-keyword">return</span> font
}
</code></pre>
<p>After that, we can add other functions responsible for creating individual <strong>CellStyle</strong> instances: </p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">createRightAlignedStyle</span><span class="hljs-params">(wb: <span class="hljs-type">Workbook</span>)</span></span>: CellStyle {
    <span class="hljs-keyword">val</span> style: CellStyle = wb.createCellStyle()
    style.alignment = HorizontalAlignment.RIGHT
    <span class="hljs-keyword">return</span> style
}

<span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">createBorderedStyle</span><span class="hljs-params">(wb: <span class="hljs-type">Workbook</span>)</span></span>: CellStyle {
    <span class="hljs-keyword">val</span> thin = BorderStyle.THIN
    <span class="hljs-keyword">val</span> black = IndexedColors.BLACK.getIndex()
    <span class="hljs-keyword">val</span> style = wb.createCellStyle()
    style.borderRight = thin
    style.rightBorderColor = black
    style.borderBottom = thin
    style.bottomBorderColor = black
    style.borderLeft = thin
    style.leftBorderColor = black
    style.borderTop = thin
    style.topBorderColor = black
    <span class="hljs-keyword">return</span> style
}

<span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">createGreyCenteredBoldArialWithBorderStyle</span><span class="hljs-params">(wb: <span class="hljs-type">Workbook</span>, boldArial: <span class="hljs-type">Font</span>)</span></span>: CellStyle {
    <span class="hljs-keyword">val</span> style = createBorderedStyle(wb)
    style.alignment = HorizontalAlignment.CENTER
    style.setFont(boldArial)
    style.fillForegroundColor = IndexedColors.GREY_25_PERCENT.getIndex();
    style.fillPattern = FillPatternType.SOLID_FOREGROUND;
    <span class="hljs-keyword">return</span> style
}

<span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">createRedBoldArialWithBorderStyle</span><span class="hljs-params">(wb: <span class="hljs-type">Workbook</span>, redBoldArial: <span class="hljs-type">Font</span>)</span></span>: CellStyle {
    <span class="hljs-keyword">val</span> style = createBorderedStyle(wb)
    style.setFont(redBoldArial)
    <span class="hljs-keyword">return</span> style
}

<span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">createRightAlignedDateFormatStyle</span><span class="hljs-params">(wb: <span class="hljs-type">Workbook</span>)</span></span>: CellStyle {
    <span class="hljs-keyword">val</span> style = wb.createCellStyle()
    style.alignment = HorizontalAlignment.RIGHT
    style.dataFormat = <span class="hljs-number">14</span>
    <span class="hljs-keyword">return</span> style
}
</code></pre>
<p>Please keep in mind that the above examples represent only a small part of <strong>CellStyle's</strong> possibilities. If you would like to see the full list, please refer to the official documentation <a target="_blank" href="https://poi.apache.org/apidocs/dev/org/apache/poi/ss/usermodel/CellStyle.html">here</a>.</p>
<h2 id="heading-step-4-create-the-reportservice-class"><strong>Step 4: Create the ReportService Class</strong></h2>
<p>As the next step, let's implement a <strong>ReportService</strong> class responsible for creating .xlsx and <strong>.xls</strong> files and returning them as ByteArray instances:</p>
<pre><code class="lang-kotlin"><span class="hljs-meta">@Service</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ReportService</span></span>(
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">val</span> stylesGenerator: StylesGenerator
) {
    <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">generateXlsxReport</span><span class="hljs-params">()</span></span>: ByteArray {
        <span class="hljs-keyword">val</span> wb = XSSFWorkbook()

        <span class="hljs-keyword">return</span> generateReport(wb)
    }

    <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">generateXlsReport</span><span class="hljs-params">()</span></span>: ByteArray {
        <span class="hljs-keyword">val</span> wb = HSSFWorkbook()

        <span class="hljs-keyword">return</span> generateReport(wb)
    }
 }
</code></pre>
<p>As you can see, the only difference between these two formats' generation is the type of <strong>Workbook</strong> implementation we've. used. For the .xlsx format we will use the <strong>XSSFWorkbook</strong> class, and for the .xls we will use <strong>HSSFWorkbook</strong><em>.</em></p>
<p>Let's add the rest of the code to the <strong>ReportService</strong>:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">generateReport</span><span class="hljs-params">(wb: <span class="hljs-type">Workbook</span>)</span></span>: ByteArray {
    <span class="hljs-keyword">val</span> styles = stylesGenerator.prepareStyles(wb)
    <span class="hljs-keyword">val</span> sheet: Sheet = wb.createSheet(<span class="hljs-string">"Example sheet name"</span>)

    setColumnsWidth(sheet)

    createHeaderRow(sheet, styles)
    createStringsRow(sheet, styles)
    createDoublesRow(sheet, styles)
    createDatesRow(sheet, styles)

    <span class="hljs-keyword">val</span> <span class="hljs-keyword">out</span> = ByteArrayOutputStream()
    wb.write(<span class="hljs-keyword">out</span>)

    <span class="hljs-keyword">out</span>.close()
    wb.close()

    <span class="hljs-keyword">return</span> <span class="hljs-keyword">out</span>.toByteArray()
}

<span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">setColumnsWidth</span><span class="hljs-params">(sheet: <span class="hljs-type">Sheet</span>)</span></span> {
    sheet.setColumnWidth(<span class="hljs-number">0</span>, <span class="hljs-number">256</span> * <span class="hljs-number">20</span>)

    <span class="hljs-keyword">for</span> (columnIndex <span class="hljs-keyword">in</span> <span class="hljs-number">1</span> until <span class="hljs-number">5</span>) {
        sheet.setColumnWidth(columnIndex, <span class="hljs-number">256</span> * <span class="hljs-number">15</span>)
    }
}

<span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">createHeaderRow</span><span class="hljs-params">(sheet: <span class="hljs-type">Sheet</span>, styles: <span class="hljs-type">Map</span>&lt;<span class="hljs-type">CustomCellStyle</span>, CellStyle&gt;)</span></span> {
    <span class="hljs-keyword">val</span> row = sheet.createRow(<span class="hljs-number">0</span>)

    <span class="hljs-keyword">for</span> (columnNumber <span class="hljs-keyword">in</span> <span class="hljs-number">1</span> until <span class="hljs-number">5</span>) {
        <span class="hljs-keyword">val</span> cell = row.createCell(columnNumber)

        cell.setCellValue(<span class="hljs-string">"Column <span class="hljs-variable">$columnNumber</span>"</span>)
        cell.cellStyle = styles[CustomCellStyle.GREY_CENTERED_BOLD_ARIAL_WITH_BORDER]
    }
}

<span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">createRowLabelCell</span><span class="hljs-params">(row: <span class="hljs-type">Row</span>, styles: <span class="hljs-type">Map</span>&lt;<span class="hljs-type">CustomCellStyle</span>, CellStyle&gt;, label: <span class="hljs-type">String</span>)</span></span> {
    <span class="hljs-keyword">val</span> rowLabel = row.createCell(<span class="hljs-number">0</span>)
    rowLabel.setCellValue(label)
    rowLabel.cellStyle = styles[CustomCellStyle.RED_BOLD_ARIAL_WITH_BORDER]
}

<span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">createStringsRow</span><span class="hljs-params">(sheet: <span class="hljs-type">Sheet</span>, styles: <span class="hljs-type">Map</span>&lt;<span class="hljs-type">CustomCellStyle</span>, CellStyle&gt;)</span></span> {
    <span class="hljs-keyword">val</span> row = sheet.createRow(<span class="hljs-number">1</span>)
    createRowLabelCell(row, styles, <span class="hljs-string">"Strings row"</span>)

    <span class="hljs-keyword">for</span> (columnNumber <span class="hljs-keyword">in</span> <span class="hljs-number">1</span> until <span class="hljs-number">5</span>) {
        <span class="hljs-keyword">val</span> cell = row.createCell(columnNumber)

        cell.setCellValue(<span class="hljs-string">"String <span class="hljs-variable">$columnNumber</span>"</span>)
        cell.cellStyle = styles[CustomCellStyle.RIGHT_ALIGNED]
    }
}

<span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">createDoublesRow</span><span class="hljs-params">(sheet: <span class="hljs-type">Sheet</span>, styles: <span class="hljs-type">Map</span>&lt;<span class="hljs-type">CustomCellStyle</span>, CellStyle&gt;)</span></span> {
    <span class="hljs-keyword">val</span> row = sheet.createRow(<span class="hljs-number">2</span>)
    createRowLabelCell(row, styles, <span class="hljs-string">"Doubles row"</span>)

    <span class="hljs-keyword">for</span> (columnNumber <span class="hljs-keyword">in</span> <span class="hljs-number">1</span> until <span class="hljs-number">5</span>) {
        <span class="hljs-keyword">val</span> cell = row.createCell(columnNumber)

        cell.setCellValue(BigDecimal(<span class="hljs-string">"<span class="hljs-subst">${columnNumber}</span>.99"</span>).toDouble())
        cell.cellStyle = styles[CustomCellStyle.RIGHT_ALIGNED]
    }
}

<span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">createDatesRow</span><span class="hljs-params">(sheet: <span class="hljs-type">Sheet</span>, styles: <span class="hljs-type">Map</span>&lt;<span class="hljs-type">CustomCellStyle</span>, CellStyle&gt;)</span></span> {
    <span class="hljs-keyword">val</span> row = sheet.createRow(<span class="hljs-number">3</span>)
    createRowLabelCell(row, styles, <span class="hljs-string">"Dates row"</span>)

    <span class="hljs-keyword">for</span> (columnNumber <span class="hljs-keyword">in</span> <span class="hljs-number">1</span> until <span class="hljs-number">5</span>) {
        <span class="hljs-keyword">val</span> cell = row.createCell(columnNumber)

        cell.setCellValue((LocalDate.now()))
        cell.cellStyle = styles[CustomCellStyle.RIGHT_ALIGNED_DATE_FORMAT]
    }
}
</code></pre>
<p>As you can see, the first thing the <strong>generateReport</strong> function does is that it styles the initialization. We pass the <strong>Workbook</strong> instance to the <strong>StylesGenerator</strong> and in return, we get a map, which we will use later to obtain appropriate CellStyles. </p>
<p>After that, it creates a new sheet within our workbook and passes a name for it. </p>
<p>Then, it invokes functions responsible for setting the columns' widths and operating on our sheet row by row. </p>
<p>Finally, it writes out our workbook to a ByteArrayOutputStream.</p>
<p>Let's take a minute and analyze what exactly each function does:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">setColumnsWidth</span><span class="hljs-params">(sheet: <span class="hljs-type">Sheet</span>)</span></span> {
    sheet.setColumnWidth(<span class="hljs-number">0</span>, <span class="hljs-number">256</span> * <span class="hljs-number">20</span>)

    <span class="hljs-keyword">for</span> (columnIndex <span class="hljs-keyword">in</span> <span class="hljs-number">1</span> until <span class="hljs-number">5</span>) {
        sheet.setColumnWidth(columnIndex, <span class="hljs-number">256</span> * <span class="hljs-number">15</span>)
    }
}
</code></pre>
<p>As the name suggests, <strong>setColumnsWidth</strong> is responsible for setting widths of columns in our sheet. The first parameter passed to the <strong>setColumnWidth</strong> indicates the columnIndex, whereas the second one sets the width (in units of 1/256th of a character width). </p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">createRowLabelCell</span><span class="hljs-params">(row: <span class="hljs-type">Row</span>, styles: <span class="hljs-type">Map</span>&lt;<span class="hljs-type">CustomCellStyle</span>, CellStyle&gt;, label: <span class="hljs-type">String</span>)</span></span> {
    <span class="hljs-keyword">val</span> rowLabel = row.createCell(<span class="hljs-number">0</span>)
    rowLabel.setCellValue(label)
    rowLabel.cellStyle = styles[CustomCellStyle.RED_BOLD_ARIAL_WITH_BORDER]
}
</code></pre>
<p>The <strong>createRowLabelCell</strong> function is responsible for adding a cell in the first column of the passed row, alongside setting its value to the specified label and setting the style. I've decided to add this function to slightly reduce the code's redundancy.</p>
<p>All of the below functions are pretty similar. Their purpose is to create a new row, invoking the <strong>createRowLabelCell</strong> function (except for <strong>createHeaderRow</strong>) and adding five columns with data to our sheet.</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">createHeaderRow</span><span class="hljs-params">(sheet: <span class="hljs-type">Sheet</span>, styles: <span class="hljs-type">Map</span>&lt;<span class="hljs-type">CustomCellStyle</span>, CellStyle&gt;)</span></span> {
    <span class="hljs-keyword">val</span> row = sheet.createRow(<span class="hljs-number">0</span>)

    <span class="hljs-keyword">for</span> (columnNumber <span class="hljs-keyword">in</span> <span class="hljs-number">1</span> until <span class="hljs-number">5</span>) {
        <span class="hljs-keyword">val</span> cell = row.createCell(columnNumber)

        cell.setCellValue(<span class="hljs-string">"Column <span class="hljs-variable">$columnNumber</span>"</span>)
        cell.cellStyle = styles[CustomCellStyle.GREY_CENTERED_BOLD_ARIAL_WITH_BORDER]
    }
}
</code></pre>
<pre><code class="lang-kotlin"><span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">createStringsRow</span><span class="hljs-params">(sheet: <span class="hljs-type">Sheet</span>, styles: <span class="hljs-type">Map</span>&lt;<span class="hljs-type">CustomCellStyle</span>, CellStyle&gt;)</span></span> {
    <span class="hljs-keyword">val</span> row = sheet.createRow(<span class="hljs-number">1</span>)
    createRowLabelCell(row, styles, <span class="hljs-string">"Strings row"</span>)

    <span class="hljs-keyword">for</span> (columnNumber <span class="hljs-keyword">in</span> <span class="hljs-number">1</span> until <span class="hljs-number">5</span>) {
        <span class="hljs-keyword">val</span> cell = row.createCell(columnNumber)

        cell.setCellValue(<span class="hljs-string">"String <span class="hljs-variable">$columnNumber</span>"</span>)
        cell.cellStyle = styles[CustomCellStyle.RIGHT_ALIGNED]
    }
}
</code></pre>
<pre><code class="lang-kotlin"><span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">createDoublesRow</span><span class="hljs-params">(sheet: <span class="hljs-type">Sheet</span>, styles: <span class="hljs-type">Map</span>&lt;<span class="hljs-type">CustomCellStyle</span>, CellStyle&gt;)</span></span> {
    <span class="hljs-keyword">val</span> row = sheet.createRow(<span class="hljs-number">2</span>)
    createRowLabelCell(row, styles, <span class="hljs-string">"Doubles row"</span>)

    <span class="hljs-keyword">for</span> (columnNumber <span class="hljs-keyword">in</span> <span class="hljs-number">1</span> until <span class="hljs-number">5</span>) {
        <span class="hljs-keyword">val</span> cell = row.createCell(columnNumber)

        cell.setCellValue(BigDecimal(<span class="hljs-string">"<span class="hljs-subst">${columnNumber}</span>.99"</span>).toDouble())
        cell.cellStyle = styles[CustomCellStyle.RIGHT_ALIGNED]
    }
}
</code></pre>
<pre><code class="lang-kotlin"><span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">createDatesRow</span><span class="hljs-params">(sheet: <span class="hljs-type">Sheet</span>, styles: <span class="hljs-type">Map</span>&lt;<span class="hljs-type">CustomCellStyle</span>, CellStyle&gt;)</span></span> {
    <span class="hljs-keyword">val</span> row = sheet.createRow(<span class="hljs-number">3</span>)
    createRowLabelCell(row, styles, <span class="hljs-string">"Dates row"</span>)

    <span class="hljs-keyword">for</span> (columnNumber <span class="hljs-keyword">in</span> <span class="hljs-number">1</span> until <span class="hljs-number">5</span>) {
        <span class="hljs-keyword">val</span> cell = row.createCell(columnNumber)

        cell.setCellValue((LocalDate.now()))
        cell.cellStyle = styles[CustomCellStyle.RIGHT_ALIGNED_DATE_FORMAT]
    }
}
</code></pre>
<h2 id="heading-step-5-implement-the-rest-reportcontroller"><strong>Step 5: Implement the REST ReportController</strong></h2>
<p>As the last step, we will implement a class named <strong>ReportController</strong>. It will be responsible for handling POST requests coming to our two REST endpoints:</p>
<ul>
<li><em>/api/report/xlsx -</em> creating a report in a <em>.xlsx</em> format </li>
<li><em>/api/report/xls</em> - same as above, but in a .xls format</li>
</ul>
<pre><code class="lang-kotlin"><span class="hljs-meta">@RestController</span>
<span class="hljs-meta">@RequestMapping(<span class="hljs-meta-string">"/api/report"</span>)</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ReportController</span></span>(
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">val</span> reportService: ReportService
) {

    <span class="hljs-meta">@PostMapping(<span class="hljs-meta-string">"/xlsx"</span>)</span>
    <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">generateXlsxReport</span><span class="hljs-params">()</span></span>: ResponseEntity&lt;ByteArray&gt; {
        <span class="hljs-keyword">val</span> report = reportService.generateXlsxReport()

        <span class="hljs-keyword">return</span> createResponseEntity(report, <span class="hljs-string">"report.xlsx"</span>)
    }

    <span class="hljs-meta">@PostMapping(<span class="hljs-meta-string">"/xls"</span>)</span>
    <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">generateXlsReport</span><span class="hljs-params">()</span></span>: ResponseEntity&lt;ByteArray&gt; {
        <span class="hljs-keyword">val</span> report = reportService.generateXlsReport()

        <span class="hljs-keyword">return</span> createResponseEntity(report, <span class="hljs-string">"report.xls"</span>)
    }

    <span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">createResponseEntity</span><span class="hljs-params">(
        report: <span class="hljs-type">ByteArray</span>,
        fileName: <span class="hljs-type">String</span>
    )</span></span>: ResponseEntity&lt;ByteArray&gt; =
        ResponseEntity.ok()
            .contentType(MediaType.APPLICATION_OCTET_STREAM)
            .header(HttpHeaders.CONTENT_DISPOSITION, <span class="hljs-string">"attachment; filename=\"<span class="hljs-variable">$fileName</span>\""</span>)
            .body(report)

}
</code></pre>
<p>The most interesting part of the above code is the <strong>createResponseEntity</strong> function, which sets the passed ByteArray with its generated report as a response body. </p>
<p>Additionally, we set the <strong>Content-Type</strong> header of the response as the <strong>application/octet-stream</strong>, and the Content-Disposition as the <strong>attachment; filename=</strong>.</p>
<h2 id="heading-step-6-test-everything-with-postman"><strong>Step 6: Test Everything With Postman</strong></h2>
<p>Finally, we can run and test our Spring Boot application, for instance with the <code>gradlew</code> command:</p>
<pre><code>./gradlew bootRun
</code></pre><p>By default, the Spring Boot application will be running on port 8080, so let's open up <a target="_blank" href="https://www.postman.com/">Postman</a> (or any other tool), specify the <strong>POST</strong> request to <strong>localhost:8080/api/report/xls</strong> and hit <strong>Send and Download</strong> button: </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/POST_xls.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>If everything went well, we should see a window allowing us to save the <strong>.xls</strong> file. </p>
<p>Similarly, let's test the second endpoint:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/POST_xlsx.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This time, the file extension should be .xlsx.</p>
<h2 id="heading-summary"><strong>Summary</strong></h2>
<p>That's all for this article! We've covered the process of generating Excel reports in a Spring Boot REST API with Apache POI and Kotlin.</p>
<p>If you enjoyed it and would like to learn other topics through similar articles, please visit my blog, <a target="_blank" href="https://codersee.com/"><strong>Codersee</strong></a>.</p>
<p>And the last thing: for the source code of a fully working project, please refer to <a target="_blank" href="https://github.com/codersee-blog/freecodecamp-spring-boot-kotlin-excel">this GitHub repository</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
