<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title>Kotlin - Tag - ISLAND</title><link>https://youngxhui.top/en/tags/kotlin/</link><description>Kotlin - Tag - ISLAND</description><generator>Hugo -- gohugo.io</generator><language>en</language><managingEditor>youngxhui@gmail.com (youngxhui)</managingEditor><webMaster>youngxhui@gmail.com (youngxhui)</webMaster><copyright>This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.</copyright><lastBuildDate>Tue, 19 May 2026 00:00:00 +0800</lastBuildDate><atom:link href="https://youngxhui.top/en/tags/kotlin/" rel="self" type="application/rss+xml"/><item><title>From Monolith iOS to Kotlin Multiplatform: SugarLite's Incremental Migration</title><link>https://youngxhui.top/en/2026/05/sugarlite-kmp-migration/</link><pubDate>Tue, 19 May 2026 00:00:00 +0800</pubDate><author><name>youngxhui</name></author><guid>https://youngxhui.top/en/2026/05/sugarlite-kmp-migration/</guid><description><![CDATA[<div class="featured-image">
                <img src="https://island-hexo.oss-cn-beijing.aliyuncs.com/20260519191237432.png" referrerpolicy="no-referrer">
            </div><p><a href="https://apps.apple.com/us/app/sugarlite/id6753901096" target="_blank" rel="noopener noreferrer">SugarLite</a> started as a pure iOS app built with SwiftUI + MVVM + Supabase Swift SDK. When the Android version became a priority, copying the business logic over to Kotlin would have doubled the maintenance burden — network layer, data models, and business rules all needed dual-platform upkeep. That&rsquo;s why we chose <strong>Kotlin Multiplatform</strong>: the <code>shared/</code> module carries all cross-platform business logic, while the iOS side only keeps SwiftUI and system framework calls (HealthKit, SwiftData, WidgetKit).</p>
<p>This post walks through the entire migration — from architectural refactoring to CI/CD adaptation, the pitfalls we hit, and what we learned along the way.</p>
<h2 id="-pre-migration-mvvm-clean-architecture-refactoring" class="headerLink">
    <a href="#-pre-migration-mvvm-clean-architecture-refactoring" class="header-mark"></a>🏗️ Pre-Migration: MVVM Clean Architecture Refactoring</h2><p>Before introducing KMP, we did an architectural refactor. The core goal was straightforward: decouple ViewModels from any external frameworks so that swapping out the underlying layer for Kotlin wouldn&rsquo;t ripple upward.</p>
<p>The resulting dependency flow:</p>
<div class="code-block highlight is-open show-line-numbers  tw:group tw:my-2">
  <div class="
    
    tw:flex 
    tw:flex-row
    tw:flex-1 
    tw:justify-between 
    tw:w-full tw:bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw:mx-2 
        tw:flex
        tw:flex-row
        tw:flex-1"
      aria-hidden="true">
          <span class="tw:group-[.is-open]:rotate-90 tw:transition-[transform] tw:duration-500 tw:ease-in-out tw:print:hidden! tw:w-min tw:h-min tw:my-1 tw:mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></span>
          <span class="tw:select-none tw:my-1! tw:block">text</span>
      </button>

   <div class="tw:flex">
      <button 
        class="
          line-number-button
          tw:mx-2 
          tw:hidden 
          tw:group-[.is-open]:block 
          tw:group-[.show-line-numbers]:text-fgColor-link 
          tw:print:hidden!" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw:select-none 
          tw:mx-2 
          tw:hidden 
          tw:group-[.is-open]:block 
          tw:group-[.is-wrap]:text-fgColor-link 
          tw:print:hidden!" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw:select-none
          tw:mx-2 
          tw:hidden
          tw:group-[.is-open]:block
          tw:hover:text-fgColor-link 
          tw:print:hidden!"
        title="Copy code">
          <span class="copy-icon tw:block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw:hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw:select-none 
          tw:mx-2 
          tw:block 
          tw:group-[.is-open]:hidden 
          tw:print:hidden!" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw:block tw:m-0 tw:p-0"><code 
    id="codeblock-id-27" 
    class="
      chroma 
      tw:block! 
      tw:p-0
      tw:m-0
      tw:transition-[max-height] 
      tw:duration-500 
      tw:ease-in-out 
      tw:group-[.is-closed]:max-h-0! 
      tw:group-[.is-wrap]:text-wrap
      tw:overflow-y-hidden
      tw:overflow-x-auto
      tw:scrollbar-thin
      "><span class="line"><span class="cl">View → ViewModel → Protocol ← Repository → External Frameworks</span></span></code></pre>
</div>
<p>Layer responsibilities:</p>
<table>
  <thead>
      <tr>
          <th>Layer</th>
          <th>Directory</th>
          <th>Allowed Imports</th>
          <th>Constraints</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>View</td>
          <td><code>Views/</code></td>
          <td>SwiftUI only</td>
          <td>Must not access Repository directly</td>
      </tr>
      <tr>
          <td>ViewModel</td>
          <td><code>ViewModels/</code></td>
          <td>Foundation only</td>
          <td>Must not import Supabase/HealthKit/SwiftData</td>
      </tr>
      <tr>
          <td>Domain</td>
          <td><code>Domain/</code></td>
          <td>Foundation</td>
          <td>Define Protocol, UseCase, Service</td>
      </tr>
      <tr>
          <td>Data</td>
          <td><code>Repositories/</code> + <code>Data/</code></td>
          <td>Any framework</td>
          <td>The only layer allowed to import Supabase, SwiftData</td>
      </tr>
  </tbody>
</table>
<p>The value of this refactoring became crystal clear later on: when we swapped the Supabase client from Swift SDK to the KMP shared module, the ViewModel layer required zero changes — it only depends on interfaces like <code>FoodReferenceRepositoryProtocol</code>, not on whether the implementation is Swift or Kotlin.</p>
<h2 id="-introducing-the-kmp-project-baseline" class="headerLink">
    <a href="#-introducing-the-kmp-project-baseline" class="header-mark"></a>📦 Introducing the KMP Project Baseline</h2><p>After the architecture cleanup, we introduced KMP. The project root structure became:</p>
<div class="code-block highlight is-open show-line-numbers  tw:group tw:my-2">
  <div class="
    
    tw:flex 
    tw:flex-row
    tw:flex-1 
    tw:justify-between 
    tw:w-full tw:bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw:mx-2 
        tw:flex
        tw:flex-row
        tw:flex-1"
      aria-hidden="true">
          <span class="tw:group-[.is-open]:rotate-90 tw:transition-[transform] tw:duration-500 tw:ease-in-out tw:print:hidden! tw:w-min tw:h-min tw:my-1 tw:mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></span>
          <span class="tw:select-none tw:my-1! tw:block">text</span>
      </button>

   <div class="tw:flex">
      <button 
        class="
          line-number-button
          tw:mx-2 
          tw:hidden 
          tw:group-[.is-open]:block 
          tw:group-[.show-line-numbers]:text-fgColor-link 
          tw:print:hidden!" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw:select-none 
          tw:mx-2 
          tw:hidden 
          tw:group-[.is-open]:block 
          tw:group-[.is-wrap]:text-fgColor-link 
          tw:print:hidden!" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw:select-none
          tw:mx-2 
          tw:hidden
          tw:group-[.is-open]:block
          tw:hover:text-fgColor-link 
          tw:print:hidden!"
        title="Copy code">
          <span class="copy-icon tw:block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw:hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw:select-none 
          tw:mx-2 
          tw:block 
          tw:group-[.is-open]:hidden 
          tw:print:hidden!" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw:block tw:m-0 tw:p-0"><code 
    id="codeblock-id-28" 
    class="
      chroma 
      tw:block! 
      tw:p-0
      tw:m-0
      tw:transition-[max-height] 
      tw:duration-500 
      tw:ease-in-out 
      tw:group-[.is-closed]:max-h-0! 
      tw:group-[.is-wrap]:text-wrap
      tw:overflow-y-hidden
      tw:overflow-x-auto
      tw:scrollbar-thin
      "><span class="line"><span class="cl">├── iosApp/                    # Original iOS project moved here
</span></span><span class="line"><span class="cl">│   ├── BloodSugarApp/         # SwiftUI source
</span></span><span class="line"><span class="cl">│   ├── BloodSugarApp.xcodeproj
</span></span><span class="line"><span class="cl">│   └── ci_scripts/            # Xcode Cloud build scripts
</span></span><span class="line"><span class="cl">├── composeApp/                # Compose Multiplatform (Android entry point)
</span></span><span class="line"><span class="cl">├── shared/                    # KMP shared module
</span></span><span class="line"><span class="cl">│   ├── src/commonMain/kotlin/ # Cross-platform business logic
</span></span><span class="line"><span class="cl">│   ├── src/androidMain/kotlin/
</span></span><span class="line"><span class="cl">│   └── src/iosMain/kotlin/
</span></span><span class="line"><span class="cl">├── gradle/
</span></span><span class="line"><span class="cl">├── build.gradle.kts
</span></span><span class="line"><span class="cl">└── settings.gradle.kts</span></span></code></pre>
</div>
<p>Key configuration in <code>shared/build.gradle.kts</code>:</p>
<div class="code-block highlight is-open show-line-numbers  tw:group tw:my-2">
  <div class="
    
    tw:flex 
    tw:flex-row
    tw:flex-1 
    tw:justify-between 
    tw:w-full tw:bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw:mx-2 
        tw:flex
        tw:flex-row
        tw:flex-1"
      aria-hidden="true">
          <span class="tw:group-[.is-open]:rotate-90 tw:transition-[transform] tw:duration-500 tw:ease-in-out tw:print:hidden! tw:w-min tw:h-min tw:my-1 tw:mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></span>
          <span class="tw:select-none tw:my-1! tw:block">kotlin</span>
      </button>

   <div class="tw:flex">
      <button 
        class="
          line-number-button
          tw:mx-2 
          tw:hidden 
          tw:group-[.is-open]:block 
          tw:group-[.show-line-numbers]:text-fgColor-link 
          tw:print:hidden!" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw:select-none 
          tw:mx-2 
          tw:hidden 
          tw:group-[.is-open]:block 
          tw:group-[.is-wrap]:text-fgColor-link 
          tw:print:hidden!" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw:select-none
          tw:mx-2 
          tw:hidden
          tw:group-[.is-open]:block
          tw:hover:text-fgColor-link 
          tw:print:hidden!"
        title="Copy code">
          <span class="copy-icon tw:block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw:hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw:select-none 
          tw:mx-2 
          tw:block 
          tw:group-[.is-open]:hidden 
          tw:print:hidden!" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw:block tw:m-0 tw:p-0"><code 
    id="codeblock-id-29" 
    class="
      chroma 
      tw:block! 
      tw:p-0
      tw:m-0
      tw:transition-[max-height] 
      tw:duration-500 
      tw:ease-in-out 
      tw:group-[.is-closed]:max-h-0! 
      tw:group-[.is-wrap]:text-wrap
      tw:overflow-y-hidden
      tw:overflow-x-auto
      tw:scrollbar-thin
      "><span class="line"><span class="cl"><span class="n">kotlin</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">android</span> <span class="p">{</span> <span class="o">..</span><span class="p">.</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">listOf</span><span class="p">(</span><span class="n">iosX64</span><span class="p">(),</span> <span class="n">iosArm64</span><span class="p">(),</span> <span class="n">iosSimulatorArm64</span><span class="p">()).</span><span class="n">forEach</span> <span class="p">{</span> <span class="n">iosTarget</span> <span class="o">-&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="n">iosTarget</span><span class="p">.</span><span class="n">binaries</span><span class="p">.</span><span class="n">framework</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">baseName</span> <span class="p">=</span> <span class="s2">&#34;Shared&#34;</span>
</span></span><span class="line"><span class="cl">            <span class="n">isStatic</span> <span class="p">=</span> <span class="k">true</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">sourceSets</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">commonMain</span><span class="p">.</span><span class="n">dependencies</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">implementation</span><span class="p">(</span><span class="n">libs</span><span class="p">.</span><span class="n">kotlinx</span><span class="p">.</span><span class="n">serialization</span><span class="p">.</span><span class="n">json</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="n">implementation</span><span class="p">(</span><span class="n">libs</span><span class="p">.</span><span class="n">kotlinx</span><span class="p">.</span><span class="n">coroutines</span><span class="p">.</span><span class="n">core</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="n">implementation</span><span class="p">(</span><span class="n">libs</span><span class="p">.</span><span class="n">kotlinx</span><span class="p">.</span><span class="n">datetime</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="n">api</span><span class="p">(</span><span class="n">libs</span><span class="p">.</span><span class="n">supabase</span><span class="p">.</span><span class="n">auth</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="n">api</span><span class="p">(</span><span class="n">libs</span><span class="p">.</span><span class="n">supabase</span><span class="p">.</span><span class="n">postgrest</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="n">api</span><span class="p">(</span><span class="n">libs</span><span class="p">.</span><span class="n">supabase</span><span class="p">.</span><span class="n">storage</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="n">api</span><span class="p">(</span><span class="n">libs</span><span class="p">.</span><span class="n">ktor</span><span class="p">.</span><span class="n">client</span><span class="p">.</span><span class="n">core</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="n">implementation</span><span class="p">(</span><span class="n">libs</span><span class="p">.</span><span class="n">koin</span><span class="p">.</span><span class="n">core</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="n">androidMain</span><span class="p">.</span><span class="n">dependencies</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">implementation</span><span class="p">(</span><span class="n">libs</span><span class="p">.</span><span class="n">ktor</span><span class="p">.</span><span class="n">client</span><span class="p">.</span><span class="n">cio</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="n">iosMain</span><span class="p">.</span><span class="n">dependencies</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">implementation</span><span class="p">(</span><span class="n">libs</span><span class="p">.</span><span class="n">ktor</span><span class="p">.</span><span class="n">client</span><span class="p">.</span><span class="n">darwin</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
</div>
<p>Two design decisions worth noting:</p>
<ol>
<li><strong><code>isStatic = true</code></strong>: A static framework avoids dynamic library signing issues in Xcode Cloud builds.</li>
<li><strong><code>api(libs.supabase.*)</code></strong>: Supabase libraries are exposed as API dependencies. The iOS side could theoretically use them directly, but we hide the details behind a wrapper layer.</li>
</ol>
<h2 id="-sinking-the-data-layer-supabase-swift-sdk--kmp-shared" class="headerLink">
    <a href="#-sinking-the-data-layer-supabase-swift-sdk--kmp-shared" class="header-mark"></a>🔄 Sinking the Data Layer: Supabase Swift SDK → KMP Shared</h2><p>This is the most critical step — moving all Supabase calls scattered across iOS repositories down into <code>shared/src/commonMain/kotlin/</code>.</p>
<h3 id="dto-layer" class="headerLink">
    <a href="#dto-layer" class="header-mark"></a>DTO Layer</h3><p>Created <code>@Serializable</code> Kotlin DTOs for all 13 tables, using <code>snake_case</code> for field mapping:</p>
<div class="code-block highlight is-open show-line-numbers  tw:group tw:my-2">
  <div class="
    
    tw:flex 
    tw:flex-row
    tw:flex-1 
    tw:justify-between 
    tw:w-full tw:bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw:mx-2 
        tw:flex
        tw:flex-row
        tw:flex-1"
      aria-hidden="true">
          <span class="tw:group-[.is-open]:rotate-90 tw:transition-[transform] tw:duration-500 tw:ease-in-out tw:print:hidden! tw:w-min tw:h-min tw:my-1 tw:mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></span>
          <span class="tw:select-none tw:my-1! tw:block">kotlin</span>
      </button>

   <div class="tw:flex">
      <button 
        class="
          line-number-button
          tw:mx-2 
          tw:hidden 
          tw:group-[.is-open]:block 
          tw:group-[.show-line-numbers]:text-fgColor-link 
          tw:print:hidden!" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw:select-none 
          tw:mx-2 
          tw:hidden 
          tw:group-[.is-open]:block 
          tw:group-[.is-wrap]:text-fgColor-link 
          tw:print:hidden!" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw:select-none
          tw:mx-2 
          tw:hidden
          tw:group-[.is-open]:block
          tw:hover:text-fgColor-link 
          tw:print:hidden!"
        title="Copy code">
          <span class="copy-icon tw:block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw:hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw:select-none 
          tw:mx-2 
          tw:block 
          tw:group-[.is-open]:hidden 
          tw:print:hidden!" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw:block tw:m-0 tw:p-0"><code 
    id="codeblock-id-30" 
    class="
      chroma 
      tw:block! 
      tw:p-0
      tw:m-0
      tw:transition-[max-height] 
      tw:duration-500 
      tw:ease-in-out 
      tw:group-[.is-closed]:max-h-0! 
      tw:group-[.is-wrap]:text-wrap
      tw:overflow-y-hidden
      tw:overflow-x-auto
      tw:scrollbar-thin
      "><span class="line"><span class="cl"><span class="nd">@Serializable</span>
</span></span><span class="line"><span class="cl"><span class="k">data</span> <span class="k">class</span> <span class="nc">FoodReferenceDto</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">id</span><span class="p">:</span> <span class="n">String</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">name</span><span class="p">:</span> <span class="n">String</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">name</span><span class="n">_en</span><span class="p">:</span> <span class="n">String</span><span class="p">?</span> <span class="p">=</span> <span class="k">null</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">category</span><span class="p">:</span> <span class="n">String</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">gi</span><span class="n">_value</span><span class="p">:</span> <span class="n">Int</span><span class="p">?</span> <span class="p">=</span> <span class="k">null</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">calories</span><span class="p">:</span> <span class="n">Double</span><span class="p">?</span> <span class="p">=</span> <span class="k">null</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// ...
</span></span></span><span class="line"><span class="cl"><span class="p">)</span></span></span></code></pre>
</div>
<h3 id="cloudsource-wrappers" class="headerLink">
    <a href="#cloudsource-wrappers" class="header-mark"></a>CloudSource Wrappers</h3><p>Each domain entity gets a <code>CloudSource</code> that encapsulates CRUD operations:</p>
<div class="code-block highlight is-open show-line-numbers  tw:group tw:my-2">
  <div class="
    
    tw:flex 
    tw:flex-row
    tw:flex-1 
    tw:justify-between 
    tw:w-full tw:bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw:mx-2 
        tw:flex
        tw:flex-row
        tw:flex-1"
      aria-hidden="true">
          <span class="tw:group-[.is-open]:rotate-90 tw:transition-[transform] tw:duration-500 tw:ease-in-out tw:print:hidden! tw:w-min tw:h-min tw:my-1 tw:mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></span>
          <span class="tw:select-none tw:my-1! tw:block">kotlin</span>
      </button>

   <div class="tw:flex">
      <button 
        class="
          line-number-button
          tw:mx-2 
          tw:hidden 
          tw:group-[.is-open]:block 
          tw:group-[.show-line-numbers]:text-fgColor-link 
          tw:print:hidden!" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw:select-none 
          tw:mx-2 
          tw:hidden 
          tw:group-[.is-open]:block 
          tw:group-[.is-wrap]:text-fgColor-link 
          tw:print:hidden!" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw:select-none
          tw:mx-2 
          tw:hidden
          tw:group-[.is-open]:block
          tw:hover:text-fgColor-link 
          tw:print:hidden!"
        title="Copy code">
          <span class="copy-icon tw:block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw:hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw:select-none 
          tw:mx-2 
          tw:block 
          tw:group-[.is-open]:hidden 
          tw:print:hidden!" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw:block tw:m-0 tw:p-0"><code 
    id="codeblock-id-31" 
    class="
      chroma 
      tw:block! 
      tw:p-0
      tw:m-0
      tw:transition-[max-height] 
      tw:duration-500 
      tw:ease-in-out 
      tw:group-[.is-closed]:max-h-0! 
      tw:group-[.is-wrap]:text-wrap
      tw:overflow-y-hidden
      tw:overflow-x-auto
      tw:scrollbar-thin
      "><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">FoodReferenceCloudSource</span><span class="p">(</span><span class="k">private</span> <span class="k">val</span> <span class="py">client</span><span class="p">:</span> <span class="n">SupabaseClient</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">suspend</span> <span class="k">fun</span> <span class="nf">fetchAll</span><span class="p">():</span> <span class="n">List</span><span class="p">&lt;</span><span class="n">FoodReferenceDto</span><span class="p">&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">client</span><span class="p">.</span><span class="n">from</span><span class="p">(</span><span class="s2">&#34;food_reference&#34;</span><span class="p">).</span><span class="n">select</span><span class="p">().</span><span class="n">decodeList</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">suspend</span> <span class="k">fun</span> <span class="nf">fetchPage</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">page</span><span class="p">:</span> <span class="n">Int</span><span class="p">,</span> <span class="n">pageSize</span><span class="p">:</span> <span class="n">Int</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">searchText</span><span class="p">:</span> <span class="n">String</span><span class="p">?,</span> <span class="n">category</span><span class="p">:</span> <span class="n">String</span><span class="p">?</span>
</span></span><span class="line"><span class="cl">    <span class="p">):</span> <span class="n">List</span><span class="p">&lt;</span><span class="n">FoodReferenceDto</span><span class="p">&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// Build PostgREST query...
</span></span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
</div>
<h3 id="koin-di-module" class="headerLink">
    <a href="#koin-di-module" class="header-mark"></a>Koin DI Module</h3><p>All CloudSources are registered in the <code>sharedModule</code>:</p>
<div class="code-block highlight is-open show-line-numbers  tw:group tw:my-2">
  <div class="
    
    tw:flex 
    tw:flex-row
    tw:flex-1 
    tw:justify-between 
    tw:w-full tw:bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw:mx-2 
        tw:flex
        tw:flex-row
        tw:flex-1"
      aria-hidden="true">
          <span class="tw:group-[.is-open]:rotate-90 tw:transition-[transform] tw:duration-500 tw:ease-in-out tw:print:hidden! tw:w-min tw:h-min tw:my-1 tw:mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></span>
          <span class="tw:select-none tw:my-1! tw:block">kotlin</span>
      </button>

   <div class="tw:flex">
      <button 
        class="
          line-number-button
          tw:mx-2 
          tw:hidden 
          tw:group-[.is-open]:block 
          tw:group-[.show-line-numbers]:text-fgColor-link 
          tw:print:hidden!" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw:select-none 
          tw:mx-2 
          tw:hidden 
          tw:group-[.is-open]:block 
          tw:group-[.is-wrap]:text-fgColor-link 
          tw:print:hidden!" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw:select-none
          tw:mx-2 
          tw:hidden
          tw:group-[.is-open]:block
          tw:hover:text-fgColor-link 
          tw:print:hidden!"
        title="Copy code">
          <span class="copy-icon tw:block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw:hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw:select-none 
          tw:mx-2 
          tw:block 
          tw:group-[.is-open]:hidden 
          tw:print:hidden!" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw:block tw:m-0 tw:p-0"><code 
    id="codeblock-id-32" 
    class="
      chroma 
      tw:block! 
      tw:p-0
      tw:m-0
      tw:transition-[max-height] 
      tw:duration-500 
      tw:ease-in-out 
      tw:group-[.is-closed]:max-h-0! 
      tw:group-[.is-wrap]:text-wrap
      tw:overflow-y-hidden
      tw:overflow-x-auto
      tw:scrollbar-thin
      "><span class="line"><span class="cl"><span class="k">val</span> <span class="py">sharedModule</span> <span class="p">=</span> <span class="n">module</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">single</span> <span class="p">{</span> <span class="nc">SupabaseClientProvider</span><span class="p">.</span><span class="n">client</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="n">single</span> <span class="p">{</span> <span class="n">FoodReferenceCloudSource</span><span class="p">(</span><span class="k">get</span><span class="p">())</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="n">single</span> <span class="p">{</span> <span class="n">BloodSugarCloudSource</span><span class="p">(</span><span class="k">get</span><span class="p">())</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// ...
</span></span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
</div>
<h2 id="-incremental-adoption-on-ios" class="headerLink">
    <a href="#-incremental-adoption-on-ios" class="header-mark"></a>🔌 Incremental Adoption on iOS</h2><p>KMP migration doesn&rsquo;t have to happen all at once. Our strategy was: &ldquo;new features go straight into KMP; old code gets replaced gradually.&rdquo; Here&rsquo;s how we migrated <code>FoodReferenceRepository</code>:</p>
<h3 id="bridging-layer" class="headerLink">
    <a href="#bridging-layer" class="header-mark"></a>Bridging Layer</h3><p>First, expose Koin container instances to Swift. In <code>iosMain</code>:</p>
<div class="code-block highlight is-open show-line-numbers  tw:group tw:my-2">
  <div class="
    
    tw:flex 
    tw:flex-row
    tw:flex-1 
    tw:justify-between 
    tw:w-full tw:bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw:mx-2 
        tw:flex
        tw:flex-row
        tw:flex-1"
      aria-hidden="true">
          <span class="tw:group-[.is-open]:rotate-90 tw:transition-[transform] tw:duration-500 tw:ease-in-out tw:print:hidden! tw:w-min tw:h-min tw:my-1 tw:mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></span>
          <span class="tw:select-none tw:my-1! tw:block">kotlin</span>
      </button>

   <div class="tw:flex">
      <button 
        class="
          line-number-button
          tw:mx-2 
          tw:hidden 
          tw:group-[.is-open]:block 
          tw:group-[.show-line-numbers]:text-fgColor-link 
          tw:print:hidden!" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw:select-none 
          tw:mx-2 
          tw:hidden 
          tw:group-[.is-open]:block 
          tw:group-[.is-wrap]:text-fgColor-link 
          tw:print:hidden!" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw:select-none
          tw:mx-2 
          tw:hidden
          tw:group-[.is-open]:block
          tw:hover:text-fgColor-link 
          tw:print:hidden!"
        title="Copy code">
          <span class="copy-icon tw:block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw:hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw:select-none 
          tw:mx-2 
          tw:block 
          tw:group-[.is-open]:hidden 
          tw:print:hidden!" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw:block tw:m-0 tw:p-0"><code 
    id="codeblock-id-33" 
    class="
      chroma 
      tw:block! 
      tw:p-0
      tw:m-0
      tw:transition-[max-height] 
      tw:duration-500 
      tw:ease-in-out 
      tw:group-[.is-closed]:max-h-0! 
      tw:group-[.is-wrap]:text-wrap
      tw:overflow-y-hidden
      tw:overflow-x-auto
      tw:scrollbar-thin
      "><span class="line"><span class="cl"><span class="k">fun</span> <span class="nf">doInitKoin</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">startKoin</span> <span class="p">{</span> <span class="n">modules</span><span class="p">(</span><span class="n">sharedModule</span><span class="p">)</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
</div>
<p>In <code>commonMain</code>, expose accessor functions:</p>
<div class="code-block highlight is-open show-line-numbers  tw:group tw:my-2">
  <div class="
    
    tw:flex 
    tw:flex-row
    tw:flex-1 
    tw:justify-between 
    tw:w-full tw:bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw:mx-2 
        tw:flex
        tw:flex-row
        tw:flex-1"
      aria-hidden="true">
          <span class="tw:group-[.is-open]:rotate-90 tw:transition-[transform] tw:duration-500 tw:ease-in-out tw:print:hidden! tw:w-min tw:h-min tw:my-1 tw:mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></span>
          <span class="tw:select-none tw:my-1! tw:block">kotlin</span>
      </button>

   <div class="tw:flex">
      <button 
        class="
          line-number-button
          tw:mx-2 
          tw:hidden 
          tw:group-[.is-open]:block 
          tw:group-[.show-line-numbers]:text-fgColor-link 
          tw:print:hidden!" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw:select-none 
          tw:mx-2 
          tw:hidden 
          tw:group-[.is-open]:block 
          tw:group-[.is-wrap]:text-fgColor-link 
          tw:print:hidden!" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw:select-none
          tw:mx-2 
          tw:hidden
          tw:group-[.is-open]:block
          tw:hover:text-fgColor-link 
          tw:print:hidden!"
        title="Copy code">
          <span class="copy-icon tw:block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw:hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw:select-none 
          tw:mx-2 
          tw:block 
          tw:group-[.is-open]:hidden 
          tw:print:hidden!" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw:block tw:m-0 tw:p-0"><code 
    id="codeblock-id-34" 
    class="
      chroma 
      tw:block! 
      tw:p-0
      tw:m-0
      tw:transition-[max-height] 
      tw:duration-500 
      tw:ease-in-out 
      tw:group-[.is-closed]:max-h-0! 
      tw:group-[.is-wrap]:text-wrap
      tw:overflow-y-hidden
      tw:overflow-x-auto
      tw:scrollbar-thin
      "><span class="line"><span class="cl"><span class="k">private</span> <span class="k">object</span> <span class="nc">KoinProvider</span> <span class="p">:</span> <span class="n">KoinComponent</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">fun</span> <span class="nf">provideFoodReferenceCloudSource</span><span class="p">():</span> <span class="n">FoodReferenceCloudSource</span> <span class="p">=</span> <span class="k">get</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">fun</span> <span class="nf">getFoodReferenceCloudSource</span><span class="p">():</span> <span class="n">FoodReferenceCloudSource</span> <span class="p">=</span>
</span></span><span class="line"><span class="cl">    <span class="nc">KoinProvider</span><span class="p">.</span><span class="n">provideFoodReferenceCloudSource</span><span class="p">()</span></span></span></code></pre>
</div>
<p>Kotlin top-level functions compile to Swift global functions, so the iOS side can directly call <code>CloudSourceProviderKt.getFoodReferenceCloudSource()</code>.</p>
<h3 id="app-launch-initialization" class="headerLink">
    <a href="#app-launch-initialization" class="header-mark"></a>App Launch Initialization</h3><p>In the SwiftUI entry point&rsquo;s <code>init()</code>:</p>
<div class="code-block highlight is-open show-line-numbers  tw:group tw:my-2">
  <div class="
    
    tw:flex 
    tw:flex-row
    tw:flex-1 
    tw:justify-between 
    tw:w-full tw:bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw:mx-2 
        tw:flex
        tw:flex-row
        tw:flex-1"
      aria-hidden="true">
          <span class="tw:group-[.is-open]:rotate-90 tw:transition-[transform] tw:duration-500 tw:ease-in-out tw:print:hidden! tw:w-min tw:h-min tw:my-1 tw:mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></span>
          <span class="tw:select-none tw:my-1! tw:block">swift</span>
      </button>

   <div class="tw:flex">
      <button 
        class="
          line-number-button
          tw:mx-2 
          tw:hidden 
          tw:group-[.is-open]:block 
          tw:group-[.show-line-numbers]:text-fgColor-link 
          tw:print:hidden!" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw:select-none 
          tw:mx-2 
          tw:hidden 
          tw:group-[.is-open]:block 
          tw:group-[.is-wrap]:text-fgColor-link 
          tw:print:hidden!" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw:select-none
          tw:mx-2 
          tw:hidden
          tw:group-[.is-open]:block
          tw:hover:text-fgColor-link 
          tw:print:hidden!"
        title="Copy code">
          <span class="copy-icon tw:block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw:hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw:select-none 
          tw:mx-2 
          tw:block 
          tw:group-[.is-open]:hidden 
          tw:print:hidden!" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw:block tw:m-0 tw:p-0"><code 
    id="codeblock-id-35" 
    class="
      chroma 
      tw:block! 
      tw:p-0
      tw:m-0
      tw:transition-[max-height] 
      tw:duration-500 
      tw:ease-in-out 
      tw:group-[.is-closed]:max-h-0! 
      tw:group-[.is-wrap]:text-wrap
      tw:overflow-y-hidden
      tw:overflow-x-auto
      tw:scrollbar-thin
      "><span class="line"><span class="cl"><span class="kd">init</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">KoinHelperKt</span><span class="p">.</span><span class="n">doInitKoin</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">AppLogger</span><span class="p">.</span><span class="n">database</span><span class="p">.</span><span class="n">info</span><span class="p">(</span><span class="s">&#34;KMP Koin initialized&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
</div>
<h3 id="repository-transformation" class="headerLink">
    <a href="#repository-transformation" class="header-mark"></a>Repository Transformation</h3><p><strong>Before</strong> (Swift Supabase SDK):</p>
<div class="code-block highlight is-open show-line-numbers  tw:group tw:my-2">
  <div class="
    
    tw:flex 
    tw:flex-row
    tw:flex-1 
    tw:justify-between 
    tw:w-full tw:bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw:mx-2 
        tw:flex
        tw:flex-row
        tw:flex-1"
      aria-hidden="true">
          <span class="tw:group-[.is-open]:rotate-90 tw:transition-[transform] tw:duration-500 tw:ease-in-out tw:print:hidden! tw:w-min tw:h-min tw:my-1 tw:mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></span>
          <span class="tw:select-none tw:my-1! tw:block">swift</span>
      </button>

   <div class="tw:flex">
      <button 
        class="
          line-number-button
          tw:mx-2 
          tw:hidden 
          tw:group-[.is-open]:block 
          tw:group-[.show-line-numbers]:text-fgColor-link 
          tw:print:hidden!" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw:select-none 
          tw:mx-2 
          tw:hidden 
          tw:group-[.is-open]:block 
          tw:group-[.is-wrap]:text-fgColor-link 
          tw:print:hidden!" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw:select-none
          tw:mx-2 
          tw:hidden
          tw:group-[.is-open]:block
          tw:hover:text-fgColor-link 
          tw:print:hidden!"
        title="Copy code">
          <span class="copy-icon tw:block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw:hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw:select-none 
          tw:mx-2 
          tw:block 
          tw:group-[.is-open]:hidden 
          tw:print:hidden!" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw:block tw:m-0 tw:p-0"><code 
    id="codeblock-id-36" 
    class="
      chroma 
      tw:block! 
      tw:p-0
      tw:m-0
      tw:transition-[max-height] 
      tw:duration-500 
      tw:ease-in-out 
      tw:group-[.is-closed]:max-h-0! 
      tw:group-[.is-wrap]:text-wrap
      tw:overflow-y-hidden
      tw:overflow-x-auto
      tw:scrollbar-thin
      "><span class="line"><span class="cl"><span class="kd">import</span> <span class="nc">Supabase</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">final</span> <span class="kd">class</span> <span class="nc">FoodReferenceRepository</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="kd">var</span> <span class="nv">supabaseClient</span><span class="p">:</span> <span class="n">SupabaseClient</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">func</span> <span class="nf">fetchAll</span><span class="p">()</span> <span class="n">async</span> <span class="kr">throws</span> <span class="p">-&gt;</span> <span class="p">[</span><span class="n">FoodReferenceDTO</span><span class="p">]</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="kd">let</span> <span class="nv">dtos</span><span class="p">:</span> <span class="p">[</span><span class="n">FoodReferenceDTO</span><span class="p">]</span> <span class="p">=</span> <span class="k">try</span> <span class="n">await</span> <span class="n">supabaseClient</span>
</span></span><span class="line"><span class="cl">            <span class="p">.</span><span class="n">from</span><span class="p">(</span><span class="s">&#34;food_reference&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">.</span><span class="n">select</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">            <span class="p">.</span><span class="n">execute</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">            <span class="p">.</span><span class="n">value</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">dtos</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
</div>
<p><strong>After</strong> (KMP CloudSource):</p>
<div class="code-block highlight is-open show-line-numbers  tw:group tw:my-2">
  <div class="
    
    tw:flex 
    tw:flex-row
    tw:flex-1 
    tw:justify-between 
    tw:w-full tw:bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw:mx-2 
        tw:flex
        tw:flex-row
        tw:flex-1"
      aria-hidden="true">
          <span class="tw:group-[.is-open]:rotate-90 tw:transition-[transform] tw:duration-500 tw:ease-in-out tw:print:hidden! tw:w-min tw:h-min tw:my-1 tw:mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></span>
          <span class="tw:select-none tw:my-1! tw:block">swift</span>
      </button>

   <div class="tw:flex">
      <button 
        class="
          line-number-button
          tw:mx-2 
          tw:hidden 
          tw:group-[.is-open]:block 
          tw:group-[.show-line-numbers]:text-fgColor-link 
          tw:print:hidden!" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw:select-none 
          tw:mx-2 
          tw:hidden 
          tw:group-[.is-open]:block 
          tw:group-[.is-wrap]:text-fgColor-link 
          tw:print:hidden!" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw:select-none
          tw:mx-2 
          tw:hidden
          tw:group-[.is-open]:block
          tw:hover:text-fgColor-link 
          tw:print:hidden!"
        title="Copy code">
          <span class="copy-icon tw:block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw:hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw:select-none 
          tw:mx-2 
          tw:block 
          tw:group-[.is-open]:hidden 
          tw:print:hidden!" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw:block tw:m-0 tw:p-0"><code 
    id="codeblock-id-37" 
    class="
      chroma 
      tw:block! 
      tw:p-0
      tw:m-0
      tw:transition-[max-height] 
      tw:duration-500 
      tw:ease-in-out 
      tw:group-[.is-closed]:max-h-0! 
      tw:group-[.is-wrap]:text-wrap
      tw:overflow-y-hidden
      tw:overflow-x-auto
      tw:scrollbar-thin
      "><span class="line"><span class="cl"><span class="kd">import</span> <span class="nc">Shared</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">final</span> <span class="kd">class</span> <span class="nc">FoodReferenceRepository</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="kd">let</span> <span class="nv">cloudSource</span><span class="p">:</span> <span class="n">FoodReferenceCloudSource</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">init</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="kc">self</span><span class="p">.</span><span class="n">cloudSource</span> <span class="p">=</span> <span class="n">CloudSourceProviderKt</span><span class="p">.</span><span class="n">getFoodReferenceCloudSource</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">func</span> <span class="nf">fetchAll</span><span class="p">()</span> <span class="n">async</span> <span class="kr">throws</span> <span class="p">-&gt;</span> <span class="p">[</span><span class="n">FoodReferenceDTO</span><span class="p">]</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="kd">let</span> <span class="nv">kmpDtos</span> <span class="p">=</span> <span class="k">try</span> <span class="n">await</span> <span class="n">cloudSource</span><span class="p">.</span><span class="n">fetchAll</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">kmpDtos</span><span class="p">.</span><span class="bp">map</span> <span class="p">{</span> <span class="n">FoodReferenceDTO</span><span class="p">(</span><span class="n">fromKmp</span><span class="p">:</span> <span class="nv">$0</span><span class="p">)</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
</div>
<p>Only three things changed: <code>import Supabase</code> → <code>import Shared</code>, raw PostgREST queries → wrapped <code>cloudSource.fetchAll()</code>, and a new <code>fromKmp</code> DTO conversion helper.</p>
<p>This pattern can be replicated for every repository. The team can migrate one at a time, in priority order.</p>
<h2 id="-xcode-cloud-cicd-adaptation" class="headerLink">
    <a href="#-xcode-cloud-cicd-adaptation" class="header-mark"></a>⚙️ Xcode Cloud CI/CD Adaptation</h2><p>The biggest challenge after introducing KMP was CI/CD. Xcode Cloud build environments don&rsquo;t include Java or Gradle by default, yet our iOS builds now depend on the <code>Shared.framework</code> compiled by Kotlin/Native.</p>
<h3 id="ci_pre_xcodebuildsh-environment-setup" class="headerLink">
    <a href="#ci_pre_xcodebuildsh-environment-setup" class="header-mark"></a>ci_pre_xcodebuild.sh: Environment Setup</h3><p>We handle Java and Gradle installation in Xcode Cloud&rsquo;s <code>ci_pre_xcodebuild.sh</code> phase:</p>
<div class="code-block highlight is-closed show-line-numbers  tw:group tw:my-2">
  <div class="
    
    tw:flex 
    tw:flex-row
    tw:flex-1 
    tw:justify-between 
    tw:w-full tw:bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw:mx-2 
        tw:flex
        tw:flex-row
        tw:flex-1"
      aria-hidden="true">
          <span class="tw:group-[.is-open]:rotate-90 tw:transition-[transform] tw:duration-500 tw:ease-in-out tw:print:hidden! tw:w-min tw:h-min tw:my-1 tw:mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></span>
          <span class="tw:select-none tw:my-1! tw:block">bash</span>
      </button>

   <div class="tw:flex">
      <button 
        class="
          line-number-button
          tw:mx-2 
          tw:hidden 
          tw:group-[.is-open]:block 
          tw:group-[.show-line-numbers]:text-fgColor-link 
          tw:print:hidden!" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw:select-none 
          tw:mx-2 
          tw:hidden 
          tw:group-[.is-open]:block 
          tw:group-[.is-wrap]:text-fgColor-link 
          tw:print:hidden!" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw:select-none
          tw:mx-2 
          tw:hidden
          tw:group-[.is-open]:block
          tw:hover:text-fgColor-link 
          tw:print:hidden!"
        title="Copy code">
          <span class="copy-icon tw:block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw:hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw:select-none 
          tw:mx-2 
          tw:block 
          tw:group-[.is-open]:hidden 
          tw:print:hidden!" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw:block tw:m-0 tw:p-0"><code 
    id="codeblock-id-38" 
    class="
      chroma 
      tw:block! 
      tw:p-0
      tw:m-0
      tw:transition-[max-height] 
      tw:duration-500 
      tw:ease-in-out 
      tw:group-[.is-closed]:max-h-0! 
      tw:group-[.is-wrap]:text-wrap
      tw:overflow-y-hidden
      tw:overflow-x-auto
      tw:scrollbar-thin
      "><span class="line"><span class="cl"><span class="cp">#!/bin/sh
</span></span></span><span class="line"><span class="cl"><span class="nb">set</span> -euo pipefail
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">ROOT_DIR</span><span class="o">=</span><span class="s2">&#34;</span><span class="k">$(</span><span class="nb">cd</span> <span class="s2">&#34;</span><span class="k">$(</span>dirname <span class="s2">&#34;</span><span class="nv">$0</span><span class="s2">&#34;</span><span class="k">)</span><span class="s2">/../..&#34;</span> <span class="o">&amp;&amp;</span> <span class="nb">pwd</span><span class="k">)</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">cd</span> <span class="s2">&#34;</span><span class="nv">$ROOT_DIR</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">GRADLE_USER_HOME</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$ROOT_DIR</span><span class="s2">/.gradle&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">HOMEBREW_NO_AUTO_UPDATE</span><span class="o">=</span><span class="m">1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">resolve_java_home<span class="o">()</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="o">[</span> -n <span class="s2">&#34;</span><span class="si">${</span><span class="nv">JAVA_HOME</span><span class="k">:-</span><span class="si">}</span><span class="s2">&#34;</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="o">[</span> -x <span class="s2">&#34;</span><span class="nv">$JAVA_HOME</span><span class="s2">/bin/java&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    <span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$JAVA_HOME</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="m">0</span>
</span></span><span class="line"><span class="cl">  <span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">for</span> version in <span class="m">21</span> <span class="m">17</span> 11<span class="p">;</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="nv">JAVA_CANDIDATE</span><span class="o">=</span><span class="k">$(</span>/usr/libexec/java_home -v <span class="s2">&#34;</span><span class="nv">$version</span><span class="s2">&#34;</span> 2&gt;/dev/null<span class="k">)</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">      <span class="k">if</span> <span class="o">[</span> -x <span class="s2">&#34;</span><span class="nv">$JAVA_CANDIDATE</span><span class="s2">/bin/java&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">        <span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$JAVA_CANDIDATE</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="m">0</span>
</span></span><span class="line"><span class="cl">      <span class="k">fi</span>
</span></span><span class="line"><span class="cl">    <span class="k">fi</span>
</span></span><span class="line"><span class="cl">  <span class="k">done</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="nb">command</span> -v brew &gt;/dev/null 2&gt;<span class="p">&amp;</span>1<span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> formula in openjdk@17 openjdk<span class="p">;</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">      <span class="k">if</span> brew list --versions <span class="s2">&#34;</span><span class="nv">$formula</span><span class="s2">&#34;</span> &gt;/dev/null 2&gt;<span class="p">&amp;</span>1<span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">        <span class="nv">JAVA_CANDIDATE</span><span class="o">=</span><span class="s2">&#34;</span><span class="k">$(</span>brew --prefix <span class="s2">&#34;</span><span class="nv">$formula</span><span class="s2">&#34;</span><span class="k">)</span><span class="s2">/libexec/openjdk.jdk/Contents/Home&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="o">[</span> -x <span class="s2">&#34;</span><span class="nv">$JAVA_CANDIDATE</span><span class="s2">/bin/java&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">          <span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$JAVA_CANDIDATE</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">          <span class="k">return</span> <span class="m">0</span>
</span></span><span class="line"><span class="cl">        <span class="k">fi</span>
</span></span><span class="line"><span class="cl">      <span class="k">fi</span>
</span></span><span class="line"><span class="cl">    <span class="k">done</span>
</span></span><span class="line"><span class="cl">  <span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="m">1</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">ensure_java<span class="o">()</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="nv">JAVA_CANDIDATE</span><span class="o">=</span><span class="s2">&#34;</span><span class="k">$(</span>resolve_java_home<span class="k">)</span><span class="s2">&#34;</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    <span class="nb">export</span> <span class="nv">JAVA_HOME</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$JAVA_CANDIDATE</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="k">else</span>
</span></span><span class="line"><span class="cl">    <span class="nb">echo</span> <span class="s2">&#34;[Xcode Cloud] Java not found. Installing openjdk@17 via Homebrew...&#34;</span>
</span></span><span class="line"><span class="cl">    brew install openjdk@17
</span></span><span class="line"><span class="cl">    <span class="nb">export</span> <span class="nv">JAVA_HOME</span><span class="o">=</span><span class="s2">&#34;</span><span class="k">$(</span>brew --prefix openjdk@17<span class="k">)</span><span class="s2">/libexec/openjdk.jdk/Contents/Home&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="k">fi</span>
</span></span><span class="line"><span class="cl">  <span class="nb">export</span> <span class="nv">PATH</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$JAVA_HOME</span><span class="s2">/bin:</span><span class="nv">$PATH</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">ensure_java
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;[Xcode Cloud] JAVA_HOME=</span><span class="nv">$JAVA_HOME</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">java -version
</span></span><span class="line"><span class="cl">./gradlew --version</span></span></code></pre>
</div>
<h3 id="build-phase-script-compiling-the-kotlin-framework" class="headerLink">
    <a href="#build-phase-script-compiling-the-kotlin-framework" class="header-mark"></a>Build Phase Script: Compiling the Kotlin Framework</h3><p>A Run Script Phase added in Xcode&rsquo;s Build Phases:</p>
<div class="code-block highlight is-open show-line-numbers  tw:group tw:my-2">
  <div class="
    
    tw:flex 
    tw:flex-row
    tw:flex-1 
    tw:justify-between 
    tw:w-full tw:bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw:mx-2 
        tw:flex
        tw:flex-row
        tw:flex-1"
      aria-hidden="true">
          <span class="tw:group-[.is-open]:rotate-90 tw:transition-[transform] tw:duration-500 tw:ease-in-out tw:print:hidden! tw:w-min tw:h-min tw:my-1 tw:mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></span>
          <span class="tw:select-none tw:my-1! tw:block">bash</span>
      </button>

   <div class="tw:flex">
      <button 
        class="
          line-number-button
          tw:mx-2 
          tw:hidden 
          tw:group-[.is-open]:block 
          tw:group-[.show-line-numbers]:text-fgColor-link 
          tw:print:hidden!" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw:select-none 
          tw:mx-2 
          tw:hidden 
          tw:group-[.is-open]:block 
          tw:group-[.is-wrap]:text-fgColor-link 
          tw:print:hidden!" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw:select-none
          tw:mx-2 
          tw:hidden
          tw:group-[.is-open]:block
          tw:hover:text-fgColor-link 
          tw:print:hidden!"
        title="Copy code">
          <span class="copy-icon tw:block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw:hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw:select-none 
          tw:mx-2 
          tw:block 
          tw:group-[.is-open]:hidden 
          tw:print:hidden!" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw:block tw:m-0 tw:p-0"><code 
    id="codeblock-id-39" 
    class="
      chroma 
      tw:block! 
      tw:p-0
      tw:m-0
      tw:transition-[max-height] 
      tw:duration-500 
      tw:ease-in-out 
      tw:group-[.is-closed]:max-h-0! 
      tw:group-[.is-wrap]:text-wrap
      tw:overflow-y-hidden
      tw:overflow-x-auto
      tw:scrollbar-thin
      "><span class="line"><span class="cl"><span class="cp">#!/bin/sh
</span></span></span><span class="line"><span class="cl"><span class="nb">set</span> -euo pipefail
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">ROOT_DIR</span><span class="o">=</span><span class="s2">&#34;</span><span class="k">$(</span><span class="nb">cd</span> <span class="s2">&#34;</span><span class="k">$(</span>dirname <span class="s2">&#34;</span><span class="nv">$0</span><span class="s2">&#34;</span><span class="k">)</span><span class="s2">/../..&#34;</span> <span class="o">&amp;&amp;</span> <span class="nb">pwd</span><span class="k">)</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">cd</span> <span class="s2">&#34;</span><span class="nv">$ROOT_DIR</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Xcode Preview optimization: skip Gradle build</span>
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED</span><span class="k">:-</span><span class="si">}</span><span class="s2">&#34;</span> <span class="o">=</span> <span class="s2">&#34;YES&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;Skipping Gradle build due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED=YES&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="nb">exit</span> <span class="m">0</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Resolve JAVA_HOME (same logic as ci_pre_xcodebuild.sh)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># ...</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">PATH</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$JAVA_HOME</span><span class="s2">/bin:</span><span class="nv">$PATH</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">./gradlew :shared:embedAndSignAppleFrameworkForXcode</span></span></code></pre>
</div>
<p>This script runs on every Xcode build, invoking the Gradle task to compile Kotlin/Native and embed the framework. For local development, we skip it during Xcode Previews via the <code>OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED</code> environment variable to avoid slowing things down.</p>
<h3 id="gotchas" class="headerLink">
    <a href="#gotchas" class="header-mark"></a>Gotchas</h3><p><strong>Sentry Script vs. Widget Extension Build Dependency Cycle</strong>: A cryptic build failure turned out to be an implicit dependency between Sentry&rsquo;s &ldquo;Upload Debug Symbols&rdquo; script and the Widget Extension&rsquo;s Embed phase. The fix was simple — just drag the Sentry script to run after the Embed phase.</p>
<p><strong>Unstable Java Runtime Resolution</strong>: Java installation paths vary across Xcode Cloud macOS images. Our final <code>resolve_java_home()</code> uses a multi-level fallback: system <code>JAVA_HOME</code> → <code>/usr/libexec/java_home</code> → Homebrew → <code>brew list</code>. This redundant lookup strategy ensures Java is found on any image version.</p>
<h2 id="-migration-strategy-what-we-learned" class="headerLink">
    <a href="#-migration-strategy-what-we-learned" class="header-mark"></a>📋 Migration Strategy: What We Learned</h2><p>Looking back, we followed a few principles:</p>
<ol>
<li><strong>DTOs/Models first</strong>: Data models have the fewest platform dependencies — sink them first.</li>
<li><strong>Repository Protocols next</strong>: Interfaces define contracts; implementations can stay on iOS for now.</li>
<li><strong>UseCases/Services after that</strong>: Pure computation logic is a natural fit for cross-platform.</li>
<li><strong>ViewModels stay put</strong>: Keep <code>@Observable</code> on iOS to preserve the SwiftUI reactive experience.</li>
<li><strong>New features go straight into KMP</strong>. For existing code, evaluate whether it can move to <code>shared/</code> when it gets touched. Don&rsquo;t migrate for migration&rsquo;s sake — avoid the &ldquo;big bang&rdquo; rewrite.</li>
</ol>
<h2 id="-references" class="headerLink">
    <a href="#-references" class="header-mark"></a>📚 References</h2><ul>
<li><a href="https://kotlinlang.org/docs/multiplatform.html" target="_blank" rel="noopener noreferrer">Kotlin Multiplatform Official Docs</a></li>
<li><a href="https://github.com/supabase-community/supabase-kt" target="_blank" rel="noopener noreferrer">Supabase Kotlin Client</a></li>
<li><a href="https://developer.apple.com/documentation/xcode/writing-custom-build-scripts" target="_blank" rel="noopener noreferrer">Xcode Cloud Custom Build Scripts</a></li>
</ul>
<hr>
<p><em>This post is based on the real migration process of the SugarLite project.</em></p>
]]></description></item></channel></rss>