<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Ben Whitley</title>
    <description>The latest articles on Forem by Ben Whitley (@benwhitley).</description>
    <link>https://forem.com/benwhitley</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F223063%2F076dc725-624f-4f9f-8411-c10da998a7e0.jpeg</url>
      <title>Forem: Ben Whitley</title>
      <link>https://forem.com/benwhitley</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/benwhitley"/>
    <language>en</language>
    <item>
      <title>Swift Closures in KMP</title>
      <dc:creator>Ben Whitley</dc:creator>
      <pubDate>Thu, 11 Jun 2020 14:09:06 +0000</pubDate>
      <link>https://forem.com/touchlab/swift-closures-in-kmp-12o7</link>
      <guid>https://forem.com/touchlab/swift-closures-in-kmp-12o7</guid>
      <description>&lt;p&gt;When working on the iOS side of Kotlin Multiplatform (KMP) projects, you'll probably find yourself using Swift closures to update your UI. At Touchlab, we find doing so to be best practice for most use cases. However, if you're not familiar with closures in Swift, they can pose a risk of creating strong reference cycles.&lt;/p&gt;

&lt;h1&gt;
  
  
  Opening the ARC
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LaWDXee---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2A68cg_JDHj4SDnj9tme6D_w.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LaWDXee---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2A68cg_JDHj4SDnj9tme6D_w.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before diving into an explanation of strong reference cycles and how to avoid them, first some broader context on the subject. The first thing to note is that Automatic Reference Counting (ARC) is what manages memory in Swift and Objective-C. For each object instance, it keeps count of the number of references to that instance, incrementing and decrementing it when references are created or destroyed, and ultimately reclaiming the memory when that count is zero.&lt;/p&gt;

&lt;p&gt;ARC is a huge topic all on its own, but know that it handles almost all of the work for you, almost all of the time, so that you don't have to worry about it. However, ARC isn't perfect, and we're here to go over one of the times that you do need to worry about it.&lt;/p&gt;

&lt;h1&gt;
  
  
  Getting Closures
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/3o6Mb7Vqfuk0n2p8Xu/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3o6Mb7Vqfuk0n2p8Xu/giphy.gif" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://i.giphy.com/media/xT5LMtGts8cNovyZEY/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/xT5LMtGts8cNovyZEY/giphy.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When writing Swift code that's calling a shared Kotlin library, closures are probably where developers are most likely to accidentally create a strong reference cycle. According to the official Swift documentation, "Closures can capture and store references to any constants and variables from the context in which they are defined." What this means is that any captured constant or variable will create a strong reference that ARC will maintain for the duration of the life of the closure, which could create a strong reference cycle.&lt;/p&gt;

&lt;p&gt;The most common risk is creating a strong reference to &lt;code&gt;self&lt;/code&gt; inside of a closure. For instance, in Kamp Kit iOS, we pass closures into the BreedModel. We use these closures to update the view when the data changes. In a larger, more complex app, a situation might arise where we want to deinitialize the ViewController, but not the BreedModel. The problem is that the closure captures &lt;code&gt;self&lt;/code&gt; - meaning the ViewController - so the ViewController cannot be deinitialized without specifying that the reference to self is weak.&lt;/p&gt;

&lt;h1&gt;
  
  
  Weak References
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/4tQmuMGdah3B6/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/4tQmuMGdah3B6/giphy.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can tell ARC that inside of your closure you want weak references to self instead of strong ones. You do this by declaring &lt;code&gt;[weak self]&lt;/code&gt; at the very beginning of your closure, before any parameter name declarations or anything else. THAT's how important it is. This essentially makes &lt;code&gt;self&lt;/code&gt; optional (Swift for nullable) inside of your closure.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_iVCBkfg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/0%2A3jQtykksQhcuofE7" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_iVCBkfg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/0%2A3jQtykksQhcuofE7" alt="Useful flowchart for deciding whether or not you should use [weak self] in your closure."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Escape from Current Context
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/QiFdVlxYkCupG/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/QiFdVlxYkCupG/giphy.gif" alt=""&gt;&lt;/a&gt;&lt;br&gt;
For those wondering how or why Swift has these language features that can lead to reference cycles, a brief moment in Swift's defense. Swift has a concept of escaping vs non-escaping closures. &lt;/p&gt;

&lt;p&gt;An escaping closure is one that is passed as an argument to a function, but may be called after that function returns. These are the types of closures you have to be careful with, and they're used frequently in KMP projects. &lt;/p&gt;

&lt;p&gt;Non-escaping closures are the default behavior in Swift, and tend to be more straightforward. Because they cannot escape their current context, they're more associated with synchronous code and code that doesn't capture references outside of its own scope. The &lt;code&gt;sort(by:)&lt;/code&gt; and &lt;code&gt;filter(_:)&lt;/code&gt; functions contain good examples of non-escaping closures.&lt;/p&gt;

&lt;p&gt;The Swift compiler will try to ensure that you know you're working with an escaping closure by forcing you to mark them with the &lt;code&gt;@escaping&lt;/code&gt; as a prefix to their type declaration. If you're working on a KMP project and you're not yet comfortable navigating Xcode, it can be difficult to confirm whether or not the closures you originally wrote in Kotlin are escaping or not, but you can check. &lt;strong&gt;Opt + Click&lt;/strong&gt; one of the constructor's parameter names to see its Swift declaration for yourself.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P8zIE01z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/0%2AtnAPNc4V9b8OZBtx" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P8zIE01z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/0%2AtnAPNc4V9b8OZBtx" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In KaMPKit, we pass in viewUpdate(for:) and errorUpdate(for:) closures into the BreedModel's constructor. The constructor is going to return/complete before those closures are ever called. Consequently, these closures must be escaping and require &lt;code&gt;[weak self]&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Guardians of the Nullability
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/ltBhl4BoHaMM/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/ltBhl4BoHaMM/giphy.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In Swift, like in Kotlin, nullability is represented with a &lt;code&gt;?&lt;/code&gt;. So after declaring &lt;code&gt;[weak self]&lt;/code&gt; at the beginning of your closure, all of the references to self inside of the closure are nullable and must be checked or unwrapped before use. Some developers accomplish this by immediately declaring &lt;code&gt;guard let self = self else { return }&lt;/code&gt; as the first line of a closure that declares &lt;code&gt;[weak self]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Without going too much into Swift guard statements (which are super cool), just know that this makes your reference to self into a strong reference for everything after it in its current scope IF self is not nil. If self is nil then the &lt;code&gt;else&lt;/code&gt; statement is executed and the closure returns. Nothing after the &lt;code&gt;else&lt;/code&gt; is executed.&lt;/p&gt;

&lt;p&gt;If the &lt;code&gt;self = self&lt;/code&gt; statement makes you uneasy, know that it's an officially supported Swift language feature, not a loophole or hack. You could also always do something more like this, to be as absolutely safe as possible:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Sp_AIoKj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/0%2A7kuMCR9_Ia8h1yD7" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Sp_AIoKj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/0%2A7kuMCR9_Ia8h1yD7" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Many, if not most, native iOS developers would probably find that excessive. The &lt;code&gt;print&lt;/code&gt; statement in particular is the Swift equivalent of driving with two hands on the wheel, leaning forward, 5 mph under the limit.&lt;/p&gt;

&lt;p&gt;The difference between unwrapping self and using optionals is more than just personal preference. If self is nil and you use a guard statement, then no code after the else statement will be executed. However, if you use self optionally in your closure, the lines of code in your closure without references to self will still be executed.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Swift is an essential part of the Kotlin Multiplatform mobile environment, so it's in your and your multiplatform mobile project's best interests to learn some of the finer points and best practices of Swift. Familiarity with concepts such as escaping closures and ARC will help you avoid some of the most common iOS-side mistakes in KMP projects. Those concepts are great jumping off points for learning more Swift. It's a truly fantastic language, capable of producing some of the most elegant and readable code that's out there.&lt;/p&gt;




&lt;h1&gt;
  
  
  Credit Where It's Due
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Closures, escaping, and preventing reference cycles in general are highly visible discussion topics in the S/O Swift community. There are too many posts and answers to link here, but I strongly recommend that community at large as a resource.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.swift.org/swift-book/LanguageGuide/Closures.html"&gt;https://docs.swift.org/swift-book/LanguageGuide/Closures.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.swift.org/swift-book/LanguageGuide/AutomaticReferenceCounting.html#ID56"&gt;https://docs.swift.org/swift-book/LanguageGuide/AutomaticReferenceCounting.html#ID56&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/flawless-app-stories/you-dont-always-need-weak-self-a778bec505ef"&gt;https://medium.com/flawless-app-stories/you-dont-always-need-weak-self-a778bec505ef&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.swiftbysundell.com/articles/capturing-objects-in-swift-closures/"&gt;https://www.swiftbysundell.com/articles/capturing-objects-in-swift-closures/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@bestiosdevelope/what-do-mean-escaping-and-nonescaping-closures-in-swift-d404d721f39d"&gt;https://medium.com/@bestiosdevelope/what-do-mean-escaping-and-nonescaping-closures-in-swift-d404d721f39d&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://fuckingclosuresyntax.com/"&gt;https://fuckingclosuresyntax.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Wholesome version: &lt;a href="http://goshdarnclosuresyntax.com/"&gt;http://goshdarnclosuresyntax.com/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>kotlin</category>
      <category>kotlinmultiplatform</category>
      <category>android</category>
      <category>ios</category>
    </item>
    <item>
      <title>Debug Kotlin with Xcode References</title>
      <dc:creator>Ben Whitley</dc:creator>
      <pubDate>Wed, 13 May 2020 14:54:32 +0000</pubDate>
      <link>https://forem.com/touchlab/debug-kotlin-with-xcode-references-7bd</link>
      <guid>https://forem.com/touchlab/debug-kotlin-with-xcode-references-7bd</guid>
      <description>&lt;p&gt;I’m going to share a very (very) simple, helpful, little trick if you want to debug a Kotlin shared framework within an iOS application. Adding Xcode references to the Kotlin files in your shared library will enable you to do frequently used development practices, such as setting breakpoints or opening files from a memory debugger.&lt;/p&gt;

&lt;p&gt;Before getting started though, it’s important to note that your shared Kotlin framework needs to be dynamic for these file references to be useful. If it isn’t, then any breakpoints you set in your Kotlin files in Xcode will not be hit. Other debugging tools and practices will not yield useful results such as function names and line numbers.&lt;/p&gt;

&lt;p&gt;If you don’t know how to get your shared Kotlin library to produce a dynamic framework, we’re using Touchlab’s &lt;a href="https://github.com/touchlab/KotlinCocoapods" rel="noopener noreferrer"&gt;fork of the Kotlin Multiplatform Cocoapods plugin&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Double or right click in the Project Navigator, which is the left side pane of Xcode that shows the project’s structure (shown below). &lt;/p&gt;

&lt;p&gt;First select &lt;strong&gt;New Group&lt;/strong&gt; from the dropdown and create a directory (“Kotlin Debug” in the example below). This is where we’re going to put the references. &lt;/p&gt;

&lt;p&gt;Next, double or right click your new directory in the Project Navigator and select &lt;strong&gt;Add Files to [Directory Name]&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;In the Finder window that appears, navigate to your shared Kotlin library. Feel free to add as many of the library files as you like, but I recommend just &lt;strong&gt;[Shared Kotlin Library]/src/commonMain/&lt;/strong&gt; and &lt;strong&gt;[Shared Kotlin Library]/src/iosMain/&lt;/strong&gt;. Together, those two directories contain all of the Kotlin files you may need to debug from your iOS application. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fakqtg2veya3u08djqr12.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fakqtg2veya3u08djqr12.png" alt="Project Navigator Dropdown Menu"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you’re using Instruments to debug memory issues in your shared Kotlin library, then you may need to close and reopen Xcode before Instruments is able to open your Kotlin files in the Xcode window containing your iOS project.&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>kotlinmultiplatform</category>
      <category>ios</category>
      <category>development</category>
    </item>
    <item>
      <title>Kotlin in iOS: Memory Debugging with Xcode and Instruments</title>
      <dc:creator>Ben Whitley</dc:creator>
      <pubDate>Wed, 13 May 2020 14:54:00 +0000</pubDate>
      <link>https://forem.com/touchlab/kotlin-in-ios-memory-debugging-with-xcode-and-instruments-2cc6</link>
      <guid>https://forem.com/touchlab/kotlin-in-ios-memory-debugging-with-xcode-and-instruments-2cc6</guid>
      <description>&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/mSlCVajRrIA"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;If you’re working on an iOS app that’s using a shared Kotlin library, you might be skeptical about your ability to debug memory issues. Not only is it possible, it’s actually really easy. And not only is it really easy, there’s a myriad of different ways to go about it, so you can choose whatever you like the most. &lt;/p&gt;

&lt;p&gt;I’m only going to focus on the way that I like to do it, but if you play around in Instruments, you might find a workflow you like even more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two Points on Project Configuration
&lt;/h2&gt;

&lt;p&gt;Before getting started, there are two configuration points to note. &lt;a href="https://github.com/touchlab/KaMPKit/" rel="noopener noreferrer"&gt;KaMPKit&lt;/a&gt;, the project in the accompanying video, comes fresh out of the box with these two points already in place.&lt;/p&gt;

&lt;p&gt;First: the iOS app will need a dynamic framework. If you need help producing one from your shared Kotlin library, checkout &lt;a href="https://github.com/touchlab/kotlincocoapods" rel="noopener noreferrer"&gt;this fork&lt;/a&gt; of the KMP Cocoapods plugin.&lt;/p&gt;

&lt;p&gt;Second: Xcode should have references to the Kotlin library files that are relevant to the iOS side. This point is optional, but recommended for debugging shared Kotlin libraries in general. Without Xcode references, the Kotlin files we find in Instruments will open in separate Xcode windows. If you don’t care about that, feel free to skip this one. Otherwise, for further explanation and help, &lt;a href="https://dev.to/touchlab/debug-kotlin-with-xcode-references-7bd"&gt;go here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Kotlin in Instruments
&lt;/h2&gt;

&lt;p&gt;In Xcode, go to &lt;strong&gt;Product → Profile&lt;/strong&gt; (or &lt;strong&gt;CMD + I&lt;/strong&gt;), which will launch Instruments. From all the options that appear, choose the Allocations tool. Make sure your target app is selected at the top. Click the red &lt;strong&gt;Record&lt;/strong&gt; button in the upper left. &lt;/p&gt;

&lt;p&gt;Reproduce the behavior that causes the memory issue, then stop recording. You’ll probably see a spike in activity in the Allocations line graph. Make sure that the lower view is set to &lt;strong&gt;Allocations → Call Trees → Call Tree&lt;/strong&gt;, like so:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9tvlg3g7tnaazapr379o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9tvlg3g7tnaazapr379o.png" alt="Kotlin in Instruments"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can inspect the call trees any number of different ways. One is to find the line containing your memory issue by going through the stacks and paying attention to the &lt;strong&gt;Bytes Used&lt;/strong&gt; column, but that’s inefficient and time consuming. &lt;/p&gt;

&lt;p&gt;Another option is the &lt;strong&gt;Involves Symbol&lt;/strong&gt; search bar at the bottom. Search for “kfun” (“Kotlin function”), which is a prefix for Kotlin functions that are exposed to the iOS side. That will narrow your search. &lt;/p&gt;

&lt;p&gt;One more option is the &lt;strong&gt;Heaviest Stack Trace&lt;/strong&gt; side view on right, which is highly likely to contain the memory issue you’re looking for. &lt;/p&gt;

&lt;p&gt;When you do finally find the symbol name you’re looking for in the call trees, right (or double) click it. In the dropdown that appears, select &lt;strong&gt;Reveal in Xcode&lt;/strong&gt;, which will pull up the relevant Kotlin file and line number in Xcode.&lt;/p&gt;

&lt;p&gt;As I said earlier, these are just a few ways that I found useful while exploring KaMPKit’s iOS project via Instruments. In exploring Instruments, you may well find a workflow you prefer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Future Research
&lt;/h2&gt;

&lt;p&gt;This is just the beginning of our exploration at Touchlab into debugging Kotlin for iOS. We’ve already created &lt;a href="https://github.com/touchlab/xcode-kotlin" rel="noopener noreferrer"&gt;an Xcode plugin&lt;/a&gt; for basic code highlighting and setting breakpoints. We’re also considering the possibility of creating a custom Instruments tool for Xcode projects consuming Kotlin libraries, unless we find another solution that we like even more. Either way, keep an eye out, because we’ll be sure to share what we find!&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>kotlinmultiplatform</category>
      <category>ios</category>
      <category>development</category>
    </item>
    <item>
      <title>Kotlin Multiplatform: Expect/Actuals in Less Than Five Minutes</title>
      <dc:creator>Ben Whitley</dc:creator>
      <pubDate>Wed, 11 Sep 2019 18:31:20 +0000</pubDate>
      <link>https://forem.com/benwhitley/kotlin-multiplatform-expect-actuals-in-less-than-five-minutes-8lo</link>
      <guid>https://forem.com/benwhitley/kotlin-multiplatform-expect-actuals-in-less-than-five-minutes-8lo</guid>
      <description>&lt;p&gt;If you're reading this you've probably heard a lot about Kotlin Multiplatform, but aren't sure where to start. The platform is evolving fast, which means a lot of the docs are out of date, and/or can be a little overwhelming. But nobody likes reading the directions, so I'm writing a series of posts that take about 5 minutes each to run through, and introduce the basics on Kotlin Multiplatform.&lt;/p&gt;

&lt;p&gt;Part 1 gets you starting from nothing. This is part 2, which focuses on &lt;code&gt;expect&lt;/code&gt;/&lt;code&gt;actual&lt;/code&gt; statements. Kotlin's native interop is one of its most distinguishing features. Unlike other "cross platform" ecosystems, Kotlin is designed to embrace the native platform it is integrating with. &lt;code&gt;expect&lt;/code&gt;/&lt;code&gt;actual&lt;/code&gt; statements are one of the main mechanisms it provides to do that.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Five minutes? Well, yes, if you've already gone through the &lt;a href="https://medium.com/@ben_98270/two-apps-in-less-than-five-minutes-with-kotlin-multiplatform-bedf454a4a7b"&gt;previous Kotlin Multiplatform article&lt;/a&gt; and completed it. We're starting &lt;a href="https://github.com/touchlab/KotlinMultiplatformStarter/tree/starter/expect/actuals"&gt;where Part 1 left off&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;One area that requires platform-specific logic is dealing with dates. We're going to create a simple &lt;code&gt;expect&lt;/code&gt; class, &lt;code&gt;KMPDate&lt;/code&gt;, which takes a date format string and lets you create a formatted string representing today's date. &lt;/p&gt;

&lt;p&gt;First, open &lt;code&gt;/app/src/commonMain/kotlin/sample/Sample.kt&lt;/code&gt;. Underneath the &lt;code&gt;Greeting&lt;/code&gt; class, create a new &lt;code&gt;expect&lt;/code&gt; class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;expect&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;KMPDate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;formatString&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;asString&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;expect&lt;/code&gt; keyword declares that the common code can expect different &lt;code&gt;actual&lt;/code&gt; implementations for each platform. In this case, &lt;code&gt;expect&lt;/code&gt; applies to a class. However, it can also apply to functions, objects, annotations, etc. See &lt;a href="https://kotlinlang.org/docs/reference/platform-specific-declarations.html"&gt;here&lt;/a&gt; for more.&lt;/p&gt;

&lt;p&gt;Go to &lt;code&gt;/app/src/main/java/sample/SampleAndroid.kt&lt;/code&gt; to create the &lt;code&gt;actual&lt;/code&gt; Android implementation. Underneath the &lt;code&gt;MainActivity&lt;/code&gt; class, add the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;actual&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;KMPDate&lt;/span&gt; &lt;span class="n"&gt;actual&lt;/span&gt; &lt;span class="k"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;formatString&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// 1&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;dateFormat&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SimpleDateFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;formatString&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 2&lt;/span&gt;

    &lt;span class="n"&gt;actual&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;asString&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;dateFormat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;// 3&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The expect declaration of &lt;code&gt;KMPDate&lt;/code&gt; stated that it takes a &lt;code&gt;formatString&lt;/code&gt;, so an &lt;code&gt;actual constructor&lt;/code&gt; implementation accompanies the &lt;code&gt;actual class&lt;/code&gt; implementation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a &lt;code&gt;SimpleDateFormat&lt;/code&gt; object using the &lt;code&gt;formatString&lt;/code&gt;. iOS has an &lt;code&gt;NSDateFormatter&lt;/code&gt; class, which is similar to &lt;code&gt;SimpleDateFormat&lt;/code&gt;, but we'll get to later. There is currently no common Kotlin implementation, but for most things, Android and iOS have equivalent features available.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;SimpleDateFormat&lt;/code&gt; object formats &lt;code&gt;Date()&lt;/code&gt; - which produces a &lt;code&gt;Date&lt;/code&gt; object representing today's date - into a string.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Next, go to &lt;code&gt;app/src/iosMain/kotlin/sample/SampleIos.kt&lt;/code&gt;, which is currently empty. Paste in the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;actual&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;KMPDate&lt;/span&gt; &lt;span class="n"&gt;actual&lt;/span&gt; &lt;span class="k"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;formatString&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// 1&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;dateFormatter&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;NSDateFormatter&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// 2&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dateFormat&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;formatString&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;actual&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;asString&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;formatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringFromDate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;NSDate&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;// 3 &lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Identical to the &lt;code&gt;actual class&lt;/code&gt; declaration on the Android side.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pass &lt;code&gt;formatString&lt;/code&gt; into an iOS &lt;code&gt;NSDateFormatter&lt;/code&gt; object, which - as mentioned earlier - achieves the same result as &lt;code&gt;SimpleDateFormat&lt;/code&gt; on Android.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;NSDateFormatter&lt;/code&gt; object formats a string based on &lt;code&gt;NSDate()&lt;/code&gt; - which produces an &lt;code&gt;NSDate&lt;/code&gt; object representing today.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Finally, go back to &lt;code&gt;/app/src/commonMain/kotlin/sample/Sample.kt&lt;/code&gt;. Inside of the &lt;code&gt;Greeting&lt;/code&gt; class, create a &lt;code&gt;KMPDate&lt;/code&gt; object that takes "MMM dd" as its date format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;date&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;KMPDate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"MMM dd"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And last but not least, use string interpolation to insert the formatted date string from each platform into the value of &lt;code&gt;hello()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;  &lt;span class="s"&gt;"Hello, Android and iOS worlds, today is ${date.asString()}!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;All done! Run you Android and iOS apps and see the dates displayed on each platform!&lt;/p&gt;

&lt;p&gt;If you come from an iOS background and want a deeper explanation of how to use Kotlin Multiplatform to make a more involved app, then you might want to check out &lt;a href="https://www.infoq.com/articles/kotlin-multiplatform-ios-developers/"&gt;this article&lt;/a&gt; I wrote.&lt;/p&gt;

&lt;p&gt;As you can see, it's all about starting small with Kotlin Multiplatform. We recently launched The Touchlab Refactory; an incremental refactoring service with KMP which focuses on a single feature at a time with no disruption to your current development workflow. Learn more &lt;a href="https://touchlab.co/refactory/"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://touchlab.co/about-us/#careers"&gt;We're hiring!&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>ios</category>
      <category>android</category>
    </item>
    <item>
      <title>Two Apps in Less than Five Minutes with Kotlin Multiplatform</title>
      <dc:creator>Ben Whitley</dc:creator>
      <pubDate>Wed, 04 Sep 2019 15:53:29 +0000</pubDate>
      <link>https://forem.com/benwhitley/two-apps-in-less-than-five-minutes-with-kotlin-multiplatform-1gm1</link>
      <guid>https://forem.com/benwhitley/two-apps-in-less-than-five-minutes-with-kotlin-multiplatform-1gm1</guid>
      <description>&lt;p&gt;If you’re reading this you’ve probably heard a lot about Kotlin Multiplatform, but aren’t sure where to start. The platform is evolving fast, which means a lot of the docs are out of date, and most of the tutorials seem to walk you through setting up projects and tools from scratch. But nobody likes reading the directions! We’re going to walk you through setting up some shared code in less than five minutes.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Prerequisite: We’ll cheat and not start the clock until you have Xcode 10.3+ and Android Studio 3.4.2 installed, and have an emulator installed and running for Android. For Xcode, find it on the Mac App Store &lt;a href="https://apps.apple.com/us/app/xcode/id497799835?mt=12"&gt;here&lt;/a&gt; and install it. Not on a Mac? Well, none of this will work (you need a Mac).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For Android Studio, go &lt;a href="https://developer.android.com/studio"&gt;here&lt;/a&gt; to get the app, follow instructions &lt;a href="https://developer.android.com/studio/install"&gt;here&lt;/a&gt; to set it up, and the instructions to setup an Android emulator &lt;a href="https://developer.android.com/studio/run/emulator"&gt;here&lt;/a&gt;. Ready? OK, now start the clock.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Clone &lt;a href="https://github.com/touchlab/KotlinMultiplatformStarter"&gt;this repository&lt;/a&gt; and open it in Android Studio. The project currently contains two separate Hello World applications: one for Android and iOS each. Run the Android app to see it display “Hello, Android world!”&lt;/p&gt;

&lt;p&gt;Now, open &lt;code&gt;/iosApp/iosApp.xcworkspace&lt;/code&gt; and run &lt;code&gt;iosApp&lt;/code&gt; in the iOS simulator to see it display “Hello, iOS world!” Although they share a folder structure, these iOS and Android apps are separate from one another. Now we’ll join them together with Kotlin Multiplatform.&lt;/p&gt;

&lt;p&gt;First, open &lt;code&gt;/app/src/commonMain/kotlin/sample/Sample.kt&lt;/code&gt;, which contains the following common code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Greeting&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Hello, Android and iOS worlds!"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Next, open &lt;code&gt;/app/src/main/java/sample/SampleAndroid.kt&lt;/code&gt; in Android Studio. It contains the Android version of the Hello World app. To make it into a KMP app, replace the value being assigned to &lt;code&gt;textView.text&lt;/code&gt; — which is currently “Hello, Android world!” — and replace it with &lt;code&gt;Greeting().hello()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Finally, go back to Xcode and open &lt;code&gt;ViewController.swift&lt;/code&gt;. Underneath &lt;code&gt;import UIKit&lt;/code&gt;, add &lt;code&gt;import app&lt;/code&gt;, which is the name of the KMP library. Then, just like in the Android app, change the value being assigned to &lt;code&gt;label.text&lt;/code&gt; from “Hello, iOS world!” to &lt;code&gt;Greeting().hello()&lt;/code&gt;. Rerun both applications, and see them both displaying the same string!&lt;/p&gt;

&lt;p&gt;“Hello, Android and iOS worlds!”&lt;/p&gt;

&lt;p&gt;All done! Stop the clock! You’re a Kotlin Multiplatform developer now!&lt;/p&gt;

&lt;p&gt;What are some good next steps? Try calling out to some native code with &lt;code&gt;expect&lt;/code&gt;/&lt;code&gt;actual&lt;/code&gt; statements, then add an existing multiplatform library like Ktor and do some networking.&lt;/p&gt;

&lt;p&gt;If you come from an iOS background and want a deeper explanation of how to use Kotlin Multiplatform to make a more involved app, then you might want to check out &lt;a href="https://www.infoq.com/articles/kotlin-multiplatform-ios-developers/"&gt;this article&lt;/a&gt; I wrote.&lt;/p&gt;

&lt;p&gt;As you can see, it’s all about starting small with Kotlin Multiplatform. We recently launched The Touchlab Refactory; an incremental refactoring service with KMP which focuses on a single feature at a time with no disruption to your current development workflow. Learn more &lt;a href="http://touchlab.co/refactory"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>ios</category>
      <category>android</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
