<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Charles Muchene]]></title><description><![CDATA[Charles Muchene]]></description><link>https://charlesmuchene.com</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1584126130366/i4BmKYhif.png</url><title>Charles Muchene</title><link>https://charlesmuchene.com</link></image><generator>RSS for Node</generator><lastBuildDate>Sun, 17 May 2026 02:40:39 GMT</lastBuildDate><atom:link href="https://charlesmuchene.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Swift Android Gradle Plugin]]></title><description><![CDATA[Introduction
Last week, the Swift for Android working group announced that Swift now supports Android. This is an exciting milestone for developers who want to leverage Swift's powerful features in Android development. To help developers explore this...]]></description><link>https://charlesmuchene.com/swift-android-gradle-plugin</link><guid isPermaLink="true">https://charlesmuchene.com/swift-android-gradle-plugin</guid><category><![CDATA[Swift for Android]]></category><category><![CDATA[Android NDK]]></category><category><![CDATA[Swift SDK]]></category><category><![CDATA[Swift]]></category><category><![CDATA[android development]]></category><category><![CDATA[gradle-plugin]]></category><category><![CDATA[Cross-Compilation]]></category><category><![CDATA[Mobile Development]]></category><category><![CDATA[Kotlin]]></category><category><![CDATA[native development]]></category><dc:creator><![CDATA[Charles Muchene]]></dc:creator><pubDate>Wed, 29 Oct 2025 05:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1761713772652/76ffadc4-b0d4-4e9e-ab3b-87f818b54af0.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>Last week, the Swift for Android working group announced that <a target="_blank" href="https://www.swift.org/blog/nightly-swift-sdk-for-android/">Swift now supports Android</a>. This is an exciting milestone for developers who want to leverage Swift's powerful features in Android development. To help developers explore this new capability, I created a <a target="_blank" href="https://github.com/charlesmuchene/swift-android-gradle-plugin">Swift Android Gradle Plugin</a> that simplifies the integration of Swift libraries into Android projects.</p>
<p>I've also built a sample application that demonstrates the plugin in action. The app generates fractal images using Swift and renders them with Jetpack Compose. You can read more about it here: https://charlesmuchene.com/swift-android-gradle-plugin-sample-app</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1761713113761/e4f070c0-e01c-4f19-b543-2712fa64c8a6.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-understanding-cross-compilation-for-android">Understanding Cross-Compilation for Android</h2>
<p>To build a Swift package for Android, we need to cross-compile Swift code to target the Android platform. Cross-compilation is the process of building code on one platform (like your development machine) to run on a different platform (Android devices).</p>
<p>This process requires several tools working together:</p>
<ol>
<li><p><strong>Swift Toolchain</strong>: The core binaries needed to build and run Swift code</p>
</li>
<li><p><strong>Swift SDK for Android</strong>: Contains all the resources needed to generate and run Swift code for Android (this is what was recently released)</p>
</li>
<li><p><strong>Android Native Development Kit (NDK)</strong>: Cross-compilation tools for native Android development, widely used for building C/C++ code for Android</p>
</li>
<li><p><strong>Swift Android Gradle Plugin</strong>: Automatically configures build tasks to invoke the required cross-compilation tools</p>
</li>
</ol>
<p>The <a target="_blank" href="https://github.com/charlesmuchene/swift-android-gradle-plugin?tab=readme-ov-file#setup">setup guide</a> in the plugin repository provides detailed instructions for installing these tools on your development machine.</p>
<h2 id="heading-key-features">Key Features</h2>
<p>The Swift Android Gradle Plugin extends Gradle's functionality by adding new tasks and DSL elements to projects containing Swift code. Here's what makes it powerful:</p>
<p><strong>Seamless Integration with Android Build System</strong><br />The plugin hooks into the Android project task graph to compile and package Swift sources automatically. It builds for all configured architectures, copies artifacts to the appropriate directories, and cleans up artifacts when the project is cleaned.</p>
<p><strong>Flexible Configuration DSL</strong><br />The plugin exposes a DSL for build configuration, allowing you to set the target API level, specify which architectures to build for, and customize other build parameters to suit your project's needs.</p>
<p><strong>Android Studio Integration</strong><br />It works with Android Gradle Plugin (AGP) APIs to suggest Swift source sets in Android Studio, providing a smoother development experience.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1761712892712/6627d1f6-4689-4930-9e63-c335aad91464.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-adding-the-plugin-to-your-project">Adding the Plugin to Your Project</h2>
<p>The Swift Android Gradle Plugin is distributed via JitPack. Here's how to add it to your project:</p>
<pre><code class="lang-kotlin"><span class="hljs-comment">// build.gradle.kts</span>
plugins {
   <span class="hljs-comment">// android app/lib plugin must be applied first</span>

   id(<span class="hljs-string">"com.charlesmuchene.swift-android-gradle-plugin"</span>) version <span class="hljs-string">"0.1.0-alpha"</span>
}

<span class="hljs-comment">// settings.gradle.kts</span>
pluginManagement {
   repositories {
      <span class="hljs-comment">// ...</span>
   }

   <span class="hljs-comment">// <span class="hljs-doctag">NOTE:</span> Plugin is not published yet!!</span>
   <span class="hljs-comment">// Clone and add plugin as an included build</span>
   includeBuild(<span class="hljs-string">"../swift-android-gradle-plugin"</span>)
}
</code></pre>
<h2 id="heading-looking-ahead">Looking Ahead</h2>
<p>The Swift SDK for Android is still in its early stages. Currently, there are numerous tools and configuration steps required before building. As the project matures, we can expect this process to become more streamlined and developer-friendly.</p>
<p>That said, you now have everything you need to start experimenting: the SDK, the <a target="_blank" href="https://github.com/charlesmuchene/swift-android-gradle-plugin">Swift Android Gradle Plugin</a>, and a <a target="_blank" href="https://charlesmuchene.com/swift-android-gradle-plugin-sample-app">sample project</a> to learn from. The foundation is here—now it's time to build.</p>
<p>Happy coding! 😎</p>
<h2 id="heading-resources">Resources</h2>
<ul>
<li><p><a target="_blank" href="https://github.com/charlesmuchene/swift-android-gradle-plugin">Swift Android Gradle Plugin Repository</a></p>
</li>
<li><p><a target="_blank" href="https://charlesmuchene.com/swift-android-gradle-plugin-sample-app">Sample App Tutorial</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/swiftlang/swift-android-examples">Swift Android Examples</a></p>
</li>
<li><p><a target="_blank" href="https://www.swift.org/documentation/articles/swift-sdk-for-android-getting-started.html">Swift SDK for Android Getting Started Guide</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Swift Android Gradle Plugin Sample App]]></title><description><![CDATA[In my previous article, I introduced the Swift Android Gradle Plugin that simplifies integrating Swift code into Android projects. To demonstrate the plugin in action, I built a sample Android app that generates fractal images using Swift and renders...]]></description><link>https://charlesmuchene.com/swift-android-gradle-plugin-sample-app</link><guid isPermaLink="true">https://charlesmuchene.com/swift-android-gradle-plugin-sample-app</guid><category><![CDATA[Swift Android]]></category><category><![CDATA[JNI Integration]]></category><category><![CDATA[Native Android Development]]></category><category><![CDATA[Mandelbrot Set]]></category><category><![CDATA[Jetpack Compose]]></category><category><![CDATA[Swift Concurrency]]></category><category><![CDATA[Android NDK]]></category><category><![CDATA[cross platform development]]></category><category><![CDATA[Swift Package Manager]]></category><dc:creator><![CDATA[Charles Muchene]]></dc:creator><pubDate>Wed, 29 Oct 2025 05:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/ocmrkY0bifM/upload/2b07f87398f42c3a6a5998774cb26755.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In my <a target="_blank" href="https://charlesmuchene.com/swift-android-gradle-plugin">previous article</a>, I introduced the <a target="_blank" href="https://github.com/charlesmuchene/swift-android-gradle-plugin">Swift Android Gradle Plugin</a> that simplifies integrating Swift code into Android projects. To demonstrate the plugin in action, I built a <a target="_blank" href="https://github.com/charlesmuchene/swift-android-gradle-plugin-sample">sample Android app</a> that generates fractal images using Swift and renders them in Jetpack Compose.</p>
<h2 id="heading-what-the-app-does">What the App Does 📱</h2>
<p>The app showcases a complete integration between Swift and Android by:</p>
<ol>
<li><p>Computing fractal images using Swift code</p>
</li>
<li><p>Mapping fractal data to colors for each pixel</p>
</li>
<li><p>Passing coloring information across the native boundary via Java Native Interface (JNI)</p>
</li>
<li><p>Creating bitmap images and rendering them in Compose</p>
</li>
<li><p>Continuously animating a zoom into the fractal image</p>
</li>
</ol>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtube.com/shorts/P03K91EgHM4">https://youtube.com/shorts/P03K91EgHM4</a></div>
<p> </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1761716270475/8a6aaaca-87a7-4ff9-b4db-12bcf019ea9a.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-project-structure">Project Structure 🏗️</h2>
<p>Here's an overview of the project layout:</p>
<pre><code class="lang-bash">App
├── build.gradle.kts
└── src
    └── main
        ├── AndroidManifest.xml
        ├── java
        │   ├── Activity
        │   ├── StateHolder
        │   ├── Compose UI
        │   └── Native lib definitions
        ├── res
        └── swift
            ├── Package.swift
            └── Sources
                ├── fractals.swift
                └── lib.swift
</code></pre>
<p>The project follows the conventional Android app structure with a key addition: the Swift source set. Let me highlight the important components.</p>
<h2 id="heading-key-components">Key Components 🔑</h2>
<h3 id="heading-1-native-library-interface">1. Native Library Interface 🚪</h3>
<p>I created a <code>SwiftLibrary</code> class that serves as the bridge between Kotlin and Swift. This class loads the native library and defines the methods we can call from our app:</p>
<pre><code class="lang-kotlin"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SwiftLibrary</span> </span>{

    <span class="hljs-keyword">init</span> {
        System.loadLibrary(<span class="hljs-string">"native-lib"</span>)
    }

    <span class="hljs-keyword">external</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">captionFromSwift</span><span class="hljs-params">()</span></span>: String

    <span class="hljs-keyword">external</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">generateFractal</span><span class="hljs-params">(
        width: <span class="hljs-type">Int</span>, 
        height: <span class="hljs-type">Int</span>, 
        scale: <span class="hljs-type">Double</span>, 
        cx: <span class="hljs-type">Double</span>, 
        cy: <span class="hljs-type">Double</span>
    )</span></span>: DoubleArray
}
</code></pre>
<h3 id="heading-2-the-swift-source-set">2. The Swift Source Set ⚡</h3>
<p>The Swift source set contains all native Swift code and should be treated as a pure Swift Package Manager (SPM) package.</p>
<p><strong>Package.swift</strong></p>
<p>This manifest file defines what to build from which sources. Here we're building a dynamic library (.so) called <code>native-lib</code>:</p>
<pre><code class="lang-swift"><span class="hljs-comment">// swift-tools-version: 6.3</span>

<span class="hljs-keyword">import</span> PackageDescription

<span class="hljs-keyword">let</span> package = <span class="hljs-type">Package</span>(
    name: <span class="hljs-string">"native-lib"</span>,
    products: [
        .library(name: <span class="hljs-string">"Fractals"</span>, targets: [<span class="hljs-string">"Fractals"</span>]),
        .library(name: <span class="hljs-string">"native-lib"</span>, type: .<span class="hljs-keyword">dynamic</span>, targets: [<span class="hljs-string">"Lib"</span>])
    ],
    targets: [
        .target(name: <span class="hljs-string">"Lib"</span>, dependencies: [<span class="hljs-string">"Fractals"</span>]), 
        .target(name: <span class="hljs-string">"Fractals"</span>)
    ]
)
</code></pre>
<blockquote>
<p>Note: The package name <code>native-lib</code> matches the name used to load the native library in our Kotlin code.</p>
</blockquote>
<p><strong>lib.swift</strong></p>
<p>This file contains the JNI definitions that link to the external methods in <code>SwiftLibrary</code>:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">import</span> Android

@_cdecl(<span class="hljs-string">"Java_com_charlesmuchene_sample_domain_SwiftLibrary_captionFromSwift"</span>)
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">captionFromSwift</span><span class="hljs-params">(
    env: UnsafeMutablePointer&lt;JNIEnv?&gt;, 
    clazz: jclass
)</span></span> -&gt; jstring { ... }

@_cdecl(<span class="hljs-string">"Java_com_charlesmuchene_sample_domain_SwiftLibrary_generateFractal"</span>)
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">generateFractal</span><span class="hljs-params">(
    env: UnsafeMutablePointer&lt;JNIEnv?&gt;, 
    clazz: jclass, 
    ...
)</span></span> -&gt; jdoubleArray { ... }
</code></pre>
<blockquote>
<p>The Android module from the Swift SDK for Android provides the JNIEnv.</p>
</blockquote>
<p><strong>fractals.swift</strong></p>
<p>This file contains pure Swift code for fractal generation, exposing the entry point function:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">generateFractal</span><span class="hljs-params">(
    width: Int, 
    height: Int, 
    scale: Double, 
    cx: Double, 
    cy: Double
)</span></span> -&gt; [<span class="hljs-type">Double</span>] { ... }
</code></pre>
<p>With limited Swift support in Android Studio, I wrote the Swift code using Xcode, which offers better language support. Tooling is one area that will likely impact Swift for Android adoption. 💔</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1761714540409/563393a4-f8d6-438e-a638-d2ed26d9788c.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-3-project-configuration">3. Project Configuration 📽️</h3>
<p>The project is a standard Android app with one important addition—the Swift Android Gradle Plugin:</p>
<pre><code class="lang-kotlin"><span class="hljs-comment">// build.gradle.kts</span>
plugins {
   <span class="hljs-comment">// android app/lib plugin must be applied first</span>

   id(<span class="hljs-string">"com.charlesmuchene.swift-android-gradle-plugin"</span>) version <span class="hljs-string">"0.1.0-alpha"</span>
}

<span class="hljs-comment">// settings.gradle.kts</span>
pluginManagement {
   repositories {
      <span class="hljs-comment">// ...</span>
   }

   <span class="hljs-comment">// <span class="hljs-doctag">NOTE:</span> Plugin is not published yet!!</span>
   <span class="hljs-comment">// Clone and add plugin as an included build</span>
   includeBuild(<span class="hljs-string">"../swift-android-gradle-plugin"</span>)
}
</code></pre>
<h2 id="heading-generating-the-fractal">Generating the Fractal 🧮</h2>
<p>The Swift code generates the Mandelbrot Set, a set of complex numbers C for which the following does not diverge.</p>
<p>$$z_{n+1} = z_n^2 + c$$</p><p><a target="_blank" href="https://youtu.be/pv1MZtTQIkg">This video</a> provides an excellent introduction to the mathematics behind the set.</p>
<p>The algorithm works as follows:</p>
<ol>
<li><p>For a given grid (width × height), map every pixel to a complex number C</p>
</li>
<li><p>For each complex number C, calculate its escape count in the Mandelbrot set</p>
</li>
</ol>
<h3 id="heading-complex-number-representation">Complex Number Representation 🌀</h3>
<p>The Mandelbrot set lives in the complex plane, so I created a struct to represent complex numbers:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">internal</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Complex</span>: <span class="hljs-title">Sendable</span> </span>{
    <span class="hljs-keyword">var</span> real: <span class="hljs-type">Double</span>
    <span class="hljs-keyword">var</span> imag: <span class="hljs-type">Double</span>

    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">squared</span><span class="hljs-params">()</span></span> -&gt; <span class="hljs-type">Complex</span> {
        <span class="hljs-keyword">let</span> newReal = real * real - imag * imag
        <span class="hljs-keyword">let</span> newImag = <span class="hljs-number">2.0</span> * real * imag
        <span class="hljs-keyword">return</span> <span class="hljs-type">Complex</span>(real: newReal, imag: newImag)
    }

    <span class="hljs-keyword">var</span> magnitudeSquared: <span class="hljs-type">Double</span> {
        <span class="hljs-keyword">return</span> real * real + imag * imag
    }
}
</code></pre>
<h3 id="heading-the-generation-algorithm">The Generation Algorithm 🌿</h3>
<p>The core algorithm iterates through each pixel, mapping it to a complex number and calculating its escape count:</p>
<pre><code class="lang-swift"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">generateMandelbrotGrid</span><span class="hljs-params">(...)</span></span> async -&gt; [[<span class="hljs-type">Double</span>]] {
    <span class="hljs-keyword">var</span> hueGrid: [[<span class="hljs-type">Double</span>]] = ...

    <span class="hljs-keyword">for</span> y <span class="hljs-keyword">in</span> <span class="hljs-number">0</span>..&lt;height {
        <span class="hljs-keyword">for</span> x <span class="hljs-keyword">in</span> <span class="hljs-number">0</span>..&lt;width {
            <span class="hljs-keyword">let</span> <span class="hljs-built_in">c</span> = mapPixelToComplex(...)
            <span class="hljs-keyword">let</span> <span class="hljs-built_in">count</span> = mandelbrotEscapeCount(<span class="hljs-built_in">c</span>: <span class="hljs-built_in">c</span>, maxIterations: maxIterations)
            <span class="hljs-keyword">let</span> colorHue = strategy.colorIndex(forCount: <span class="hljs-built_in">count</span>)
            hueGrid[y][x] = colorHue
        }
    }

    <span class="hljs-keyword">return</span> hueGrid
}
</code></pre>
<h2 id="heading-coloring-strategies">Coloring Strategies 🎨</h2>
<p>To visualize the fractal, I map each escape count to a color hue. I created a protocol-based system that allows different coloring strategies to be plugged in for various visual effects:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">protocol</span> <span class="hljs-title">MandelbrotColoringStrategy</span>: <span class="hljs-title">Sendable</span> </span>{
    <span class="hljs-keyword">var</span> maxIterations: <span class="hljs-type">Int</span> { <span class="hljs-keyword">get</span> }

    <span class="hljs-comment">/// Maps the escape count (Int) to a color index (e.g., Hue: 0.0 to 1.0)</span>
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">colorIndex</span><span class="hljs-params">(forCount <span class="hljs-built_in">count</span>: Int)</span></span> -&gt; <span class="hljs-type">Double</span>
}

<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">DiscreteColoringStrategy</span>: <span class="hljs-title">MandelbrotColoringStrategy</span> </span>{ ... }

<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">ContinuousColoringStrategy</span>: <span class="hljs-title">MandelbrotColoringStrategy</span> </span>{ ... }

<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">InsideColoringStrategy</span>: <span class="hljs-title">MandelbrotColoringStrategy</span> </span>{ ... }
</code></pre>
<p>The demo video uses <code>DiscreteColoringStrategy</code> with 50 iterations. This lower iteration count enables faster rendering during zoom animations, though it results in lower fractal resolution.</p>
<h2 id="heading-data-transfer-via-jni">Data Transfer via JNI 📄</h2>
<p>Data serialization from native code to the Android runtime is the biggest bottleneck in our app. The Mandelbrot generation produces a 2D array of doubles representing escape counts mapped to colors. Passing 2D arrays across JNI is complex and slow.</p>
<p>To improve efficiency, I flatten the array into a single contiguous double array in row-major order:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">fileprivate</span> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">prepareDataForJNI</span><span class="hljs-params">(grid: [[Double]])</span></span> -&gt; [<span class="hljs-type">Double</span>] {
    grid.flatMap { $<span class="hljs-number">0</span> }
}
</code></pre>
<p>The Kotlin code receives this flat array, converts from HSV to RGB, and uses the colors to construct the image.</p>
<blockquote>
<p><strong>Future Optimization</strong>: <a target="_blank" href="https://openjdk.org/jeps/454">JEP 454: Foreign Function &amp; Memory API</a> was introduced in Java 22. This API enables Java programs to call native libraries and process native data without JNI's brittleness. When Android catches up to Java 22, we could access Mandelbrot data in off-heap memory directly from the app, eliminating this optimization dance.</p>
</blockquote>
<h2 id="heading-swift-concurrency-and-a-recursive-code-fractal">Swift Concurrency and a 'Recursive Code Fractal' 🫨</h2>
<p>The <code>generateMandelbrotGrid</code> function uses Swift's structured concurrency to perform CPU-intensive tasks efficiently. It divides the large problem into smaller, independent tasks (calculating each row), then uses a TaskGroup to solve them in parallel:</p>
<pre><code class="lang-swift"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">generateMandelbrotGrid</span><span class="hljs-params">(...)</span></span> async -&gt; [[<span class="hljs-type">Double</span>]] {
    <span class="hljs-keyword">var</span> hueGrid: [[<span class="hljs-type">Double</span>]] = ...

    await withTaskGroup(of: (<span class="hljs-type">Int</span>, [<span class="hljs-type">Double</span>]).<span class="hljs-keyword">self</span>) { group <span class="hljs-keyword">in</span>
        <span class="hljs-keyword">for</span> y <span class="hljs-keyword">in</span> <span class="hljs-number">0</span>..&lt;height {
            group.addTask { [capture list] <span class="hljs-keyword">in</span>
                <span class="hljs-keyword">var</span> hueRow = <span class="hljs-type">Array</span>(repeating: <span class="hljs-number">0.0</span>, <span class="hljs-built_in">count</span>: width)
                <span class="hljs-keyword">for</span> x <span class="hljs-keyword">in</span> <span class="hljs-number">0</span>..&lt;width {
                    <span class="hljs-keyword">let</span> <span class="hljs-built_in">c</span> = mapPixelToComplex(...)
                    <span class="hljs-keyword">let</span> <span class="hljs-built_in">count</span> = mandelbrotEscapeCount(<span class="hljs-built_in">c</span>: <span class="hljs-built_in">c</span>, maxIterations: maxIterations)
                    hueRow[x] = strategy.colorIndex(forCount: <span class="hljs-built_in">count</span>)
                }
                <span class="hljs-keyword">return</span> (y, hueRow)
            }
        }
        <span class="hljs-keyword">for</span> await (y, row) <span class="hljs-keyword">in</span> group {
            hueGrid[y] = row
        }
    }

    <span class="hljs-keyword">return</span> hueGrid
}
</code></pre>
<p>The <code>async</code> keyword signals that the function performs asynchronous work and can pause without blocking threads. The <code>await withTaskGroup(...)</code> pauses execution until all child tasks complete. Each task produces a tuple <code>(Int, [Double])</code> containing the row index and calculated pixel data.</p>
<p>The Swift runtime schedules tasks to run concurrently across available CPU cores, significantly speeding up the process compared to sequential loops. The <code>for await (y, row) in group</code> loop receives results as tasks finish, and structured concurrency guarantees all tasks complete before proceeding.</p>
<h3 id="heading-the-concurrency-challenge">The Concurrency Challenge 🧩</h3>
<p>Everything worked smoothly until implementing the caller function, <code>generateFractal</code>. This function receives JNI input, creates a coloring strategy, generates the Mandelbrot grid, and returns data to the JNI call.</p>
<p>My initial implementation launched the generator in a Task and used a semaphore to block the thread:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">var</span> result: [<span class="hljs-type">Double</span>] = []
<span class="hljs-keyword">let</span> semaphore = <span class="hljs-type">DispatchSemaphore</span>(value: <span class="hljs-number">0</span>)

<span class="hljs-type">Task</span> { [capture list] <span class="hljs-keyword">in</span>
    <span class="hljs-keyword">let</span> renderedGrid = await generateMandelbrotGrid(...)
    result = prepareDataForJNI(grid: renderedGrid)
    semaphore.signal()
}

semaphore.wait()

<span class="hljs-keyword">return</span> result
</code></pre>
<p>This failed with a compiler error:</p>
<pre><code class="lang-swift">error: sending value of non-<span class="hljs-type">Sendable</span> type '() async -&gt; ()' risks causing data races
</code></pre>
<p>The problem? A data race. The Task's closure and the <code>generateFractal</code> function can access the result array concurrently, which is unsafe in Swift's concurrency model. The DispatchSemaphore waits for the Task, but doesn't protect the shared <code>result</code> variable from concurrent access.</p>
<h3 id="heading-the-actor-solution">The Actor Solution 🎭</h3>
<p>To protect shared mutable state, I used an Actor to safely manage state and bridge the concurrent and synchronous worlds. Actors serialize access to internal state, guaranteeing only one piece of code can modify the result at a time:</p>
<pre><code class="lang-swift">actor <span class="hljs-type">ResultHolder</span>&lt;<span class="hljs-type">T</span>: <span class="hljs-type">Sendable</span>&gt; {
    <span class="hljs-keyword">var</span> value: <span class="hljs-type">T?</span>

    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">setResult</span><span class="hljs-params">(<span class="hljs-number">_</span> newValue: T)</span></span> {
        <span class="hljs-keyword">self</span>.value = newValue
    }

    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">getResultOrDefault</span><span class="hljs-params">(<span class="hljs-number">_</span> defaultValue: T)</span></span> -&gt; <span class="hljs-type">T</span> {
        <span class="hljs-keyword">self</span>.value ?? defaultValue
    }
}
</code></pre>
<p>Refactoring to use the Actor:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> resultHolder = <span class="hljs-type">ResultHolder</span>&lt;[<span class="hljs-type">Double</span>]&gt;()
<span class="hljs-keyword">let</span> semaphore = <span class="hljs-type">DispatchSemaphore</span>(value: <span class="hljs-number">0</span>)

<span class="hljs-type">Task</span> { [capture list] <span class="hljs-keyword">in</span>
    <span class="hljs-keyword">let</span> renderedGrid = await generateMandelbrotGrid(...)
    <span class="hljs-keyword">let</span> data = prepareDataForJNI(grid: renderedGrid)
    await resultHolder.setResult(data)
    semaphore.signal()
}

semaphore.wait()

<span class="hljs-keyword">return</span> resultHolder.getResultOrDefault([])
</code></pre>
<p>This resolved the data race but introduced a new issue: we must <code>await</code> the call to <code>getResultOrDefault</code> too. The async issue had just moved further down! 🥺</p>
<p>To resolve this, I created a <code>runBlocking</code> function that allows retrieving the result from the actor synchronously. Interestingly, this function has a similar structure to the logic in <code>generateFractal</code>—a recursive code fractal! 🫨</p>
<pre><code class="lang-swift"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">runBlocking</span>&lt;T: Sendable&gt;<span class="hljs-params">(operation: @escaping @Sendable <span class="hljs-params">()</span></span></span> async -&gt; <span class="hljs-type">T</span>) -&gt; <span class="hljs-type">T</span> {
    <span class="hljs-keyword">var</span> result: <span class="hljs-type">T?</span>
    <span class="hljs-keyword">let</span> semaphore = <span class="hljs-type">DispatchSemaphore</span>(value: <span class="hljs-number">0</span>)

    <span class="hljs-type">Task</span> {
        result = await operation()
        semaphore.signal()
    }

    semaphore.wait()
    <span class="hljs-keyword">return</span> result! <span class="hljs-comment">// Safe to force-unwrap: semaphore guarantees result is set</span>
}
</code></pre>
<p>The final <code>generateFractal</code> implementation:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> resultHolder = <span class="hljs-type">ResultHolder</span>&lt;[<span class="hljs-type">Double</span>]&gt;()
<span class="hljs-keyword">let</span> semaphore = <span class="hljs-type">DispatchSemaphore</span>(value: <span class="hljs-number">0</span>)

<span class="hljs-type">Task</span> { [capture list] <span class="hljs-keyword">in</span>
    <span class="hljs-keyword">let</span> renderedGrid = await generateMandelbrotGrid(...)
    <span class="hljs-keyword">let</span> data = prepareDataForJNI(grid: renderedGrid)
    await resultHolder.setResult(data)
    semaphore.signal()
}

semaphore.wait()

<span class="hljs-keyword">return</span> runBlocking {
    await resultHolder.getResultOrDefault([])
}
</code></pre>
<h2 id="heading-kotlin-concurrency-choosing-the-right-dispatcher">Kotlin Concurrency: Choosing the Right Dispatcher 🚫</h2>
<p>At first glance, <code>Dispatchers.Default</code> seems like the right choice since we're performing CPU-bound work. However, from the Kotlin perspective, we're invoking native methods (JNI calls) that block the calling JVM thread while native code executes.</p>
<p><code>Dispatchers.IO</code> is designed specifically for blocking operations and has ideal behavior for our use case:</p>
<ul>
<li><p>Uses an on-demand, uncapped (or very large) pool of worker threads</p>
</li>
<li><p>When a thread is blocked by a native call, a new thread can be created to handle other IO tasks, preventing starvation of the Default pool</p>
</li>
<li><p>Ensures native Swift code execution doesn't unnecessarily delay other parts of the application</p>
</li>
</ul>
<h2 id="heading-animating-the-fractal">Animating the Fractal 💫</h2>
<p>After the first UI composition, we request the initial fractal image at the default scale. This calls through <code>SwiftLibrary</code>, suspends until the native code responds with the flattened hue array, then maps hue values to RGB and creates a bitmap:</p>
<pre><code class="lang-kotlin"><span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">createImage</span><span class="hljs-params">(hueArray: <span class="hljs-type">DoubleArray</span>, width: <span class="hljs-type">Int</span>, height: <span class="hljs-type">Int</span>)</span></span>: ImageBitmap {
    <span class="hljs-keyword">val</span> bitmap = createBitmap(width, height)

    <span class="hljs-keyword">for</span> (y <span class="hljs-keyword">in</span> <span class="hljs-number">0</span> until height) {
        <span class="hljs-keyword">for</span> (x <span class="hljs-keyword">in</span> <span class="hljs-number">0</span> until width) {
            <span class="hljs-keyword">val</span> index = y * width + x
            <span class="hljs-keyword">val</span> hue = hueArray[index].toFloat()
            <span class="hljs-keyword">val</span> color = Color.hsv(hue * <span class="hljs-number">360f</span>, <span class="hljs-number">1.0f</span>, <span class="hljs-number">1.0f</span>)
            bitmap[x, y] = color.toArgb()
        }
    }

    <span class="hljs-keyword">return</span> bitmap.asImageBitmap()
}
</code></pre>
<p>When the image updates in Compose, we animate a float value that updates the image scale, creating a zoom effect. When the animation finishes, we request the next fractal image from the native layer at the new scale. The native layer generates the hue array at the given scale and returns the image, creating a continuous loop.</p>
<h2 id="heading-conclusion">Conclusion 😮‍💨</h2>
<p>This project was both fun and challenging to create. Juggling Compose, app logic, and Swift code is certainly demanding. However, the project showcases an architecture close to production-ready, using modern Android components driven by logic living in native Swift code.</p>
<p>I'm curious to see how adoption of Swift SDK for Android evolves. You now have the SDK, the <a target="_blank" href="https://github.com/charlesmuchene/swift-android-gradle-plugin">Swift Android Gradle Plugin</a>, and this sample project to learn from. Go build something amazing.</p>
<p>Happy coding! 😎</p>
<h2 id="heading-resources">Resources 🚚</h2>
<ul>
<li><p><a target="_blank" href="https://charlesmuchene.com/swift-android-gradle-plugin">Swift Android Gradle Plugin Introduction</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/charlesmuchene/swift-android-gradle-plugin-sample">Swift Android Gradle Plugin Sample App Repository</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/swiftlang/swift-android-examples">Swift Android Examples</a></p>
</li>
<li><p><a target="_blank" href="https://www.swift.org/documentation/articles/swift-sdk-for-android-getting-started.html">Swift SDK for Android Getting Started Guide</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Jetliner XR]]></title><description><![CDATA[Taking Flight with Android XR: Building a Jetliner Demo
I spent the last few days exploring Android XR, Google's latest platform for extended reality applications. After working through the documentation and experimenting with the SDK, I built a demo...]]></description><link>https://charlesmuchene.com/jetliner-xr</link><guid isPermaLink="true">https://charlesmuchene.com/jetliner-xr</guid><category><![CDATA[SceneCore]]></category><category><![CDATA[Samsung Galaxy XR]]></category><category><![CDATA[Google XR]]></category><category><![CDATA[3D Android development]]></category><category><![CDATA[Galaxy XR]]></category><category><![CDATA[Android XR]]></category><category><![CDATA[Jetpack Compose]]></category><category><![CDATA[Spatial Computing]]></category><category><![CDATA[extended reality]]></category><category><![CDATA[xr development]]></category><category><![CDATA[ARCore]]></category><dc:creator><![CDATA[Charles Muchene]]></dc:creator><pubDate>Mon, 20 Oct 2025 13:20:24 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1760843871356/72112fd0-744f-42fe-88a5-b3f52996c20d.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-taking-flight-with-android-xr-building-a-jetliner-demo">Taking Flight with Android XR: Building a Jetliner Demo</h1>
<p>I spent the last few days exploring <code>Android XR</code>, Google's latest platform for extended reality applications. After working through the documentation and experimenting with the SDK, I built a demo application featuring an <em>A320neo jetliner</em> in a holding pattern. The project served as a practical way to understand the spatial computing capabilities now available to Android developers. In the video below, you’ll see a typical interaction with an XR device to launch the demo app, navigate from <em>Home Space</em> to <em>Full Space</em> mode and a user looking around in the 3D environment.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.youtube.com/watch?v=gZrtjnjU_G0">https://www.youtube.com/watch?v=gZrtjnjU_G0</a></div>
<p> </p>
<h2 id="heading-android-xr-spatial-computing-on-android">Android XR: Spatial Computing on Android 🌌</h2>
<p>Android XR represents Google's renewed commitment to extended reality for the masses, developed in collaboration with Samsung and Qualcomm. The platform extends the familiar Android development environment into three-dimensional space, allowing developers to build applications that blend digital content with physical environments.</p>
<p>The platform provides three core capabilities that shaped my approach to the jetliner demo:</p>
<ol>
<li><p>Developers can <em>spatialize</em> their applications, positioning UI in 3D space rather than constraining them to a traditional 2D screen.</p>
</li>
<li><p><em>SceneCore</em> enables loading and manipulating 3D models with straightforward APIs.</p>
</li>
<li><p><em>ARCore</em> integration allows applications to understand and interact with the physical environment around the user.</p>
</li>
</ol>
<p>Samsung's Project Moohan (aka <em>Galaxy XR</em> ?) launches tomorrow on October 21st at the "Worlds Wide Open" event. This marks the first commercial headset running Android XR, providing developers with actual hardware to target compared to the emulator environment currently available.</p>
<h2 id="heading-prerequisites">Prerequisites 🧰</h2>
<p>I built the demo on AS Narwhal 4 Feature Drop | 2025.1.4. The emulator used was an <em>Android 14 (“UpsideDownCake”) arm64-v8a, api level 34, google-xr headset</em> with <em>12GB</em> disk size — see <a target="_blank" href="https://github.com/charlesmuchene/jetliner-xr?tab=readme-ov-file#android-xr-emulator">these instructions</a> on how to set it up. These are the versions for the dependencies used for XR:</p>
<pre><code class="lang-kotlin">androidx-compose = { group = <span class="hljs-string">"androidx.xr.compose"</span>, name = <span class="hljs-string">"compose"</span>, version = <span class="hljs-string">"1.0.0-alpha07"</span> }
androidx-runtime = { group = <span class="hljs-string">"androidx.xr.runtime"</span>, name = <span class="hljs-string">"runtime"</span>, version = <span class="hljs-string">"1.0.0-alpha06"</span> }
androidx-scenecore = { group = <span class="hljs-string">"androidx.xr.scenecore"</span>, name = <span class="hljs-string">"scenecore"</span>, version = <span class="hljs-string">"1.0.0-alpha07"</span> }
</code></pre>
<h2 id="heading-jetpack-compose-for-xr-extending-familiar-patterns">Jetpack Compose for XR: Extending Familiar Patterns 🎨</h2>
<p>What made Android XR approachable was how it leveraged existing Jetpack Compose knowledge. I have been writing Compose UI for a couple of years now, and the XR SDK introduced spatial extensions that felt natural to adopt. The learning curve focused on <em>spatial thinking</em> rather than completely new frameworks. Here are 2 spatial composables and their use in the demo app:</p>
<p><strong>Subspace</strong>: This composable creates a partition of 3D space for spatial layouts. Subspaces are only rendered when spatialization is enabled i.e. in Full Space mode. This capability allowed me to structure my application for both traditional and spatial environments without maintaining separate codebases/modules. For example, here’s my main layout:</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">MainScreen</span><span class="hljs-params">()</span></span> {
    The3DContent() <span class="hljs-comment">// Contains a Subspace, thus only rendered in Full Space Mode</span>
    The2DContent() <span class="hljs-comment">// Rendered in Home Space Mode</span>
}

<span class="hljs-meta">@Composable</span>
<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">The3DContent</span><span class="hljs-params">()</span></span> {
    Subspace {
        Jetliner()
    }
}
</code></pre>
<p><strong>Volume</strong>: The Volume composable integrates <em>SceneCore</em> entities directly into the Compose hierarchy. This allows me to add and position the 3D jetliner model. The Volume acts as a container for 3D content while maintaining the declarative patterns of Compose.</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">Jetliner</span><span class="hljs-params">()</span></span> {
    ...

    Volume(modifier = modifier) { parent -&gt;
        jetlinerEntity.parent = parent
    }
}
</code></pre>
<p><strong>SpatialPanel</strong>: SpatialPanels are used to display 2D content in 3D space. The XR codelabs have a good example of using these panels.</p>
<p><strong>Orbiter</strong>: This composable attaches UI elements to SpatialPanels, creating companion interfaces that follow panels through space. The orbiter is the ideal choice for contextual UI that needs to remain accessible regardless of panel position.</p>
<p>There are a couple of other <em>Spatial</em>-prefixed composables available in the SDK for creating immersive experiences e.g. Row, CurvedRow, Column, Box, Dialog, Popup, ExternalSurface.</p>
<p>You can find the complete Jetliner XR project at <a target="_blank" href="https://github.com/charlesmuchene/jetliner-xr">github.com/charlesmuchene/jetliner-xr</a>, demonstrating how some of these composables work together in a functional application.</p>
<h2 id="heading-the-jetliners-holding-pattern-implementation">The Jetliner’s Holding Pattern Implementation ✈️</h2>
<p>The core of the application lives in <code>ui/composables/Jetliner.kt</code>. I loaded an <em>A320neo</em> 3D model — sourced from "A320neo" (<a target="_blank" href="https://skfb.ly/oKTUt">https://skfb.ly/oKTUt</a>) by pranav27 on Sketchfab under Creative Commons Attribution. Loading models in android XR uses SceneCore APIs that support <a target="_blank" href="https://www.khronos.org/Gltf">glTF</a> resources. After loading, I then positioned the model within a <em>Volume</em>. To demo spatial capabilities, the model needed to move continuously, mimicking a holding pattern: the elliptical flight path that pilots execute when awaiting landing clearance — I watch <a target="_blank" href="https://www.youtube.com/@MentourPilot">Mentour Pilot</a> 👨‍✈️.</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">Jetliner</span><span class="hljs-params">()</span></span> {
    <span class="hljs-keyword">val</span> modelEntity = loadModelEntity()

    AnimateModelEntity(modelEntity)

    Volume(modifier = modifier) { ... }
}
</code></pre>
<p>I implemented the movement animation using Jetpack Compose’s animation APIs and SceneCore's entity transform system. The animation updates the Jetliner’s position and rotation on each frame, calculating new coordinates along an elliptical path.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760887343948/59b150a4-4abb-4e69-b71a-dcf04a0f9bfc.png" alt class="image--center mx-auto" /></p>
<p>I control the 2 ellipse radii (a, b), the speed of travel (set by the animation time), and the banking angle of the aircraft. The animation loop runs continuously, providing smooth movement visible from any viewing angle. After that, it’s just a matter of fine-tuning these parameters to create an almost realistic holding pattern. Users wearing an XR device can walk around the virtual environment and marvel at the Jetliner’s motion.</p>
<pre><code class="lang-kotlin"><span class="hljs-meta">@Composable</span>
<span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">AnimateModelEntity</span><span class="hljs-params">(modelEntity: <span class="hljs-type">GltfModelEntity</span>?)</span></span> {
    <span class="hljs-keyword">val</span> angle = animatedAngle()
    <span class="hljs-keyword">val</span> pose = calculatePose(angle)
    modelEntity?.setPose(pose)
}

<span class="hljs-meta">@Composable</span>
<span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">animatedAngle</span><span class="hljs-params">()</span></span>: <span class="hljs-built_in">Float</span> {
    <span class="hljs-comment">// Returns an angle between 0 and 360</span>
    <span class="hljs-comment">// duration: 12s</span>
    <span class="hljs-comment">// easing: Linear</span>
}

<span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">calculatePose</span><span class="hljs-params">(angle: <span class="hljs-type">Float</span>)</span></span>: Pose {
    <span class="hljs-comment">// Convert to radians</span>
    radians = angle × (π / <span class="hljs-number">180</span>)

    <span class="hljs-comment">// Calculate elliptical position using parametric equations</span>
    x = radiusX × cos(radians)
    z = radiusZ × sin(radians)

    <span class="hljs-comment">// Add vertical oscillation and offset</span>
    hover = sin(radians × <span class="hljs-number">6</span>) × <span class="hljs-number">0.2</span>
    position = (x, <span class="hljs-number">6</span> + hover, z - <span class="hljs-number">15</span>)

    <span class="hljs-comment">// Calculate forward direction (tangent to ellipse)</span>
    forwardX = -radiusX × sin(radians)
    forwardZ = radiusZ × cos(radians)
    forward = normalize(forwardX, <span class="hljs-number">0</span>, forwardZ)

    <span class="hljs-comment">// Apply banking angle (varies 15-25° through turn)</span>
    bankAngle = <span class="hljs-number">20</span> + <span class="hljs-number">5</span> × cos(radians × <span class="hljs-number">2</span>)
    up = rotate(UP_VECTOR, around: forward, <span class="hljs-keyword">by</span>: bankAngle)

    <span class="hljs-comment">// Combine into orientation</span>
    orientation = lookTowards(forward, up)

    Pose(position, orientation)
}
</code></pre>
<h2 id="heading-building-for-spatial-computing">Building for Spatial Computing 🏗️</h2>
<p>Android XR lowers the barrier for developers to explore spatial computing. The platform provides first-class tools; Jetpack Compose for XR, Material Design for XR, and SceneCore, built on languages and patterns already familiar to the Android community. This approach differs significantly from traditional XR development, which typically required game engine expertise.</p>
<p>My jetliner demo was a straightforward implementation, but it validated the development experience. The time from concept to working 3D application was compressed compared to what I expected. Official documentation provided a good starting point, and the Compose-based APIs felt intuitive.</p>
<p>Tomorrow's Project Moohan launch transitions Android XR from emulator-based development to physical hardware. This shift matters — testing spatial experiences on actual headsets reveals usability considerations that emulators cannot fully capture. For example, I would like to walk around the environment, experience raycasting, scale models, move panels with my hands etc. The availability of commercial hardware should accelerate both developer experimentation and practical application development.</p>
<p>For developers considering Android XR, the existing Android skillset translates directly. The spatial aspects add a new dimension, literally 😉, but the underlying development patterns remain consistent. Starting with small experiments, like positioning a simple 3D object or creating a floating panel, provides hands-on learning without overwhelming complexity.</p>
<h2 id="heading-gotchas">Gotchas 🫨</h2>
<ul>
<li><p>Controlling your perspective in the 3D environment on the emulator takes some time to get used to. There are only 4 controls (interaction, view direction, movement, forward/backward) but I constantly forgot to switch between them to get the control I wanted. To be fair, each control has handy keyboard shortcuts that one can learn to switch between controls effectively.</p>
</li>
<li><p>There’s a non-critical but spammy log from the XR SDK printed for every render frame. You can filter this out from logcat by setting a pattern like to: <code>-message: "Attempt to remove non-JNI local reference"</code></p>
</li>
</ul>
<p><code>2025-10-19 10:48:04.708 com.charlesmuchene.xr W Attempt to remove non-JNI local reference</code></p>
<ul>
<li><p>My Jetliner animation was not as smooth as I expected. I used the code snippet below to measure the <em>animation fps</em>. The measurements in my logs showed anything between <em>18.0 to 27.0</em> fps. It could be due to the emulated environment I was running the project on or the size of my Jetliner model. On a dedicated XR hardware, I expect smoother animations for reasonably sized models.</p>
<pre><code class="lang-kotlin">  <span class="hljs-keyword">val</span> fpsState = remember { mutableStateOf(<span class="hljs-string">"Calculating FPS..."</span>) }
  <span class="hljs-keyword">val</span> frameCount = remember { mutableIntStateOf(<span class="hljs-number">0</span>) }
  <span class="hljs-keyword">val</span> lastTime = remember { mutableLongStateOf(System.currentTimeMillis()) }

  <span class="hljs-comment">// Log the FPS every second</span>
  LaunchedEffect(<span class="hljs-built_in">Unit</span>) {
      <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) {
          kotlinx.coroutines.delay(<span class="hljs-number">1000</span>) <span class="hljs-comment">// Wait for 1 second</span>
          <span class="hljs-keyword">val</span> currentTime = System.currentTimeMillis()
          <span class="hljs-keyword">val</span> elapsed = (currentTime - lastTime.longValue) / <span class="hljs-number">1000f</span>
          <span class="hljs-keyword">val</span> fps = frameCount.intValue / elapsed
          fpsState.value = String.format(Locale.getDefault(), <span class="hljs-string">"FPS: %.1f"</span>, fps)
          Log.d(<span class="hljs-string">"Animation-FPS"</span>, fpsState.value)

          <span class="hljs-comment">// Reset for the next second</span>
          lastTime.longValue = currentTime
          frameCount.intValue = <span class="hljs-number">0</span>
      }
  }

  <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> Increment frame count on each calculation of the pose</span>
</code></pre>
</li>
</ul>
<h2 id="heading-conclusion">Conclusion 🚀</h2>
<p>The platform is ready. The tools are in alpha. The first XR consumer device launches tomorrow. For those interested in spatial computing, this represents an accessible entry point built on established technologies. What will you build?</p>
<p>Happy coding! 😎</p>
<p>Resources: <a target="_blank" href="https://developer.android.com/develop/xr">Android XR documentation</a> | <a target="_blank" href="https://github.com/charlesmuchene/jetliner-xr">Jetliner XR project on GitHub</a></p>
]]></content:encoded></item><item><title><![CDATA[Pref Editor]]></title><description><![CDATA[The Android Developer's Preference Testing Nightmare
How many times have you been in this situation? You're developing an Android app, need to test different preference values, and find yourself stuck in this frustrating cycle 😢:

Change a preferenc...]]></description><link>https://charlesmuchene.com/pref-editor-how-to-modify-android-preferences-in-real-time-during-development</link><guid isPermaLink="true">https://charlesmuchene.com/pref-editor-how-to-modify-android-preferences-in-real-time-during-development</guid><category><![CDATA[AI Workflow]]></category><category><![CDATA[mcp]]></category><category><![CDATA[Android]]></category><category><![CDATA[Shared Preferences]]></category><category><![CDATA[Android Debug]]></category><category><![CDATA[adb]]></category><category><![CDATA[android development]]></category><dc:creator><![CDATA[Charles Muchene]]></dc:creator><pubDate>Sun, 22 Jun 2025 16:52:01 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/oAujRLsfydI/upload/d173ee065ad8d2248e862d5abd67359b.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-the-android-developers-preference-testing-nightmare">The Android Developer's Preference Testing Nightmare</h2>
<p>How many times have you been in this situation? You're developing an Android app, need to test different preference values, and find yourself stuck in this frustrating cycle 😢:</p>
<ol>
<li><p>Change a preference value in code</p>
</li>
<li><p>Build the app (wait 30+ seconds)</p>
</li>
<li><p>Install on device (wait another 15 seconds)</p>
</li>
<li><p>Navigate to the screen to test</p>
</li>
<li><p>Realize you need a different value</p>
</li>
<li><p>Repeat the entire process</p>
</li>
</ol>
<p>If you're nodding your head, you're not alone. <strong>This workflow wastes hours of development time every week.</strong> Whether you're working with legacy SharedPreferences or the modern Preferences DataStore, testing different preference configurations shouldn't require constant app rebuilds.</p>
<p>Enter <a target="_blank" href="https://github.com/charlesmuchene/pref-editor-mcp-server"><strong>Pref Editor</strong></a> – a game-changing tool that lets you view and modify Android app preferences directly on your device in real-time, without root access.</p>
<h2 id="heading-what-is-pref-editor">What is Pref Editor?</h2>
<p><a target="_blank" href="https://github.com/charlesmuchene/pref-editor-mcp-server">Pref Editor</a> is a developer tool that provides instant access to your Android app's preference files during development. It works with both:</p>
<ul>
<li><p><strong>SharedPreferences</strong> (legacy preference storage)</p>
</li>
<li><p><strong>Preferences DataStore</strong> (modern preference storage)</p>
</li>
</ul>
<h3 id="heading-the-old-way-vs-the-new-way">The Old Way vs. The New Way</h3>
<p><strong>Traditional Workflow:</strong></p>
<ul>
<li><p>Edit code → Build → Install → Test</p>
</li>
<li><p>2-5 minutes per change</p>
</li>
<li><p>Lost context switching</p>
</li>
<li><p>Multiple APK builds required</p>
</li>
</ul>
<p><strong>With Pref Editor:</strong></p>
<ul>
<li><p>Edit preference → Test immediately</p>
</li>
<li><p>5-10 seconds per change</p>
</li>
<li><p>Stay in testing flow</p>
</li>
<li><p>Zero rebuilds needed</p>
</li>
</ul>
<h2 id="heading-key-features-that-save-development-time">Key Features That Save Development Time</h2>
<h3 id="heading-no-root-required">✅ <strong>No Root Required</strong></h3>
<p>Works on any Android device with USB debugging enabled – no need to root your test devices.</p>
<h3 id="heading-real-time-editing">✅ <strong>Real-Time Editing</strong></h3>
<p>Changes take effect immediately without app restarts in most cases.</p>
<h3 id="heading-type-safety">✅ <strong>Type Safety</strong></h3>
<p>Built-in validation prevents you from saving incompatible data types (e.g., string in an integer field).</p>
<h3 id="heading-rollback-protection">✅ <strong>Rollback Protection</strong></h3>
<p>Every edit can be backed up automatically to enable reverting the changes if necessary (desktop version only).</p>
<h3 id="heading-ai-powered-natural-language-control">✅ <strong>AI-Powered Natural Language Control</strong></h3>
<p>Use plain English commands like "Toggle the dark mode preference" or "Set user level to 5".</p>
<h2 id="heading-two-powerful-versions-to-choose-from">Two Powerful Versions to Choose From</h2>
<p>Pref Editor comes in two variants designed for different development workflows:</p>
<h3 id="heading-1-desktop-application-gui">1. Desktop Application (GUI)</h3>
<p>Perfect for visual preference management and team members who prefer graphical interfaces.</p>
<p><strong>Best for:</strong></p>
<ul>
<li><p>Developers who prefer visual interfaces</p>
</li>
<li><p>Team members less comfortable with command-line tools</p>
</li>
<li><p>Complex preference debugging sessions</p>
</li>
</ul>
<h3 id="heading-2-mcp-server-ai-powered">2. MCP Server (AI-Powered)</h3>
<p>Ideal for developers who want to integrate preference editing into their AI-assisted workflow.</p>
<p><strong>Best for:</strong></p>
<ul>
<li><p>Developers using GitHub Copilot or Claude</p>
</li>
<li><p>Teams adopting AI-driven development workflows</p>
</li>
<li><p>Quick preference changes without leaving the IDE</p>
</li>
<li><p>Natural language preference management</p>
</li>
</ul>
<hr />
<h2 id="heading-getting-started-desktop-application">Getting Started: Desktop Application</h2>
<h3 id="heading-prerequisites">Prerequisites</h3>
<ul>
<li><p>Android device with USB debugging enabled</p>
</li>
<li><p>ADB (Android Debug Bridge) installed</p>
</li>
<li><p>Java 17 or higher</p>
</li>
</ul>
<h3 id="heading-installation-amp-setup">Installation &amp; Setup</h3>
<ol>
<li><p><strong>Download the Desktop App</strong></p>
<p> <a target="_blank" href="https://github.com/charlesmuchene/pref-editor-desktop/releases/latest">https://github.com/charlesmuchene/pref-editor-desktop/releases/latest</a></p>
</li>
<li><p><strong>Enable USB Debugging</strong></p>
<ul>
<li><p>Go to Settings → About Phone</p>
</li>
<li><p>Tap "Build Number" 7 times to enable Developer Options</p>
</li>
<li><p>Go to Settings → Developer Options</p>
</li>
<li><p>Enable "USB Debugging"</p>
</li>
</ul>
</li>
<li><p><strong>Connect Your Device</strong></p>
<pre><code class="lang-bash"> <span class="hljs-comment"># Verify ADB connection</span>
 adb devices
 <span class="hljs-comment"># Should show your device as "device" (not "unauthorized")</span>
</code></pre>
</li>
</ol>
<h3 id="heading-basic-usage-walkthrough">Basic Usage Walkthrough</h3>
<h4 id="heading-step-1-launch-and-select-device">Step 1: Launch and Select Device</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750572933607/6bf2db9a-98eb-4e9d-b56a-a77028dc51f5.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p>Launch Pref Editor Desktop</p>
</li>
<li><p>Your connected devices appear in the listing</p>
</li>
<li><p>Select/filter your target device</p>
</li>
</ul>
<h4 id="heading-step-2-choose-your-app">Step 2: Choose Your App</h4>
<ul>
<li><p>Browse/filter installed applications</p>
</li>
<li><p>Search by package name or app name</p>
</li>
<li><p>Select the app whose preferences you want to edit</p>
</li>
</ul>
<h4 id="heading-step-3-select-preference-file">Step 3: Select Preference File</h4>
<p>Common preference file names include:</p>
<ul>
<li><p>shared_prefs/[package_name]_preferences.xml</p>
</li>
<li><p>shared_prefs/user_settings.xml</p>
</li>
<li><p>files/datastore/app_config.preferences_pb</p>
</li>
</ul>
<h4 id="heading-step-4-edit-preferences">Step 4: Edit Preferences</h4>
<ul>
<li><p>View all preference key-value pairs</p>
</li>
<li><p>Edit any value inline</p>
</li>
<li><p>Changes are validated by data type</p>
</li>
<li><p>Click "Save" to apply changes immediately</p>
</li>
</ul>
<h3 id="heading-real-world-example-testing-user-onboarding">Real-World Example: Testing User Onboarding</h3>
<pre><code class="lang-xml"><span class="hljs-comment">&lt;!-- Before: User hasn't completed onboarding --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">boolean</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"onboarding_completed"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"false"</span> /&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">integer</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"onboarding_step"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"0"</span> /&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">string</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"user_level"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"beginner"</span> /&gt;</span>

<span class="hljs-comment">&lt;!-- After: Simulate experienced user --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">boolean</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"onboarding_completed"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"true"</span> /&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">integer</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"onboarding_step"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"5"</span> /&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">string</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"user_level"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"expert"</span> /&gt;</span>
</code></pre>
<p><strong>Result</strong>: Instantly test your app's behavior for users at different onboarding stages without creating multiple test accounts or rebuilding.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750574223975/ca03cc14-093c-4d08-b841-a4cdedecc3e4.png" alt class="image--center mx-auto" /></p>
<hr />
<h2 id="heading-getting-started-mcp-server-ai-powered">Getting Started: MCP Server (AI-Powered)</h2>
<p>The MCP (Model Context Protocol) server brings AI-powered preference editing directly to your IDE. Use natural language to modify preferences while coding.</p>
<blockquote>
<p>There are plans to re-implement this using ddmlib to take advantage of pre-installed JVM toolchain.</p>
</blockquote>
<h3 id="heading-prerequisites-1">Prerequisites</h3>
<ul>
<li><p>Node.js 16+ or npx (or use <a target="_blank" href="https://hub.docker.com/mcp/server/pref-editor">docker image</a>)</p>
</li>
<li><p>Android Studio with GitHub Copilot plugin</p>
</li>
<li><p>OR Claude Desktop</p>
</li>
<li><p>OR VS Code with compatible AI extension</p>
</li>
</ul>
<h3 id="heading-android-studio-setup">Android Studio Setup</h3>
<ol>
<li><p><strong>Install the MCP Server</strong></p>
<pre><code class="lang-bash"> npm install -g @charlesmuchene/pref-editor-mcp-server

 // OR

 docker pull charlesmuchene/pref-editor-mcp-server
</code></pre>
</li>
<li><p><strong>Configure GitHub Copilot</strong></p>
<ul>
<li><p>Open Android Studio</p>
</li>
<li><p>Click the "Agent mode" tab in Copilot</p>
</li>
<li><p>Click "Add tools" button</p>
</li>
<li><p>Click "Add More tools..." (opens <em>mcp.json</em> file)</p>
</li>
</ul>
</li>
<li><p><strong>Add Server Configuration</strong></p>
<pre><code class="lang-json"> {
   <span class="hljs-attr">"servers"</span>: {
     <span class="hljs-attr">"pref-editor-mcp-server"</span>: {
       <span class="hljs-attr">"type"</span>: <span class="hljs-string">"stdio"</span>,
       <span class="hljs-attr">"command"</span>: <span class="hljs-string">"npx"</span>, <span class="hljs-comment">// or docker</span>
       <span class="hljs-attr">"args"</span>: [<span class="hljs-string">"@charlesmuchene/pref-editor-mcp-server"</span>]
     }
   }
 }
</code></pre>
</li>
</ol>
<h3 id="heading-natural-language-commands-you-can-use">Natural Language Commands You Can Use</h3>
<pre><code class="lang-json"><span class="hljs-comment">// Toggle boolean preferences</span>
<span class="hljs-string">"Toggle the dark mode setting"</span>
<span class="hljs-string">"Enable notifications for this user"</span>
<span class="hljs-string">"Turn off the tutorial flag"</span>

<span class="hljs-comment">// Update numeric values  </span>
<span class="hljs-string">"Set the user level to 10"</span>
<span class="hljs-string">"Increase the retry count by 5"</span>
<span class="hljs-string">"Change the timeout to 30 seconds"</span>

<span class="hljs-comment">// Modify string preferences</span>
<span class="hljs-string">"Update the username to 'testuser123'"</span>
<span class="hljs-string">"Set the API endpoint to staging"</span>
<span class="hljs-string">"Change the theme to 'material_dark'"</span>

<span class="hljs-comment">// Add new preferences</span>
<span class="hljs-string">"Add a new preference called 'feature_flag_enabled' with value true"</span>
<span class="hljs-string">"Create a timestamp preference with the current epoch time"</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750574531070/fec736b6-2104-4e4f-86d2-8b5480304f88.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-example-ai-workflow">Example AI Workflow</h3>
<pre><code class="lang-json">Developer: <span class="hljs-string">"I need to test the premium user experience"</span>
AI + Pref Editor: 
✅ Set user_subscription_status to <span class="hljs-string">"premium"</span>
✅ Set subscription_expiry to future date
✅ Enable all premium features
✅ Update user tier to <span class="hljs-string">"gold"</span>

Developer: <span class="hljs-string">"Now test the expired subscription flow"</span>  
AI + Pref Editor:
✅ Set subscription_expiry to past date
✅ Set user_subscription_status to <span class="hljs-string">"expired"</span>
✅ Disable premium features
✅ Add grace_period_days with value <span class="hljs-number">7</span>
</code></pre>
<hr />
<h2 id="heading-common-use-cases-and-time-savings">Common Use Cases and Time Savings</h2>
<h3 id="heading-1-feature-flag-testing">1. Feature Flag Testing</h3>
<p><strong>Before</strong>: Rebuild app for each feature flag combination (5 minutes per test)</p>
<p><strong>After</strong>: Toggle flags instantly (10 seconds per test)</p>
<p><strong>Time Saved</strong>: 4+ minutes per test × 10 tests = 40+ minutes daily</p>
<h3 id="heading-2-user-state-simulation">2. User State Simulation</h3>
<p><strong>Before</strong>: Create multiple user accounts or reset app data</p>
<p><strong>After</strong>: Modify user preferences directly</p>
<p><strong>Time Saved</strong>: 2-3 minutes per user state test</p>
<h3 id="heading-3-api-environment-switching">3. API Environment Switching</h3>
<p><strong>Before</strong>: Change code, rebuild, test each environment</p>
<p><strong>After</strong>: Switch API endpoints via preferences</p>
<p><strong>Time Saved</strong>: 3-5 minutes per environment switch</p>
<h3 id="heading-4-onboarding-flow-testing">4. Onboarding Flow Testing</h3>
<p><strong>Before</strong>: Clear app data and repeat onboarding</p>
<p><strong>After</strong>: Set completion flags and test any step</p>
<p><strong>Time Saved</strong>: 5+ minutes per onboarding test</p>
<h2 id="heading-troubleshooting-common-issues">Troubleshooting Common Issues</h2>
<h3 id="heading-device-not-detected">Device Not Detected</h3>
<pre><code class="lang-bash"><span class="hljs-comment"># Check ADB connection</span>
adb devices

<span class="hljs-comment"># If "unauthorized", check device screen for USB debugging dialog  </span>
<span class="hljs-comment"># If no devices, try:</span>
adb kill-server
adb start-server
</code></pre>
<h3 id="heading-permission-denied-errors">Permission Denied Errors</h3>
<pre><code class="lang-bash"><span class="hljs-comment"># Ensure USB debugging is enabled</span>
<span class="hljs-comment"># Try different USB cable (data cable, not charge-only)</span>
<span class="hljs-comment"># Enable "Disable adb authorization timeout" in Developer Options</span>
</code></pre>
<h3 id="heading-app-not-listed">App Not Listed</h3>
<pre><code class="lang-bash"><span class="hljs-comment"># App must be installed on device</span>
<span class="hljs-comment"># Some system apps may be filtered out</span>
<span class="hljs-comment"># Try searching by exact package name</span>
</code></pre>
<h3 id="heading-preferences-not-updating">Preferences Not Updating</h3>
<pre><code class="lang-bash"><span class="hljs-comment"># Some apps cache preferences - try force-stopping the app</span>
<span class="hljs-comment"># Verify the correct preference file is selected</span>
<span class="hljs-comment"># Check if app is using DataStore vs SharedPreferences</span>
</code></pre>
<hr />
<h2 id="heading-which-version-should-you-choose">Which Version Should You Choose?</h2>
<h3 id="heading-choose-desktop-app-if">Choose Desktop App if:</h3>
<ul>
<li><p>✅ You prefer visual interfaces</p>
</li>
<li><p>✅ You frequently do complex preference debugging</p>
</li>
</ul>
<h3 id="heading-choose-mcp-server-if">Choose MCP Server if:</h3>
<ul>
<li><p>✅ You use AI coding assistants (Copilot, Claude, etc.)</p>
</li>
<li><p>✅ You want to stay in your IDE while testing</p>
</li>
<li><p>✅ You prefer command-line/text-based workflows</p>
</li>
</ul>
<h3 id="heading-why-not-both">Why Not Both?</h3>
<p>Many developers use both versions:</p>
<ul>
<li><p><strong>MCP Server</strong> for quick changes during active development</p>
</li>
<li><p><strong>Desktop App</strong> for detailed debugging sessions and team collaboration</p>
</li>
</ul>
<hr />
<h2 id="heading-performance-impact-and-best-practices">Performance Impact and Best Practices</h2>
<h3 id="heading-performance-considerations">Performance Considerations</h3>
<ul>
<li><p><strong>Minimal Impact</strong>: Reading preferences has negligible performance overhead</p>
</li>
<li><p><strong>Safe Editing</strong>: Type validation prevents crashes from invalid data</p>
</li>
<li><p><strong>Non-Intrusive</strong>: No code changes required in your app</p>
</li>
</ul>
<h3 id="heading-best-practices">Best Practices</h3>
<ol>
<li><p><strong>Backup Important States</strong>: Use the automatic backup feature (only on GUI version) before major changes</p>
</li>
<li><p><strong>Test Edge Cases</strong>: Try invalid values to ensure your app handles them gracefully</p>
</li>
<li><p><strong>Document Configurations</strong>: Save useful preference combinations as presets</p>
</li>
<li><p><strong>Team Standards</strong>: Establish naming conventions for shared preference configurations</p>
</li>
</ol>
<hr />
<h2 id="heading-conclusion-reclaim-your-development-time">Conclusion: Reclaim Your Development Time</h2>
<p>Developer time is precious, and every minute spent waiting for builds is a minute not spent solving real problems. Pref Editor transforms Android preference testing from a time-consuming bottleneck into an instant, seamless process.</p>
<h3 id="heading-what-you-gain">What You Gain:</h3>
<ul>
<li><p><strong>2-5 minutes saved per preference change</strong> (that's hours per week for most developers)</p>
</li>
<li><p><strong>Faster iteration cycles</strong> leading to better-tested features</p>
</li>
<li><p><strong>Reduced context switching</strong> and improved focus</p>
</li>
<li><p><strong>Enhanced debugging capabilities</strong> for preference-related issues</p>
</li>
<li><p><strong>Better collaboration</strong> between developers and QA teams</p>
</li>
</ul>
<h3 id="heading-getting-started-today">Getting Started Today:</h3>
<ol>
<li><p><strong>For GUI lovers</strong>: <a target="_blank" href="https://github.com/charlesmuchene/pref-editor-desktop">Download Pref Editor Desktop</a></p>
</li>
<li><p><strong>For AI enthusiasts</strong>: <a target="_blank" href="https://github.com/charlesmuchene/pref-editor-mcp-server">Install Pref Editor MCP Server</a></p>
</li>
<li><p><strong>For teams</strong>: Try both and see which fits your workflow better</p>
</li>
</ol>
<p>The future of Android development is about removing friction and focusing on what matters: building great user experiences. Pref Editor is your first step toward a more efficient, enjoyable development process.</p>
<p><strong>Ready to revolutionize your Android preference workflow?</strong> Try Pref Editor today and join the developers who've already reclaimed hours of their development time each week.</p>
<p>Happy Androiding! 😎</p>
<hr />
<h2 id="heading-additional-resources">Additional Resources</h2>
<ul>
<li><p><strong>Desktop App Repository</strong>: <a target="_blank" href="https://github.com/charlesmuchene/pref-editor-desktop">Pref Editor Desktop</a></p>
</li>
<li><p><strong>MCP Server Repository</strong>: <a target="_blank" href="https://github.com/charlesmuchene/pref-editor-mcp-server">Pref Editor MCP Server</a></p>
</li>
<li><p><strong>Docker Hub</strong>: <a target="_blank" href="https://hub.docker.com/mcp/server/pref-editor">Pref Editor MCP Server</a></p>
</li>
<li><p><strong>Core Library</strong>: <a target="_blank" href="https://github.com/charlesmuchene/pref-editor-js">Pref Editor Library</a></p>
</li>
<li><p><strong>Issues &amp; Feature Requests</strong>: Contribute to the project's development: <a target="_blank" href="https://github.com/charlesmuchene/pref-editor-desktop/issues">Desktop App</a> / <a target="_blank" href="https://github.com/charlesmuchene/pref-editor-mcp-server/issues">MCP Server</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Iterator Pattern]]></title><description><![CDATA[The Iterator design pattern is a well-known and often-used pattern. It allows us to access elements in a collection without the need to know about the underlying storage details. We get this functionality from an object known as an iterator of the co...]]></description><link>https://charlesmuchene.com/iterator-pattern</link><guid isPermaLink="true">https://charlesmuchene.com/iterator-pattern</guid><category><![CDATA[iterator]]></category><category><![CDATA[Android]]></category><category><![CDATA[Java]]></category><category><![CDATA[Africa]]></category><dc:creator><![CDATA[Charles Muchene]]></dc:creator><pubDate>Thu, 11 May 2023 01:01:33 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/SfPOkp6-2eA/upload/bf27ce5a5ade109b7beac837209df6b5.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The <code>Iterator</code> design pattern is a well-known and often-used pattern. It allows us to access elements in a collection without the need to know about the underlying storage details. We get this functionality from an object known as an <strong>iterator</strong> of the collection.</p>
<p>Different languages support creating iterators when working with collections. Check out <a target="_blank" href="https://charlesmuchene.com/can-i-borrow-the-moved-iterator">this article</a> for an example of using iterators in the Rust language. In the JVM land, a language like Java has the concept of a collections framework. In the framework, we find a <code>Set</code>, a <code>List</code>, and a <code>Deque</code> among other types. All these types define a <a target="_blank" href="https://docs.oracle.com/en/java/javase/20/docs/api/java.base/java/util/Collection.html"><code>Collection</code></a> of elements that can be iterated. Their difference lies in how elements are stored and retrieved.</p>
<p>All Java collections conform to the <a target="_blank" href="https://docs.oracle.com/en/java/javase/20/docs/api/java.base/java/lang/Iterable.html"><code>Iterable</code></a> interface. This interface requires that any object that conforms to it, provide an implementation that will return an instance of an <a target="_blank" href="https://docs.oracle.com/en/java/javase/20/docs/api/java.base/java/util/Iterator.html"><code>Iterator</code></a>:</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Iterator</span>&lt;<span class="hljs-title">E</span>&gt; </span>{

    <span class="hljs-function"><span class="hljs-keyword">boolean</span> <span class="hljs-title">hasNext</span><span class="hljs-params">()</span></span>;

    <span class="hljs-function">E <span class="hljs-title">next</span><span class="hljs-params">()</span></span>;

    ...
}
</code></pre>
<p>The idea behind this definition is that for any iterator, we can:</p>
<ul>
<li><p>Check if there's a next element in the iteration</p>
</li>
<li><p>Ask for the next element</p>
</li>
</ul>
<p>By combining these two operations, we can traverse any generic collection without consideration of how the elements are stored and for any number of elements.</p>
<blockquote>
<p>If we call <code>iterator.hasNext()</code> and it returns <code>false</code>, what happens if we call <code>iterator.next()</code>? 🤔</p>
</blockquote>
<p>While we can directly invoke the above traversal methods to advance an iteration, most JVM languages offer iteration syntactic sugar that <a target="_blank" href="https://docs.oracle.com/javase/specs/jls/se20/html/jls-14.html#jls-14.14.2">decomposes</a> to these calls on an <code>Iterator</code>. Let us consider the following example:</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> numbers = 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-keyword">for</span> (number <span class="hljs-keyword">in</span> numbers) {
        println(number)
    }
}
</code></pre>
<p>The <a target="_blank" href="https://gist.github.com/charlesmuchene/61d868b41f28022f0d1747054b868d55#file-learningiterators-class-L35-L49">byte code</a> result of compiling the above snippet shows a couple of <code>INVOKEINTERFACE</code> calls to methods on the <code>Iterator</code> interface. Decompiling this byte code, we get the stripped-out listing below:</p>
<pre><code class="lang-java">List numbers = CollectionsKt.listOf(<span class="hljs-keyword">new</span> Integer[]{<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>});
Iterator var2 = numbers.iterator();

<span class="hljs-keyword">while</span>(var2.hasNext()) {
  <span class="hljs-keyword">int</span> number = ((Number)var2.next()).intValue();
  System.out.println(number);
}
</code></pre>
<p>We see that the compiler extracts an <code>Iterator</code> from our <strong>numbers</strong> collection and replaces the <em>for-loop</em> construct with a <em>while-loop</em>. It then invokes <code>hasNext()</code> to check the existence of the next element. If this returns true, a call to <code>next()</code> retrieves the next element in the collection and we act on it. These last two steps are executed <code>numbers.size()</code> times. This is the typical use case of the iterator pattern for built-in collection types. Let's look at a use case in Android.</p>
<h2 id="heading-iterating-on-android-fragments">Iterating on Android Fragments</h2>
<p>Android facilitates building UI by composing several standalone UI portions. When we create these modular UI portions, we bind them to a <a target="_blank" href="https://developer.android.com/guide/fragments">Fragment</a> and add these fragment instances to an <a target="_blank" href="https://developer.android.com/guide/components/activities/intro-activities">Activity</a>.</p>
<p>The following snippet shows a method that retrieves ids of all fragments added to an Activity.</p>
<pre><code class="lang-kotlin"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SomeActivity</span> : <span class="hljs-type">AppCompatActivity</span></span>() {

    <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">fragmentIds</span><span class="hljs-params">()</span></span>: List&lt;<span class="hljs-built_in">Int</span>&gt; = 
        supportFragmentManager
            .fragments
            .map(Fragment::getId)
}
</code></pre>
<p>It might not be obvious that the iterator pattern is in use here. But if we dig into the <code>map(...)</code> call, we find that it is an <a target="_blank" href="https://github.com/JetBrains/kotlin/blob/924c28507067cbfbf78a6509ea89eabe496e34ca/libraries/stdlib/common/src/generated/_Collections.kt#L1542-L1550">extension</a> function that iterates and maps elements in an <code>Iterable</code> according to the given transform function. There are a couple more such extensions that add operators applicable to the implementations of <code>Iterable</code>.</p>
<p>As seen, we are oblivious to how the fragments are stored in the <a target="_blank" href="https://developer.android.com/guide/fragments/fragmentmanager">FragmentManager</a>. Our algorithm receives each added fragment, extracts its id, and adds this id to a list of fragment ids. This operation is powered by the iterator pattern.</p>
<h2 id="heading-countries-of-africa">Countries of Africa</h2>
<p>As a final example, let's look at a <a target="_blank" href="https://github.com/charlesmuchene/african-countries">Compose desktop</a> app with a custom implementation of the iterator pattern.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1683399652563/734d3401-344e-46b3-b4b7-7761967b6388.jpeg" alt="https://ontheworldmap.com/africa/africa-political-map.jpg" class="image--center mx-auto" /></p>
<p><a target="_blank" href="https://ontheworldmap.com/africa/africa-political-map.jpg">https://ontheworldmap.com/africa/africa-political-map.jpg</a></p>
<p>The African continent has 54 countries. In our sample code, each country is represented by a couple of properties such as its <em>name</em>, <em>flag</em> etc. We model the continent using a type, <code>Africa</code>, as shown below. By conforming to <code>Iterable</code>, we can iterate through all constituent countries of <code>Africa</code>. We can achieve this by defining an internal iterator, <code>CountryIterator</code>, and returning its instance for a call to <code>iterator()</code> on <code>Africa</code>. In our implementation, we maintain the state of the iteration using the <code>nextIndex</code> property.</p>
<pre><code class="lang-kotlin"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Africa</span></span>(<span class="hljs-keyword">private</span> <span class="hljs-keyword">val</span> countries: Countries) : Iterable&lt;Country&gt; {

    <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">iterator</span><span class="hljs-params">()</span></span>: Iterator&lt;Country&gt; = CountryIterator(countries)

    <span class="hljs-keyword">private</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CountryIterator</span></span>(<span class="hljs-keyword">private</span> <span class="hljs-keyword">val</span> countries: Countries) : Iterator&lt;Country&gt; {

        <span class="hljs-keyword">private</span> <span class="hljs-keyword">var</span> nextIndex = <span class="hljs-keyword">if</span> (countries.isEmpty()) -<span class="hljs-number">1</span> <span class="hljs-keyword">else</span> <span class="hljs-number">0</span>

        <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">hasNext</span><span class="hljs-params">()</span></span>: <span class="hljs-built_in">Boolean</span> = nextIndex <span class="hljs-keyword">in</span> countries.indices

        <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">next</span><span class="hljs-params">()</span></span>: Country {
            <span class="hljs-keyword">if</span> (!hasNext()) <span class="hljs-keyword">throw</span> NoSuchElementException(<span class="hljs-string">"No more countries"</span>)
            <span class="hljs-keyword">return</span> countries[nextIndex].also {
                nextIndex += <span class="hljs-number">1</span>
            }
        }
    }
}
</code></pre>
<p>We then iterate through all countries, adding a corresponding <a target="_blank" href="https://github.com/charlesmuchene/african-countries/blob/main/src/jvmMain/kotlin/UI.kt#L64-L78"><code>CountryRow</code></a> item in the <a target="_blank" href="https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/package-summary#LazyColumn(androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.LazyListState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.foundation.layout.Arrangement.Vertical,androidx.compose.ui.Alignment.Horizontal,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)"><code>LazyColumn</code></a> for each country.</p>
<pre><code class="lang-kotlin">LazyColumn {
    <span class="hljs-keyword">val</span> iterator = africa.iterator()
    <span class="hljs-keyword">while</span> (iterator.hasNext()) {
        <span class="hljs-keyword">val</span> country = iterator.next()
        item(key = country.code) {
            CountryRow(country = country)
        }
    }
}
</code></pre>
<p>This creates the country UI listing as shown:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1683437827954/e559c7ad-fdf9-45e3-bc4d-2ed024c16d3b.png" alt class="image--center mx-auto" /></p>
<p>Get the full source on <a target="_blank" href="https://github.com/charlesmuchene/african-countries">GitHub</a>.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>We can iterate over a collection multiple times, create iterators that mutate the collection, iterate an ordered collection backward and so much more. The iterator pattern is a welcome addition to our set of patterns for software design.</p>
<p>Happy coding!</p>
]]></content:encoded></item><item><title><![CDATA[Composite Pattern]]></title><description><![CDATA[The composite design pattern allows us to create a tree structure of objects. The key idea with the pattern is that given a root component, we can access all nodes in the structure. Such access is granted using a common interface that refers to eithe...]]></description><link>https://charlesmuchene.com/composite-pattern</link><guid isPermaLink="true">https://charlesmuchene.com/composite-pattern</guid><category><![CDATA[Android]]></category><category><![CDATA[view]]></category><category><![CDATA[Kotlin]]></category><category><![CDATA[Composite Design Pattern]]></category><category><![CDATA[Viewgroup]]></category><dc:creator><![CDATA[Charles Muchene]]></dc:creator><pubDate>Mon, 17 Apr 2023 19:46:55 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/w-52qPOBScU/upload/8c12bb5ccc5c6da93851cf83f5505645.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The composite design pattern allows us to create a tree structure of objects. The key idea with the pattern is that given a root component, we can access all nodes in the structure. Such access is granted using a common interface that refers to either of two object types:</p>
<ul>
<li><p>Leaf - a primitive object</p>
</li>
<li><p>Composite - a group of component objects</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1681329559741/e08f9872-3e6f-4178-bf74-4aed60f21799.jpeg" alt class="image--center mx-auto" /></p>
<p>We (mostly) do not care which underlying object type the interface is representing but we can always find out if need be (<em>see bonus example section</em>). As shown in the diagram above, the <em>component</em> is the common interface for accessing the structure. A <em>composite</em> stores instances of child components -- either leaves or other composites.</p>
<p>With the composite pattern, you only need a reference to the root component and with it, you have access to the rest of the tree. Let us look at an implementation of this pattern in Android.</p>
<h2 id="heading-the-android-viewgroup">The Android View(Group)</h2>
<p>From the Android docs on <a target="_blank" href="https://developer.android.com/reference/android/view/View">View</a> and <a target="_blank" href="https://developer.android.com/reference/android/view/ViewGroup">ViewGroup</a>, we derive a visualization similar to the one above:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1681760037067/ddf3d78b-7bff-41ae-926d-f6f50ee3b2ba.jpeg" alt class="image--center mx-auto" /></p>
<blockquote>
<ul>
<li><p><code>View</code> is the base class for building UI elements (the <em>component</em>)</p>
</li>
<li><p>A widget is a view representing an interactive UI component (a <em>leaf</em>)</p>
</li>
<li><p>A <code>Viewgroup</code> is a view representing a container component to hold other <code>View</code>s (the <em>composite</em>)</p>
</li>
</ul>
</blockquote>
<p>We use the relationship described here to create rich Android UIs, comprised of a hierarchy of <code>View</code>s. A subtle but important consequence is that each layout is referenced through a single <code>View</code> instance i.e. the root node of the view tree structure. The Activity class provides a <code>setContentView</code> api that accepts a root <code>View</code> instance for representing its UI.</p>
<pre><code class="lang-kotlin"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TheActivity</span> : <span class="hljs-type">AppCompatActivity</span></span>() {

    <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-comment">// Some inflated view e.g. using viewbinding</span>
        <span class="hljs-keyword">val</span> rootView: View = ...

        setContentView(rootView)
    }
}
</code></pre>
<p>The <code>View</code> argument to the <code>setContentView</code> method could be representing a one-button UI or a whole suite of widget combinations in a UI hierarchy. All the Activity requires is a reference to the root of the view hierarchy.</p>
<p>Consider two xml-based layouts. One has a <strong>TextView</strong> as the only view component in the layout and the other, a <strong>ConstraintLayout</strong> (a <em>ViewGroup</em>) that contains a <strong>TextView</strong>. Inflating each of these layouts in an Activity, we visually get the same UI.</p>
<pre><code class="lang-xml"><span class="hljs-comment">&lt;!-- activity_ui_with_single_widget.xml --&gt;</span>

<span class="hljs-meta">&lt;?xml version="1.0" encoding="utf-8"?&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">TextView</span> <span class="hljs-attr">xmlns:android</span>=<span class="hljs-string">"http://schemas.android.com/apk/res/android"</span>
    <span class="hljs-attr">xmlns:tools</span>=<span class="hljs-string">"http://schemas.android.com/tools"</span>
    <span class="hljs-attr">android:id</span>=<span class="hljs-string">"@+id/textView"</span>
    <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"match_parent"</span>
    <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"wrap_content"</span>
    <span class="hljs-attr">android:gravity</span>=<span class="hljs-string">"center"</span>
    <span class="hljs-attr">android:text</span>=<span class="hljs-string">"@string/app_name"</span>
    <span class="hljs-attr">android:textSize</span>=<span class="hljs-string">"@dimen/textSize"</span>
    <span class="hljs-attr">tools:context</span>=<span class="hljs-string">".MainActivity"</span> /&gt;</span>
</code></pre>
<pre><code class="lang-xml"><span class="hljs-comment">&lt;!-- activity_ui_with_viewgroup --&gt;</span>

<span class="hljs-meta">&lt;?xml version="1.0" encoding="utf-8"?&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">androidx.constraintlayout.widget.ConstraintLayout</span> <span class="hljs-attr">xmlns:android</span>=<span class="hljs-string">"http://schemas.android.com/apk/res/android"</span>
    <span class="hljs-attr">xmlns:app</span>=<span class="hljs-string">"http://schemas.android.com/apk/res-auto"</span>
    <span class="hljs-attr">xmlns:tools</span>=<span class="hljs-string">"http://schemas.android.com/tools"</span>
    <span class="hljs-attr">android:id</span>=<span class="hljs-string">"@+id/container"</span>
    <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"match_parent"</span>
    <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"match_parent"</span>
    <span class="hljs-attr">tools:context</span>=<span class="hljs-string">".MainActivity"</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">TextView</span>
        <span class="hljs-attr">android:id</span>=<span class="hljs-string">"@+id/textView"</span>
        <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"match_parent"</span>
        <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"wrap_content"</span>
        <span class="hljs-attr">android:text</span>=<span class="hljs-string">"@string/app_name"</span>
        <span class="hljs-attr">android:textSize</span>=<span class="hljs-string">"@dimen/textSize"</span>
        <span class="hljs-attr">android:gravity</span>=<span class="hljs-string">"center"</span>
        <span class="hljs-attr">app:layout_constraintBottom_toBottomOf</span>=<span class="hljs-string">"parent"</span>
        <span class="hljs-attr">app:layout_constraintLeft_toLeftOf</span>=<span class="hljs-string">"parent"</span>
        <span class="hljs-attr">app:layout_constraintRight_toRightOf</span>=<span class="hljs-string">"parent"</span>
        <span class="hljs-attr">app:layout_constraintTop_toTopOf</span>=<span class="hljs-string">"parent"</span> /&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">androidx.constraintlayout.widget.ConstraintLayout</span>&gt;</span>
</code></pre>
<p>To render a UI on the screen, the Android framework invokes methods in the <code>View</code> class such as <code>onMeasure</code> and <code>onDraw</code>. These invocations are then dispatched accordingly to all nodes in the tree structure; either to a <strong>Widget</strong> or a <strong>ViewGroup</strong>. This is the composite design pattern in use.</p>
<h2 id="heading-a-bonus-example">A bonus example</h2>
<p>For a bonus example of the composite pattern, let's model a hypothetical representation for a filesystem. (You can find a more robust design in the <a target="_blank" href="https://docs.oracle.com/javase/7/docs/api/java/io/File.html">Java IO package</a>)</p>
<p>A file in our design can be represented as follows:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">sealed</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">File</span> </span>{
    <span class="hljs-keyword">val</span> name: String
}
</code></pre>
<p><code>File</code> is the common interface as laid out in the pattern. We'll keep this interface simple by ignoring other typical file attributes e.g. permissions, extension etc.</p>
<p>For the basic filesystem elements, our design allows for two types of files - a <em>normal</em> and a <em>directory</em> file.</p>
<pre><code class="lang-kotlin"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Normal</span></span>(<span class="hljs-keyword">override</span> <span class="hljs-keyword">val</span> name: String) : File

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Directory</span></span>(
    <span class="hljs-keyword">override</span> <span class="hljs-keyword">val</span> name: String,
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">val</span> files: MutableList&lt;File&gt; = mutableListOf()
) : File, MutableCollection&lt;File&gt; <span class="hljs-keyword">by</span> files
</code></pre>
<p>A <em>normal</em> file's definition is trivial, overriding the required <em>name</em> property as a constructor parameter to conform to the <code>File</code> contract.</p>
<p>The <em>directory</em> file is a tad bit involved but conveniently expressible using <a target="_blank" href="https://kotlinlang.org/">Kotlin</a>. We start by overriding the required <em>name</em> property as a constructor parameter. Since a directory is a mutable collection of other <code>File</code>s, we model it using the <code>MutableCollection</code> interface and delegate the collection's implementation to a <code>MutableList</code> instance. The list instance also facilitates the actual storage of <code>File</code> entries.</p>
<p>The relationship for <code>File</code>, <code>Normal</code> and <code>Directory</code> can be viewed as follows:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1681760048602/d381d8b3-debb-460a-96af-2828f2c30cb6.jpeg" alt class="image--center mx-auto" /></p>
<p>If we are tasked with printing all files for a sample filesystem shown below, our use of the composite design makes it straightforward.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1681760057879/261e600c-8e5f-4b81-94b6-f2da90cf0041.jpeg" alt class="image--center mx-auto" /></p>
<p>Given a starting directory, here's a typical <code>walk</code> implementation:</p>
<pre><code class="lang-kotlin"><span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">walk</span><span class="hljs-params">(file: <span class="hljs-type">File</span>, printer: <span class="hljs-type">Printer</span>)</span></span> {
    <span class="hljs-keyword">if</span> (file !<span class="hljs-keyword">is</span> Directory) <span class="hljs-keyword">return</span> <span class="hljs-comment">// runtime-type-check</span>

    <span class="hljs-keyword">for</span> (child <span class="hljs-keyword">in</span> file) {
        printer.print(child)
        walk(child, printer)
    }
}
</code></pre>
<p>The <code>walk</code> method takes as arguments a <code>File</code> instance and a <code>Printer</code>. In Kotlin, we can <a target="_blank" href="https://kotlinlang.org/docs/typecasts.html">check the type</a> represented by a <code>File</code> instance at runtime using the <code>is</code> operator. This allows for an early return in the method by ignoring <code>Normal</code> files during a recursion as they are not iterable. Each child file in a directory is then printed and then we recurse. Can you work out the output of this algorithm?</p>
<pre><code class="lang-kotlin"><span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-keyword">interface</span> Printer {</span>
    <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">print</span><span class="hljs-params">(file: <span class="hljs-type">File</span>)</span></span>
}
</code></pre>
<p>Using the <code>File</code> type for our printing method, as shown above, we can print any <code>File</code> instance - whether a <em>normal</em> or <em>directory</em> file - as <a target="_blank" href="https://en.wikipedia.org/wiki/Liskov_substitution_principle">Liskov Substitution principle</a> applies. Therefore, given a root directory file, we get access to all files in the tree structure thanks to the composite pattern.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>The composite design pattern is useful for modeling a tree structure where individual objects and composites are treated uniformly. Given a handle to the root node, you can act on all nodes in the structure. This pattern occurs time and again in written software and is a good addition to your software architecture toolbelt.</p>
<p>Happy coding!</p>
<p>Thanks, <a target="_blank" href="https://www.linkedin.com/in/ali-ziwa/">Ali</a> for your review and suggestions.</p>
]]></content:encoded></item><item><title><![CDATA[Can I borrow the Moved Iterator?]]></title><description><![CDATA[The concept of Ownership is no doubt one of Rust's most unique feature. I recently worked on a command line program using Rust and encountered a scenario where I couldn't get Ownership right. In this article, we discuss a similar scenario and my solu...]]></description><link>https://charlesmuchene.com/can-i-borrow-the-moved-iterator</link><guid isPermaLink="true">https://charlesmuchene.com/can-i-borrow-the-moved-iterator</guid><category><![CDATA[Rust]]></category><category><![CDATA[rust lang]]></category><dc:creator><![CDATA[Charles Muchene]]></dc:creator><pubDate>Thu, 06 Apr 2023 20:04:22 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/SCtlFdgTw1A/upload/8f2e9ba57ba7a4d51de69d60f33c7d77.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The concept of <strong>Ownership</strong> is no doubt one of <a target="_blank" href="https://www.rust-lang.org/">Rust</a>'s most unique feature. I recently worked on a <a target="_blank" href="https://charlesmuchene.com/rusty-crates-in-the-cargo">command line program</a> using Rust and encountered a scenario where I couldn't get <em>Ownership</em> right. In this article, we discuss a similar scenario and my solution.</p>
<h2 id="heading-scenario">Scenario</h2>
<p>Say we are required to print all the numbers in a given range. But before printing the last number, output "<em>I knew it was &lt;last-number&gt;!</em>".</p>
<pre><code class="lang-rust"><span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">print_em</span></span>(numbers: Range&lt;<span class="hljs-built_in">u32</span>&gt;) {
    <span class="hljs-keyword">let</span> last = numbers.end;
    <span class="hljs-keyword">for</span> number <span class="hljs-keyword">in</span> numbers {
        <span class="hljs-keyword">if</span> number == last {
            <span class="hljs-built_in">println!</span>(<span class="hljs-string">"I knew last was {}!"</span>, number);
        }
        <span class="hljs-built_in">println!</span>(<span class="hljs-string">"{number}"</span>);
    }
}
</code></pre>
<p>Straightforward! The requirements are changed such that we're given an <code>Iterator</code> instead of a <code>Range</code>. A possible refactor would look like the following:</p>
<pre><code class="lang-rust"><span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">print_em</span></span>(numbers: <span class="hljs-keyword">impl</span> <span class="hljs-built_in">Iterator</span>&lt;Item=<span class="hljs-built_in">u32</span>&gt;) {
    <span class="hljs-keyword">let</span> last = numbers.last().expect(<span class="hljs-string">"No last number"</span>);
    <span class="hljs-keyword">for</span> number <span class="hljs-keyword">in</span> numbers {
        <span class="hljs-keyword">if</span> number == last {
            <span class="hljs-built_in">println!</span>(<span class="hljs-string">"I knew last was {}!"</span>, number);
        }
        <span class="hljs-built_in">println!</span>(<span class="hljs-string">"{number}"</span>);
    }
}
</code></pre>
<p>In this snippet, we change the type of the parameter to an <code>impl Iterator&lt;Item=u32&gt;</code> i.e. any type that implements the <code>Iterator</code> trait with an associated type of <code>u32</code>.</p>
<hr />
<p>Our program, however, fails to compile after this change. To determine the last value, we call <code>numbers.last()</code>. This call <a target="_blank" href="https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html#variables-and-data-interacting-with-move"><strong>moves</strong></a> <code>numbers</code> because we have to <em>consume</em> the iterator to reach the <em>last</em> number. <code>numbers</code> is then invalidated and we cannot use it again. This move is highlighted by the compiler as shown below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1680801624780/dfd8cdbd-75b9-43e1-ac21-5b955df7e58e.png" alt class="image--center mx-auto" /></p>
<p>Is there another way to determine the last item in an iterator without consuming it?</p>
<h2 id="heading-a-peekable-approach">A Peekable approach</h2>
<p>Checking the docs, we find <a target="_blank" href="https://doc.rust-lang.org/std/iter/struct.Peekable.html"><code>Peekable</code></a> - an iterator that wraps another iterator. <code>Peekable</code> provides a <code>peek()</code> method that will return an optional reference to the <code>next()</code> value without advancing the iterator. Hmm. Promising.</p>
<p>Using a <code>Peekable</code> while inside an iteration, we can <code>peek()</code> and inspect the optional. If it is the <code>None</code> variant, then we are in the last iteration. Perfect!</p>
<pre><code class="lang-rust"><span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">print_em</span></span>(numbers: <span class="hljs-keyword">impl</span> <span class="hljs-built_in">Iterator</span>&lt;Item=<span class="hljs-built_in">u32</span>&gt;) {
    <span class="hljs-keyword">let</span> <span class="hljs-keyword">mut</span> peekable = numbers.peekable();
    <span class="hljs-keyword">for</span> number <span class="hljs-keyword">in</span> peekable {
        <span class="hljs-keyword">if</span> <span class="hljs-keyword">let</span> <span class="hljs-literal">None</span> = peekable.peek() {
            <span class="hljs-built_in">println!</span>(<span class="hljs-string">"I knew last was {}!"</span>, number);
        }
        <span class="hljs-built_in">println!</span>(<span class="hljs-string">"{number}"</span>);
    }
}
</code></pre>
<p>Refactor. Save. <code>cargo check</code>. Bam! 🤯</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1680803677285/e36171e5-20dc-4233-9f8a-497dec0a9b0f.png" alt class="image--center mx-auto" /></p>
<p>What now? Another move? Well, I suppose these are common gotchas in Rust. Let's take a closer look at the note in the compiler output:</p>
<blockquote>
<p><code>into_iter</code> takes ownership of the receiver <code>self</code>, which moves <code>peekable</code></p>
</blockquote>
<p>Back in the <a target="_blank" href="https://doc.rust-lang.org/std/iter/index.html#for-loops-and-intoiterator">docs</a>, we look for <code>into_iter()</code>. We learn that in the standard library, all <code>Iterator</code>s implement the <a target="_blank" href="https://doc.rust-lang.org/std/iter/trait.IntoIterator.html"><code>IntoIterator</code></a> trait and just return themselves. Also, when using a <em>for loop</em>, some de-sugaring happens at compile time for implementations of <code>IntoIterator</code> i.e. <code>peekable::into_iter()</code> is called and that moves our <code>peekable</code>!</p>
<p>Recap: we can take a peek into the future but our iterator is consumed by the de-sugar magic. We, therefore, need to get around this <em>move</em> or avoid it altogether. So, what's our next move? 😎</p>
<h2 id="heading-change-the-loop-structure">Change the loop structure</h2>
<p>Rust has three kinds of loops:</p>
<ul>
<li><p><code>for</code> - loop over an iterator -- <em>not suitable for our situation</em> 🙅🏾‍♂️</p>
</li>
<li><p><code>loop</code> - loop forever until we stop it -- <em>a possible solution</em> 🤷🏾‍♂️</p>
</li>
<li><p><code>while</code> - loop while a condition is true -- <em>a better solution</em> 🙋🏾‍♂️</p>
</li>
</ul>
<p>Using a <code>while</code> loop syntax, we can <a target="_blank" href="https://doc.rust-lang.org/book/ch18-00-patterns.html">pattern-match</a> the <code>peekable.next()</code> and bind the value to <code>number</code> in each iteration. With this change, we can iterate over our <code>numbers</code> and <code>peek()</code> to determine if the current number is the last one. Mission accomplished!</p>
<pre><code class="lang-rust"><span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">print_em</span></span>(numbers: <span class="hljs-keyword">impl</span> <span class="hljs-built_in">Iterator</span>&lt;Item=<span class="hljs-built_in">u32</span>&gt;) {
    <span class="hljs-keyword">let</span> <span class="hljs-keyword">mut</span> peekable = numbers.peekable();
    <span class="hljs-keyword">while</span> <span class="hljs-keyword">let</span> <span class="hljs-literal">Some</span>(number) = peekable.next() {
        <span class="hljs-keyword">if</span> <span class="hljs-keyword">let</span> <span class="hljs-literal">None</span> = peekable.peek() {
            <span class="hljs-built_in">println!</span>(<span class="hljs-string">"I knew last was {}!"</span>, number);
        }
        <span class="hljs-built_in">println!</span>(<span class="hljs-string">"{number}"</span>);
    }
}
</code></pre>
<p>The code above is safe, consumes the iterator once and adapts to an iterator of any given number of elements. Bam! 🥳</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Rust, like any language, takes some getting used to. Learning the gotchas, the standard library and, generally, getting a hang of things in an ecosystem. What better way to learn anything than by doing it?</p>
<p>Tip: when working on a project, have a browser tab open at <a target="_blank" href="https://doc.rust-lang.org/std/index.html">https://doc.rust-lang.org/std/index.html</a>. Searching works like a charm and the docs are even more charming!</p>
<p>Happy coding!</p>
]]></content:encoded></item><item><title><![CDATA[Rusty Crates in the Cargo]]></title><description><![CDATA[Rust is the most loved programming language according to this StackOverflow developer survey. From its consistent ranking, 7 years in a row, it seems Rustaceans are benefiting from the performance, reliability and productivity the language provides. ...]]></description><link>https://charlesmuchene.com/rusty-crates-in-the-cargo</link><guid isPermaLink="true">https://charlesmuchene.com/rusty-crates-in-the-cargo</guid><category><![CDATA[Rust]]></category><category><![CDATA[rust lang]]></category><category><![CDATA[Beginner Developers]]></category><dc:creator><![CDATA[Charles Muchene]]></dc:creator><pubDate>Thu, 06 Apr 2023 19:28:44 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/pEK3AbP8wa4/upload/8244425e250ff93293a533ae75d7a93b.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><a target="_blank" href="https://www.rust-lang.org/">Rust</a> is the most loved programming language according to this <a target="_blank" href="https://survey.stackoverflow.co/2022/#most-loved-dreaded-and-wanted-language-love-dread">StackOverflow developer survey</a>. From its consistent ranking, 7 years in a row, it seems <em>Rustaceans</em> are benefiting from the <em>performance</em>, <em>reliability</em> and <em>productivity</em> the language provides. Adoption of the language is on the rise. For instance, the Android Open Source Project now has <a target="_blank" href="https://security.googleblog.com/2022/12/memory-safe-languages-in-android-13.html">some implementations</a> written in Rust and boasts of a decrease in memory safety vulnerabilities. With some time on my hands, let me check out Rust 😎!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1679978179849/a4da95d6-09bc-433e-b38d-383cab031cb9.png" alt="Ferris - the unofficial Rust lang mascot" class="image--center mx-auto" /></p>
<h2 id="heading-rusty-tree">Rusty Tree 🌲</h2>
<p>I created a command line program, <strong>rusty-tree</strong>, that lists the contents of the current directory. The complete <a target="_blank" href="https://github.com/charlesmuchene/rusty-tree">source is on GitHub</a>. When run, you'll get output similar to:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1680711463688/91705c00-48c8-4b8d-a598-18281dee955e.png" alt="rusty-tree output" class="image--center mx-auto" /></p>
<p>If you've worked with <a target="_blank" href="https://www.swift.org/about/">Swift</a>, you'll have some headstart understanding Rust's syntax such as <code>Result&lt;T, E&gt;</code>, <code>associated types</code>, <code>tuples</code>, <code>Option</code>(al), <code>let</code>, <code>mut</code>(ating) <code>struct</code>, <code>Self</code>, <code>references (&amp;)</code>, and <code>reference counting</code>. Most concepts in Rust will be familiar but others are uniquely new. Two Rusty terms useful before proceeding:</p>
<ul>
<li><p><strong>Crate</strong> - is a compilation unit in Rust</p>
</li>
<li><p><strong>Cargo</strong> - is the package manager for Rust</p>
</li>
</ul>
<h3 id="heading-the-entry-point">The Entry Point 🚪</h3>
<pre><code class="lang-rust">...
<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {
    <span class="hljs-keyword">if</span> <span class="hljs-keyword">let</span> <span class="hljs-literal">Err</span>(e) = run() {
        eprintln!(<span class="hljs-string">"Error: {e}"</span>);
        process:exit(<span class="hljs-number">1</span>);
    }
}
</code></pre>
<p>The entry function, <code>main()</code>, for our program aka binary crate is short but packs a lot! It contains an if-control structure but with an unsual syntax for evaluating the condition. This is called <a target="_blank" href="https://doc.rust-lang.org/book/ch18-00-patterns.html">pattern matching</a>. The pattern is <code>Err(e)</code> and is matched against the return value of <code>run()</code>. If the value is an <code>Err</code>, bind the error it contains to a variable <code>e</code> then evaluate the code block.</p>
<p>The function <code>run()</code> returns an instance of an enum <code>Result</code> - either a success (<code>Ok</code>) or a failure (<code>Err</code>). This enumeration is generic over the types of data for either case as shown below:</p>
<pre><code class="lang-rust"><span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-title">Result</span></span>&lt;T, E&gt; {
    <span class="hljs-literal">Ok</span>(T),
    <span class="hljs-literal">Err</span>(E)
}

<span class="hljs-comment">// An example of a function definition that</span>
<span class="hljs-comment">// either returns a success value or an error</span>
<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">a_rust_function</span></span>() -&gt; <span class="hljs-built_in">Result</span>&lt;Success, Error&gt; {
    ...
}
</code></pre>
<p>Note that <code>run()</code> returns a <code>Result</code> - a <a target="_blank" href="https://github.com/charlesmuchene/rusty-tree/blob/b247492b80d1c7d02403a0912cd1d03013710760/src/lib.rs#L99">type alias</a> defined as <code>type Result&lt;T = ()&gt; = std::result::Result&lt;T, RustyError&gt;;</code></p>
<p>Back to <code>main()</code>. <code>e</code> is an instance of <a target="_blank" href="https://github.com/charlesmuchene/rusty-tree/blob/b247492b80d1c7d02403a0912cd1d03013710760/src/error.rs#L9"><code>RustyError</code></a> - a custom error type used in the program. Now to the fun part.</p>
<h3 id="heading-the-heart">The Heart ❤️</h3>
<p>The logic for our <code>rusty-tree</code> program is spread over two functions: <strong>run</strong> and <strong>list</strong>.</p>
<hr />
<ol>
<li><code>run()</code></li>
</ol>
<pre><code class="lang-rust"><span class="hljs-keyword">pub</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">run</span></span>() -&gt; <span class="hljs-built_in">Result</span> {
    printer(<span class="hljs-built_in">String</span>::from(<span class="hljs-string">"."</span>));

    <span class="hljs-keyword">let</span> read_dir = env::current_dir()?.read_dir()?;
    list(read_dir, <span class="hljs-built_in">String</span>::new())?;
    <span class="hljs-literal">Ok</span>(())
}
</code></pre>
<p>We start by printing a "<strong>.</strong>" to denote the current directory. Next, from the process's environment, we grab the current directory and extract an iterator (<a target="_blank" href="https://doc.rust-lang.org/stable/std/fs/struct.ReadDir.html"><code>ReadDir</code></a>) for the directory's contents. We then call <code>list(..)</code> with this iterator and an empty prefix string.</p>
<p>The above function uses a nifty shortcut for propagating errors - the <code>?</code> operator. Remember how errors are handled using <code>Result</code> in Rust? The <code>?</code> operator unwraps the result of a function call, e.g. <code>env::current_dir()</code>, and if it is an <code>Ok</code> it returns the value inside <code>Ok</code>. If it is an <code>Err</code>, it performs an early return of the function in scope propagating the error <code>Result</code> to the caller.</p>
<hr />
<ol>
<li><code>list()</code></li>
</ol>
<p>The listing algorithm is straightforward:</p>
<ul>
<li><p>Given a directory, iterate over its contents</p>
</li>
<li><p>Print each entry found (<em>skipping hidden entries</em>)</p>
</li>
<li><p>If an entry is a directory, repeat these steps</p>
</li>
</ul>
<pre><code class="lang-rust"><span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">list</span></span>(read_dir: ReadDir, prefix: <span class="hljs-built_in">String</span>) -&gt; <span class="hljs-built_in">Result</span> {
    <span class="hljs-keyword">let</span> <span class="hljs-keyword">mut</span> peekable = read_dir
        .filter(|entry| !is_hidden(entry))
        .peekable();

    ...

    <span class="hljs-literal">Ok</span>(())
}
</code></pre>
<p>In the <code>list()</code> function, we filter the entries in the iterator to exclude <a target="_blank" href="https://github.com/charlesmuchene/rusty-tree/blob/3abcd6d0962dfeb2419061241818fcd51a5502a6/src/lib.rs#L79-L91">hidden</a> files. Iterators in Rust are evaluated lazily hence the above snippet just sets up the 'operation pipeline' in preparation for the iteration.</p>
<blockquote>
<p>Curious about <code>peekable()</code>? Check out: <a target="_blank" href="https://charlesmuchene.com/can-i-borrow-the-moved-iterator">Can I borrow the Moved Iterator?</a></p>
</blockquote>
<pre><code class="lang-rust"><span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">list</span></span>(read_dir: ReadDir, prefix: <span class="hljs-built_in">String</span>) -&gt; <span class="hljs-built_in">Result</span> {
    ...
    <span class="hljs-keyword">while</span> <span class="hljs-keyword">let</span> <span class="hljs-literal">Some</span>(entry) = peekable.next() {
        ...
        printer(<span class="hljs-built_in">format!</span>(<span class="hljs-string">"{}{}{}"</span>, prefix, symbol.symbol, file_name));

        <span class="hljs-keyword">if</span> file_type.is_dir() {
            <span class="hljs-keyword">let</span> read_dir = entry.path().read_dir()?;
            <span class="hljs-keyword">let</span> prefix = <span class="hljs-built_in">format!</span>(<span class="hljs-string">"{}{}"</span>, prefix, symbol.separator);
            list(read_dir, prefix)?;
        }
    }
    <span class="hljs-literal">Ok</span>(())
}
</code></pre>
<p>The next implementation is a while loop that iterates as long as <code>peekable.next()</code> yields <code>Some(..)</code> value; <code>entry</code> is bound to the value from the iterator. This is a similar pattern-matching syntax as discussed in the previous section.</p>
<p>In each iteration, we print the filename (along with its prefix) and then check if the current entry is a directory. If it is, <code>entry.path().read_dir()?</code> acquires an iterator for the entry's contents and recursively lists them.</p>
<p>When all entries are printed, <code>list()</code> returns an <code>Ok(())</code> to signal success.</p>
<h3 id="heading-the-run">The Run 🏃🏾‍♂️</h3>
<p>With the algorithm <a target="_blank" href="https://github.com/charlesmuchene/rusty-tree/blob/main/src/lib.rs#L30-L61">implemented</a>, we can invoke <code>cargo r</code> to run the project:</p>
<pre><code class="lang-bash">$ cargo r
.
├── Cargo.toml
├── LICENSE
├── Cargo.lock
├── README.md
└── src
  ├── test.rs
  ├── error.rs
  ├── lib.rs
  └── main.rs
</code></pre>
<p>And to keep test coverage above zero 😀, <code>cargo t</code> yields all green ✅!</p>
<pre><code class="lang-bash">$ cargo t
...
running 3 tests
<span class="hljs-built_in">test</span> <span class="hljs-built_in">test</span>::<span class="hljs-built_in">test</span>::create_filename_symbol ... ok
<span class="hljs-built_in">test</span> <span class="hljs-built_in">test</span>::<span class="hljs-built_in">test</span>::create_last_filename_symbol ... ok
<span class="hljs-built_in">test</span> <span class="hljs-built_in">test</span>::<span class="hljs-built_in">test</span>::extract_filename ... ok

<span class="hljs-built_in">test</span> result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished <span class="hljs-keyword">in</span> 0.00s
</code></pre>
<h3 id="heading-conclusion">Conclusion 🎬</h3>
<p>Programs written in Rust are inspected for correctness at compile time by the <a target="_blank" href="https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html#the-borrow-checker">borrow checker</a>, <a target="_blank" href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/index.html">type checking</a> etc. For example, the Rust compiler will flag the creation of a dangling reference or prevent a data race when using "Safe Rust" - I tried it. I also found the compiler error reporting impressive with the formatting, concise messages, useful hints and error codes to explain an error, usually with an example e.g. <a target="_blank" href="https://doc.rust-lang.org/error_codes/E0384.html">default variable immutability</a>.</p>
<p>Rust is fun, has a steep learning curve, a strict compiler, pleasant docs, unique language concepts, and a cool unofficial mascot. I am interested in it to write software for embedded DIY projects but obviously, it's resourceful for performing a variety of other development tasks.</p>
<p>So, when is the next SO developer survey? 😀</p>
<p>Happy coding!</p>
]]></content:encoded></item><item><title><![CDATA[Template Method Pattern - The ViewModel]]></title><description><![CDATA[In this article, we'll go over the template method pattern and take a look at the Android ViewModel class as an example implementation of the pattern.
The ViewModel
The ViewModel is an application architecture component we've come to love and talk ab...]]></description><link>https://charlesmuchene.com/template-method-pattern-in-the-viewmodel</link><guid isPermaLink="true">https://charlesmuchene.com/template-method-pattern-in-the-viewmodel</guid><category><![CDATA[ViewModel]]></category><category><![CDATA[Android]]></category><category><![CDATA[android app development]]></category><category><![CDATA[design patterns]]></category><dc:creator><![CDATA[Charles Muchene]]></dc:creator><pubDate>Wed, 22 Mar 2023 01:39:28 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/bF2vsubyHcQ/upload/907637c333a59c4b36d690025f740280.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article, we'll go over the template method pattern and take a look at the Android ViewModel class as an example implementation of the pattern.</p>
<h3 id="heading-the-viewmodel">The ViewModel</h3>
<p>The <code>ViewModel</code> is an application architecture component we've come to love and talk about -- <em>VM</em> in MVVM architecture. The Android team has packaged a <a target="_blank" href="https://developer.android.com/reference/androidx/lifecycle/ViewModel">ViewModel</a> in the lifecycle library that we can subclass to model data for our views. From the docs:</p>
<blockquote>
<p>A ViewModel is always created in association with a scope (a fragment or an activity) and will be retained as long as the scope is alive. E.g. if it is an Activity, until it is finished.</p>
</blockquote>
<p>If the ViewModel is created in association with a scope, wouldn't it be nice to know when the scope is destroyed? Well, it is. Enter the Template Method Pattern.</p>
<h3 id="heading-the-template-method-pattern">The Template Method Pattern</h3>
<p>The Template Method Pattern is a behavioral pattern in which a step in an operation is deferred to subclasses - a classic case for code reuse. The superclass defines a "hook" with some default behavior and subclasses can extend it if necessary.</p>
<p>Looking at the definition of the Android <a target="_blank" href="https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:lifecycle/lifecycle-viewmodel/src/main/java/androidx/lifecycle/ViewModel.java;drc=e6343798f327cef0b792e27e6a895d6b7724e45e;l=168">ViewModel</a>, we find a method <code>clear()</code>.</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ViewModel</span> </span>{
    ... <span class="hljs-comment">// other important things</span>

    <span class="hljs-meta">@MainThread</span>
    <span class="hljs-keyword">final</span> void clear() {
        ... <span class="hljs-comment">// omitted clean-up logic</span>
        onCleared();
    }

    <span class="hljs-keyword">protected</span> void onCleared() {
        <span class="hljs-comment">// the hook</span>
    }
}
</code></pre>
<p><code>clear()</code> is invoked to perform clean-up logic and in the end, it calls <code>onCleared()</code>. (<em>clear() is called when ViewModel</em> <a target="_blank" href="https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:lifecycle/lifecycle-viewmodel/src/main/java/androidx/lifecycle/ViewModelStore.kt;drc=187e9a2088c3f281cfb617b9bedd94b9a3546d8b;l=69"><em>scope is destroyed</em></a>)</p>
<p>The default implementation for <code>onCleared()</code> is a no-op in the parent class but the <em>protected</em> keyword in the signature tells us that subclasses can have a go at it - and that's our hook, the template method pattern. Any code you put in the overridden method on a ViewModel subclass will be invoked when the ViewModel's scope is destroyed.</p>
<h3 id="heading-example">Example</h3>
<p>Take an example where you have a <a target="_blank" href="https://github.com/reactive-streams/reactive-streams-jvm/blob/v1.0.4/api/src/main/java/org/reactivestreams/Subscription.java">subscription</a> from some implementation of the <a target="_blank" href="https://github.com/reactive-streams/reactive-streams-jvm#api-components">reactive streams specification</a>. <code>onCleared()</code> then becomes a suitable last-resort callback for canceling the subscription. Thanks to the template method pattern, we know it is invoked when the ViewModel is destroyed.</p>
<pre><code class="lang-kotlin"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PatternViewModel</span> : <span class="hljs-type">ViewModel</span></span>() {
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">val</span> subscription: Subscription = ...

    <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">onCleared</span><span class="hljs-params">()</span></span> {
        subscription.cancel()
    }
}
</code></pre>
<h3 id="heading-conclusion">Conclusion</h3>
<p>Design patterns make the software we write reusable, and clearer to read and maintain. The template method pattern occurs over and over again in production software and is a useful pattern to learn and use.</p>
<p>Happy coding.</p>
]]></content:encoded></item><item><title><![CDATA[The case for Flutter]]></title><description><![CDATA[tldr;
Here's a few hours work -- mostly spent on Flutter's documentation. This' good.

Cross Platform Frameworks
I once, back in 2015, worked with a cross platform framework, Ionic. This was an app rewrite to native Android. That's it. I avoid any wo...]]></description><link>https://charlesmuchene.com/the-case-for-flutter</link><guid isPermaLink="true">https://charlesmuchene.com/the-case-for-flutter</guid><category><![CDATA[iOS]]></category><category><![CDATA[Android]]></category><category><![CDATA[flutter]]></category><dc:creator><![CDATA[Charles Muchene]]></dc:creator><pubDate>Thu, 05 Nov 2020 07:46:07 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1604562459019/eQDJBuPyA.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="tldr">tldr;</h1>
<p>Here's a few hours work -- mostly spent on <code>Flutter</code>'s documentation. This' good.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1604556970197/7oeri1yue.gif" alt="output2.gif" /></p>
<h1 id="cross-platform-frameworks">Cross Platform Frameworks</h1>
<p>I once, back in 2015, worked with a cross platform framework, <a target="_blank" href="https://ionicframework.com">Ionic</a>. This was an app rewrite to native Android. That's it. I avoid any work having to do with React Native, Flutter, Xamarin you name them. See. I have been a  native iOS, Android dev for more than 5 years now and all has been well for me in this arena. Cross platform tech in my (previous) view is slow, cumbersome to work with, little to no support by major IDEs I prefer, you name it. But that's until <code>Flutter</code> came along.</p>
<h1 id="flutter-hints">Flutter hints</h1>
<p>I came across Flutter sometime in 2018. My reaction was, "Yet another cross-platform framework 😏". At that time I was in my second year adopting <code>Kotlin</code> at my workplace and was not about to start looking into Flutter.</p>
<p>Just last week, I was thinking of a hobby app. I use such to hone my development skills but I always do them in 2s: <strong>iOS</strong> (Swift, Xcode and all), then <strong>Android</strong> (Kotlin, Studio and all). This takes quite some time, as you can imagine, but in the end it's always worthwhile. This time it was different. I wanted an app done -- and fast. Enter <code>Flutter</code>.</p>
<p>One codebase for multiple target platforms is something we've always wanted on mobile -- think what <code>Java</code> did for desktop. And Flutter seems to have nailed it. Or put differently, caught my attention.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1604515095093/B07wepXxy.png" alt="flutter_logo.png" /></p>
<h1 id="the-framework">The framework</h1>
<p>It's been a couple of days playing around with the framework and here are my thoughts.</p>
<ul>
<li><p><strong>Dart</strong>.
What a language! Derives a lot from other modern languages. Feels 'fluid' like Javascript, but it's statically typed. It's functional, object oriented, imperative with support for both <strong>AOT</strong> (Ahead of Time) and <strong>JIT</strong> (Just in Time) compilation. I'll mention more in the Dart section later in this article.</p>
</li>
<li><p><strong>Minimalist structure</strong></p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1604515825158/Mvo_VHc1X.png" alt="Screen Shot 2020-11-04 at 9.45.33 hwa-inī.png" />
A Flutter project is configured using a yaml file: <code>pubspec.yaml</code>. Assets e.g. images, fonts, sdk, dependencies, project name, description are all declared here. One wonderful thing about the project structure is that you work on the <code>lib</code> directory for the majority of the time.</p>
<p>CLI commands are concise too.</p>
<pre><code>$ flutter create amazing_app

$ flutter run
</code></pre><p>There's a common phrase in the Flutter community:</p>
<blockquote>
<p>Everything is a widget.</p>
</blockquote>
<p>How minimalist can it get than that? Flutter is a UI framework and you'll be working with widgets a lot!</p>
<ul>
<li><p><strong>Composition over Inheritance</strong>.
This was a favourite discussion point to ask in screening interviews. Let Flutter teach you. The fundamental idea of <code>composition</code> is to <em>promote reusability and enhance decoupling</em> in your codebase.
From the sdk itself to the framework API, Flutter is built with composition in mind. Say you need to display a list item for your app. Compose it from widgets. What will be the body of my new awesome screen? You got it. Any widget courtesy of composition!
This doesn't mean there's no inheritance. In fact you will often be extending some existing common widgets: <code>StatefulWidget</code> and <code>StatelessWidgets</code>. But the core design of the framework embraces composition to give you control.</p>
</li>
<li><p><strong>IDE support</strong>.
Through the power of plugins, Flutter development is a breeze in VS Code, Android Studio (and IntelliJ) and even on Emacs! The plugins provide formatting, hot reloading, common Flutter code snippets, debugging tools etc.</p>
</li>
</ul>
<p>Flutter is a welcome addition to my tools. Expressive UI, native performance and fast development are some of the biggest benefits you get from it. Learn more at the official <a target="_blank" href="https://flutter.dev/">website</a>.</p>
<h1 id="dart">Dart</h1>
<p>Dart is brilliant. Having done some <em>Javascript</em>, <em>Swift</em>, <em>Java</em>, <em>Kotlin</em>, <em>Typescript</em>, I can appreciate the effort by the language developers in making a modern language. (I'll also use these languages as my references in this section).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1604517654048/l-QL_qVO4.png" alt="dart_logo.png" /></p>
<p>Some of the key language highlights I have come across are:</p>
<ul>
<li><p><strong>Type inference</strong>.
Every modern language needs to have this feature in my opinion. Compilers are becoming smarter with every release. Dart uses the <code>var</code>, <code>final</code>, <code>const</code> keywords to declare a variable. If the context has enough information, it will infer the correct type. You can always provide an explicit type or use casting to disambiguate.</p>
</li>
<li><p><strong>First class functions</strong>.
Dart supports higher order functions with the <code>Function</code> type to represent functions. Single expression functions have a special syntax similar to Kotlin's.</p>
</li>
<li><p><strong>Generics</strong>.
Of course. 🙈</p>
</li>
<li><p><strong>Extension methods</strong>.
Swift and Kotlin come to mind. This is the ability of Dart to add a method on an <a target="_blank" href="https://dart.dev/guides/language/extension-methods">existing type</a>.</p>
</li>
<li><p><strong>Null safety</strong>.
As of the time of writing, this feature of the Dart's type system is in tech preview. The implementation is familiar to Kotlin or Swift users -- types in your code are <em>non-nullable by default</em>. You explicitly declare the nullability of a type using a <code>?</code> after the type e.g. <code>int?</code>. More information <a target="_blank" href="https://dart.dev/null-safety">here</a>.</p>
</li>
<li><p><strong>Built-in concurrency</strong>.
Dart has <code>async-await</code> keywords and <em>then-able</em> <code>Futures</code> that allow us to write asynchronous code.</p>
<pre><code>Future&lt;<span class="hljs-built_in">num</span>&gt; derivePlanksConstant(energy, frequency) <span class="hljs-keyword">async</span> =&gt; <span class="hljs-comment">/* Ask the universe. */</span>;
</code></pre><p>Streams, json de/encoding, HttpServer 😱, math library, collections, a whole html library and so much more. More on a <a target="_blank" href="https://dart.dev/guides/libraries/library-tour">tour</a> of Dart's libraries.</p>
</li>
</ul>
<h1 id="grimacing-points">Grimacing points 😬</h1>
<p>Finally, here's a rant on not-so-good things from both Flutter and Dart.</p>
<ul>
<li><p><strong>State</strong>! State is cumbersome to write and understand on the first run. I've found IDEs helpful with the restructuring to accommodate state. </p>
<blockquote>
<p>Disclaimer: I have found out that understanding under-the-hood working of Flutter clarifies why state is implemented this way -- widgets are just blueprints for what to render and state is stored by element in the element tree and not the widget in the widget tree).</p>
</blockquote>
</li>
<li><p><strong>Underscore for private scope</strong>. Seriously Dart?</p>
</li>
<li><p><strong>Native platform UI</strong>. Flutter controls every pixel by drawing on a canvas. If you need a native platform there's some work on your side. Some widgets are adaptive eg. Switch but still you have to explicitly ask it to adapt to the platform look. In fact, the nature of the platform widgets comes from the material theming. For iOS look and feel, you need to use Cupertino widgets (Cupertino because of trademark issues I presume).</p>
</li>
<li><p><strong>Semicolons</strong>. I have to include this. Having written quite some Swift code of late, I'm finding myself forgetting the semicolon a lot. This' not a deal-breaker though. We've had a lot more Java days.</p>
</li>
</ul>
<h1 id="conclusion">Conclusion</h1>
<p>Love them, hate them, cross platform frameworks have done well for themselves. Addition of Flutter to the list by a tech giant only suggests there's a need and freelance opportunities online tell the same story.</p>
<p>The speed at which you can spin up an app for both platforms using Flutter is just mind blowing! Having done native development for both iOS and Android, I can appreciate the niche this framework is addressing. </p>
<p>What can I say?</p>
<blockquote>
<p>Welcome <code>Flutter</code> to my toolbelt. </p>
</blockquote>
<p>Have a project? Let's <a target="_blank" href="https://www.linkedin.com/in/charlesmuchene">connect</a>.</p>
<p>Happy coding! 😎</p>
<h1 id="references">References</h1>
<ul>
<li><p><a target="_blank" href="https://flutter.dev">Flutter</a></p>
</li>
<li><p><a target="_blank" href="https://dart.dev">Dart</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[The Raspberry Pi Internet Speed Test]]></title><description><![CDATA[Results here.
Project not running? I've probably turned off the Pi or using it for another project. Source code: https://github.com/charlesmuchene/speedtest

RaspberryPi
A RaspberryPi is a credit card sized computer: a favorite for hobby electronics ...]]></description><link>https://charlesmuchene.com/the-raspberry-pi-internet-speed-test</link><guid isPermaLink="true">https://charlesmuchene.com/the-raspberry-pi-internet-speed-test</guid><category><![CDATA[Raspberry Pi]]></category><dc:creator><![CDATA[Charles Muchene]]></dc:creator><pubDate>Mon, 26 Oct 2020 06:50:31 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1602875076373/3_QRFTZyE.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p>Results <a target="_blank" href="https://a579956ef857.ngrok.io">here</a>.
Project not running? I've probably turned off the Pi or using it for another project. Source code: https://github.com/charlesmuchene/speedtest</p>
</blockquote>
<h1 id="raspberrypi">RaspberryPi</h1>
<p>A <a target="_blank" href="https://www.raspberrypi.org">RaspberryPi</a> is a credit card sized computer: a favorite for hobby electronics or just a plain computer to play around with. For this article, I choose the latter.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602875039021/a0v0JrOsp.png" alt="rasppi.png" /></p>
<h1 id="primer">Primer</h1>
<p>Working from home in 2020 has come with its own requirements, one being a stable internet connection. Freezing in a zoom call or missing the last part of a meeting has nothing but frustrated those of us in never ending meetings for work, study, meets etc. I wanted to do a speed test on my ISP's service.
My go to service for such tests if <a target="_blank" href="https://fast.com">fast.com</a>. It has been reliable and quite accurate but I have to continuously reload the browser and record my speeds. However, I recently learnt of <a target="_blank" href="https://www.speedtest.net">speedtest.net</a>, quite an intuitive name. In addition to the browser (and other clients), <code>speedtest</code> has a CLI client. Perfecto! 🎉</p>
<p>Enough chat. Let's build this.</p>
<h1 id="the-project">The Project</h1>
<p>To run a speed test, we need our computer setup.</p>
<h2 id="the-pi">The Pi</h2>
<p>My Raspberry is a Pi 3 Model with a Quad Core 1.2GHz Broadcom BCM2837 64bit CPU, and 1GB RAM. Not bad at all for this project. Check out the full specs on the <a target="_blank" href="https://www.raspberrypi.org/products/raspberry-pi-3-model-b">official website</a>. It had a 16GB sdcard running Android Things OS for a previous project I did in 2018 on <a target="_blank" href="https://github.com/charlesmuchene/adb">Android Debug Bridge</a>. This had to go out and in came Raspberry Pi OS.
The Pi organization has a new way of burning the OS on an sdcard: the <code>Raspberry Pi Imager</code>. Let's give this a try.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1603649077234/rpE1QvaL5.png" alt="Screen Shot 2020-10-10 at 5.11.23 hwa-inī.png" /></p>
<p>I chose a headless version of the OS as I don't need the desktop -- who needs one? 😀. This is suitable for my use case, SSHing and terminal work, and above all, a lightweight download, 400MB.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1603649112106/ZcH3-KvGH.png" alt="Screen Shot 2020-10-10 at 5.11.37 hwa-inī.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1603649421024/18gMoLUMv.png" alt="Screen Shot 2020-10-10 at 5.43.08 PM.png" /></p>
<p>After a few minutes, the download completes, verified and ready for us to boot the Pi.</p>
<h3 id="configuration">Configuration</h3>
<p>The installed Raspberry Pi OS is a port of Debian and thus with a quick search online, you can get anything up and running.
As my Pi is headless, I added empty file to the boot partition named <code>ssh</code> to enable ssh. I followed this awesome, quick help on the <a target="_blank" href="https://www.raspberrypi.org/documentation/remote-access/ssh">official website</a>. With this in place, I boot the Pi and plugin an ethernet cable from my home router.</p>
<p>Next, we need a way to 'get into the Pi'. To find out its address, I used <a target="_blank" href="https://www.raspberrypi.org/documentation/remote-access/ip-address.md">this</a> quick help. My Pi version runs an mDNS, and thus with just a ping to <code>raspberrypi.local</code>, voila! Address resolved!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1603650251452/FL4BcaR58.png" alt="Screen Shot 2020-10-25 at 9.23.53 hwa-inī.png" /></p>
<p>Having to plugin the Pi to the router for configuration and internet access is tedious and obviously limiting on the location you can place it. A quick search on the official website, I find a short article on enabling wireless access <a target="_blank" href="https://www.raspberrypi.org/documentation/configuration/wireless/wireless-cli.md">here</a>. Now we are one wire-less.</p>
<h2 id="tools">Tools</h2>
<p>SSHing into the Pi, I run an update on the OS and installed some tools. Here's the fun part.</p>
<h3 id="ooklas-speedtest">Ookla's speedtest</h3>
<p>The <a target="_blank" href="https://www.speedtest.net/apps/cli">instructions</a> on their website are sufficient to have the cli tool up and running on the Pi. After installation, a quick run of <code>speedtest</code> on the Pi's terminal seems to do the job.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1603652048962/4K2njW_c-.png" alt="Screen Shot 2020-10-25 at 9.50.36 hwa-inī.png" /></p>
<p><code>Speedtest</code>'s cli client is suitable for my use since I can launch it using a bash script. In addition, the tool has different options on the output of the test with the default one, <strong>human readable format</strong> (shown above) being good enough for me. But I'll have to parse this to extract the interesting parts. More on this later.</p>
<h3 id="the-cronjob">The cronjob</h3>
<p>I wrote a short script to run the speedtest after every 10 mins for 1 week then killed the job. <a target="_blank" href="https://crontab.guru/#*/10_*_*_*_*">Crontab guru</a> can help you out on this.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1603690086662/waiiVKM_Z.png" alt="Screen Shot 2020-10-25 at 10.35.50 hwa-inī.png" /></p>
<p>For reference here's the <code>speed.sh</code>. It executes the <code>speedtest</code> and appends a stripped down version of the output to a file.</p>
<pre><code><span class="hljs-comment">#!/bin/bash</span>

output_file=~/internet/result
output=$((speedtest | tail -n <span class="hljs-number">5</span>) <span class="hljs-number">2</span>&gt;&amp;<span class="hljs-number">1</span>)
url=$((<span class="hljs-keyword">echo</span> <span class="hljs-string">"<span class="hljs-subst">$output</span>"</span> | tail -n <span class="hljs-number">1</span> | cut -d / -f <span class="hljs-number">6</span>) <span class="hljs-number">2</span>&gt;&amp;<span class="hljs-number">1</span>)
output=$((<span class="hljs-keyword">echo</span> <span class="hljs-string">"<span class="hljs-subst">$output</span>"</span> | head -n <span class="hljs-number">4</span>) <span class="hljs-number">2</span>&gt;&amp;<span class="hljs-number">1</span>)
<span class="hljs-keyword">echo</span> &gt;&gt; $output_file
<span class="hljs-keyword">echo</span> <span class="hljs-string">"**********************************************"</span> &gt;&gt; $output_file
<span class="hljs-keyword">echo</span> $(date) &gt;&gt; $output_file
<span class="hljs-keyword">echo</span> <span class="hljs-string">"**********************************************"</span> &gt;&gt; $output_file
<span class="hljs-keyword">echo</span> <span class="hljs-string">"<span class="hljs-subst">$output</span>"</span> &gt;&gt; $output_file
<span class="hljs-keyword">echo</span> <span class="hljs-string">"Url: <span class="hljs-subst">$url</span>"</span> &gt;&gt; $output_file
</code></pre><h3 id="node-js">Node Js</h3>
<p>Next, I install <a target="_blank" href="https://nodejs.org">Node Js</a>. I use it to parse the output file of the speedtest in to the respective parts: <code>download</code>, <code>upload</code>, <code>loss</code> and <code>latency</code>.</p>
<pre><code><span class="hljs-keyword">const</span> { EOL } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'os'</span>);
<span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);
<span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>);

<span class="hljs-keyword">let</span> latencyRegex = <span class="hljs-regexp">/latency:\s+(\d{1,3}\.\d{1,2})/gi</span>;
<span class="hljs-keyword">let</span> downloadRegex = <span class="hljs-regexp">/download:\s+(\d{1,3}\.\d{1,2})/gi</span>;

...

<span class="hljs-keyword">const</span> inputStream = fs.createReadStream(path.join(__dirname, <span class="hljs-string">'result'</span>)).setEncoding(<span class="hljs-string">'utf-8'</span>);
inputStream.on(<span class="hljs-string">'data'</span>, <span class="hljs-function">(<span class="hljs-params">chunk</span>) =&gt;</span> {
    <span class="hljs-keyword">let</span> text = Buffer.from(chunk).toString(<span class="hljs-string">'utf-8'</span>);

...

    [ timeRegex, latencyRegex, downloadRegex, uploadRegex, lossRegex ].forEach(<span class="hljs-function">(<span class="hljs-params">regex</span>) =&gt;</span>
        populateData(text, regex, currentLastIndex, data)
    );

    <span class="hljs-comment">// Write data to file</span>
    outputStream.write(data.flatMap(<span class="hljs-function">(<span class="hljs-params">element</span>) =&gt;</span> element.join()).join(EOL));

    <span class="hljs-comment">// If out of bounds, flush back to readstream</span>
    <span class="hljs-keyword">if</span> (chunk.length - currentLastIndex &gt; <span class="hljs-number">0</span>) inputStream.unshift(text.substring(currentLastIndex), <span class="hljs-string">'utf-8'</span>);
});

inputStream.on(<span class="hljs-string">'end'</span>, <span class="hljs-function">() =&gt;</span> {
    inputStream.close();
    ...
});

inputStream.on(<span class="hljs-string">'error'</span>, <span class="hljs-built_in">console</span>.log);

...
</code></pre><p>The complete script can be found at <code>play.js</code> on this project's repository here: https://github.com/charlesmuchene/speedtest.</p>
<h3 id="lighttpd">Lighttpd</h3>
<p>For presentation, I wanted access on the browser. I installed <a target="_blank" href="https://www.lighttpd.net">Lighttpd</a>, a lightweight server with a small memory footprint to serve the files of the project - a html file, a js file and the parsed output from the above operation.
For the results, I chose to draw a line graph depicting the performance of my connection using <a target="_blank" href="https://d3js.org">D3</a> -- a popular Js lib for graphing.</p>
<pre><code><span class="hljs-keyword">let</span> svg = d3
        .select(<span class="hljs-string">`#data<span class="hljs-subst">${index}</span>`</span>)
        .append(<span class="hljs-string">'svg'</span>)
...
            svg
                .append(<span class="hljs-string">'path'</span>)
                .datum(data)
                .attr(<span class="hljs-string">'fill'</span>, <span class="hljs-string">'none'</span>)
                .attr(<span class="hljs-string">'stroke'</span>, colors[index])
                .attr(<span class="hljs-string">'stroke-width'</span>, <span class="hljs-number">1.5</span>)
                .attr(<span class="hljs-string">'d'</span>, d3.line().x(<span class="hljs-function">(<span class="hljs-params">d</span>) =&gt;</span> x(d.x)).y(<span class="hljs-function">(<span class="hljs-params">d</span>) =&gt;</span> y(d.y[index])));
...
        }
    );
</code></pre><p>The complete file is available <a target="_blank" href="https://github.com/charlesmuchene/speedtest/blob/main/data.js">here</a></p>
<h3 id="remote-access">Remote Access</h3>
<p>Whenever I want to tunnel into my local system, I go for <a target="_blank" href="https://ngrok.com">ngrok</a>. This' perfect to show you my results.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1603692983662/tuyNxhm8k.png" alt="Screen Shot 2020-10-26 at 9.16.03 ruc-inī.png" /></p>
<h1 id="results">Results</h1>
<p>If all goes well, you can check the fruits of your labor from your ngrok's public url: mine is <a target="_blank" href="https://a579956ef857.ngrok.io">here</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1603693127091/iqbju_221.png" alt="Screen Shot 2020-10-26 at 9.18.22 ruc-inī.png" /></p>
<p>From these results, it looks like my connection is quite unstable.</p>
<blockquote>
<p>PS: Sending this to my ISP for reimbursement 😁</p>
<p>The speeds in the resulting project are not hypothetical and don't come cheap where I live. But you're reading of a successful project, no? 🤷🏾‍♂️</p>
</blockquote>
<h1 id="conclusion">Conclusion</h1>
<p>This was fun for me to do. I ended up adding some LEDs to show when my server was online. But it'd be interesting to blink an LED for every http request. Anyways, you can do so much more with a Pi. Check online tutorials and DIYs for more.</p>
<p>Happy tinkering/coding!</p>
<h1 id="references">References</h1>
<ul>
<li><p><a target="_blank" href="https://github.com/charlesmuchene/speedtest">Source Code</a></p>
</li>
<li><p><a target="_blank" href="https://www.raspberrypi.org">Raspberry Pi</a></p>
</li>
<li><p><a target="_blank" href="https://www.speedtest.net">speedtest.net</a></p>
</li>
<li><p><a target="_blank" href="https://nodejs.org">Node Js</a></p>
</li>
<li><p><a target="_blank" href="https://d3js.org">D3</a></p>
</li>
<li><p><a target="_blank" href="https://ngrok.com">Ngrok</a></p>
</li>
<li><p><a target="_blank" href="https://crontab.guru/#*/10_*_*_*_*">Crontab Guru</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Optional of an Optional]]></title><description><![CDATA[During a recent debugging session, I came across an Optional of an Optional of an entity. 😱 Well, I've read about this in theory but experiencing it in practice is definitely interesting. Intro first.
Optional Basics
Optional is a (generic) type tha...]]></description><link>https://charlesmuchene.com/optional-of-an-optional</link><guid isPermaLink="true">https://charlesmuchene.com/optional-of-an-optional</guid><category><![CDATA[Swift]]></category><category><![CDATA[iOS]]></category><dc:creator><![CDATA[Charles Muchene]]></dc:creator><pubDate>Thu, 10 Sep 2020 16:47:41 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1599756446947/7o-ancCxU.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>During a recent debugging session, I came across an <code>Optional</code> of an <code>Optional</code> of an entity. 😱 Well, I've read about this in theory but experiencing it in practice is definitely interesting. Intro first.</p>
<h1 id="optional-basics">Optional Basics</h1>
<p>Optional is a (generic) type that is used to represent the <em>presence</em> or <em>absence</em> of a value. Here's its declaration:</p>
<pre><code>@frozen
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-title">Optional</span>&lt;<span class="hljs-title">Wrapped</span>&gt;: <span class="hljs-title">ExpressibleByNilLiteral</span> </span>{
  <span class="hljs-comment">/// The absence of a value.</span>
  <span class="hljs-keyword">case</span> <span class="hljs-keyword">none</span>

  <span class="hljs-comment">/// The presence of a value, stored as `Wrapped`.</span>
  <span class="hljs-keyword">case</span> some(<span class="hljs-type">Wrapped</span>)

  ... 
}
</code></pre><blockquote>
<p>I've left out some method definitions in the type such as <code>map</code>, <code>flatMap</code> etc along with a couple of its extensions.</p>
</blockquote>
<p><code>@frozen</code> is a Swift attribute that guarantees no further cases will be added (removed or reordered) on the enum declaration (This facilitates some compiler optimizations and allows a user to perform an exhaustive matching on the cases with no need for a default/'unknown' case check. For more info, check out <a target="_blank" href="https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md">this</a> and <a target="_blank" href="https://github.com/apple/swift-evolution/blob/master/proposals/0260-library-evolution.md">this</a> Swift Evolution proposal).
<code>Wrapped</code> is the generic type to be wrapped by the Optional.
<code>ExpressibleByNilLiteral</code> conformance denotes that this type that can be initialized using the nil literal, <code>nil</code>.</p>
<p>Before continuing with our discussion, it's important to mention that the Optional type gets some extra compiler love:</p>
<ul>
<li>A trailing question mark (<code>?</code>) on a type is treated as an Optional wrapping that type. This eases <em>reading</em> and <em>writing</em> Optionals in code. For instance, the following two declarations are the same.</li>
</ul>
<p>--&gt; <code>let optionalString: Optional&lt;String&gt; = nil</code></p>
<p>--&gt; <code>let optionalString: String? = nil</code></p>
<ul>
<li><code>If let</code>, <code>while let</code>, <code>guard</code> statements can evaluate the Optional and control program flow based on the <em>presence</em> or <em>absence</em> of the wrapped value.</li>
<li>Sending a message to an Optional that represents an absence of a value results in a no-op e.g. <code>optionalString?.removeAll()</code> does nothing if <code>optionalString</code> is <code>nil</code>.</li>
<li>Checking for equality with an Optional type (where <code>Wrapped</code> conforms to <code>Equatable</code>) promotes the non-optional value to an optional to make the types e.g. <code>nonOptionalString == optionalString</code> works out of the box.</li>
</ul>
<p>These and many other nifty 'tricks' make working with Optional beautiful in Swift.</p>
<h1 id="optional-of-an-optional">Optional of an Optional</h1>
<p>Being a generic, Optional can thus be over any type including another Optional something like <code>Optional&lt;Optional&lt;String&gt;&gt;</code> aka <code>String??</code>. </p>
<p>Take an example of the following declaration. What's the type of <code>languages</code>?</p>
<pre><code><span class="hljs-keyword">let</span> languages = [<span class="hljs-string">"Swift"</span>, <span class="hljs-string">"Kotlin"</span>, <span class="hljs-literal">nil</span>, <span class="hljs-string">"Rust"</span>]
</code></pre><p>A quick glance would yield an assumption of <code>Array&lt;Any&gt;</code> but on closer inspection, we note that it's intuitive for the compiler to  infer <code>Array&lt;Optional&lt;String&gt;&gt;</code> aka <code>Array&lt;String?&gt;</code> of which it does. </p>
<p>What's the type of <code>first</code> here <code>let first = languages.first</code>? </p>
<p>Now you've got it. It's a <code>Optional&lt;Optional&lt;String&gt;&gt;</code>. </p>
<p>Here's my attempt to explain. An element of the <code>languages</code> array is an Optional wrapping a string. The <code>first</code> property of an array (declared as <code>public var first: Element? { get }</code>) yields an Optional wrapping the <code>Element</code> -- the single type held by the array. In our case, it's an Optional wrapping a String and hence we get <code>Optional&lt;Optional&lt;String&gt;&gt;</code> 🤯!</p>
<p>Therefore, in the snippet below, you need to be aware that <em>print</em> is working with an <code>Optional&lt;String&gt;</code> (from reasons mentioned so far).</p>
<pre><code><span class="hljs-keyword">guard</span> <span class="hljs-keyword">let</span> first = languages.first <span class="hljs-keyword">else</span> { <span class="hljs-keyword">return</span> }

<span class="hljs-built_in">print</span>(first)
</code></pre><p>In many cases, the compiler will emit warnings and offer fixes such as:
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1599753543784/x3EGPEOve.png" alt="Screen Shot 2020-09-10 at 6.52.32 hwa-inī.png" /></p>
<p>or subtle ones like the following (<em>NB: <code>self.deserializeEntity(from:)</code> returns a <code>T?</code></em>):
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1599753566164/VQt3GOXYa.png" alt="Screen Shot 2020-09-10 at 6.54.54 hwa-inī.png" /></p>
<h1 id="conclusion">Conclusion</h1>
<p>And there you have it. Optionals make representing absence of a thing intuitive in Swift and have many uses such as in collections to denote a sentinel value when retrieving an element or during iteration. Being a generic, Optionals can be over any type including a couple of optionals such as <code>String?????</code> -- which is the valid, rather unuseful, type: <code>Optional&lt;Optional&lt;Optional&lt;Optional&lt;Optional&lt;String&gt;&gt;&gt;&gt;&gt;</code>.</p>
<p>Anyways. You get the idea. 🙈</p>
<pre><code><span class="hljs-keyword">let</span> signOut: <span class="hljs-type">String?</span> = <span class="hljs-string">"Happy Coding!"</span>

<span class="hljs-built_in">print</span>(signOut!)
</code></pre><h1 id="references">References</h1>
<ul>
<li><a target="_blank" href="https://github.com/apple/swift-evolution">Swift Evolution</a></li>
<li><a target="_blank" href="https://github.com/apple/swift/tree/master/stdlib/public/core">Swift Core Lib</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Attribute it to...]]></title><description><![CDATA[(Reader beware: The use of @ doesn't constitute links to Twitter handles or Hashnode mentions 🤕)
Attributes
A Swift attribute attributes a declaration or type. Seriously. Merriam Webster defines an attribute as a quality, character, or characteristi...]]></description><link>https://charlesmuchene.com/attribute-it-to</link><guid isPermaLink="true">https://charlesmuchene.com/attribute-it-to</guid><category><![CDATA[iOS]]></category><category><![CDATA[Swift]]></category><dc:creator><![CDATA[Charles Muchene]]></dc:creator><pubDate>Thu, 02 Jul 2020 16:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1593668027663/9VwmAGleb.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>(<strong>Reader beware</strong>: The use of <code>@</code> doesn&#39;t constitute links to Twitter handles or Hashnode mentions 🤕)</p>
<h1 id="attributes">Attributes</h1>
<p>A Swift attribute attributes a declaration or type. Seriously. Merriam Webster defines an attribute as a <em>quality, character, or characteristic ascribed to someone or something</em>. Therefore, as such, we have something in our program say a declaration and we&#39;d like to annotate it.</p>
<p>The Swift documentation has the following to say:</p>
<blockquote>
<p>A Swift attribute provides more information about a declaration or type.</p>
</blockquote>
<p>Swift attributes are very similar to annotations in other languages. It&#39;s a form of providing metadata to your programs. Attributes serve different purposes but in the end, they are just instructions for the compiler.</p>
<h2 id="syntax">Syntax</h2>
<p>An attribute is specified by prefixing it&#39;s name with an <code>@</code> symbol e.g. <code>@State</code>. Some attributes accept arguments to provide more information on their functionality with the following syntax: <code>@attribute(arguments)</code>.</p>
<p>Swift has 2 categories of attributes:</p>
<ul>
<li><strong>Type</strong>: this kind is applicable to types only</li>
<li><strong>Declaration</strong>: applies to declarations only</li>
</ul>
<h1 id="sample-attributes">Sample attributes</h1>
<p>Let&#39;s look at a few attributes you might might be familiar with.</p>
<h2 id="discardableresult">discardableResult</h2>
<p>I think this was my first attribute to write (so I write it first 😎). This attribute is used to suppress the compiler&#39;s warning when we don&#39;t use the result of a function/method call that returns a value.</p>
<p>Say we have a method to start a poll that returns a boolean to indicate whether the polling process started successfully or not. Furthermore, for some particular invocations, we do not care about this return value. If we ignore the return value of the call, we get the following compile time warning:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1593677501651/zsfr-MVeY.png" alt="Screen Shot 2020-07-02 at 11.11.08 ruc-inī.png"></p>
<p>To inform the compiler we sometimes don&#39;t care about the returned result, we attribute the <em>poll</em> method with <code>@discardableResult</code>.</p>
<pre><code><span class="hljs-meta">@discardableResult</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">poll</span><span class="hljs-params">()</span></span> -&gt; <span class="hljs-type">Bool</span> {
    ...
}

<span class="hljs-comment">// call site</span>
poll() <span class="hljs-comment">// no compiler warning reported here</span>
</code></pre><p><strong>Alamofire</strong>, a popular networking library, heavily uses this attribute e.g. see its <a target='_blank' rel='noopener noreferrer'  href="https://github.com/Alamofire/Alamofire/blob/master/Source/Request.swift">Request.swift</a> file.</p>
<h2 id="uiapplicationmain">UIApplicationMain</h2>
<p>The all familiar <code>@UIApplicationMain</code> is in all Swift iOS applications. It indicates that the attributed class is the Application&#39;s delegate.</p>
<pre><code><span class="hljs-meta">@UIApplicationMain</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AppDelegate</span>: <span class="hljs-type">UIResponder {</span></span>
    ...
}
</code></pre><p>There&#39;s usually one application delegate thus the <code>UIApplication.shared.delegate</code> will return an instance of the above attributed class.</p>
<h2 id="objc">objc</h2>
<p>Working with UIKit has definitely exposed you to this attribute. The <code>@objc</code> instructs the compiler to avail the attributed declaration for use in Objective-C code. Let&#39;s take a tap action for example.</p>
<pre><code><span class="hljs-keyword">let</span> gestureRecognizer = <span class="hljs-type">UITapGestureRecognizer</span>(target: <span class="hljs-keyword">self</span>, action: #selector(tapAction(<span class="hljs-number">_</span>:)))
<span class="hljs-keyword">self</span>.actionView.addGestureRecognizer(gestureRecognizer)

<span class="hljs-meta">@objc</span> <span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">tapAction</span><span class="hljs-params">(<span class="hljs-number">_</span> recognizer: UITapGestureRecognizer)</span></span> {
    <span class="hljs-comment">// useful action</span>
}
</code></pre><p>In this example, the <em>tapAction(_:)</em> declaration is exposed to Objective-C for dispatch at runtime to respond to the tap action on <em>self.actionView</em>. The <code>@objc</code> attribute hints for this exposure.</p>
<h2 id="testable">testable</h2>
<p>Ah. Testing. A test bundle is a target for a project. As such, the module under test needs to be imported for invocation in the test bundle. <code>@testable</code> is used to attribute an import declaration of the module&#39;s code for use in testing eg:</p>
<pre><code><span class="hljs-meta">@testable</span> <span class="hljs-keyword">import</span> TheProject
</code></pre><p>&quot;Why?&quot;, you may ask. Swift&#39;s documentation says the following about adding <code>@testable</code> attribute on an import declaration:</p>
<ul>
<li>The imported module must be compiled with testing enabled</li>
<li>Entities in the imported module that are marked with the internal access-level modifier are imported as if they were declared with the public access-level modifier</li>
<li>Classes and class members that are marked with the internal or public access-level modifier are imported as if they were declared with the open access-level modifier</li>
</ul>
<h2 id="escaping">escaping</h2>
<p>Swift supports closures - <em>self-contained blocks of code passed around</em>. A closure escapes a function when it&#39;s passed as an argument but invoked after the function returns. Lets create a <code>Queue</code> structure that enqueues tasks to be performed after some time:</p>
<pre><code><span class="hljs-keyword">final</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Queue</span> </span>{

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">let</span> queue: <span class="hljs-type">DispatchQueue</span> = .main

    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">enqueue</span><span class="hljs-params">(after deadline: DispatchTime, execute work: @escaping <span class="hljs-params">()</span></span></span> -&gt; <span class="hljs-type">Void</span>) {
        <span class="hljs-keyword">self</span>.queue.asyncAfter(deadline: deadline, execute: work)
    }

}
</code></pre><p>Our <code>enqueue</code> method schedules some work to be done after a given deadline using <a target='_blank' rel='noopener noreferrer'  href="https://developer.apple.com/documentation/dispatch/dispatchqueue">DispatchQueue</a>. This request is delegated to a <code>DispatchQueue</code> using a method <code>asyncAfter</code>, that executes the given closure after a given <code>deadline</code>. The provided closure, <em>work</em>, therefore escapes (executes after the methods return) both our <em>enqueue</em> method and the <em>asyncAfter</em> method. Omitting the <code>@escaping</code> attribute in the <em>enqueue(after:execute:)</em> definition results in the following compiler error:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1593676187955/u5TuziWqQ.png" alt="Screen Shot 2020-07-02 at 10.45.58 ruc-inī.png"></p>
<p>As shown in the above code snippet, we need to attribute the closure declaration with <code>@escaping</code>. With this in place, our <em>Queue</em> class is ready to be used for scheduling work:</p>
<pre><code><span class="hljs-keyword">let</span> queue = <span class="hljs-type">Queue</span>()
queue.enqueue(after: .now() + <span class="hljs-number">0.3</span>) {
    <span class="hljs-built_in">print</span>(<span class="hljs-string">"Delayed work"</span>)
}
</code></pre><h2 id="propertywrapper">propertyWrapper</h2>
<p>This is a recent addition to the Swift&#39;s attributes list that is applied to classes, structs or enumerations. It creates a custom attribute with the same name as the attributed type. A factory of attributes? It appears so. This makes it a powerful attribute and a useful one for that matter. For this reason (and the wide application in SwiftUI), I&#39;ll dedicate an article to discuss <code>@propertyWrapper</code>s.</p>
<h1 id="conclusion">Conclusion</h1>
<p>We&#39;ve taken a look at some common attributes and their use cases. There&#39;re many more. Check out the <a target='_blank' rel='noopener noreferrer'  href="https://docs.swift.org/swift-book/ReferenceManual/Attributes.html">Swift attribute documentation</a>. </p>
<p>SwiftUI, the declarative UI framework, makes heavy use of Swift attributes such as <code>@State</code>, <code>@Environment</code>, <code>@Published</code>, <code>@EnvironmentObject</code> and many more making this an even more important concept to learn. Happy coding!</p>
<h1 id="references">References</h1>
<ul>
<li><p><a target='_blank' rel='noopener noreferrer'  href="https://docs.swift.org/swift-book/ReferenceManual/Attributes.html">Swift Attributes Docs</a></p>
</li>
<li><p><a target='_blank' rel='noopener noreferrer'  href="https://github.com/Alamofire/Alamofire">Alamofire</a></p>
</li>
<li><p><a target='_blank' rel='noopener noreferrer'  href="https://docs.swift.org/swift-book/LanguageGuide/Closures.html">Closures</a></p>
</li>
<li><p><a target='_blank' rel='noopener noreferrer'  href="https://developer.apple.com/documentation/dispatch/dispatchqueue">DispatchQueues</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[It's a Struct world]]></title><description><![CDATA[Structures
A Struct is a Swift language construct that can be used to encapsulate state and behaviour. It's the recommended way of storing state and modeling behaviour. What's the alternative you ask? Classes. The two are similar in many ways but als...]]></description><link>https://charlesmuchene.com/its-a-struct-world</link><guid isPermaLink="true">https://charlesmuchene.com/its-a-struct-world</guid><category><![CDATA[iOS]]></category><category><![CDATA[SwiftUI]]></category><category><![CDATA[Swift]]></category><dc:creator><![CDATA[Charles Muchene]]></dc:creator><pubDate>Tue, 30 Jun 2020 15:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1593499031363/-lwjdP9sV.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="structures">Structures</h1>
<p>A <strong>Struct</strong> is a Swift language construct that can be used to encapsulate state and behaviour. It&#39;s the recommended way of storing state and modeling behaviour. What&#39;s the alternative you ask? <em>Classes</em>. The two are similar in many ways but also have a some huge distinctions. Luckily there are some <a target='_blank' rel='noopener noreferrer'  href="https://developer.apple.com/documentation/swift/choosing_between_structures_and_classes">guidelines</a> from Apple on when to use which.</p>
<h2 id="value-vs-reference">Value vs Reference</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1593499284348/gIs7sR3Oh.gif" alt="value-ref.gif"></p>
<p><strong>Structs</strong> are value types.</p>
<blockquote>
<p>A value type is a type whose value is copied when it’s assigned to a variable or constant, or when it’s passed to a function.</p>
</blockquote>
<p>Passing a struct around results in a copy. This is optimised in the language in the case of large structs. Nevertheless, any changes you make to a struct instance result in a different instance. The alternative is a class -- a reference type. Classes are fundamentally shared instances. Upon creating an instance, you pass around its reference and any local modifications are visible to the caller code.</p>
<h2 id="syntax">Syntax</h2>
<pre><code><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Tweet</span> </span>{ }
</code></pre><p>We&#39;d then use <code>let awesomeTweet = Tweet()</code> to create an instance. Well, that&#39;s not useful enough and so structs can store state through properties: <em>stored (variable or constant) or computed</em>. In addition, we can model behaviour via methods on the struct.</p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Tweet</span> </span>{
    <span class="hljs-keyword">let</span> text: <span class="hljs-type">String</span>
    <span class="hljs-keyword">let</span> date: <span class="hljs-type">Date</span>
    <span class="hljs-keyword">var</span> imageUrl: <span class="hljs-type">String?</span>

    <span class="hljs-keyword">mutating</span> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">edit</span><span class="hljs-params">(<span class="hljs-number">_</span> newText: String)</span></span> {
        <span class="hljs-comment">// Sorry you can't edit a tweet! 😎</span>
        <span class="hljs-comment">// The text is declared as a **let** property</span>
    }

}
</code></pre><h3 id="memberwise-initializers">Memberwise Initializers</h3>
<p>One of the nice features a struct has over a class is a <em>memberwise initializer</em>. This is an initializer generated automatically by the compiler. For example, the above tweet definition can be initialized as follows: <code>let tweet = Tweet(text: &quot;🇰🇪&quot;, date: .distantFuture, imageUrl: nil)</code> without us declaring an explicit initializer.</p>
<blockquote>
<p>One of my best <a target='_blank' rel='noopener noreferrer'  href="https://github.com/apple/swift-evolution/blob/master/proposals/0242-default-values-memberwise.md">Swift proposal</a> was by <a target='_blank' rel='noopener noreferrer'  href="https://github.com/Azoy">Alejandro Alonso</a>. This was a proposal for the compiler to synthesize a memberwise initializer taking into account the default values. This was implemented in <strong>Swift 5.1</strong>. So you can already enjoy this welcome addition.</p>
</blockquote>
<p>Now, say I&#39;m using the iOS Twitter app for real-time tweeting. The Tweet struct can declare a default date (<em>.now</em> -&gt; <code>private extension Date { static let now: Date = .init(timeIntervalSinceNow: 0) }</code>) and all I have to provide is the <strong>text</strong> and perhaps the optional <strong>image url</strong>.</p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Tweet</span> </span>{
    <span class="hljs-keyword">let</span> text: <span class="hljs-type">String</span>
    <span class="hljs-keyword">let</span> date: <span class="hljs-type">Date</span> = .now
    <span class="hljs-keyword">var</span> imageUrl: <span class="hljs-type">String?</span> = <span class="hljs-literal">nil</span>

    ...
}
</code></pre><p>Voila! <code>let tweet = Tweet(text: &quot;🇰🇪&quot;)</code></p>
<h2 id="adopting-protocols">Adopting Protocols</h2>
<p>One of the strong arguments in using structs is to share behaviour using protocol inheritance. Structs can adopt protocols. <code>Equatable</code> and <code>Hashable</code> protocols get great language support -- the compiler automatically synthesizes their requirements.</p>
<p>Consider two instances of tweets:</p>
<pre><code><span class="hljs-keyword">let</span> tweet = <span class="hljs-type">Tweet</span>(text: <span class="hljs-string">"🇰🇪"</span>)
<span class="hljs-keyword">let</span> anotherTweet = <span class="hljs-type">Tweet</span>(text: <span class="hljs-string">"🤷🏾‍♂️"</span>)
</code></pre><p>A comparison is of course not supported automatically and the compiler won&#39;t allow it. After all what is the comparison on? Memory address? One property?. Thus <code>let areEqual = tweet == anotherTweet</code> results in a compiler error. But say we need to enable this comparison behavior based on the properties. Well, we simply adopt the <code>Equatable</code> protocol and automatically get this behavior (implementation).</p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Tweet</span>: <span class="hljs-title">Equatable</span> </span>{
    ...
}
</code></pre><p>Now, the previous comparison is permitted. <code>Hashable</code> protocol adoption can also get automatic protocol requirements synthesis. Nothing prevents us from implementing these requirements but some compiler &#39;magic&#39; is always welcome.</p>
<h2 id="deep-down">Deep down</h2>
<p>Structs are used extensively in the language. Numbers, arrays, strings, dictionaries etc are all implemented as <em>Structs</em>. Take <em>arrays</em> for instance.</p>
<p>The Swift&#39;s collection library declares an array as a generic struct:</p>
<pre><code>@frozen <span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Array</span>&lt;<span class="hljs-title">Element</span>&gt; </span>{
    @inlinable <span class="hljs-keyword">public</span> <span class="hljs-keyword">mutating</span> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">append</span><span class="hljs-params">(<span class="hljs-number">_</span> newElement: Element)</span></span>
    ...
}
</code></pre><p>You&#39;ll also note that all methods that mutate an array say:</p>
<ul>
<li>append</li>
<li>insert</li>
<li>remove</li>
<li>replace</li>
<li>pop</li>
</ul>
<p>are all marked as <code>mutating</code> -- a compiler requirement when modifying value types.</p>
<p>Nonetheless, as mentioned earlier, collections get some optimization to reduce the performance cost of copying by sharing the storage memory. Instance copying is still effectively done after a modification on the copy. You can read more on the swift language guide <a target='_blank' rel='noopener noreferrer'  href="https://docs.swift.org/swift-book/LanguageGuide/ClassesAndStructures.html">here</a>.</p>
<h1 id="conclusion">Conclusion</h1>
<p>Much more can be said about structs but the key takeaway is:</p>
<blockquote>
<p>Always use structures by default</p>
</blockquote>
<p>The idea of protocol inheritance and using structs has been heavily adopted by <strong>SwiftUI</strong> as demonstrated in its usage samples. So it&#39;s a worthwhile investment to learn and use. And there you have it: <strong>Structs</strong>. Happy coding!</p>
<h1 id="references">References</h1>
<ul>
<li><p><a target='_blank' rel='noopener noreferrer'  href="https://docs.swift.org/swift-book/LanguageGuide/ClassesAndStructures.html">Swift Docs</a></p>
</li>
<li><p><a target='_blank' rel='noopener noreferrer'  href="https://developer.apple.com/documentation/swift/choosing_between_structures_and_classes">Apple Docs</a></p>
</li>
<li><p><a target='_blank' rel='noopener noreferrer'  href="https://github.com/apple/swift-evolution/blob/master/proposals/0242-default-values-memberwise.md">Proposal: SE-0242</a></p>
</li>
<li><p><a target='_blank' rel='noopener noreferrer'  href="https://developer.apple.com/documentation/swift/adopting_common_protocols">Adopting common protocols</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Ruler of iOS apps - UIScrollView]]></title><description><![CDATA[Premise
What does a Product listing, Shopping cart, Orders list, Chat messages' list, Contacts list, Maps, etc have in common? They are all scrollable content: content that can't fit on the screen at once. All these are built using one underlying ui ...]]></description><link>https://charlesmuchene.com/ruler-of-ios-apps-uiscrollview</link><guid isPermaLink="true">https://charlesmuchene.com/ruler-of-ios-apps-uiscrollview</guid><category><![CDATA[iOS]]></category><dc:creator><![CDATA[Charles Muchene]]></dc:creator><pubDate>Tue, 16 Jun 2020 09:41:38 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1592296805598/9jgFgL4py.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="premise">Premise</h2>
<p>What does a Product listing, Shopping cart, Orders list, Chat messages&#39; list, Contacts list, Maps, etc have in common? They are all scrollable content: content that can&#39;t fit on the screen at once. All these are built using one underlying ui component: <code>UIScrollView</code>.</p>
<h1 id="uiscrollview">UIScrollView</h1>
<p>Apple&#39;s documentation states that a UIScrollView is:</p>
<blockquote>
<p>A view that allows scrolling and zooming of its contained views.</p>
</blockquote>
<p>That&#39;s a pretty good summary about this ui component. I call it, the <strong>ruler of apps</strong>. See. Handheld devices have quite a small screen real estate unlike lap or desk held devices such as your Macbook or iMac. And thus content has to be crunched to fit and be displayed efficiently and for quick consumption.</p>
<p>This view is so conveniently named since, in its main use case, the content to be displayed is much larger than it&#39;s bounds (usually covering the whole device screen) and thus it needs to be scrolled to view the rest of the content. (Technically, it also supports a zooming gesture also but we won&#39;t discuss that here.)</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1591588918872/Xhl1amCuA.png" alt="scroll_view.001.png"></p>
<p>As shown in the diagram above, the visible content rectangle corresponds to the scroll view&#39;s bounds. Any content outside this region is not drawn. To view the clipped content, you scroll up or down. (I&#39;ve put cell-like content that simulates a table or collection view but you can put any content you desire, sized however you like, say a map or a huge image that you can scroll horizontally and/or vertically).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1592205926275/bZKLAb_tK.gif" alt="scroll_view.gif"></p>
<p>Let&#39;s take a look at some of the frequently used properties of a scroll view.</p>
<h2 id="content-size">Content Size</h2>
<p>Question. How does the scroll view know how big its scrollable content is? <code>contentSize</code>. This is a <code>CGSize</code> typed property on the scroll view that is very fundamental to its functionality. To denote when the scroll view&#39;s content has been scrolled all the way downward (and rightward if allowing horizontal scrolling), the scroll view&#39;s bounds origin is at point <code>.zero</code>. On the other hand, the furthest you can scroll upward (and leftward, if allowing horizontal scrolling) is governed by the <code>contentSize</code>. And thus this property gives us the limits of scrolling. I like to think of the scrollable portion of the scroll view being determined by the rect <code>CGRect(origin: .zero, size: contentSize)</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1592299342681/Di29BLKNi.png" alt="contentsize.001.png"></p>
<p>Two scenarios can be spun from this. </p>
<ol>
<li><p>When the <em>contentSize</em> is <strong>smaller than or equal</strong> to the scroll view&#39;s bounds (non-scrollable 😎)</p>
</li>
<li><p>When the <em>contentSize</em> is <strong>larger than</strong> the scroll view&#39;s bounds</p>
</li>
</ol>
<h3 id="non-scrollable">Non-scrollable</h3>
<p>When the content size is less than or equal to the scroll view&#39;s bounds, there&#39;s nothing to scroll -- all content is visible within the bounds.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1592205985811/Bi32B-Ct3.jpeg" alt="fit.001.jpeg"></p>
<h3 id="scrollable">Scrollable</h3>
<p>When the content size is larger than the scroll view&#39;s bounds, scrolling is required to be able to view all content. The animation below shows scrolling to origin point <code>.zero</code> and then to the furthest scroll possible represented by the <code>contentSize</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1592206132348/TBYf70c4F.gif" alt="pan.gif"></p>
<h2 id="content-inset">Content Inset</h2>
<p>The <code>contentInset</code> give us a margin around the scroll view&#39;s content. Say we add edge insets of 100 on either side of the scroll view, the resulting setup is as shown below. Note that the subview is still positioned relative to the scroll view&#39;s origin <code>CGRect(x: 0, y: 0, width: 100, height: 100)</code> but appears to have a 100 units padding from the top and left edges of the scroll view. This is as a result of giving the scroll view content inset.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1592211021994/dcYoA1SGE.png" alt="scrollviewinsets.png"></p>
<p>Here&#39;s the source for the above hierarchy.</p>
<div class="gist-block embed-wrapper" data-gist-show-loading="false" data-id="2d144f89b7bffa5988e7b790c4a103c8"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a href="https://gist.github.com/charlesmuchene/2d144f89b7bffa5988e7b790c4a103c8" class="embed-card" data-card-width="600px" data-card-key="2e4d628b39a64b99917c73956a16b477" data-card-controls="0" data-card-theme="light">https://gist.github.com/charlesmuchene/2d144f89b7bffa5988e7b790c4a103c8</a></div><h2 id="adjusted-content-inset">Adjusted Content Inset</h2>
<p>I had not become fond of <code>adjustedContentInset</code> property until recently when I had to account for the safe area of an edge-to-edge scroll view. I learnt about safe area propagation in the view hierarchy from Matt Neuburg&#39;s <a target='_blank' rel='noopener noreferrer'  href="https://www.oreilly.com/library/view/programming-ios-13/9781492074601/">Programming iOS 13</a> book. I highly recommend this book.</p>
<p>As the name of the property connotes, this value accounts for the content insets that have been adjusted. &quot;Adjusted by what?&quot;, you may ask. Safe area insets. This value can be thought to be expressed as: <code>adjustedContentInset = contentInset + safeAreaInset</code>.</p>
<p>Looking at the above relation, adjusted content inset would be relatively easy to calculate and no need for an extra property on the scroll view. It&#39;s there because there&#39;s more. There&#39;s another property that controls this value -- specifically the safe area inset part: <code>contentInsetAdjustmentBehavior</code>. Lucky for us, the resulting adjusted insets are calculated automatically with respect to the <em>content inset adjustment behavior</em>. This behavior property takes one of the options enumerated in the <a target='_blank' rel='noopener noreferrer'  href="https://developer.apple.com/documentation/uikit/uiscrollview/contentinsetadjustmentbehavior">documentation</a> (<em>.always, .never, .scrollableAxes, or .automatic</em>) to alter the final value of the <code>adjustedContentInset</code>. In summary, you choose any of these options to configure how you want the safe area insets to adjust your scroll view&#39;s content inset.</p>
<h2 id="content-offset">Content Offset</h2>
<p>This is a <code>CGPoint</code> property that denotes the current scroll position. Its range is governed by the scrollable portion of the scroll view mentioned earlier: <code>CGRect(origin: .zero, size: contentSize)</code>.</p>
<h2 id="scroll-view-delegate">Scroll View Delegate</h2>
<p>Ah delegates! I guess my most love-to-hate architectural decision by Apple. Whenever I switch from other frameworks and work with iOS, I&#39;m always fond of looking for which delegates are available for me to explore. Usually there&#39;s one or sometimes, a protocol-chain of delegates.</p>
<p>The scroll view&#39;s delegate is a class adopting the <code>UIScrollViewDelegate</code> protocol. There&#39;re a handful of methods for you to explore but the one method I&#39;ve kinda always used is the <code>scrollViewDidScroll(_:)</code>. This method tells you that the scroll view has scrolled. In most scenarios, this method is called several times hence a guard statement or some code that executes fast is necessary not to do too much processing during scrolls. To detect when dragging will begin, end and so on, check out Apple&#39;s <a target='_blank' rel='noopener noreferrer'  href="https://developer.apple.com/documentation/uikit/uiscrollviewdelegate">documentation</a> on other delegate methods available.</p>
<h1 id="static-subviews">Static subviews</h1>
<p>I recently had to implement a feature where a view was to stay stationary in relation to the scroll view&#39;s content scrolling. Upon some digging, I found out about the scroll view&#39;s <code>frameLayoutGuide</code>. This property is controlled by the scroll view&#39;s frame and serves as a great way to create static subviews positioned wherever you&#39;d like on the scroll view&#39;s frame.</p>
<h1 id="subclasses">Subclasses</h1>
<p>Some of the main scroll view&#39;s subclasses you might be familiar with are the well known <code>UITableView</code> and it&#39;s superior cousin, <code>UICollectionView</code>. These classes build upon the basics discussed above (and in the documentation) to give a great developer experience in presenting scrollable content. They are also a great source of iOS interview questions 😎.</p>
<h1 id="conclusion">Conclusion</h1>
<p>We&#39;ve just scratched the surface on working with a scroll view. As hinted, it forms the basis of many iOS app designs and development. The basic premise of scrollable (and zoomable) functionality fits well with the paradigm of providing an entry point to seemingly endless content. Many apps heavily use a scroll view or any of its subclasses to present content to users. In one way or the other, you&#39;ll work with this view in your development lifetime: embrace it. Let it rule. Happy coding!</p>
<h1 id="references">References</h1>
<ul>
<li><p><a target='_blank' rel='noopener noreferrer'  href="https://developer.apple.com/documentation/uikit/uiscrollview">Apple&#39;s UIScrollView documentation</a></p>
</li>
<li><p><a target='_blank' rel='noopener noreferrer'  href="https://www.oreilly.com/library/view/programming-ios-13/9781492074601/">Programming iOS 13</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Activity vs UIViewController Lifecycle]]></title><description><![CDATA[I've had the opportunity to work on Android for a while now building a career on it. In 2017, I got the privilege to dive head on into the iOS waters when I built an MVP app for my previous company. Back then, I learnt by trying to map the concepts o...]]></description><link>https://charlesmuchene.com/activity-vs-uiviewcontroller-lifecycle</link><guid isPermaLink="true">https://charlesmuchene.com/activity-vs-uiviewcontroller-lifecycle</guid><category><![CDATA[Mobile Development]]></category><dc:creator><![CDATA[Charles Muchene]]></dc:creator><pubDate>Mon, 27 Apr 2020 06:23:04 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1587883505360/zW7Zzqbgy.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I&#39;ve had the opportunity to work on <em>Android</em> for a while now building a career on it. In 2017, I got the privilege to dive head on into the iOS waters when I built an MVP app for my previous company. Back then, I learnt by trying to map the concepts one-to-one: <em>AppCompatActivity</em> to <em>UIViewController</em>, <em>XML layouts</em> to <em>StoryBoard/Nib Files</em> etc. Luckily, the company hired a full-time iOS dev who shaped the app in accordance to iOS platform guidelines and industry standards. I retreated to do minor bug fixes and code reviews as I watched and learnt iOS development from the pros.</p>
<p>Sometime back, I came across a view controller lifecycle-related challenge which I cover in another <a target='_blank' rel='noopener noreferrer'  href="https://charlesmuchene.hashnode.dev/hooking-into-apps-lifecycle-events-ios-ef433cefdbce">article</a>. That led me to this discussion between Activity and ViewController lifecycle callbacks.</p>
<h2 id="tl-dr">Tl;dr</h2>
<blockquote>
<p>The Android and iOS teams have taken different approaches in application platform designs. Blindly borrowing concepts from either platform will only result to <em>chaos</em> in your app development. Invest time learning each. 😎</p>
</blockquote>
<hr>
<h1 id="assumptions">Assumptions</h1>
<p>In my opinion, taking a one-to-one possible mapping in concepts can be a shortcut to dive into the other platform but I think understanding the basics of how each works will be most helpful in the long run.</p>
<p>One of the biggest assumptions I made was that <em>Activity lifecycle callbacks</em> map to <em>ViewController callbacks</em>. Let’s look why this isn’t necessarily the case as we look beyond the basics.</p>
<h1 id="activity-uiviewcontroller-lifecycle">Activity/UIViewController Lifecycle</h1>
<h2 id="activity">Activity</h2>
<p>From the <a target='_blank' rel='noopener noreferrer'  href="https://developer.android.com/reference/android/app/Activity.html">Android documentation</a> we get the following:</p>
<blockquote>
<p>An <strong>activity</strong> is a single, focused thing that the user can do. Almost all <strong>activities</strong> interact with the user, so the Activity class takes care of creating a window …</p>
</blockquote>
<p>But let us go with a clearer explanation presented <a target='_blank' rel='noopener noreferrer'  href="https://developer.android.com/guide/components/fundamentals">elsewhere</a> in the documentation:</p>
<blockquote>
<p>An <strong><em>activity</em></strong> is the entry point for interacting with the user. It represents a single screen with a user interface.</p>
</blockquote>
<p>You use an instance of the activity to place your UI but we are more interested in its lifecycle (and related callbacks).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1587882685892/cGyy4lsla.png" alt="activity_lifecycle.png"></p>
<p>Activity lifecycle (source developer.android.com)</p>
<p>From the image above, we can count <strong>7</strong> lifecycle callbacks methods exposed by the activity to hook up your logic. There are other supporting callbacks, for instance, methods to save the activity state in a bundle. All these are in response to the activity’s lifecycle itself. For an instance, when the activity is going away (e.g the app is backgrounded), a series of callbacks in the activity, starting with <em>onPause(),</em> are invoked in response. One may expect a corresponding behavior in the ViewController but let’s have a look at it.</p>
<h2 id="uiviewcontroller">UIViewController</h2>
<p>From <a target='_blank' rel='noopener noreferrer'  href="https://developer.apple.com/documentation/uikit/uiviewcontroller">Apple’s documentation</a>, a UIViewController is:</p>
<blockquote>
<p>An object that manages a view hierarchy for your UIKit app.</p>
</blockquote>
<p>From the documentation, we can see that one of the main responsibilities of the view controller is to manage a <strong>view</strong> (for which it maintains a reference using the <em>view</em> property). In the view controller, you can override view callbacks e.g. <em>viewDidAppear()</em>, <em>viewWillDisappear()</em> etc. Check out the state transition diagram and corresponding literature <a target='_blank' rel='noopener noreferrer'  href="https://developer.apple.com/documentation/uikit/uiviewcontroller">here</a>. These callbacks are in relation to the <strong>view</strong> that the UIViewController is <em>managing</em> and <strong>not</strong> the UIViewController itself.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1587883305037/RbdaXpGL0.png" alt="viewcontroller_lifecycle.png"></p>
<p>UIViewController&#39;s View lifecycle (source https://developer.apple.com/documentation/uikit/uiviewcontroller)</p>
<p>Nevertheless, in regards to detecting when the UIViewController is going away, the best bet is to still rely on the <strong>view*()</strong> callbacks e.g. <em>viewDidDisappear()</em> is invoked after a view controller has been dismissed by the presenting controller. NB: <strong>child</strong> view controllers <em>have</em> lifecycle methods e.g. <em>willMove()</em>, <em>didMove()</em> etc in which you can use in your app. Also, WatchKit has methods <em>awake()</em>, <em>*Activate()</em> and <em>*Appear()</em> that hook up well with the <a target='_blank' rel='noopener noreferrer'  href="https://developer.apple.com/documentation/watchkit/wkinterfacecontroller">WKInterfaceController’s</a> lifecycle events.</p>
<hr>
<p><em>viewDidLoad()</em>, therefore, is technically <em>not</em> the corresponding equal for <em>onCreate()</em> even though both are called in the initial stages of their parents’ lifecycles. The former is called after the controller’s <em>view</em> is loaded into memory and the latter is invoked when the <em>activity</em> is starting. Clearly, these two can’t just be mapped one-to-one!</p>
<h1 id="conclusion">Conclusion</h1>
<p>Hope this article has debunked any ideas of blindly comparing Activity’s and UIViewController view’s lifecycle callbacks. I can learn a thing or two on how you approach either platform using the knowledge you know about the other.</p>
<h1 id="resources">Resources</h1>
<ul>
<li><a target='_blank' rel='noopener noreferrer'  href="https://developer.apple.com/documentation/uikit/uiviewcontroller">View Controller</a></li>
<li><a target='_blank' rel='noopener noreferrer'  href="https://developer.android.com/guide/components/activities/activity-lifecycle">Activity</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Custom Response Handler in Alamofire]]></title><description><![CDATA[Alamofire is an elegant HTTP networking library de facto in iOS development; perhaps in the same league as Retrofit in Android programming. It’s built to be asynchronous from ground up as it uses Apple’s URL loading system thus full of handlers (chec...]]></description><link>https://charlesmuchene.com/custom-response-handler-in-alamofire</link><guid isPermaLink="true">https://charlesmuchene.com/custom-response-handler-in-alamofire</guid><dc:creator><![CDATA[Charles Muchene]]></dc:creator><pubDate>Sun, 26 Apr 2020 07:15:19 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1587884702517/es-TeNUJA.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1587884747300/jN30RDaEt.png" alt="alamofire_logo.png"></p>
<p><a target='_blank' rel='noopener noreferrer'  href="https://github.com/Alamofire/Alamofire">Alamofire</a> is an elegant HTTP networking library de facto in iOS development; perhaps in the same league as <a target='_blank' rel='noopener noreferrer'  href="https://square.github.io/retrofit/">Retrofit</a> in Android programming. It’s built to be asynchronous from ground up as it uses Apple’s <a target='_blank' rel='noopener noreferrer'  href="https://developer.apple.com/documentation/foundation/url_loading_system/">URL loading system</a> thus full of handlers (check out <a target='_blank' rel='noopener noreferrer'  href="https://github.com/RxSwiftCommunity/RxAlamofire">RxAlamofire</a> to enjoy an even nicer api for your networking needs).</p>
<h1 id="making-a-request">Making a Request</h1>
<p><em>Alamofire 5</em> has a new namespace, <strong>AF</strong>, that encapsulates all of its request methods. Thus to make a get request, prefix your <code>request</code> method with <code>AF</code> (this was previously available in the global namespace).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1587884822967/jz8mESXkD.png" alt="code_1.png"></p>
<h1 id="handling-response">Handling Response</h1>
<p>The <code>request</code> method returns a <code>DataRequest</code> object which handles in-memory data download. When a request is done, the parent <code>Request</code> class has a <code>finish</code> method invoked to start registered response serializers. The serializers adopt the <code>ResponseSerializer</code> protocol which is a composition of <code>DataResponseSerializerProtocol</code> (to handle data response) and the <code>DownloadResponseSerializerProtocol</code> (to handle download response). Some of the built in serializers are:</p>
<ul>
<li>DataResponseSerializer</li>
<li>StringResponseSerializer</li>
<li>JSONResponseSerializer</li>
<li>DecodableResponseSerializer</li>
</ul>
<p>Out of the box, Alamofire has 6 response handlers that utilize these serializers to hand you a serialized response. They are:</p>
<ul>
<li>Generic handler — unserialized response</li>
<li>Serializer handler — serializes response using the provided serializer</li>
<li>Data handler — serializes response into Foundations’ <code>Data</code> struct</li>
<li>String handler — yields a <code>String</code> struct</li>
<li>JSON handler — uses Foundation’s JSONSerialization — yields <code>Any</code></li>
<li>Decodable handler — serializes into a<code>Decodable</code> type</li>
</ul>
<p>Here’s a signature to add a handler for JSON serialized response:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1587884855647/qhVlOiUjI.png" alt="code_2.png"></p>
<h1 id="the-need">The Need</h1>
<p>Ignoring network and server errors, api calls typically have a response and Alamofire treats a completed network request as successful by default. (The library can also handle an <code>EmptyResponse</code>).<code>DataRequest</code> can take a validation closure to determine if the response is interpreted as an error (based on an unacceptable status code, incorrect MIME type or the given closure).</p>
<p>Imagine we are login in a user on an iOS app. The api is documented to give us back a <code>Token</code> object when the credentials are valid or a custom <code>APIError</code> object otherwise. If our <code>Token</code> struct conforms to the <code>Decodable</code> protocol, we can use the <code>responseDecodable</code> handler to receive a decoded <code>Token</code> object from the response.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1587884921357/eJGqs4UfU.png" alt="code_3.png"></p>
<p><em>JWT token object</em></p>
<p>The login request (request payload omitted) could be made as follows.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1587884960867/X5IhF7mTt.png" alt="code_4.png"></p>
<p>If the credentials provided were valid, the response variable is of type <code>AFDataResponse&lt;Token&gt;</code> which is a typealias for <code>DataResponse&lt;Token, AFError&gt;</code> where <code>AFError</code> is a custom error type by Alamofire. What if the credentials were invalid? How do we receive the decoded <code>APIError</code> object?</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1587884989796/0k_w6Y0oD.png" alt="code_5.png"></p>
<p>If <code>APIError</code> conforms to the <code>Decodable</code> protocol, as shown below, we could write a custom serializer and handler that returns to us a <code>Result&lt;Token, APIError&gt;.</code></p>
<h1 id="custom-serializer">Custom Serializer</h1>
<p>To write a custom data serializer, you write a class that conforms to the <code>DataResponseSerializerProtocol.</code> The protocol is defined as follows:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1587885013771/Y4Tyh_LeH.png" alt="code_6.png"></p>
<blockquote>
<p>Note that to handle disk downloads as well, your custom serializer should also adopt the <code>DownloadResponseSerializerProtocol</code>.</p>
</blockquote>
<p>As noted above, Alamofire has an inbuilt decodable data serializer. We create a custom <code>TwoDecodableResponseSerializer</code> that uses a composition of <code>DataResponseSerializers</code>, one for each type we want decodable. After a short ceremony of making sure the response is even valid for decoding, we invoke either serializer conditionally. I pass in a _HTTP status cod_e to determine when to invoke the <code>APIError</code> serializer.</p>
<div class="gist-block embed-wrapper" data-gist-show-loading="false" data-id="afb68afb136f4dcba39b5432cd6ab10c"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a href="https://gist.github.com/charlesmuchene/afb68afb136f4dcba39b5432cd6ab10c" class="embed-card" data-card-width="600px" data-card-key="2e4d628b39a64b99917c73956a16b477" data-card-controls="0" data-card-theme="light">https://gist.github.com/charlesmuchene/afb68afb136f4dcba39b5432cd6ab10c</a></div><h1 id="custom-handler">Custom Handler</h1>
<p>A custom handler is straight forward. It uses the serializer we’ve written above. I’ve made it generic to accept any type that is <code>Decodable</code>.</p>
<div class="gist-block embed-wrapper" data-gist-show-loading="false" data-id="2fa95caf9eda6904717dd8bc94254d9c"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a href="https://gist.github.com/charlesmuchene/2fa95caf9eda6904717dd8bc94254d9c" class="embed-card" data-card-width="600px" data-card-key="2e4d628b39a64b99917c73956a16b477" data-card-controls="0" data-card-theme="light">https://gist.github.com/charlesmuchene/2fa95caf9eda6904717dd8bc94254d9c</a></div><p>And we use it as shown below:</p>
<div class="gist-block embed-wrapper" data-gist-show-loading="false" data-id="0687156ed005bfa558323153a49e87fb"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a href="https://gist.github.com/charlesmuchene/0687156ed005bfa558323153a49e87fb" class="embed-card" data-card-width="600px" data-card-key="2e4d628b39a64b99917c73956a16b477" data-card-controls="0" data-card-theme="light">https://gist.github.com/charlesmuchene/0687156ed005bfa558323153a49e87fb</a></div><hr>
<p>And that’s it.</p>
<p>The <a target='_blank' rel='noopener noreferrer'  href="https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#creating-a-custom-response-serializer">documentation</a> has a section on creating a custom serializer (for your specific type of data). Happy coding.</p>
<h1 id="reading">Reading</h1>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" data-card-width="600px" data-card-key="2e4d628b39a64b99917c73956a16b477" href="https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md" data-card-controls="0" data-card-theme="light">https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md</a></div>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" data-card-width="600px" data-card-key="2e4d628b39a64b99917c73956a16b477" href="https://developer.apple.com/documentation/foundation/url_loading_system" data-card-controls="0" data-card-theme="light">https://developer.apple.com/documentation/foundation/url_loading_system</a></div>
]]></content:encoded></item><item><title><![CDATA[Hooking into App’s Lifecycle  within UIViewController]]></title><description><![CDATA[Requirement
I’m building an application in which I would like to play an animation when the (root) view controller comes into the foreground and pause it when it (app) goes to the background.
The Platform
iOS exposes the Application Delegate that pro...]]></description><link>https://charlesmuchene.com/hooking-into-apps-lifecycle-events-ios</link><guid isPermaLink="true">https://charlesmuchene.com/hooking-into-apps-lifecycle-events-ios</guid><dc:creator><![CDATA[Charles Muchene]]></dc:creator><pubDate>Sun, 26 Apr 2020 06:53:06 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1587884426970/U69ymUD5E.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="requirement">Requirement</h1>
<p>I’m building an application in which I would like to play an animation when the (root) view controller comes into the foreground and pause it when it (app) goes to the background.</p>
<h1 id="the-platform">The Platform</h1>
<p>iOS exposes the Application Delegate that provides callback methods to hook into in response to the application’s foreground/background transition. This is great if all you want to do is write application-wide logic. In this article, I discuss how I handled a view controller specific logic in response to the application’s lifecycle events.</p>
<h1 id="approach">Approach</h1>
<p>Luckily for me, the platform sends notifications in response to a change in app’s lifecycle events as highlighted in the <a target='_blank' rel='noopener noreferrer'  href="https://developer.apple.com/documentation/uikit/uiapplicationdelegate">documentation</a>:</p>
<ul>
<li><strong>didBecomeActiveNotification</strong>: Posted when the app becomes active.</li>
<li><strong>didEnterBackgroundNotification</strong>: Posted when the app enters the background.</li>
<li><strong>willEnterForegroundNotification</strong>: Posted when the app is entering the foreground.</li>
<li><strong>willResignActiveNotification</strong>: Posted when the app is no longer active.</li>
<li><strong>willTerminateNotification</strong>: Posted when the app is about to terminate.</li>
</ul>
<p>A typical usage registers the containing view controller as an observer to the desired notification perhaps in the <em>init</em> method. The registration also takes an objc method to callback when the notification is received.</p>
<pre><code><span class="hljs-selector-tag">NotificationCenter</span><span class="hljs-selector-class">.default</span><span class="hljs-selector-class">.addObserver</span>(<span class="hljs-selector-tag">self</span>, <span class="hljs-selector-tag">selector</span>: <span class="hljs-selector-id">#selector</span>(<span class="hljs-selector-tag">onAppDidEnterBackground</span>), <span class="hljs-selector-tag">name</span>: <span class="hljs-selector-tag">UIApplication</span><span class="hljs-selector-class">.didEnterBackgroundNotification</span>, <span class="hljs-selector-tag">object</span>: <span class="hljs-selector-tag">nil</span>)
</code></pre><p>Your callback method in the view controller will have such a signature:</p>
<pre><code><span class="hljs-meta">@objc</span> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">onAppDidEnterBackground</span><span class="hljs-params">()</span></span> {
   <span class="hljs-comment">// some awesome logic</span>
}
</code></pre><h1 id="conclusion">Conclusion</h1>
<p>This works for me since the view controller is the root controller. For modally presented view controllers, I can, and probably would, use the <strong>view*</strong> lifecycle callbacks to achieve the same e.g. <em>viewWillDisappear()</em>.</p>
]]></content:encoded></item><item><title><![CDATA[Learning Android/iOS development]]></title><description><![CDATA[Starting out development
My first programming language to learn was Visual Basic 6. I had this book that gave a nice introduction to the language with all the Sub…End Sub, Dim title() As String etc. Using forms with drag and drop support, I’d create ...]]></description><link>https://charlesmuchene.com/learning-android-ios-development</link><guid isPermaLink="true">https://charlesmuchene.com/learning-android-ios-development</guid><category><![CDATA[newbie]]></category><category><![CDATA[Android]]></category><category><![CDATA[iOS]]></category><dc:creator><![CDATA[Charles Muchene]]></dc:creator><pubDate>Sun, 26 Apr 2020 06:02:59 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1587882055291/47GD4h9i7.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="starting-out-development">Starting out development</h1>
<p>My first programming language to learn was <em>Visual Basic 6</em>. I had this book that gave a nice introduction to the language with all the <em>Sub…End Sub</em>, <em>Dim title() As String</em> etc. Using forms with drag and drop support, I’d create beautiful UI on my PC that gave me that super power I longed for — <em>instructing a computer to do what I want</em>. If you think about it, that’s what programming is all about.</p>
<p>I desired to write mobile apps but didn’t know where to start. My research led to <em>Java2ME</em> and NetBeans 6.0 was installed. I toyed around with this new found tech but lacked a proper introduction to the language used — Java.</p>
<p>If I remember correctly, the first Java book to encounter on was <a target='_blank' rel='noopener noreferrer'  href="https://www.oreilly.com/library/view/sams-teach-yourself/9780133755848/">Teach Yourself Java in 21 days</a>. Such a quick walk through of the language! Later on, I found out about <a target='_blank' rel='noopener noreferrer'  href="http://deitel.com/Books/Java/JavaHowtoProgramLateObjectsVersion11e/tabid/3685/Default.aspx">Deitel &amp; Deitel, Java How to Program</a><em>, 6th Edition</em> and I fell in love with their books and mode of teaching. Armed with these, I went on to write <em>routines</em> for those pesky maze games on the Java2ME platform.</p>
<h1 id="android-programming">Android Programming</h1>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1587881765381/Zqfg2502_.jpeg" alt="android.jpeg"></p>
<p>I first laid my hands on Android development at a Google event dubbed</p>
<p><strong>gKenya 2.0</strong> (I think I also attended <em>gKenya 1.0</em> 🤔). I’m surprised the schedule is still up <a target='_blank' rel='noopener noreferrer'  href="https://sites.google.com/site/gkenya20/">here</a> at the time of writing. Day 2 was the most interesting as it was focused on developers. Someone at the event made a remark:</p>
<blockquote>
<p>If you know Java, you know 50% Android development!</p>
</blockquote>
<p>That was my cue. How true this was, I left it to chance. I learnt the basics; Activities, Services, Broadcast Receiver and Content Providers. This got me going as I continued to learn from the official documentation and samples I would gather online + Stack Overflow. I have written several hobby apps since then (just <a target='_blank' rel='noopener noreferrer'  href="https://play.google.com/store/apps/details?id=com.charlesmuchene.kotlin.learn">published</a> one of them — <a target='_blank' rel='noopener noreferrer'  href="https://github.com/charlesmuchene/learn-kotlin-app">open source</a>) and also had a chance to be a consultant on an app rewrite; Ionic to native Android.</p>
<p>Full time employment as a mobile application developer altered the course of my development career. Writing a hobby app is one thing. Delivering a business solution is another. Being in a work environment adheres to two major points:</p>
<ul>
<li>Delivering quality solutions</li>
<li>Delivering those solutions in a timeframe</li>
</ul>
<p>These two requirements seem paradoxical for a beginner/junior developer but experience teaches you that’s how a business runs. To the first point, you need to learn Computer Science fundamentals; commonly used data structures such as arrays, sets, lists, maps, hash tables etc as well as have some skills in problem solving — knowing how and when to use these data structures alongside common techniques like Dynamic Programming or general recursion. My two go to practice sites are the famous <a target='_blank' rel='noopener noreferrer'  href="https://leetcode.com/">LeetCode</a> and <a target='_blank' rel='noopener noreferrer'  href="https://codesignal.com/">CodeSignal</a>. <a target='_blank' rel='noopener noreferrer'  href="https://www.pramp.com/">Pramp</a> is also a good resource especially for interview-like preparation.</p>
<h1 id="ios-programming">iOS Programming</h1>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1587881783172/KEoGMVOUr.jpeg" alt="ios.jpeg"></p>
<p>Diving into iOS was by self-inflicted fire. I had to deliver a clone of an Android app within the shortest time possible. I mention this in the introductory section of another <a target='_blank' rel='noopener noreferrer'  href="/@charlesmuchene/activity-vs-uiviewcontroller-lifecycle-5a7a5a2e219f">article</a>. <a target='_blank' rel='noopener noreferrer'  href="https://developer.apple.com/library/archive/referencelibrary/GettingStarted/DevelopiOSAppsSwift/">Official documentation</a> served me well for this task as well as samples online for a couple of features. YouTube tutorials from <a target='_blank' rel='noopener noreferrer'  href="https://www.youtube.com/channel/UCuP2vJ6kRutQBfRmdcI92mA">Brian Voong</a>, <a target='_blank' rel='noopener noreferrer'  href="https://www.youtube.com/channel/UCbTw29mcP12YlTt1EpUaVJw">Sean Allen</a>, <a target='_blank' rel='noopener noreferrer'  href="https://www.youtube.com/channel/UCAK-zGL8Gf7oZQciX4JZvbA/">Cocoacasts</a>, <a target='_blank' rel='noopener noreferrer'  href="https://www.youtube.com/channel/UCysEngjfeIYapEER9K8aikw">Brian Advent</a> among others came in handy in bootstrapping my iOS learning journey. Awesome writers such <a target='_blank' rel='noopener noreferrer'  href="https://www.swiftbysundell.com/">John Sundell</a> and <a target='_blank' rel='noopener noreferrer'  href="https://www.hackingwithswift.com/">Paul Hudson</a> keep me up to date with content. I am currently reading <a target='_blank' rel='noopener noreferrer'  href="https://www.amazon.com/iOS-13-Programming-Fundamentals-Swift/dp/1492074535">iOS 13 Programming fundamentals</a>, a great book by <a target='_blank' rel='noopener noreferrer'  href="https://twitter.com/mattneub">Matt Neuberg</a>.</p>
<hr>
<p>YouTube has been a great resource in my learning. I’ve watched videos from <a target='_blank' rel='noopener noreferrer'  href="https://www.youtube.com/channel/UCCBVCTuk6uJrN3iFV_3vurg">Devoxx</a>, <a target='_blank' rel='noopener noreferrer'  href="https://www.youtube.com/user/androiddevelopers">Android Dev Summit &amp; Google IO</a>, WWDC <a target='_blank' rel='noopener noreferrer'  href="https://www.youtube.com/channel/UC-ngzACBMva8T81KEyIwwmQ">videos</a>, <a target='_blank' rel='noopener noreferrer'  href="https://www.youtube.com/channel/UCD8yeTczadqdARzQUp29PJw">William Fiset</a> (Graph theory + Data Structures) and <a target='_blank' rel='noopener noreferrer'  href="https://www.youtube.com/channel/UClEEsT7DkdVO_fkrBw0OTrA">My Code School</a> (Algorithms and DS).</p>
<h1 id="conclusion">Conclusion</h1>
<p>I engage a lot with my peers on their view on development and find out how they keep up with the industry: books, conference videos, code labs, tutorials, blog posts, twitter, OSS and podcasts among others come up as some ways to learn content. I write apps using Swift, Kotlin and Java. These 3 languages, in addition to the various frameworks and libraries on Android and iOS, sure keep me learning something everyday. Keep learning!</p>
<h1 id="resources">Resources</h1>
<h2 id="data-structures-algorithms">Data Structures + Algorithms</h2>
<ul>
<li><a target='_blank' rel='noopener noreferrer'  href="https://www.youtube.com/channel/UCD8yeTczadqdARzQUp29PJw">William Fiset</a></li>
<li><a target='_blank' rel='noopener noreferrer'  href="https://www.youtube.com/channel/UClEEsT7DkdVO_fkrBw0OTrA">My Code School</a></li>
<li><a target='_blank' rel='noopener noreferrer'  href="https://mitpress.mit.edu/books/introduction-algorithms-third-edition">Introduction to Algorithms</a></li>
<li><a target='_blank' rel='noopener noreferrer'  href="https://leetcode.com/">LeetCode</a></li>
<li><a target='_blank' rel='noopener noreferrer'  href="https://codesignal.com/">CodeSignal</a></li>
<li><a target='_blank' rel='noopener noreferrer'  href="https://www.hackerrank.com/">HackerRank</a></li>
<li><a target='_blank' rel='noopener noreferrer'  href="https://medium.com/basecs">BaseCS</a></li>
</ul>
<h2 id="ios">iOS</h2>
<ul>
<li><a target='_blank' rel='noopener noreferrer'  href="https://www.oreilly.com/library/view/ios-13-programming/9781492074526/">Matt Neuburg</a></li>
<li><a target='_blank' rel='noopener noreferrer'  href="https://www.swiftbysundell.com/">John Sundell</a></li>
<li><a target='_blank' rel='noopener noreferrer'  href="https://www.hackingwithswift.com/">Paul Hudson</a></li>
<li><a target='_blank' rel='noopener noreferrer'  href="https://developer.apple.com/videos/">WWDC + other videos</a></li>
<li><a target='_blank' rel='noopener noreferrer'  href="https://github.com/kickstarter/ios-oss">Kickstarter iOS OSS</a></li>
<li><a target='_blank' rel='noopener noreferrer'  href="https://www.youtube.com/channel/UCysEngjfeIYapEER9K8aikw">Brian Advent</a></li>
<li><a target='_blank' rel='noopener noreferrer'  href="https://www.youtube.com/channel/UCAK-zGL8Gf7oZQciX4JZvbA">Cocoacasts</a></li>
<li><a target='_blank' rel='noopener noreferrer'  href="https://www.youtube.com/channel/UCbTw29mcP12YlTt1EpUaVJw">Sean Allen</a></li>
<li><a target='_blank' rel='noopener noreferrer'  href="https://www.youtube.com/channel/UCuP2vJ6kRutQBfRmdcI92mA">Brian Voong</a></li>
</ul>
<h2 id="android">Android</h2>
<ul>
<li><a target='_blank' rel='noopener noreferrer'  href="https://kotlinlang.org/docs/reference/">Kotlin</a></li>
<li><a target='_blank' rel='noopener noreferrer'  href="https://www.youtube.com/user/androiddevelopers">Android Dev Summit + IO</a></li>
<li><a target='_blank' rel='noopener noreferrer'  href="https://codelabs.developers.google.com/">Codelabs</a></li>
<li><a target='_blank' rel='noopener noreferrer'  href="https://www.youtube.com/channel/UCCBVCTuk6uJrN3iFV_3vurg">Devoxx</a></li>
<li><a target='_blank' rel='noopener noreferrer'  href="https://github.com/kickstarter/android-oss">Kickstarter Android OSS</a></li>
<li><a target='_blank' rel='noopener noreferrer'  href="https://fragmentedpodcast.com/">Fragmented Podcast</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[A day with Kotlin Strings]]></title><description><![CDATA[Characters 101

Tl;dr A string is a linear sequence of characters.

A character is a symbol representing a digit or letter say 7 or @. Computers in essence see these as sequences of 0s and 1s and thus we need a way to translate them from what we huma...]]></description><link>https://charlesmuchene.com/a-day-with-kotlin-strings</link><guid isPermaLink="true">https://charlesmuchene.com/a-day-with-kotlin-strings</guid><category><![CDATA[Kotlin]]></category><dc:creator><![CDATA[Charles Muchene]]></dc:creator><pubDate>Sat, 25 Apr 2020 10:26:29 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1587807902442/tPtfkFKqT.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="characters-101">Characters 101</h1>
<blockquote>
<p>Tl;dr A string is a linear sequence of characters.</p>
</blockquote>
<p>A character is a symbol representing a digit or letter say 7 or @. Computers in essence see these as sequences of 0s and 1s and thus we need a way to translate them from what we humans know and interpret them as to what computers can understand and this is called <code>character encoding</code>.</p>
<p>In computing, you&#39;ve definitely come across the most popular of these encodings -- ASCII (<em>American Standard Code for Information Interchange</em>). As a standard, it gives us a way to encode (represent) upper and lower case English letters, numbers, and punctuation symbols mapped to 7-bit numbers and thus it can only encode a maximum of 128 characters.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1587799208954/E0G-KmJhD.jpeg" alt="strings.001.jpeg"></p>
<p>On a side note, the folks at <a target='_blank' rel='noopener noreferrer'  href="http://ansi.org/">ANSI</a> who came up with this encoding did a clever thing. They set the MSB to <code>1</code> and started counting from <code>1</code> to represent upper case <code>A</code> and these follow in sequence till <code>Z</code>. The same was done for lower case letters but with a <code>11</code> prefix. This makes it easy to know the position of the character in the alphabet given its <em>LSB bits</em>. See the illustration below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1587799347693/SMotDtKF7.jpeg" alt="strings.002.jpeg"></p>
<p>To make things interesting, we&#39;ve evolved to create more and more encodings to suite our communication needs separately and this bred incompatibilities when communicating across language or region boundaries. Therefore a standard was adopted - <code>Unicode</code> maintained by the <a target='_blank' rel='noopener noreferrer'  href="https://home.unicode.org/">Unicode Consortium</a>. This encoding supports a large character set (ASCII got the privilege of being a subset of this set encoding the first 128 characters). As of this writing, the specification can represent <strong>143,859</strong> characters!</p>
<p><em>Unicode</em> is often defined as <em>UTF-8</em>, <em>UTF-16</em> or <em>UTF-32</em> where <em>UTF</em> stands for <code>Unicode Transformation Format</code> and the number for the number of digits used to represent each character. Being a large character set, Unicode therefore facilitates encoding of the ever evolving characters like emojis 😎. Specification <a target='_blank' rel='noopener noreferrer'  href="http://www.unicode.org/versions/Unicode13.0.0/">13.0.0</a> added <strong>55</strong> new emoji characters!</p>
<h1 id="the-kotlin-char-">The Kotlin <code>Char</code></h1>
<p>As at version 1.3.72, the Kotlin language guarantees the following character sets to be available on every implementation of the JVM platform.</p>
<ul>
<li><strong>UTF_8</strong>: (<em>Eight-bit UCS Transformation Format.</em>)</li>
<li><strong>UTF_16</strong>: (<em>Sixteen-bit UCS Transformation Format, byte order identified by an optional byte-order mark.</em>)</li>
<li><strong>UTF_16BE</strong>: (<em>Sixteen-bit UCS Transformation Format, big-endian byte order.</em>)</li>
<li><strong>UTF_16LE</strong>: (<em>Sixteen-bit UCS Transformation Format, little-endian byte order.</em>)</li>
<li><strong>US_ASCII</strong>: (<em>Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the Unicode character set.</em>)</li>
<li><strong>ISO_8859_1</strong>: (<em>ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1.</em>)</li>
<li><strong>UTF_32</strong>: (<em>32-bit Unicode (or UCS) Transformation Format, byte order identified by an optional byte-order mark</em>)</li>
<li><strong>UTF_32LE</strong>: (<em>32-bit Unicode (or UCS) Transformation Format, little-endian byte order.</em>)</li>
<li><strong>UTF_32BE</strong>: (<em>32-bit Unicode (or UCS) Transformation Format, big-endian byte order.</em>)</li>
</ul>
<p>Kotlin <a target='_blank' rel='noopener noreferrer'  href="https://kotlinlang.org/docs/reference/basic-types.html#characters">characters</a> are represented by the <code>Char</code> type. Literals are surrounded by single quotes e.g. &#39;F&#39; or &#39;\u1F069&#39;. With that primer on characters, let&#39;s look at Strings. </p>
<h1 id="the-kotlin-string-">The Kotlin <code>String</code></h1>
<p>This is represented by the type <code>String</code> and is a classic example of an immutable type i.e. when you form a sequence of characters and need to alter their order, insert, remove or any kind of mutation, a new instance is created to reflect this.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1587803366608/R3QjBOh2x.jpeg" alt="strings.001.jpeg"></p>
<p>The <code>String</code> type in Kotlin conforms to the <code>CharSequence</code> interface. This interface gives us 3 useful members.</p>
<pre><code><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">CharSequence</span> </span>{

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">val</span> length: <span class="hljs-built_in">Int</span>

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">operator</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">get</span><span class="hljs-params">(index: <span class="hljs-type">Int</span>)</span></span>: <span class="hljs-built_in">Char</span>

    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">subSequence</span><span class="hljs-params">(startIndex: <span class="hljs-type">Int</span>, endIndex: <span class="hljs-type">Int</span>)</span></span>: CharSequence
}
</code></pre><p>These are self documenting. Highlighting the second one, <code>get(index:)</code> is defined as an operator and allows us to index <code>Char</code>s in a String via a subscript with a 0-based index:</p>
<pre><code><span class="hljs-keyword">val</span> name = <span class="hljs-string">"SenseiDev"</span>

println(name[<span class="hljs-number">6</span>]) <span class="hljs-comment">// D</span>
</code></pre><p>The Kotlin String definition on the JVM is as follows:</p>
<pre><code><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">String</span> : <span class="hljs-type">Comparable</span>&lt;<span class="hljs-type">String</span>&gt;, <span class="hljs-type">CharSequence {</span></span>
    <span class="hljs-keyword">companion</span> <span class="hljs-keyword">object</span> {}

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">operator</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">plus</span><span class="hljs-params">(other: <span class="hljs-type">Any</span>?)</span></span>: String

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">val</span> length: <span class="hljs-built_in">Int</span>

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">get</span><span class="hljs-params">(index: <span class="hljs-type">Int</span>)</span></span>: <span class="hljs-built_in">Char</span>

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">subSequence</span><span class="hljs-params">(startIndex: <span class="hljs-type">Int</span>, endIndex: <span class="hljs-type">Int</span>)</span></span>: CharSequence

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">compareTo</span><span class="hljs-params">(other: <span class="hljs-type">String</span>)</span></span>: <span class="hljs-built_in">Int</span>
}
</code></pre><p>Remember all classes are final in Kotlin, hence enforcing the immutability highlighted earlier.  As seen above, there are some additions to what the <code>CharSequence</code> interface defines that are particular to the <code>String</code> type.</p>
<ol>
<li><code>plus</code> operator. This allows us to concatenate strings with the <code>+</code> operator e.g. <code>&quot;SenseiDev&quot; + 5</code>. (NB: the definition of the <code>+</code> operator is defined on the <code>String</code> type and hence it is not commutative i.e. it&#39;s a compile error to define <code>5 + &quot;SenseiDev&quot;</code> -- unless you have such an extension function on <em>Int</em>)!</li>
<li>A <code>String</code> can be compared to another <code>String</code> as allowed by the <code>Comparable</code> interface and the <code>compareTo</code> method.</li>
<li>An empty companion object</li>
</ol>
<p>The Kotlin compiler has other neat tricks e.g it allows you to:</p>
<ul>
<li>Create <code>String</code> instances from literals e.g. <code>val language = &quot;Kotlin&quot;</code></li>
<li>Express literal raw <code>String</code> using triple quotes: <strong>&quot;&quot;&quot;</strong></li>
<li>Add template expressions to <code>String</code> literals e.g. <code>val displayAmount = &quot;Ksh. ${quantity * basePrice}&quot;</code></li>
</ul>
<h2 id="the-jvm-bridge">The JVM Bridge</h2>
<p>You might be wondering, &quot;Wait a minute. That&#39;s weird. Those are very few members on the String class while we have much more functionality from the class in our JVM programs e.g. <em>toUpperCase()</em>, <em>replace()</em>, etc.&quot; Well, you&#39;re right my friend. Kotlin has a whole hundreds-of-lines file called <code>StringsJVM.kt</code> in the package <code>kotlin.text</code> that defines all your favorite methods as <em>extension functions</em> on the <code>CharSequence</code> interface, the <code>String</code> class or its <code>companion object</code> and this is the file where most (if not all) of the JVM bridging is defined.</p>
<p>One fascinating highlight in the <code>StringsJVM.kt</code> file are the constructor-seeming function calls that are single line expressions to construct a <code>String</code> e.g. <code>String(chars: CharArray)</code>. To remove function call overhead, these functions are declared as <code>inline</code>. This depicts how Kotlin language features (top-level functions and inline functions) work together while improving developer productivity.</p>
<h1 id="conclusion">Conclusion</h1>
<p>We use the <code>String</code> class so often when writing our programs as it&#39;s useful in expressing a lot from our real world. String manipulation and the available operations are clearly important to understand as a developer. To dig deeper, I came across an <a target='_blank' rel='noopener noreferrer'  href="https://www.baeldung.com/java-string-pool">article</a> on Baeldung that discusses String interning in the JVM and some of the changes in regards to treating the String class. Check it out.</p>
<p>This article covered some fundamentals of the String class and the APIs exposed by the Kotlin Language in regards to the representing Strings. Happy coding!</p>
<h1 id="references">References</h1>
<ul>
<li><a target='_blank' rel='noopener noreferrer'  href="https://home.unicode.org/">Unicode Consortium</a></li>
<li><a target='_blank' rel='noopener noreferrer'  href="https://techterms.com/definition/characterencoding">Tech Terms</a></li>
<li><a target='_blank' rel='noopener noreferrer'  href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/-charsets/">Kotlin Character Sets</a> </li>
<li><a target='_blank' rel='noopener noreferrer'  href="https://kotlinlang.org/docs/reference/basic-types.html">Kotlin Basic Types</a></li>
</ul>
]]></content:encoded></item></channel></rss>