<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Alexito's World</title><description>by Alejandro Martinez</description><link>https://alejandromp.com</link><language>en</language><lastBuildDate>Wed, 21 Aug 2024 19:47:37 +0000</lastBuildDate><pubDate>Wed, 21 Aug 2024 19:47:37 +0000</pubDate><ttl>250</ttl><atom:link href="https://alejandromp.com/blog/feed.xml" rel="self" type="application/rss+xml"/><item><guid isPermaLink="true">https://alejandromp.com/blog/swift-package-manager-dependency-owners</guid><title>Swift Package Manager Dependency Owners</title><description></description><link>https://alejandromp.com/blog/swift-package-manager-dependency-owners</link><pubDate>Wed, 21 Aug 2024 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>In my team, one of the things we always make sure of is keeping our dependencies up to date. We rarely add a dependency without a really good reason, and when we do, we assign an <strong>owner</strong> who is responsible for keeping it up to date.</p><p>These owners always keep an eye on new updates and make it a task to go through them as soon as they can. But sometimes, life happens, and one is not able to keep up with it. More often than not, though, the reason why updates are not kept on top of is simply because people forget that it's part of their responsibilities. And I don't blame them. Right now, we just keep the list of owners in our documentation site, which is a very passive way of doing things.</p><p>Instead, we've now worked on upgrading our nightly notification system! This existing system not only runs a set of unit tests and sends a message with test results and code coverage to our Slack channel, but it also shows a list of outdated dependencies thanks to <a href="https://github.com/kiliankoe/swift-outdated">swift-outdated</a> and some custom code on top that is part of our development tools.</p><p>So before, the message just included a table of dependencies to be updated:</p><blockquote><p>| Package | swift-composable-architecture | 1.12.0 | 1.13.0 | ❗️</p></blockquote><p>But now, we've added an <code>@mention</code> to the Slack user responsible for each outdated dependency.</p><p>In my experience, the reason updates often get neglected is simply because it can be easy to forget or overlook tasks that aren't constantly in front of you. That's why I think having a <a href="https://www.youtube.com/watch?v=XtwsJtdH_q8">system for notes</a> is so crucial - it helps keep important responsibilities top-of-mind. By providing a daily reminder of the pending updates they are responsible for, our new notification system has helped streamline things for the whole team.</p><p>Doing this is very simple since we already have the infrastructure in place. It was just a matter of having a mapping between dependencies and Slack users in our CLI. Something very low-tech that does the work 👌</p><p>But there was an extra requirement of mine: if there is a dependency we don't have an owner for, we send an error on the nightly message so we can assign one immediately. This is something not trivial with <code>swift-outdated</code> because that reads from the <code>.resolved</code> file, which has no information about what dependencies are transitive and which ones are directly yours. Since in our opinion, we don't want to be bothered with transitive dependencies, we don't assign owners to those.</p><p>To solve this, we read the <code>Package.swift</code> file in advance so we know what the direct dependencies are. This is quite simple, as SPM makes it very easy to get a JSON representation of a package: <code>swift package dump-package</code>.</p><p>So work done.</p><p>But you know me, I can't avoid getting excited with interesting ideas. So when discussing how to approach this with my team, I wondered... what if we could attach the owner to the dependency itself in the <code>Package.swift</code> file? Well, hold my glass of water.</p><p>Something I love about SPM is that the package definition file is actually a Swift file, which means you can run Swift code in it. Thanks to that, we can add an API to the <code>PackageDescription</code> that does what we want.</p><pre><code>.<span class="splash-call">package</span>(url: <span class="splash-string">"..."</span>, exact: <span class="splash-string">"..."</span>, owner: <span class="splash-string">"..."</span>)
</code></pre><p>To do this, we can extend the SPM types with our own method. Of course, we need to return what SPM expects.</p><pre><code><span class="splash-keyword">extension</span> <span class="splash-type">PackageDescription</span>.<span class="splash-type">Package</span>.<span class="splash-type">Dependency</span> {
    <span class="splash-keyword">static func</span> package(
        url: <span class="splash-type">String</span>,
        exact version: <span class="splash-type">Version</span>,
        owner: <span class="splash-type">String</span>
    ) -&gt; <span class="splash-type">PackageDescription</span>.<span class="splash-type">Package</span>.<span class="splash-type">Dependency</span> {
        .<span class="splash-call">package</span>(url: url, exact: version)
    }
}
</code></pre><p>So what's the point of having the new parameter if it's not used? Well, that we have it in the same source, and we can extract it from it!</p><p>But if you're thinking SPM dump will include this data, well, of course, it won't, as SPM doesn't know anything about it. That doesn't mean we can't get it; it just means it's our work. For things like this, I always rely on <a href="https://github.com/pointfreeco/swift-parsing">swift-parsing</a>, and it makes it quite easy to extract the dependency from the file.</p><p>This is the output of running a quick proof of concept command line:</p><pre><code>▶ ./spm-owners <span class="splash-type">Package</span>.<span class="splash-property">swift</span>
┏━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┓
┃   ┃ <span class="splash-type">Package</span>                       ┃ <span class="splash-type">Version</span>  ┃ <span class="splash-type">Owner</span>    ┃
┃   ┃ &lt;<span class="splash-type">String</span>&gt;                      ┃ &lt;<span class="splash-type">String</span>&gt; ┃ &lt;<span class="splash-type">String</span>&gt; ┃
┡━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━┩
│ <span class="splash-number">0</span> │ swift-parsing                 │ <span class="splash-number">0.13.0</span>   │ <span class="splash-type">Martin</span>   │
│ <span class="splash-number">1</span> │ swift-argument-parser         │ <span class="splash-number">1.5.0</span>    │ <span class="splash-type">Martin</span>   │
│ <span class="splash-number">2</span> │ swift-composable-architecture │ <span class="splash-number">1.13.0</span>   │ <span class="splash-type">Alex</span>     │
└───┴───────────────────────────────┴──────────┴──────────┘
</code></pre><p>I love this! Having the ownership data as part of the <code>Package.swift</code> makes it so things are always in sync and up to date.</p><p>Of course, I'm not using this in our team's system because it's not production-ready; it's just a proof of concept. The big disadvantage is that although <code>Package.swift</code> can run Swift code, you can't just import a separate package, which means one would have to copy-paste the code above manually. Not a deal-breaker, but not nice enough for me to want to maintain 😂 If one could import in the package file, it would be another story.</p><p>So there you go, an interesting proof of concept that has kept me entertained for a couple of hours. I wish SPM would officially support a way to accomplish this, somehow to be able to add metadata and that it would be kept for other tools. And maybe there is, and I'm not aware?</p><p>You can check out the proof of concept on the <a href="https://github.com/alexito4/spm-owners">spm-owners</a> repo, if you are curious.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/backport-swiftui-modifiers</guid><title>Backport SwiftUI modifiers</title><description></description><link>https://alejandromp.com/blog/backport-swiftui-modifiers</link><pubDate>Fri, 20 Oct 2023 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>Every year SwiftUI improves and gets new modifiers that widen the capabilities of the framework. Sadly, as responsible developers, we can't use any of that because our users take some time to update and, as opposed to the Android ecosystem where Jetpack Compose is just a library embedded in every app, we need to wait for our users to be at the required minimum OS version to enjoy those fancy new tools.</p><p>Or do we?</p><p>There are some APIs that are easy to backport if we disregard the old versions of the operative system. This may sound awful but is a valid option that is worth considering. If you know you have a very little percentage of users stuck in the old version but you can't get rid of it because of some policy, you know the impact is very minimal. And if time has already passed and dropping that version is on the horizon, you have more reason to plan for the future and not get stuck in the past. No matter what, we should make sure that users in the old version don't get a bad experience. It may be not perfect and modern, but they still should be able to use the app properly. It's a case-by-case decision that you have to take, but if you do, here is how to pull it off.</p><h2 id="porting-swiftui-modifiers">Porting SwiftUI modifiers</h2><p>We will focus on SwiftUI modifiers. Other features can also be backported, but they will need slightly different techniques. The one for modifiers is actually quite simple, but it always depends on the functionality itself.</p><p>I've used this technique for a while, and it works very well. For example the <a href="https://developer.apple.com/documentation/swiftui/view/scrolldismisseskeyboard(_:)">scrollDismissesKeyboard(_:)</a> modifier is a good candidate. It's a new functionality that users in old versions won't miss because they wouldn't have access to it before (well, unless your app was UIKit, again, case by case).</p><p>The first step is to copy the modifier function signature in your own <code>View</code> extension:</p><pre><code><span class="splash-keyword">extension</span> <span class="splash-type">View</span> {
    <span class="splash-comment">/// docs...</span>
    <span class="splash-keyword">@available</span>(iOS <span class="splash-number">16.0</span>, macOS <span class="splash-number">13.0</span>, tvOS <span class="splash-number">16.0</span>, watchOS <span class="splash-number">9.0</span>, *)
    <span class="splash-keyword">public func</span> scrollDismissesKeyboard(<span class="splash-keyword">_</span> mode: <span class="splash-type">ScrollDismissesKeyboardMode</span>) -&gt; <span class="splash-keyword">some</span> <span class="splash-type">View</span>
}
</code></pre><p>I also recommend copying over the documentation so the users of this function will get all the info they need. Just as if it was the legitimate function from the framework.</p><p>Conceptually the implementation of the function is very simple: we check in which OS version we are and we call the SwiftUI function when available and fallback to something else when not. This applies to all modifiers you want to port, but there are two things to consider.</p><h2 id="fallback-on-old-os">Fallback on old OS</h2><p>What do you do as a fallback? That's the first question to consider and it will depend on the feature, its complexity, how much worth it is for you and a multitude of other aspects, technical and non-technical. This is the "case by case" part of this work.</p><p>In this example, the fallback is simply to do nothing. And that works for many cases, really. To implement this, we just need to return self in the old version so our modifier does nothing with the view.</p><pre><code><span class="splash-keyword">if #available</span>(iOS <span class="splash-number">16.0</span>, *) {
    <span class="splash-keyword">self</span>
        .<span class="splash-call">scrollDismissesKeyboard</span>(mode)
} <span class="splash-keyword">else</span> {
    <span class="splash-keyword">self</span>
}
</code></pre><p>That's what we want, easy, right? Well, remember that for this to work, we need to opt in this function into the ViewBuilder DSL. Check out <a href="https://alejandromp.com/blog/viewbuilder-vs-anyview/">ViewBuilder vs. AnyView</a> for more details about this.</p><p>If your modifier didn't take any parameters, that would be all you needed, but that's rarely the case.</p><h2 id="backport-parameters">Backport parameters</h2><p>Most modifiers take some parameters to adjust its functionality. Those types are often new and thus not present in old versions, so we need to port those too.</p><p>The process for that is similar, just copy the existing types into your own file.</p><pre><code><span class="splash-keyword">public struct</span> ScrollDismissesKeyboardMode {
    <span class="splash-keyword">public static var</span> automatic: <span class="splash-type">ScrollDismissesKeyboardMode</span> { <span class="splash-keyword">get</span> }
    <span class="splash-keyword">public static var</span> immediately: <span class="splash-type">ScrollDismissesKeyboardMode</span> { <span class="splash-keyword">get</span> }
    <span class="splash-keyword">public static var</span> interactively: <span class="splash-type">ScrollDismissesKeyboardMode</span> { <span class="splash-keyword">get</span> }
    <span class="splash-keyword">public static var</span> never: <span class="splash-type">ScrollDismissesKeyboardMode</span> { <span class="splash-keyword">get</span> }
}
</code></pre><p>Now that's a fine way to start, but I find it significantly easier to work with an <code>enum</code>. That way, you don't have to worry about internal implementations or storing any data. Furthermore, I also recommend prefixing the name of the type so is distinct from the SwiftUI one. This is not strictly necessary, but I've found that makes the compiler way happier as it helps distinguish the functions easily. It's also a hint to the user of the function that there are some shenanigans going on.</p><p>So let's convert that type to an enum instead:</p><pre><code><span class="splash-keyword">public enum</span> MyScrollDismissesKeyboardMode {
    <span class="splash-keyword">case</span> automatic
    <span class="splash-keyword">case</span> immediately
    <span class="splash-keyword">case</span> interactively
    <span class="splash-keyword">case</span> never
}
</code></pre><p>This makes it so the usage side can use the same dot syntax and names as with the original function while using our custom types. But we still need to give SwiftUI its own types, so I always add a property to do the conversion.</p><pre><code><span class="splash-comment">// MyScrollDismissesKeyboardMode</span>
    <span class="splash-keyword">@available</span>(iOS <span class="splash-number">16.0</span>, *)
    <span class="splash-keyword">var</span> swiftUI: <span class="splash-type">ScrollDismissesKeyboardMode</span> {
        <span class="splash-keyword">switch self</span> {
        <span class="splash-keyword">case</span> .<span class="splash-dotAccess">automatic</span>: <span class="splash-keyword">return</span> .<span class="splash-dotAccess">automatic</span>
        <span class="splash-keyword">case</span> .<span class="splash-dotAccess">immediately</span>: <span class="splash-keyword">return</span> .<span class="splash-dotAccess">immediately</span>
        <span class="splash-keyword">case</span> .<span class="splash-dotAccess">interactively</span>: <span class="splash-keyword">return</span> .<span class="splash-dotAccess">interactively</span>
        <span class="splash-keyword">case</span> .<span class="splash-dotAccess">never</span>: <span class="splash-keyword">return</span> .<span class="splash-dotAccess">never</span>
        }
    }
</code></pre><p>This property is only available in the new OS since when we call it we will be in the correct version.</p><p>Now we can switch the function to use the new type.</p><pre><code>   <span class="splash-keyword">@ViewBuilder func</span> scrollDismissesKeyboard(
      <span class="splash-keyword">_</span> mode: <span class="splash-type">MyScrollDismissesKeyboardMode</span>
  ) -&gt; <span class="splash-keyword">some</span> <span class="splash-type">View</span> {
      <span class="splash-keyword">if #available</span>(iOS <span class="splash-number">16.0</span>, *) {
          <span class="splash-keyword">self</span>
              .<span class="splash-call">scrollDismissesKeyboard</span>(mode.<span class="splash-property">swiftUI</span>)
      } <span class="splash-keyword">else</span> {
          <span class="splash-keyword">self</span>
      }
  }
</code></pre><p>And that's the function fully back ported. We take our custom parameter, and if we are in the new version, convert it to the SwiftUI one and call the real modifier. Otherwise, we just return the view unmodified.</p><h2 id="using-our-function">Using our function</h2><p>With this, the usage side would look exactly as with the real code.</p><pre><code><span class="splash-type">SomeView</span>()
  .<span class="splash-call">scrollDismissesKeyboard</span>(.<span class="splash-dotAccess">immediately</span>)
</code></pre><p>For that to work you just need to make sure your function is in your module, or if it's in a separate package (which I always <a href="https://alejandromp.com/blog/ios-app-architecture-in-2022">recommend</a>) you need to import it in your file.</p><p>This works because your code always takes precedence over system frameworks. This means the compiler will pick your custom function and types before SwiftUI's.</p><h2 id="obsoleted">Obsoleted</h2><p>Another very useful tip is to use an availability annotation to ensure the compiler will remind you to remove this code when your minimum target matches the one that introduced the modifier. For this, we can add an <code>@available</code> with the <code>obsoleted</code> parameter.</p><pre><code><span class="splash-keyword">@available</span>(iOS, obsoleted: <span class="splash-number">16.0</span>, message: <span class="splash-string">"SwiftUI.View.scrollDismissesKeyboard is available on iOS 16."</span>)
</code></pre><p>This is very helpful and makes the compiler work for you.</p><h2 id="pick-your-battles">Pick your battles</h2><p>Just like deciding what to do as a fallback based on tradeoffs, choosing which parameters and features to support is important too.</p><p>For example, if we want to port <a href="https://developer.apple.com/documentation/swiftui/view/presentationdetents(_:)">presentationDetents(_:)</a> we will find out is a bit more complex. The custom detent needs some generic work that might not be trivial, so when you see that sort of complexity you can decide to just ignore it. Remember that this code is for you. It's likely that you are not trying to make a full featured framework for the entire world, so if you don't need some functionality right now, just skip it. By the time you need it, you will use the native solution already.</p><p>So in this case, you may decide to simplify the detents you offer:</p><pre><code><span class="splash-keyword">public enum</span> MyPresentationDetent: <span class="splash-type">Hashable</span> {
    <span class="splash-keyword">case</span> medium
    <span class="splash-keyword">case</span> large
    <span class="splash-keyword">case</span> fraction(<span class="splash-keyword">_</span> fraction: <span class="splash-type">CGFloat</span>)
    <span class="splash-keyword">case</span> height(<span class="splash-keyword">_</span> height: <span class="splash-type">CGFloat</span>)
    <span class="splash-comment">// no custom detent supported</span>
}
</code></pre><h2 id="more-than-back-porting">More than back-porting</h2><p>This technique is not only useful to back port functionality to older OSs but also to improve functionality and make it work the way you want. You can use the same technique, ignoring the version checks, and that will give you a way to offer more reusable parameters and options and to have a reusable place to include extra logic, all of that while keeping the same syntax as the system.</p><p>This is beneficial because it allows your code to be easily adjusted when Apple adds new options natively, saving you from having to completely refactor multiple views.</p><h2 id="conclusion">Conclusion</h2><p>This technique is just another tool on your belt. It's up to you to decide when is appropriate to use it, but I recommend you to think about it. There are plenty of times when we could use modern APIs with little problem while keeping compatibility with older systems.</p><p>Just have it in mind, analyze the tradeoffs and decide.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/yumi-and-the-nightmare-painter-review</guid><title>Yumi and the Nightmare Painter, review</title><description></description><link>https://alejandromp.com/blog/yumi-and-the-nightmare-painter-review</link><pubDate>Tue, 18 Jul 2023 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>It's time to review and reflect about Yumi and the Nightmare Painter, the third instalment in The Year of Sanderson and the second in the Cosmere. This will probably become one of my favorite books of the Cosmere and be in my top tier of fiction books.</p><p>Rating: <a href="https://www.goodreads.com/review/edit/60531416">5/5</a></p><p>I haven't experienced many world-hopping narratives, so what might come across as a trope to some was very appealing to me. The execution of the plot is brilliant, especially the dynamic where the two main characters need to learn to live each other's life. It is fascinating how Painter, who comes from a modern world akin to ours, needs to understand and follow the constraints of a world made by doctrine. In contrast, we observe Yumi thrust into a more open-minded world as she navigates her inner suppression and confronts her fears.</p><p>The asymmetry goes further than that. Painter having to live in Yumi's body initiates a subtle, yet impactful, conversation about the experience of living in a body that doesn't align with one's identity, a conversation still too often silenced in our society. On the other hand, Yumi keeping her own body introduces a more conventional underpinning of deception to the plot. The contrast between these two representations of what is living in a foreign world operates on many levels that are fascinating to read. The origin of these differences and the magic behind them are a mystery that keeps you hooked until the end.</p><p>Setting aside the fantasy and magic of the story, which in typical Sanderson's fashion is one of the best ones I've experienced, what resonated deeply with me was the core theme of personal growth. The journey of self-improvement that forces the characters to open their mind and shift their perspective, dismantling their own dogmas and fears. Among the many narrative threads, a particular subplot I really liked was about meditation. What started as a push for the other character to do meditation in the only correct way evolved into the understanding that each person is different and has its own path to tranquility, of emptying their mind or even of not emptying it at all. Coming to terms with the difference between each individual was an enriching and fulfilling experience.</p><p>The other part I liked a lot was the intricacies of the love story. As I often tell my wife, love finds its way in every tale, even in those that don't exactly belong to the romance genre. I've never been captivated by the romance genre, but I still find myself seduced by the deep connections that love weaves into every story. With "Yumi and the Nightmare Painter", while the main plot is about figuring out what happened and how to fix it, through the course of the story we see how two strangers naturally bound thanks to mutual understanding and sharing their fears. This evolution culminates in a lovely relationship that plays an integral part of the climax. It's a delight to see the author be less shy with certain scenes and letting these human aspects arise n the story.</p><p>Now, the question that everybody asks: Is this book enjoyable if you haven't read the Cosmere? Well, I can't tell you for sure because for me the Cosmere is the main reason I love Sanderson's work. I'm a sucker for interconnected stories and worlds and is where a big part of my enjoyment comes from. Yet, I truly think that you can enjoy this, and all other stories, without being an expert in Realmatic Theory. The story stands on its own and is self-contained. You will miss on the occasional nod to the rest of the Cosmere but that is normal and expected. So don't ignore this book just because of this.</p><p>I want to conclude with the only point of critique I have about this book, a concern that involves none other than our beloved and mischievous Hoid. The voice of the book being narrated by Hoid is very interesting. It feels different from other occasions while still being clearly Hoid. This narrative choice worked really well. However, I have to admit that there are a couple of moments where the exposition runs for a bit too long, even for me. This was particularly notable towards the end of the story, when the prose stops showing the events and just lets the narrator tell us exactly what happens in what feels like an "info dump". Granted, it makes sense from the narration point of view, as Hoid is narrating the story to somebody in the Cosmere, but while I was immersed in the story this pulled me out of the fiction immediately and made me ask: am I accepting this because the author is Brandon Sanderson? Would I accept it from another author lacking the same level of reputation?</p><p>The immediate answer that came to mind was that I would have been more critical of another author. However, after some introspection, I realised how I ignored a critical factor: context. Brandon Sanderson has not only carved his reputation through the years, but directly made a tremendous impact on me. Of course I can accept a bit of whimsicalness from time to time if that's what he enjoys. I shouldn't forget that's precisely why I baked the secret projects and why I love them so much!</p><p>In summary, a resounding endorsement. Must read. Cosmere pinnacle, and top fantasy book.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/death-s-end-review</guid><title>Death's End - The naïveté of humankind, review</title><description></description><link>https://alejandromp.com/blog/death-s-end-review</link><pubDate>Tue, 4 Jul 2023 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>The conclusion of the Remembrance of Earth's Past Trilogy comes to an end. The story has come far since those first chapters of The Three-Body Problem so focused on Chinese history that one had to read translators comments to understand the intention of the words. Now, after many years after the crisis began, humanity lives in a completely different world, confronting threats that were unimaginable before.</p><p>I really like how we see the conclusion of some of the recurrent characters, some who I ended up despising and others that I felt close to. But the character that makes more progress is humanity itself. The challenges that face humanity in this story are eye opening. The author not only presents a sci-fi story to spark a wild imagination, but it also solidifies philosophical questions and shows the possible consequences of our naïve space exploration.</p><p>For years, we have been wondering if we are alone in the universe, if there is life beyond the heat of our sun. And assuming we are not as special as we usually pretend, why we haven't found it yet. Remembrance of Earth's Past puts us in a fictional result of those thoughts. It tells us what could happen if we keep asking those questions instead of asking if we should even look for other civilizations. Maybe we should do everything we can to make ourselves invisible in the vastness of the dark forest.</p><p>Seeing the consequences of the Dark Forest theory, introduced in the previous book, and put beyond what I could have imagined, is also great. The author keeps surprising me with additional levels of power and technology. I always wonder how much further can power go in a science-fiction scenario. I'm used to see fantasy grow the power to extremes, but how can you do that with hard science and technology? The technologies and fundamental theories explored by this series are mind blowing. From new forms of communication to technology to travel at light-speed, even higher dimensional physics, the series explores mind-blowing concepts that will make me read additional explanations and summaries to grasp fully.</p><p>As with everything I read, some details run wild in my imagination, morphing and growing to eventually settle in some part of the <a href="https://pulubiworlds.com">Pulubi</a>. It's what I love the most about reading, how it fuels the infinite machine of imagination to bring into existence new forms.</p><p>One concept that fascinated me the most is to see how the author raises the question of what makes us humans. During the events of the book, we find on multiple occasions when humanity itself considers how some fellow humans have lost their humanity, how they are <em>something else</em> entirely. I often find thoughts like this come from brutal acts that dehumanize the characters in question or from a scientific long evolution that departs the physical form from the original. But in this case, the author makes us question how seemingly small acts and just a bit of time can come to question if those committing them are still one of us. Seeing how being isolated in a spaceship in an unreachable part of the universe makes one question their relation to humanity. Or how stuffing the entire human race in a confine space and make it fight for survival to the extreme would make us consider if those taking part in such survival <em>game</em> are still human.</p><p>Overall, I really liked the book and the series. Very thought provoking, with plenty of ideas that will keep echoing in the back of my mind for a long time.</p><p>Now let's see how the adaptations fare in comparison.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/swift-5-9-macros-unlock-mixins</guid><title>Unlocking Mixins with Swift 5.9 Macros</title><description></description><link>https://alejandromp.com/blog/swift-5-9-macros-unlock-mixins</link><pubDate>Mon, 12 Jun 2023 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>It's been a while since the last time I thought about traits and mixins in Swift, but the <a href="https://alejandromp.com/blog/wwdc23-notes/">WWDC23</a> presentations about macros brought a lot of memories from those times when I really lamented not having that functionality in the language. Thankfully, <a href="https://alejandromp.com/tags/swift/">Swift</a> 5.9 gives us a form or meta-programming that allows us to get some basic support for mixins.</p><p>It's still not fully generic since macros don't give you all the type information you need for that yet, but they are functional and usable via ad hoc macros.</p><p>But also I don't think we have a big need for them anymore, the development landscape has changed a lot since those days.</p><p>Check out this video:</p><iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/znqIjEE0a84" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe><p>Previous conversations about traits and mixins:</p><ul><li><a href="https://alejandromp.com/blog/uiviewcontroller-extension-keyboard-avoidance/">UIViewController extension for keyboard avoidance, and the missing features of Swift | Alexito's World</a></li><li><a href="https://alejandromp.com/blog/im-not-the-only-one-that-wants-traits-in-swift/">I'm not the only one that wants traits in Swift | Alexito's World</a></li><li><a href="https://alejandromp.com/blog/jonathan-blow-libraries-discussion-jai/">Jonathan Blow's libraries discussion | Alexito's World</a></li></ul>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/wwdc23-notes</guid><title>WWDC23 notes</title><description></description><link>https://alejandromp.com/blog/wwdc23-notes</link><pubDate>Fri, 9 Jun 2023 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>WWDC23 is over and as previous year I'm sharing my <strong>unedited</strong> notes from all the sessions I've watched.</p><p>This year has been quite entertaining as the main focus has been on the new platform, something that hasn't taken too much brain power of mine. visionOS is very cool, but it still feels like a very narrow and futuristic device. For what I care, the software and the engineering, there are two parts: apps as we know them, and new spatial design. For the first one there is not much difficult things to learn since is all based on all the farmeworks we know and love. For the spatial design it requires bringing 3Dc ontent into apps, which is a different discipline that although I've dabbled with, it's not in my priorities right now. The combination of that means all the visionOS talks have been a breeze to go trough, like watching a scifi show.</p><p>The rest of sessions have been on the usual topics and frameworks. In general I've found all of them quite straightforward, without anything new or revolutionary that would make by brain go boom. Most of this is thanks to Swift being open source, which removes the surprise factor of the things I'm interested in by a lot. I basically knew everything coming on that front already. So that leaves SwiftUI as the delightful surprise machine.</p><p>I'm not complaining, is good to have a year a bit more relaxed. Before WWDC started I already decided to take this year a bit calmed, for my own mental health. I could jump in the wagon of content generation but I prefer to enjoy it, treat it as entertainment and learn with it. It's way more fun!</p><h2 id="favorite-sessions">Favorite sessions</h2><p>After long nights and early mornings, I've watched more than 90 sessions. That's pretty much every single session that is not gaming, ML, web or business related 😂. It's not that much time when you watch it an higher speed ⏭️ I surprised even myself, but with all the sessions being quite low in new content time flew by, it was very enjoyable!</p><p>From all of those the ones I've kept bookmarket are:</p><ul><li><a href="https://developer.apple.com/wwdc23/10156">Explore SwiftUI animation</a></li><li><a href="https://developer.apple.com/wwdc23/10160">Demystify SwiftUI performance</a></li><li><a href="https://developer.apple.com/wwdc23/10037">Explore pie charts and interactivity in Swift Charts</a></li><li><a href="https://developer.apple.com/wwdc23/10170">Beyond the basics of structured concurrency</a></li><li><a href="https://developer.apple.com/wwdc23/10248">Analyze hangs with Instruments</a>, probably the best session with hands-on explanations on how to solve performance issues, exploring all different situations and giving nuggets of knowledge along the way.</li></ul><p>Even if this year the content was not super impactful for me, every single session and presenter is amazing. The quality is over the clouds. They all are interesting to watch and listen, and present the topics in a very entertaining and interesting manner. And I love how Apple, a huge coorporation, let's every presenter add a bit of their own personality to the videos. It makes them so much approachable. My congratulations to all the ones involved in making this sessions so enjoyable!</p><h2 id="raw-notes">Raw Notes</h2><blockquote><p>This won't include every detail in all sessions. The notes reflect things that have caught my attention and that I want to remember their existence for later. Details are best obtained by going to the documentation when needed knowledge is up to date.</p></blockquote><h3>Keynote</h3><ul><li>Stickers in third party apps like emojis?</li><li>Journal! gratitude and memories with suggestions from photos, music, trips...<ul><li>suggestions api</li><li>health mood tracking with state of mind, assessments</li><li>Craig: "multiple timers, we truly live in an age of wonders."</li><li>vision health, how much time spent outdoors in sunlight, screen distance</li></ul></li></ul><h3>SotU</h3><blockquote><p>With WidgetKit, you can surface your content in many places across the system. With App Intents, your app's functionality is integrated into the system even more seamlessly. With TipKit, you can surface beautiful tips directly in your app. And with AirDrop, you can make it even more convenient for your users to share content with those nearby.</p></blockquote><ul><li>WidgetKit<ul><li>Available on StanBy mode, lockscreen on ipad, and mac desktop. with background removed.</li><li>Identify the background (.containerBackground modifier) and update its padding (remove it, it comes by default now).</li><li>Interactivity with buttons and toggles to trigger App Intents.</li><li>Transitions supported.</li><li>TipKit</li><li>Configure tooltips to be displayed to users with rules. Sync across devices.</li><li>Values:</li><li>Accessibility:<ul><li>new pause animated images flag</li><li>avoid bright flashing lights in videos</li></ul></li><li>Privacy</li><li>App Store</li><li>New swiftui api to make the subscribe screens following apple standards.</li><li>Xcode</li><li><img src="https://alejandromp.com/blog/wwdc23-notes/WWDC23 xcode summary.jpg"/></li><li>Code generation for asset catalogs</li><li>Macro for swiftui previews (and for uikit and appkit!)</li><li>visionOS</li><li>Windows, Volumes and Spaces</li><li>Existing apps are just using Windows, but if you rebuild you get the proper look and feel with materials.</li><li><img src="https://alejandromp.com/blog/wwdc23-notes/WWDC23 visionOS stack.jpg"/></li><li>ZStacks can have depth.</li><li>Mix SwiftUI with RealityKit.</li><li>Ornaments fix UI elements to the side of the window, great for toolbars and menus.</li><li>Hover effects where the user looks.</li></ul></li></ul><h3>SwiftUI</h3><img src="https://alejandromp.com/blog/wwdc23-notes/WWDC23 swiftui summary.jpg"/><h4>Charts</h4><ul><li>Pie and Donut charts with new SectorMark</li><li>Chart Selection that automatically handles the gesture recognitizers to allow selection along axis, ranges and angles. Allows to provide a custom gesture whilte still making it easy to select the value based on the gesture location.</li><li>Scrollable with chartScrollableAxis and specify the visible domain. It also supports scroll target behaviours.</li></ul><h4>Inspectors</h4><p>Views that show further detail of selected content. Is a right sidebar that adapts to a sheet on smaller sizes.</p><h4>Presentation</h4><p>New <code>presentationBackground</code> to change the background of the sheets overlays, the overlay that covers the entire screen.</p><p><code>presentationBackgroundInteraction</code> let's you enable the interaction of the content behind even when a sheet is up.</p><p><code>presentationCornerRadius(_:)</code></p><p><code>presentationContentInteraction(_:)</code></p><p><code>presentationCompactAdaptation(_:)</code> Some of these modifiers also work when Inspectors are presented as sheets.</p><h4>Animations</h4><p>Phases:</p><ul><li>loop between phases applying styles on each one.</li><li>starts immediately on appearance</li><li>or pass a trigger to animate when it changes</li></ul><p>Keyframes:</p><ul><li>Run parallel animation tracks, inside each track is a sequence</li><li>Refreshes the view on every frame</li><li>MapKit has support to keyframe the camera</li><li>KeyFrameTimeline allows you to evaluate an animation, and even display it in a chart.</li></ul><p>UnitCurve and Spring contain the algorithms/curves that drive the change of values. You can use them directly to get a value at a specific point in time.</p><p>CustomAnimation protocol to write custom animation curves. Can impleemnt velocty and merge behaviour to mix with other animations that was triggered while another was running.</p><p>Transaction is now public. Is another implicit-data flow construct, a dictionary that is passed trough the view hierarchy on every update and discarded at the end. it's used for animatable views to know if they should animate on this update. It's what withAnimation does, and the animation modifier touches. Now you can add your own data to know if during a body update it was triggered programmatically or by the user for example. A new animation modifier with a closure let's you apply the animation just to specific effects instead of inserting it in the view hierarchy. the other children views are not affected by this animation, unlike the normal animation modifier that injects the animation to all children.</p><ul><li>transfer velocity auomatically, smooth spring by default</li><li>sfsymbol animated</li><li>contentTransition(.numericText(value: totalCaffeine.value))</li></ul><h4>Observable</h4><p>macro, so we just need State <img src="https://alejandromp.com/blog/wwdc23-notes/WWDC23 swiftui property wrappers.jpg"/>te and Environment wrappers now.</p><h4>Scroll effects</h4><p><code>scrollTransition</code> to modify the rows when the enter the visible area.</p><p><code>scrollTargetBehaviour(.paging)</code> for full screen paging deceleration</p><p><code>scrollTargetBehaviour(.viewAligned)</code> to decelerate targeting a view, to mark which views are targets use <code>scrollTargetLayout</code> for lazy stacks (important because not all views are created yet, but the stack knows and will tell the scroll) or <code>scrollTarget</code> for the individual views themselves. Can use custom behaviours with <code>ScrollTargetBehaviour</code> conformance.</p><p><code>safeAreaPadding</code> modifier, so the scrollview still extends to the full screen but its views are padded (both your content and its scroll indicators).</p><p><code>contentMargin</code> modifier to specify padding only to the content or to the scroll indicators.</p><p><code>containerRelativeFrame</code> to let the view grow based on the container size. And can use parameters to let multiple views share the space, making grid like layouts.</p><p><code>scrollPosition(id:</code> gives a binding to scroll to that view.</p><h4>Visual Effects</h4><p>It gets the content and a geometry proxy.</p><p>You can use a coordinate space outside of the view, and compute the distance of a point in the space to the view using the proxy, then use that distance to change the content with effects.</p><h4>Vertical tabs in watchkit</h4><h4>Menu palette</h4><p>Picker with the palette style</p><h4>Performance</h4><p>Make sure IDs are fast to compute. Just pass to views what they need, otherwise they depend on more. ForEach should just have 1 view so it can match the ID with it. It eagerly gets all IDs, but lazy the views. If there are more views it needs to easily get them too which is bad.</p><h4>Focus</h4><p>You can specify the interaction for when a view is focused. (edit or activate) Default focus to specify which element should be focused by default. New onKeyPress modifier. Focus values to tell menu commands which view is in focus. Focus sections to let directional focus (like in tvOS) fall into a non-adjacent view that otherwise wouldn't be elegible for focus.</p><h3>Widgets</h3><ul><li>Animations and transitions when the data of the widget changes</li><li>Interactive<ul><li>Can use buttons and toggles with new inits that trigger an app intent.</li><li>App intent interactions are ensured to trigger a reload immediatly, unlike tmieline changes.</li><li>Invalidate content modifier for specific views that should show interaction update to the user faster, specially when is on mac since it goes over wifi.</li><li>Toggle optimistically updates the state so appear faster</li><li>Widgets show in mac via continuity</li><li>Widgets for watch stack have design recommendations, instead of hardcoded layouts like in the original apis</li><li><img src="https://alejandromp.com/blog/wwdc23-notes/WWDC23 watch widgets layouts.jpg"/></li></ul></li></ul><h3>CoreData</h3><ul><li>Composite attributes, alternative to transformables</li><li>Staged schema migrations</li><li>Deferred migrations, to delay the cleanup of schema migrations (colum or table removals) for later to not block the user.</li></ul><h3>SwiftData</h3><img src="https://alejandromp.com/blog/wwdc23-notes/WWDC23 swiftdata summary.jpg"/><ul><li>Built on top of proven core data persistance layer (?what does this mean??)</li><li>Schemas and definitions all in code, with macros. No external schema files.</li><li>@Model gives you:<ul><li>Persistence</li><li>Schema modeling</li><li>Lightweight migration</li><li>Relationship management</li><li>iCloud synchronization</li><li>Spotlight search</li><li>Undo/Redo</li><li>@Query to fetch and show results in SwiftUI.</li><li>Model container understands the relationships of the schema so even if you just give it 1 type it will infer the related types it needs to persist.</li><li>Advanced model configuration and schema can combine multiple different schemas with different stores into 1.</li><li>Get the model context trough the environment to operate with the database. It propagates changes to the model container.</li><li>It uses the undo manager from the environment to automatically support undo/redo.</li><li>Auto saves in sync with SwiftUI related events and system events. You can also save manually.</li><li>Fetch trough the context with fetch descriptor and the new predicate macros, which give compiler validated queries.</li><li>Use the context enumerate method to effeminately fetch lists of data, uses automatically batch processing under the hood, and safe mutation guards. It can be customized.</li><li>Document based apps by using a SwiftData model as a packaged file</li><li>But models are still classes... they haven't embraced an immutable model. Pretty weird. :(</li></ul></li></ul><h3>CloudKit</h3><p>CKSyncEngine. Between high level core data integration and low level operations.</p><h3>TipKit</h3><p>Looks very interesting, specially with the rules system that will prompt the tips at the appropiate moment and a consistent UI.</p><h3>Foundation</h3><ul><li>Improvements in gramatical agreement with other arguments and even concepts outside the string.</li><li>New terms of address for pronouns</li><li>Resumable upload url session tasks, and support in SwiftNIO</li></ul><h3>Swift</h3><ul><li>if/switch expressions</li><li>improved result builders</li><li>type parameter packs</li><li>macros<ul><li><img src="https://alejandromp.com/blog/wwdc23-notes/WWDC23 macro roles.jpg"/></li><li><img src="https://alejandromp.com/blog/wwdc23-notes/WWDC23 swift build-in code expansion.jpg"/></li><li><img src="https://alejandromp.com/blog/wwdc23-notes/WWDC23 macro role protocols.jpg"/></li><li><img src="https://alejandromp.com/blog/wwdc23-notes/WWDC23 macro name specifiers.jpg"/></li><li>native swift foundation</li><li>ownership</li><li>c++ interoperatibility</li><li>discarding task group</li></ul></li></ul><h3>Xcode</h3><ul><li>Improved suggestions order</li><li>New localization strings catalog format<ul><li>Eventually will replace strings and stringdict.</li><li>Allows variant of strings based on platform (click vs tap)</li><li>Can make multiple catalogs to have different string tables</li><li>Xcode automatically extracts localizable strings from code. Use localised initialisers in strings and LocalizedStringResource.</li><li>In SwiftUI use LocalizedStringResource in your views to accept localizable strings</li><li>Code gen asset catalog and localisation access</li><li>Documentation preview in editor assistant</li><li>Preview macro and UIKit/appkit support</li><li>Bookmarks</li><li>Source control improvements</li><li>test results new design</li><li>oslog integration in Xcode output, with filters</li><li>Streamlined workflows for app distribution</li></ul></li></ul><h3>UIKit</h3><p>Custom traits let you bridge with swiftui environment Status bar changes color automatically Page control with progress and timer. Menu palette New text selection style. Comes from free with system text views. Now can also be used in custom text views together with the loupe. New <code>UITextItemTagAttributeName</code> to tag ranges in a text so we can get interactions, ideal for "See More" in text! And it has new APIs to change the default menu behaviour when interacting with them. List and bullets supported in attributed string.</p><h3>AppKit</h3><ul><li>Table column customizations for free</li><li>NSProgress support in NSProgressIndicator</li><li>Popover background can expand to the chevron</li><li>NSBezier path, CGPath interoperability</li><li>CADisplayLink!</li><li>More Sendable everywhere!</li></ul><h3>App Intents</h3><p>Improvements on app intents App shortcuts are now discoverable in Spotlight, design for it. <img src="https://alejandromp.com/blog/wwdc23-notes/WWDC23 app intents integrations.jpg"/></p><h3>Accessibility</h3><ul><li>isToggle trait</li><li>AccessibilityNotification.{Anouncement}.post</li><li>Anouncement priority to avoid interruptions</li><li>Direct touch options</li><li>Accessibility shape</li></ul><h3>App Clips</h3><ul><li>new size limit 50mb for digital invocations</li><li>Default app clips urls hosted by the app store</li><li>launching app clips from apps</li></ul><h3>Privacy</h3><ul><li>new calendar write only permission</li><li>New embedded photos picker that is smaller, so users picks what they want without requiring to give gallery permissions.<ul><li>Customizable: Hide accessory UI, buttons, specify frame and padding, get selections in real time.</li><li>Inline style, ideal to combine with hidden accessories.</li><li>Compact style that is just a row.</li><li>new macOS window picker to screen recording</li><li>support for OHTTP relay</li><li>Communication safety for apps with Sensitive Content Analysis framework to detect nudity. sensitive content warning to blur images.</li><li>Xcode privacy manifest generates privacy details from third party sdks.</li><li>Tracking domains help the system block calls to those domains until the user has agreed to be tracked.</li><li>New Instrument that displays requests to potentially tracking domains</li><li>Required reason APIs are apis that have potential to be misused for fingerprinting. apps and sdks must declare a reason to use them.</li><li>Signatures for third party sdks to validate the code comes from the correct authors.</li></ul></li></ul><h3>Core Location</h3><p>New Monitor API based on actors.</p><h3>Other</h3><ul><li>VisionKit to integrate photo subject lifting into our apps.</li><li>Accessibility audits now can be automated in UI Tests</li><li>SFSymbols components to mix in your custom ones.</li><li>Push Notification Console website<ul><li>Send push to specific device for testing and development</li><li>Delivery log to know what went wrong. Put device in low power mode to not receive them.</li><li>Debug tool to validate tokens.</li><li>Improved App Store Connect APIs and a swift server library</li><li>DockKit is pretty cool. I didn't know iOS had this functionality out of the box!</li><li>Keyboard is now out of process.</li><li>Remember to use the keyboard autolayout guide in UIKit. In SwiftUI the safe area includes the keyboard automatically. If you are still using the old notifications check out the session <a href="https://developer.apple.com/wwdc23/10281">Keep up with the keyboard</a> because with all the recent keyboard modes it doesn't behave as expected.</li></ul></li></ul>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/lawful-times-1-2-breach-of-peace-and-rebel-creed-review</guid><title>Lawful Times 1 &amp; 2, review</title><description></description><link>https://alejandromp.com/blog/lawful-times-1-2-breach-of-peace-and-rebel-creed-review</link><pubDate>Sat, 3 Jun 2023 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>I approached the Lawful Times series from a position of having watched the author's YouTube videos for a long time and sharing some of his taste about fiction. Considering this, I was certain that I would, at the very least, find the experience enjoyable. However, I was pleasantly surprised to find myself captivated and craving more from this series.</p><p>Rating: <a href="https://www.goodreads.com/review/show/5561196836">3/5</a></p><p>But I had another motive to read Daniel's words: to convince myself that I could write too. As someone who has been grappling with self-doubt regarding the worthiness of putting my thoughts into words, I actively seek any fragment that can fuel the self-confidence required to embark on such an endeavor. Seeing what Daniel has accomplished is another stone in the unfinished building of trusting myself. With this, I don't mean to diminish his work. Quite the opposite. He has accomplished something many could only dream of. But it also helps me believe, and, as with many things in life, that's the first step towards going anywhere. The rest is time and dedication and, well, that will need other stones and bricks.</p><p>But let's talk about the series itself.</p><p>I'm very intrigued by all the possibilities of the world building. That is not something that happens often, but it's also not surprising seeing the amount of reading that Daniel has made and how much of it matches my taste. Watching the videos where he explains a bit of the world building and magic system also makes me desire to see even more stories based on this world. What I really liked the most in these first two novellas is how they are so character focused. The plot leaves the intriguing world-building as a backdrop for an emotionally intense story. It would have been very easy to focus on the interesting bits of the world and its magic, but that would have made for a poor story. Very well done and something to learn from.</p><p>The other aspect I liked is how the words are not shy about using swear words when necessary. I always find most prose to be severely censored when, in reality, most people swear from time to time. Used poorly can make the text become distasteful, but when used appropriately, it makes me feel closer to the characters and the reality they are living.</p><p>Another notable aspect of Daniel's words is their fearless embrace of horror and visceral scenes. They are far and between, but when they come, they pack a big punch. Others would have skimmed through the events in the scene without focusing on delivering the impact they needed. I really appreciate Daniel being bold delivering the perfect amount of explicitness in the moments where the story benefited from it. Touché.</p><p>Overall, I admire the smart move of starting with novellas. It brings the focus to a concise plot and lets us taste of this world while leaving us wanting more. I hope Daniel returns to this series soon because I want to see how things progress forward.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/dark-one-forgotten-review</guid><title>Dark One: Forgotten - A Captivating Fictional Podcast Experience</title><description></description><link>https://alejandromp.com/blog/dark-one-forgotten-review</link><pubDate>Thu, 18 May 2023 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>I've always been an avid fan of podcasts, but surprisingly, I had never listened any true crime audio serials. It was an absolute delight to have my first experience with a fictional one through Dark One: Forgotten. It transported me back to the days when podcasts were crafted purely out of passion and genuine love, rather than being driven by money. The combination of the captivating mystery intertwined with the knowledge that there's a fictional element at play made it impossible for me stop listening. I wholeheartedly recommend this immersive experience!</p><p>What truly adds to the allure of Dark One: Forgotten is the collaborative effort of Sanderson and Wells. Their partnership holds immense potential, evident through the subtle traces of their individual brilliance that I discovered within this production. This exciting glimpse into their combined creativity has left me eagerly anticipating what they have in store for us next.</p><p>Rating: <a href="https://www.goodreads.com/review/show/5272812423">4/5</a></p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/the-sandman-act-iii-review</guid><title>The Sandman: Act III, review</title><description></description><link>https://alejandromp.com/blog/the-sandman-act-iii-review</link><pubDate>Tue, 16 May 2023 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>Last year, I embarked on an incredible journey through the first two acts of The Sandman audio series, and now, at long last, I've been immersed in the highly-anticipated third act. The Sandman keeps being an extraordinary masterpiece; simply calling it an audio-book fails to capture its true essence. Every aspect of the production, from the exceptional cast to the mesmerizing sound design and enchanting music, harmoniously blend together to create an incredible experience.</p><p>Rating: <a href="https://www.goodreads.com/review/show/5272009539">3.5-4/5</a></p><p>The third act of The Sandman continues to follow its captivating path, although I must admit that I found myself longing for more moments with Dream, as he isn't the central figure in many of the episodes. Nonetheless, each episode remains very enjoyable thanks to the diverse range of characters whose individual storylines weave together seamlessly, adding depth and richness to the overall narrative.</p><p>Despite my initial yearning for the previous storylines, I found myself thoroughly engrossed in the captivating arc that followed Delirium, Dream's extraordinary younger sister, in her quest to find their lost brother, a pursuit dismissed by the rest of the familay. Her character is nothing short of fascinating, with her whimsical demeanor and unpredictable nature adding a unique layer of intrigue to the narrative. This arc not only deepens our understanding of the Endless family but also grants us the opportunity to delve deeper into the intricate tapestry of the Sandman universe, introducing characters from other times.</p><p>Undoubtedly, the most captivating arc is the one set in the inn at the end of all worlds. The disconnected short stories, narrated by an intriguing ensemble of characters, are all fascinating. What adds to its allure is the intriguing framing narrative, which builds anticipation and culminates in a impactful and mysterious ending. While the concept of such a place is a common fantasy trope, the masterful execution by Gaiman makes it work exceptionally well within the story, providing valuable lessons to learn from.</p><p>I eagerly await the culmination of this extraordinary journey in The Sandman, I hope Act four is not too far away.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/the-frugal-wizard-s-handbook-for-surviving-medieval-england-review</guid><title>The Frugal Wizard’s Handbook for Surviving Medieval England, review</title><description></description><link>https://alejandromp.com/blog/the-frugal-wizard-s-handbook-for-surviving-medieval-england-review</link><pubDate>Sat, 29 Apr 2023 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>And here we are again, the second book of The Year of Sanderson has arrived. This time though, I didn't jump on it immediately, unlike <a href="https://alejandromp.com/blog/tress-of-the-emerald-sea/">Tress</a>, this is not a Cosmere novel so I was not so eager to devour it; I was deep in another world of Critical Role, <a href="https://alejandromp.com/blog/back-to-critical-role">catching up with the show</a> and <a href="https://alejandromp.com/blog/critical-role-vox-machina-kith-kin">reading a novel</a>.</p><p>But then I started <strong>The Frugal Wizard’s Handbook for Surviving Medieval England</strong>, what a title!, and remembered how curious I got when Sanderson read the first chapters on his promotional videos last year. That excitement got the best of me. That was three days ago.</p><p>Rating: <a href="https://www.goodreads.com/review/show/4605245405">4/5</a>. <em>Four of five stars. The author keeps delivering. Interesting premise, world and characters. Funny and mysterious in equal parts. Would recommend.</em></p><p>Like Tress, the Frugal Wizard is a different beast from what I'm used to with Sanderson, something that definitely will give him critical reviews again, from those that prefer their favorite authors to stay monotone. For me? I loved it. The way Sanderson mixes the seriousness of the mystery with the lightheartedness of the premise and the marketing materials of the Guide is nothing short of brilliant. It's a testament to his talent that he can balance all of it so effectively, and it's one of the many things I'm really enjoying about his more recent work.</p><p>The world-building in this book is so clever. For those who have followed Sanderson outside of his books, you may know that he has two unbreakable rules that he follows on the Cosmere: no time travel and no multiverse. I love those rules, and they are ones I've followed on my amateur fiction creation too. They are very important to keep the stakes of a story. As soon as time travel or multiple versions of the same characters are introduced, consequences lose their impact.</p><p>But in the Frugal world, he doesn't have to follow Cosmere rules, and he has broken them, not to the detriment of the story, but quite the opposite. The "Medieval England" of the story is not <em>our</em> Medieval England, the main character hasn't travelled to the past; instead, he has travelled to an alternate dimension that is similar but not exactly like ours. This is brilliant because it keeps the consequences of time travel away from the plot, and still it gives a chance to develop stories with what feels like time travellers. At the same time is not a multiverse of clones, but one where each dimension is slightly different, which means those are different and real people that the characters, and the reader, can care about. Brilliant!</p><p>In the same vein, I loved the main character. That he starts without memory in a strange land and starts remembering things of his past that may or not be correct is great. It's so relatable, not the loss of memory, but how our present mind can wrongly interpret old memories. The character is very flawed and we can feel the roller coaster of emotions and realisations that he's going through the entire book.</p><p>And finally, the setting of medieval England is very nice. I'm not a historical fiction reader but this was very interesting, mainly because one knows Sanderson style and you know he can't resist giving a twist to any world he builds. The mystery of knowing where things may differ from our history kept me on my toes, not at the level of the Cosmere, but enough to keep me going.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/critical-role-vox-machina-kith-kin</guid><title>Critical Role: Vox Machina — Kith &amp; Kin, review</title><description></description><link>https://alejandromp.com/blog/critical-role-vox-machina-kith-kin</link><pubDate>Mon, 24 Apr 2023 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>As I advanced in <a href="https://alejandromp.com/blog/back-to-critical-role">Back to Critical Role</a>, I've been reading a book from Critical Role, the adventures of Vex and Vax before the events of Vox Machina. This came out because I was completing the YouTube channel and saw a promotional video about the book. I immediately got curious about how the world and characters were portrait in writing, so I just went for it!</p><p>Rating: <a href="https://www.goodreads.com/review/show/5488990189">3/5</a></p><p>I really liked how the present of the story is mixed with flashbacks of their past. Knowing the characters from the show, it felt like I was getting a view of multiple moments of their life, all in one book. The best thing was how the ends and beginning of the chapters segued so well into and from the flashbacks. It was very enjoyable.</p><p>The story's narrow focus was appropriate to highlighting the characters instead of the world of Exandria. By splitting them up, readers were given a chance to learn more about each character individually, which was particularly rewarding given how much of their plotline is about sticking together.</p><p>Overall, quite happy with the book. It is what it is without pretensions of trying to be what is not. Very enjoyable, would recommend for any fan of the show.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/back-to-critical-role</guid><title>Back to Critical Role</title><description></description><link>https://alejandromp.com/blog/back-to-critical-role</link><pubDate>Sun, 23 Apr 2023 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>After finishing <a href="https://alejandromp.com/blog/a-crown-of-swords-the-wheel-of-time-7-review/">A Crown of Swords,</a> I started with the next book but got stuck in the prologue. The Wheel of Times prologues are so annoying because they are very long and about characters I rarely care about. It's a way to put you up to speed with those characters, but is very draining.</p><h2 id="back-to-campaign-2">Back to campaign 2</h2><p>That allied with other things that were going on in my life and Critical Role crossed my YouTube suggestions again. I stopped watching Campaign 2 a while ago and a thought came to me, "what if I watch it again". I needed to put something that could stay in the background and didn't require me to focus on all the characters in the world, something to pull my mind away from the shitty reality I was living in.</p><p>And those I was hooked to Critical Role, yet again ^^</p><p>Although I had paused the show during what seemed like a quiet period, a few episodes later, the story took shape. The mysteries grew more complex, and the tension escalated, leading up to what I can confidently say was one of the most unforgettable moments I've ever seen:</p><blockquote><p>What Laura did in #CriticalRoleSpoilers episode 93 of campaign 2 with the cupcakes 🧁 represents the things you only get in roleplay based storytelling. (Yes I’ve been catching up a bit 😂) <a href="https://mastodon.social/@alexito4/110051028330849919">Mastodon post</a></p></blockquote><p>After that, the party got involved in plots that would endanger Exandria, magic from ancient civilizations and political intrigue; all of that made me pause book reading for a bit and instead focus my fiction consumption on Critical Role.</p><p>That's how after so many hours I finished watching campaign two, with an epic final battle that just kept getting better and better. With moments that got me on the edge of my sit, and where tears peaked from my eyes.</p><p>Those moments made me remember why I love watching Critical Role. As I <a href="https://mastodon.social/@alexito4/110123409970684981">quickly posted</a>, this is just another form of storytelling, but one that can make you feel more than any other. I truly believe this cast makes the most epic fiction there is to be, not because of the story, but because of the impact that it has on you. The passion, the emerging plot, the jokes and fun they have, the tears... Other mediums can hardly achieve this high emotional mix.</p><p>I really wish more people could enjoy this, but as with many good things it has, the over five-hundred hours one needs to enjoy it means this is not something for everybody. Even for me, somebody that watches at 2x (or more) it's a big time investment.</p><p>Totally worth it for something that no other form of storytelling can offer.</p><h2 id="can't-replicate">Can't replicate</h2><p>After campaign two, I was so hooked that entered a <em>completionist</em> mode where I just went and watched every video in Critical Role's YouTube channel. Including one-shots and the short alternative campaign of Exandria Unlimited.</p><p>Watching this other show made me remember why Critical Role is the only live-play I keep coming back to. Everything I've said about emerging story telling is true, but the reality is that Critical Role hooks because of its cast. Not only because they are great voice actors and know how to make you forget it's just a story, but because they are all super nice to spend hours with and the chemistry they have between themselves is gorgeous. Basically, Critical Role is its cast. The story and events are the epic parts, but none of that works without the people.</p><p>I've watched my fair share of role-play shows, but none of them have managed to capture my attention and keep me invested like Critical Role. Even though I finished Exandria Unlimited, I realized that it was the cast that made the first two campaigns truly memorable. While I appreciate that Critical Role has grown into a major production house, is expanding into new territories and including other voices that deserve to be heard, I fear that this might dilute the essence of what made the show so special for me.</p><h2 id="to-campaign-3!">To Campaign 3!</h2><p>At the moment of writing, I've made it through the first 10 episodes of campaign three, and it's been a bit of a strange beginning with mixed emotions about carrying over some characters from Exandria Unlimited. However, I was pleasantly surprised to find that my apprehension about a different cast affecting my enjoyment is not an absolute. Robbie's delightful presence in campaign three has erased any doubts I had and made the experience all the more enjoyable! And of course, my positive feelings about Robbie's presence in campaign three are not meant to be a critique of anyone else who participated in Exandria Unlimited or any other guests. It's simply a personal sentiment that's difficult to articulate, based on the social dynamics and human interactions that make the show so special.</p><p>For now, Campaign 3 hasn't hooked me completely yet, although it has a few things going for it; in-world and external.</p><p>The weird set of character choices is very interesting and is already showing many interesting interactions. It's interesting how fresh it seems to have a robot and undead in the main cast, interesting because this is fantasy after all!</p><p>The chance to explore a new continent of Exandria is always exciting as it engages my world-building brain to its max. I'm interested to see more places besides the city where the characters started, because in my mind Marquet was mainly a dessert, but hearing things about jungles and other populated areas piques my interest.</p><p>But the thing that really makes me curious about where the campaign is going is what's been happening in the real world with WotC. I've heard rumblings of God level events in this campaign, which makes me excited to see Matthew get rid of the last bit of ties that Exandria has with D&amp;D lore. This idea just got more exciting a few days ago when they confirmed the ongoing development of their own RPG.</p><h2 id="more-exandria-to-come">More Exandria to come</h2><p>Exploring different worlds and immersing myself in their intricacies is a passion of mine. While I could potentially use that time to focus on writing my own material, the human brain is complex and mine is not collaborating lately. Life happens. Therefore, I find myself indulging in the vast universe of Exandria instead, not just through gameplay, but also through a novel from Critical Role.</p><p>Fiction is truly unlimited.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/a-crown-of-swords-the-wheel-of-time-7-review</guid><title>A Crown of Swords (The Wheel of Time, #7), review</title><description></description><link>https://alejandromp.com/blog/a-crown-of-swords-the-wheel-of-time-7-review</link><pubDate>Sat, 18 Mar 2023 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>After just 12 days, I just finished A Crown of Swords, the 7th book of The Wheel of Time.</p><p>Given some personal circumstances, I find myself with more time to listen to audiobooks, so that's why this is probably the fastest I've ever read a book in my life. After <a href="https://alejandromp.com/blog/the-wheel-of-time-6-lord-of-chaos-review/">Lord of Chaos</a> I've found the seventh book more interesting.</p><p>Rating: <a href="https://www.goodreads.com/review/show/3428221113">4/5</a></p><p>This book just continues the events of the story, so my overall opinion is still a bit of the same. It feels like we're just watching events happen, following people around doing things that sometimes feel too mundane or without a clear and specific purpose. It's like we are seeing the scenes that would be cut in other stories. But it still has its charm, and in this instance <em>more happens</em>.</p><p>It's probably because we follow Rand for longer, doing random things all over. I really like how at this point he's more comfortable with his powers and position, although he still feels terribly responsible for many things, which clearly shows the mental burden he carries.</p><p>We see the powers taking place also with Matt and his Ta'veren status. I really like this because it feels like a passive power that none of them control and that sometimes turns out well and sometimes doesn't. It's not an absolute, they are as much in the hands of destiny as their enemies.</p><p>I really like Matt, so the fact that we follow him for a while on this book it's also a positive for me. It's even nicer because we have most of our main characters together, well, mostly split in two, but it's much nicer than having them all individually doing their own thing.</p><p>There are also a bunch more confrontations that make me wonder and be hooked into the plot. I loved how the Aes Sedai are forced to realise that they should chill a bit and stop pretending they are the rules of the world. Yes, I freaking hate the Aes Sedai 😂, not all of course, but the air of superiority that surrounds them is so exaggerated and palpable on every scene that becomes infuriating. That's what has made me love the appearance of the Asha'man.</p><p>One thing that still tickles me after having finished is how there are a couple of scenes that don't resolve with answers. There are a couple of characters that appear and we don't know who they are. I love this sense of mystery which is not that common in this story.</p><p>And I guess that summarizes my issue with the overall story. There is no mystery. Don't get me wrong, of course there are things we don't know and get revealed on time. But overall there is no big mystery that I'm eager to know. We know who is the Dark Lord; their followers are known; even the steps we need to take to destroy them and what needs to happen in the last battle. We may not know all the details, but there is no big mystery either. We are just here for the ride of seeing our characters' lives.</p><p>Nothing illustrates more clearly this aspect of just progressing through a big plot that the ending of the books. They mostly seem just another scene that could be anywhere else, and the ending of this book seven is no different. After spending the entire book following Rand around, the book ends just by doing another one of his incursions. Yes, there is a bit of a bigger battle and a tense chapter, which is great!, but the payout doesn't feel that big.</p><p>In any case, I already have book 8 ready. Let's go!</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/non-nominal-types-workaround-for-domain-modeling</guid><title>Non-nominal types workaround for domain modeling</title><description></description><link>https://alejandromp.com/blog/non-nominal-types-workaround-for-domain-modeling</link><pubDate>Thu, 9 Mar 2023 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>One of the many things I love about working with <a href="https://alejandromp.com/tags/pointfree-composable-architecture/">The Composable Architecture</a> is how it encourages the developer to focus on domain modeling. I think that properly designing the models or entities of a domain is one of the biggest contributors into good code, and the lack of it makes everything way harder than it should be. Thankfully <a href="https://alejandromp.com/tags/swift/">Swift</a> is a great language that allows us to express almost everything we need to in a very strict and concise way, another reason the language of your choice matters most than people pretends.</p><p>So the topic I will discuss here is not really specific to the TCA, but more about domain modeling and types. Let's start by exposing the issue:</p><h2 id="modeling-the-problem">Modeling the problem</h2><p>Let's imagine we want to model the result of some side effect, like an API call, that can succeed and fail. We can easily do this with Swift's <code>Result&lt;Success, Failure&gt;</code> type, but in this case we <strong>do not care</strong> about the success data at all, only about the failure. In other words, we want to know which specific error occurred, but if it succeeded we don't want to know anything about the success data.</p><p>Of course if you have done any meaningful coding with TCA this will feel very familiar, and indeed is where I find this more often, with its other variations of I only care about success data and not the error, I don't care about any of the two, etc... But let's ignore that for now and see what the issue is and why is so important to model this correctly.</p><h2 id="algebra">Algebra</h2><p>What? Math? Seriously? Yes! It's actually the easiest way of realizing what you are doing when modeling a solution. Don't fear, it's very simple.</p><blockquote><p>If you want to learn more about <a href="https://www.pointfree.co/collections/algebraic-data-types">Algebraic Data Types</a> I really recommend <a href="https://www.pointfree.co/subscribe/personal?ref=4Fj20c5I">subsribing to Pointfree</a> (get one month free with this link)</p></blockquote><p>Let's first think how many potential scenarios the most basic design gives us:</p><pre><code><span class="splash-type">Result</span>&lt;<span class="splash-type">Int</span>, <span class="splash-type">Error</span>&gt;
</code></pre><p>With this type, we have <code>n</code> possibilities for the integer in case of success, and <code>m</code> possibilities for the error in case of failure. (let's assume <code>Int</code> is what the side effect responds with). These are <code>n + m</code> cases we would have to deal with, too many! Remember, we don't care about the success data.</p><p>So if we don't care about the success and only about the error, maybe we can ditch the Result type completely and just use the Error.</p><pre><code><span class="splash-type">Error</span>
</code></pre><p>That will give us <code>m</code> possibilities, but we are lacking a way to know if it succeeded. We want to know that it succeeded, but not about its specific data. But Swift already provides with a tool for it, <code>Optional</code>.</p><pre><code><span class="splash-type">Optional</span>&lt;<span class="splash-type">Error</span>&gt; <span class="splash-comment">// Error?</span>
</code></pre><p>Now we have <code>m</code> from the <code>Error</code> and <code>1</code> from the optional nil case, so <code>m + 1</code>. Exactly the amount of cases we wanted!</p><p>Simple right?</p><p>But let's say we want to still use the <code>Result</code> type for consistency with the rest of the code. How can we use that type, which requires a <code>Success</code> and still keep the same <code>m + 1</code>? We need a type that only gives us 1 option, and again, we have one. Swift calls it <code>Void</code> or <code>()</code> (the empty tuple), called Unit in other languages. With that knowledge, let's use <code>Result</code> again.</p><pre><code><span class="splash-type">Result</span>&lt;<span class="splash-type">Void</span>, <span class="splash-type">Error</span>&gt;
</code></pre><p>Thanks to <code>Void</code> we can use the <code>Result</code> type and still have <code>1 + m </code> cases to deal with.</p><p>This may seem like a minor thing, after all, you could just use the original data (<code>Int</code>) and just ignore it on your code. But that's a slippery slope that makes your code harder to reason about. When your future self comes back and reads the code, the types will explain the story of what is happening without having to read the code. The compiler will make you remember the decisions you took when you already forgot them. Such is the power of properly modeling domains with a proper type system.</p><h2 id="the-limitations">The limitations</h2><p>This is all nice but we need to use this response in another type, in the case of the TCA we need to embed this in an Action enum, but it could be any other type you use to carry data around.</p><p>This is how it would look if we cared about the success data:</p><pre><code><span class="splash-keyword">struct</span> ApiResponse {
    <span class="splash-keyword">let</span> response: <span class="splash-type">Result</span>&lt;<span class="splash-type">Int</span>, <span class="splash-type">Error</span>&gt;
}
</code></pre><p>All well so far. But let's make this type more realistic and make it conform to <code>Equatable</code>, which is something we need most of the time.</p><pre><code><span class="splash-keyword">struct</span> ApiResponse: <span class="splash-type">Equatable</span> { <span class="splash-comment">// Type 'ApiResponse' does not conform to protocol 'Equatable'</span>
</code></pre><p>Boom! 💥 The compiler can't synthesise the conformance because our <code>Result</code> type is not equatable. <code>Int</code> is obviously fine, the problem is the <code>Error</code>.</p><p>The reason for this is a rabbit whole we don't have time to get into now, but there are multiple solutions for it. Thankfully PointFree has already provided one for the users of the TCA in the form of <code>TaskResult&lt;Success&gt;</code> (<a href="https://pointfreeco.github.io/swift-composable-architecture/main/documentation/composablearchitecture/taskresult">docs</a>) so we can ignore this exact problem and move on to the one I want to discuss.</p><pre><code><span class="splash-keyword">struct</span> ApiResponse: <span class="splash-type">Equatable</span> {
    <span class="splash-keyword">let</span> response: <span class="splash-type">TaskResult</span>&lt;<span class="splash-type">Int</span>&gt;
}
</code></pre><p>Now the compiler is happy again. Keep in mind that even if we don't see the <code>Error</code> type anymore, the failure case is still there <code>case failure(Error)</code> so we still have the data we care about.</p><p>But we are still using the awful <code>Int</code>, let's switch back to use our lovely <code>Void</code>.</p><pre><code><span class="splash-keyword">struct</span> ApiResponse: <span class="splash-type">Equatable</span> { <span class="splash-comment">// Type 'ApiResponse' does not conform to protocol 'Equatable'</span>
    <span class="splash-keyword">let</span> response: <span class="splash-type">TaskResult</span>&lt;<span class="splash-type">Void</span>&gt;
}
</code></pre><p>💥 Here we are again! Now it's <code>Void</code> that is not <code>Equatable</code> and if you know a bit about Swift you know why.</p><p><code>Void</code> is a non-nominal type, which in simple terms it means there is not a name you can use to refer to it in some language features. One such feature is protocol conformance, which allows types to adopt a set of behaviors defined by a protocol, in this case equatability. Because Void is not a named type, Swift does not inherently know whether it conforms to any given protocol. Although we might want to make Void conform to Equatable ourselves by defining an extension, we can't do it because we cannot reference it by name! Therefore, we can't retroactively make Void conform to any protocol. 😞</p><pre><code><span class="splash-keyword">extension</span> <span class="splash-type">Void</span>: <span class="splash-type">Equatable</span> {} <span class="splash-comment">// Non-nominal type 'Void' cannot be extended</span>
</code></pre><p>So if we can't use <code>Void</code>, maybe we can use the alternative of using an <code>Optional</code>?</p><p>Well, that brings us back the problem with <code>Error</code> that we solved with <code>TaskResult</code> so is not a solution.</p><pre><code><span class="splash-keyword">struct</span> ApiResponse: <span class="splash-type">Equatable</span> { <span class="splash-comment">// Type 'ApiResponse' does not conform to protocol 'Equatable'</span>
    <span class="splash-keyword">let</span> response: <span class="splash-type">Error</span>?
}
</code></pre><h2 id="equatablevoid">EquatableVoid</h2><p>My favorite solution to this problem is just to make <code>Void</code> a nominal type. Of course you can't make the existing one but you can just make your own. Remember how we described Void as the empty tuple <code>()</code>? A tuple is an anonymous product type, but we can use a named product type instead.</p><pre><code><span class="splash-keyword">struct</span> EquatableVoid: <span class="splash-type">Equatable</span> {}
</code></pre><p>Our <code>EquatableVoid</code> it has the same shape a <code>Void</code>, it only has 1 possible value which we can get by calling the initializer <code>EquatableVoid()</code>. Is not as nice as just <code>()</code> but such is the price we need to pay.</p><p>With this new type, we can change our response and finally have what we want:</p><pre><code><span class="splash-keyword">struct</span> ApiResponse: <span class="splash-type">Equatable</span> {
    <span class="splash-keyword">let</span> response: <span class="splash-type">TaskResult</span>&lt;<span class="splash-type">EquatableVoid</span>&gt;
}
</code></pre><p>This gives us <code>1 + m</code> cases, no more, no less. We have expressed exactly our domain.</p><p>We can use our types like so:</p><pre><code><span class="splash-keyword">let</span> ok = <span class="splash-type">ApiResponse</span>(response: <span class="splash-type">TaskResult</span>&lt;<span class="splash-type">EquatableVoid</span>&gt;.<span class="splash-call">success</span>(<span class="splash-type">EquatableVoid</span>()))
<span class="splash-keyword">let</span> ko = <span class="splash-type">ApiResponse</span>(response: <span class="splash-type">TaskResult</span>&lt;<span class="splash-type">EquatableVoid</span>&gt;.<span class="splash-call">failure</span>(<span class="splash-type">Badabum</span>.<span class="splash-property">granBadabum</span>))
</code></pre><p>And work with them in a switch statement exactly like we wanted:</p><pre><code><span class="splash-keyword">switch</span> response {
<span class="splash-keyword">case</span> .<span class="splash-dotAccess">success</span>(<span class="splash-keyword">let</span> void):
    <span class="splash-comment">// not much you can do here, you only have 1 possible value that is always the same</span>
<span class="splash-keyword">case</span> .<span class="splash-dotAccess">failure</span>(<span class="splash-keyword">let</span> error):
    <span class="splash-comment">// but here you have all errors so you can work with them as you please</span>
}
</code></pre><h2 id="other-unsatisfactory-solutions">Other unsatisfactory solutions</h2><p>There are, of course, other solutions that have other tradeoffs, so as usual I give you the tools so you can take the decision on your own.</p><p>You could use the optional alternative by using a specific error type that was equatable: <code>SpecificEquatableErrorForYourDomain?</code>. That would work but then you need to reconcile your specific error type with Swift's untyped errors. With time I've learned to embrace Swift's error system and stop fighting it, so I don't recommend this. Is a fix for this exact part of the code, but you will have to write patches in other parts to deal with any errors and default cases.</p><p>Another solution would be to use <code>NSError</code>, which is convertible to <code>Error</code> and is equatable. I tend to run away from it. I'm fine receiving it from Objective-C APIs but I want my Swift code to be Swift code. <code>NSError</code> loses the type safety at the usage side. You can't cast it to a specific type but need to rely on strings and integers. It's not a tradeoff I'm willing to make.</p><p>And I imagine there are other ways of solving this with different tradeoffs, but I'm not aware of one that gives me what I want in a better way :)</p><h2 id="other-usages-of-this-technique">Other usages of this technique</h2><p>This technique is not something new that I only use for this case, in fact this is the third occurrence in my codebase of this solution.</p><p>In our project, we use the TCA to its fullest and I made a generic loading system that we are very happy with. The closure that lets you customize how to get the data receives a parameter that can be injected from other domains. Think of an ID that you need to fetch a user, for example. But not all screens need parameters, so you would want to define the generic type as <code>Void</code>, but again it needs to be equatable. In this case, I employ another trick that let developers avoid even constructing this type at all.</p><pre><code><span class="splash-keyword">public typealias</span> NoParameter = <span class="splash-type">_NoParameter</span>?
<span class="splash-keyword">public struct</span> _NoParameter: <span class="splash-type">Equatable</span> {}
</code></pre><p>By using <code>NoParameter</code> as the generic type, developers (in fact our library has this default cause supported) can just pass nil when constructing the domain and they don't have to deal with the parameter in their implementation.</p><blockquote><p>I should talk about our generic loading system because I think is pretty neat. <a href="https://mastodon.social/@alexito4">Ping me</a> if it's something you would be interested in :)</p></blockquote><p>Another place where this pattern occurred is in the API library I implemented, which uses Swift's generic type system to make it very simple to define endpoints. In an endpoint, there is a generic parameter that defines the response model you want to decode, but of course, sometimes you don't really want to decode anything. The same goes for the generic parameter that specifies which parameter to send to the API. For that, again, you would love to use <code>Void</code> but it's not <code>Decodable</code> or <code>Encodable</code> so it won't work.</p><pre><code><span class="splash-keyword">public struct</span> Ignore: <span class="splash-type">Equatable</span>, <span class="splash-type">Codable</span> {}
</code></pre><p>Maybe I should think about making a <code>SuperVoid</code> that covers all the cases :)</p><h2 id="conclusion">Conclusion</h2><p>Domain modeling matters, and having a language with a type system that supports us when designing, is crucial. Swift gets very far, but it still has some limitations with non-nominal types that thankfully can be solved by defining our own types to cover for these cases.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/the-wheel-of-time-6-lord-of-chaos-review</guid><title>Lord of Chaos (The Wheel of Time #6), review</title><description></description><link>https://alejandromp.com/blog/the-wheel-of-time-6-lord-of-chaos-review</link><pubDate>Sun, 5 Mar 2023 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>And here we are again! After <a href="https://alejandromp.com/blog/pausing-the-wheel-of-time/">pausing The Wheel of Time</a> and having ready all the Cosmere I decided it was time to go back to the epic adventures of Rand al'Thor.</p><p>After just short of a month, I've read (a.k.a. listened) the sixth book in the series, <a href="https://www.goodreads.com/book/show/35231.Lord_of_Chaos">Lord of Chaos (The Wheel of Time, #6)</a>, what an epic ending to the over 40 hours of audiobook!</p><p>Rating: <a href="https://www.goodreads.com/review/show/3428221089">3.5/5</a></p><p>I've shared my overall feelings about the series before and I don't think they have changed, especially with this installment which feels quite slow. I still love the series for its depth and world, but what makes it really shine are its realised characters and the epicness of its events. Unfortunately, these epic moments diluted among a mountain of text that spends too much time to on chores.</p><p>I've spent the vast majority of the book just wondering where things were going because they were not going anywhere. Too many points of view and too much time spent in scenes that didn't move the plot. And is an awful feeling because I really wish I loved more those scenes! I'm pretty sure that all of them are necessary, because when I think about the Wheel of Time I can imagine a fully realised world full of incredible characters, and I doubt this would still be the case without all those filling scenes.</p><p>So yes, I'm not saying there is too much filling, but I'm saying there is a <em>bit</em> too much? Again, is hard for me to reconcile this feeling.</p><p>Because then, when a scene actually moves the plot forward, you could hear me scream! 🙀 There are moments so memorable and epics in this book that when I finished it last night, I immediately got better feelings about it.</p><p>Seeing our characters reunite, Rand accepting his position on all of this, and also friendships that are being muddled by world events... it's very impressive.</p><p>During this same month I've been watching Castle, the serial tv show. The fact that every episode has little to do with the previous but that as the seasons go, the writers add more and more details into the overall story line, made me realise that it's how I started looking at the Wheel of Time. Usually when I read fantasy I'm tied to the three story act, expecting the plot to move forward towards a conclusion, but after six books I think that the way to read the Wheel of Time is far from that. Each individual book doesn't strongly follow the classical formula, yes there is a meaningful ending, but the book doesn't really build up only towards that. It's closer to a tv show where we just spent time with the characters while they are doing their own thing, sometimes we spent time with them to know them better (too often) even if the plot doesn't benefit from it. So I've changed my attitude and now I'm just reading the Wheel of Time enjoying the ride with no expectation of what needs to happen or when.</p><p>It's a bittersweet realisation but I think this will propel me to the upcoming books, and I still love what's going on, so I really want to get to the conclusion of the series. I can't wait to get more epic moments like the last chapter of this book. Rand is such a freaking main character!</p><p>This experience is being strange indeed. I see myself trying to understand what I love and what I hate about the epic story, and I really can't pinpoint what's going on. I have plenty of critiques but I still see how this is one of the best epic stories ever written and I'm still loving the ride. So weird.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/fated-blight-review</guid><title>Fated Blight, review</title><description></description><link>https://alejandromp.com/blog/fated-blight-review</link><pubDate>Sat, 4 Feb 2023 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>Fated Blight is the first entrance in the trilogy of <a href="https://www.goodreads.com/series/354089-the-sum-of-ages">The Sum of Ages Series</a> and I think this is a very good first book. I got this book via a giveaway in <a href="https://app.thestorygraph.com">The StoryGraph</a> and it has been a pleasure.</p><p>Rating: <a href="https://www.goodreads.com/review/show/5271978074">3/5</a></p><p>I really loved having characters of a different race and seeing a different mythology, Philippine, feed the world where the story takes place. It was a breath of fresh air in a space filled with <em>English</em> lore. On top of that, reading some <em>Spanish</em> sounding words in a fantasy novel was new to me and made me a bit more special than usual.</p><p>The underwater scenes require a special mention. They made me live things that I have not experienced before in other books. It felt very original to me. And the writing was to the point, it can be tricky to make the reader connect with otherworldly situations in a way that makes us feel like we are there. Even though being underwater might not seem as unfamiliar as other environments, I have only been a few meters below the surface, and those who have gone deeper, it was surely not without the aid of an oxygen tank. Those scenes being rooted in reality, albeit a reality that few have experienced, made them just more impactful to me.</p><p>Something I was not a fan of is how the two POVs were so disconnected throughout the entire book. I was waiting for the characters to touch point always in the next chapter, but to no avail. I imagine they will get closer later in the series, but not having them connect in the first book broke my expectations and made me be more aware of this flaw. More than it deserves, because I don't think it's a bad thing that the two main characters have their separate paths, but I was not expecting it.</p><p>The story of the boy didn't quite hit the mark. Aside from the main action scene, the rest of the story felt like a prolonged setup. While it was interesting and left me curious to know more about the world, I found myself more entertained with Olenka's narrative.</p><p>Overall, I'm quite happy with it! I enjoyed the reading and I'm interested in knowing more. The next books definitively go on my to read list and I hope to get to them soon! 👏</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/an-exploration-of-formatstyle-as-a-dependency</guid><title>An exploration of FormatStyle as a Dependency</title><description></description><link>https://alejandromp.com/blog/an-exploration-of-formatstyle-as-a-dependency</link><pubDate>Fri, 20 Jan 2023 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>Buckle up. This is an adventurer journal while exploring what's the best way of exposing the <em>new</em> style of formatting APIs in Foundation. We will walk through the paths of the type system, including existential types, generics and type erasure; and discover the magical possibilities of the dependency system.</p><h2 id="a-clash-of-styles">A clash of styles</h2><p>This idea came to mind after finding a clashing in styles of development. When I work on my side projects and I have to do things quickly, mostly for fun, I love the new formatting APIs, <code>thePast.formatted(.relative(presentation: .numeric, unitsStyle: .abbreviated))</code>. But then when working in a proper product, in a team, with a long-term vision, you need to use proper engineering techniques, which often involves doing dependency injection.</p><p>I use PointFree's dependency library (as part of the TCA) which I've discussed previously (<a href="https://alejandromp.com/blog/on-the-new-pointfree-swift-dependencies/">On the new Point-Free swift-dependencies library</a>) but this applies to any other DI technique pretty much. Usually when you want to DI something that lets you format, the best way is to provide a function that takes the input value and gives you an output value, typically a <code>String</code>.</p><pre><code><span class="splash-keyword">public struct</span> DateFormatter {
    <span class="splash-keyword">public let</span> format: (<span class="splash-keyword">_</span> date: <span class="splash-type">Date</span>) -&gt; <span class="splash-type">String</span>
}
</code></pre><p>Then the <code>live</code> implementation of this dependency can use a <code>DateFormatter</code> or the new <code>.formatted</code> style. The advantage of having this API as a dependency is that it allows you to <strong>very</strong> easily switch the implementation for testing and previews.</p><pre><code><span class="splash-keyword">static var</span> testValue: <span class="splash-type">DateFormatter</span> = <span class="splash-type">XCTUnimplemented</span>(<span class="splash-string">"</span>\(<span class="splash-type">Self</span>.<span class="splash-keyword">self</span>)<span class="splash-string">.format"</span>)
<span class="splash-keyword">static var</span> previewValue: <span class="splash-type">DateFormatter</span> = { <span class="splash-keyword">_ in</span> <span class="splash-string">"Tue, Nov 29"</span> }
<span class="splash-keyword">static var</span> liveValue = { $0.<span class="splash-call">formatted</span>(...) }
</code></pre><p>Being able to just have a hard-coded value for previews or testing without having to deal with the formatters themselves is a tremendous benefit that can't be underestimated.</p><p><strong>But</strong> as nice as this is, I resented the usage side not being as nice and natural as using the Foundation fluent API.</p><pre><code><span class="splash-call">formatDate</span>(selectedDay.<span class="splash-property">date</span>)
</code></pre><p>It's not bad, but I prefer the fluent API in this case. I just enjoy it a lot more when working on my side projects, so I started thinking how I could keep the joyfulness of the code but still adding the seriousness of DI.</p><h2 id="formatstyle-instances">FormatStyle instances</h2><p>To start, I had to learn more about how the newly fluent API worked. I explored it in the past but Apple's documentation is not super clear in this area, but then I was pointed to <a href="https://goshdarnformatstyle.com/"><strong>Gosh Darn Format Style!</strong></a> which does a great job of explaining how the API works.</p><p>The key is understanding that behind these fancy fluent APIs there is one protocol: <code>FormatStyle</code>. All the dot syntax calls create types conforming to that protocol and fluently mutate them. In other words, you can hold an instance of the style that you want.</p><pre><code><span class="splash-comment">// wo this seems so complex!</span>
(<span class="splash-number">2.5</span>).<span class="splash-call">formatted</span>(.<span class="splash-dotAccess">number</span>.<span class="splash-call">decimalSeparator</span>(strategy: .<span class="splash-dotAccess">always</span>).<span class="splash-call">precision</span>(.<span class="splash-call">integerLength</span>(<span class="splash-number">1</span>)))

<span class="splash-comment">// but is just really a mutation of structs</span>
<span class="splash-keyword">let</span> numberStyle = <span class="splash-type">FloatingPointFormatStyle</span>&lt;<span class="splash-type">Double</span>&gt;.<span class="splash-property">number</span>
<span class="splash-keyword">let</span> withDecimalSeparator = numberStyle.<span class="splash-call">decimalSeparator</span>(strategy: .<span class="splash-dotAccess">always</span>)
<span class="splash-keyword">let</span> withPrecision = withDecimalSeparator.<span class="splash-call">precision</span>(.<span class="splash-call">integerLength</span>(<span class="splash-number">1</span>))
(<span class="splash-number">2.5</span>).<span class="splash-call">formatted</span>(withPrecision)
</code></pre><p>This seems obvious, but I think this API has so many combinations and you get so overwhelmed with the auto-completion, that is sometimes hard to realise the simplicity of it. I think the eye-opening moment is when you actually understand that the API surface is not in the extension of the <em>input type</em> but in the fluent extensions of the concrete <code>FormatStyle</code>. The <code>Date</code>, <code>Double</code>, ... types are not the ones with the complex API, they just have one method, the <code>.formatted</code> call. It's in their specific formatter styles that the complexity resides.</p><p>What this also means is that you can easily create your predefined instances of styles in order to reuse them in your application. I think this is key because otherwise the risk of slightly doing different formats in different views is too big.</p><pre><code><span class="splash-keyword">extension</span> <span class="splash-type">FormatStyle</span> <span class="splash-keyword">where</span> <span class="splash-type">Self</span> == <span class="splash-type">FloatingPointFormatStyle</span>&lt;<span class="splash-type">Double</span>&gt; {
    <span class="splash-keyword">public static var</span> numberFancy: <span class="splash-type">FloatingPointFormatStyle</span>&lt;<span class="splash-type">Double</span>&gt; {
        <span class="splash-type">Self</span>.<span class="splash-property">number</span>.<span class="splash-call">decimalSeparator</span>(strategy: .<span class="splash-dotAccess">always</span>).<span class="splash-call">precision</span>(.<span class="splash-call">integerLength</span>(<span class="splash-number">1</span>))
    }
}

<span class="splash-comment">// Use numberFancy instead of the long chain from before</span>
(<span class="splash-number">2.5</span>).<span class="splash-call">formatted</span>(.<span class="splash-dotAccess">numberFancy</span>)
</code></pre><h2 id="dependency-inject-formatstyle">Dependency inject FormatStyle</h2><p>With this ability in our hands, let's go back to defining how it would ideally work with dependency injection.</p><p>If we consider I would love to keep the fluent API and have DI the obvious usage looks like this:</p><pre><code><span class="splash-keyword">@Dependency</span>(\.<span class="splash-property">numberFancy</span>) <span class="splash-keyword">var</span> style
number.<span class="splash-call">formatted</span>(style)
</code></pre><p>The simple way of accomplishing this with the dependency system just involves declaring the dependency using the <code>FloatingPointFormatStyle</code> type.</p><pre><code><span class="splash-keyword">extension</span> <span class="splash-type">DependencyValues</span> {
    <span class="splash-keyword">var</span> numberFancy: <span class="splash-type">FloatingPointFormatStyle</span>&lt;<span class="splash-type">Double</span>&gt; {
        <span class="splash-keyword">get</span> { <span class="splash-keyword">self</span>[<span class="splash-type">NumberFancyFormatterStyleKey</span>.<span class="splash-keyword">self</span>] }
        <span class="splash-keyword">set</span> { <span class="splash-keyword">self</span>[<span class="splash-type">NumberFancyFormatterStyleKey</span>.<span class="splash-keyword">self</span>] = newValue }
    }
}

<span class="splash-keyword">private enum</span> NumberFancyFormatterStyleKey: <span class="splash-type">DependencyKey</span> {
    <span class="splash-keyword">static let</span> liveValue: <span class="splash-type">FloatingPointFormatStyle</span>&lt;<span class="splash-type">Double</span>&gt; = .<span class="splash-dotAccess">number</span>.<span class="splash-call">decimalSeparator</span>(strategy: .<span class="splash-dotAccess">always</span>).<span class="splash-call">precision</span>(.<span class="splash-call">integerLength</span>(<span class="splash-number">1</span>))
}
</code></pre><p>If you have used the Dependency system, this should be pretty familiar. We just declare the <code>DependencyKey</code> and provide the property <code>DependencyValues</code> to get the <code>KeyPath</code>. The important part is how we can now declare the <code>FloatingPointFormatStyle</code> we want and that is injected into our code, while it lets us still use the nice fluent syntax.</p><p>And we are done, right? Nope!</p><h2 id="hardcoding-an-output">Hardcoding an output</h2><p>Remember the advantage of using a function: we can <em>easily</em> provide test and preview values without having to deal with the formatters themselves. With the new setup we lost this ability, there is no way, to my knowledge, to mutate a style implementation like <code>FloatingPointFormatStyle</code> and force it to return a custom string.</p><p>The alternative I pursued was to create a custom format style, after all, <code>FormatStyle</code> is just a protocol. It may seem that each input type, like numbers or dates, is tied to a specific FormatStyle type, but that's not true. It may be confusing because the types are nested and so it feels they are hardcoded, but in reality, the <code>formatted</code> function is generic.</p><pre><code><span class="splash-comment">// From Foundation extension BinaryFloatingPoint</span>
<span class="splash-keyword">func</span> formatted&lt;S&gt;(<span class="splash-keyword">_</span> format: <span class="splash-type">S</span>) -&gt; <span class="splash-type">S</span>.<span class="splash-type">FormatOutput</span> <span class="splash-keyword">where</span> <span class="splash-type">Self</span> == <span class="splash-type">S</span>.<span class="splash-type">FormatInput</span>, <span class="splash-type">S</span> : <span class="splash-type">FormatStyle</span>
</code></pre><p>This constrained function lets you pass any <code>FormatStyle</code> with a <code>FormatInput</code> associated type that it's a <code>BinaryFloatingPoint</code>. This means that it accepts a <code>FloatingPointFormatStyle</code> but also a custom type with the correct associated types.</p><p>Let's make a format style that always returns the same string:</p><pre><code><span class="splash-keyword">struct</span> HardcodedNumberFormatStyle: <span class="splash-type">FormatStyle</span> {
    <span class="splash-keyword">typealias</span> FormatInput = <span class="splash-type">Double</span>
    <span class="splash-keyword">typealias</span> FormatOutput = <span class="splash-type">String</span>
    
    <span class="splash-keyword">func</span> format(<span class="splash-keyword">_</span> value: <span class="splash-type">FormatInput</span>) -&gt; <span class="splash-type">FormatOutput</span> {
        <span class="splash-keyword">return</span> <span class="splash-string">"hardcoded"</span>
    }
}
</code></pre><p>And we can use this to format the Double from before:</p><pre><code>number.<span class="splash-call">formatted</span>(<span class="splash-type">HardcodedNumberFormatStyle</span>())
</code></pre><blockquote><p>To make it look nicer, we should provide an extension to allow dot syntax as shown above.</p></blockquote><p>This is all good, but how do we stuff this in our dependency system?</p><pre><code><span class="splash-keyword">private enum</span> NumberFancyFormatterStyleKey: <span class="splash-type">DependencyKey</span> {
	<span class="splash-keyword">static let</span> liveValue: <span class="splash-type">FloatingPointFormatStyle</span>&lt;<span class="splash-type">Double</span>&gt; = ...
  <span class="splash-keyword">static let</span> testValue = <span class="splash-type">HardcodedNumberFormatStyle</span>()
</code></pre><p>Of course, this doesn't compile, the types of <code>liveValue</code> and <code>testValue</code> don't match. But again, we don't care about the specific types, just about the input and output types of the format style. So maybe if we use generics...</p><h2 id="welcome-to-type-system-land">Welcome to type system land</h2><p>If we change the type to <code>some FormatStyle</code> the dependency is fine, but also useless. You can't use the style because it's not constrained, so the formatted function won't accept it. The solution would be to specify the associated types like <code>some FormatStyle&lt;Double, String&gt;</code> but sadly, the <code>FormatStyle</code> protocol doesn't offer primary associated types. So we can't use generics at this level.</p><p>A solution that occurred to me is to create a wrapper type that dispatches to the correct formatter accordingly. But the question is how to decide the dispatch.</p><pre><code><span class="splash-keyword">struct</span> WrappedNumberFormatStyle: <span class="splash-type">FormatStyle</span> {
    <span class="splash-keyword">func</span> format(<span class="splash-keyword">_</span> value: <span class="splash-type">Double</span>) -&gt; <span class="splash-type">String</span> {
        <span class="splash-keyword">return</span> <span class="splash-type">FloatingPointFormatStyle</span> or <span class="splash-type">HardcodedNumberFormatStyle</span>
    }
}
</code></pre><p>A typical way I would do this is by passing the correct style at init time. After all, the dependency system makes the decision for us.</p><pre><code><span class="splash-keyword">private enum</span> NumberFancyFormatterStyleKey: <span class="splash-type">DependencyKey</span> {
    <span class="splash-keyword">static let</span> liveValue: <span class="splash-type">WrappedNumberFormatStyle</span> = .<span class="splash-keyword">init</span>(<span class="splash-type">FloatingPointFormatStyle</span>&lt;<span class="splash-type">Double</span>&gt;.<span class="splash-property">number</span> ...)
    <span class="splash-keyword">static let</span> testValue: <span class="splash-type">WrappedNumberFormatStyle</span> = .<span class="splash-keyword">init</span>(<span class="splash-type">HardcodedNumberFormatStyle</span>())
}
</code></pre><p>But of course, this raises the question of how we store the style generically. Maybe we can try to make the type generic...</p><pre><code><span class="splash-keyword">struct</span> WrappedNumberFormatStyle&lt;Wrapped: <span class="splash-type">FormatStyle</span>&gt;: <span class="splash-type">FormatStyle</span> <span class="splash-keyword">where</span> <span class="splash-type">Wrapped</span>.<span class="splash-type">FormatInput</span> == <span class="splash-type">Double</span>, <span class="splash-type">Wrapped</span>.<span class="splash-type">FormatOutput</span> == <span class="splash-type">String</span> {
</code></pre><p>But even if the type itself compiles, we have solved nothing. Generics end up polluting the api surface and it means we are back at the same problem. Using a different <code>Wrapped</code> type results in a different <code>WrappedNumberFormatStyle</code>.</p><p>Another possibility is to keep the wrapped property type erased and enforce the correct types in the init, that's a technique that works well when you want to erase some types.</p><pre><code><span class="splash-keyword">struct</span> WrappedNumberFormatStyle: <span class="splash-type">FormatStyle</span> {
    <span class="splash-keyword">private let</span> wrapped: any <span class="splash-type">FormatStyle</span>
    
    <span class="splash-keyword">init</span>&lt;T: <span class="splash-type">FormatStyle</span>&gt;(wrapped: <span class="splash-type">T</span>) <span class="splash-keyword">where</span> <span class="splash-type">T</span>.<span class="splash-type">FormatInput</span> == <span class="splash-type">Self</span>.<span class="splash-type">FormatInput</span>, <span class="splash-type">T</span>.<span class="splash-type">FormatOutput</span> == <span class="splash-type">Self</span>.<span class="splash-type">FormatOutput</span> {
        <span class="splash-keyword">self</span>.<span class="splash-property">wrapped</span> = wrapped
    }
</code></pre><p>But this doesn't compile because the existential type itself doesn't conform to <code>Codable</code>, <code>Equatable</code> and <code>Hashable</code>, all protocol requirements inherited from <code>FormatStyle</code>. This means we would need to type erase all the requirements of those protocols... and at that point I'm starting to lose interest.</p><p>But just for fun, let's assume that we don't care about those requirements right now and move on, <a href="https://alejandromp.com/blog/hole-driven-development-swift-fatalerror">hole driven development</a> for the win. The next challenge is to make the format call compile.</p><pre><code><span class="splash-keyword">func</span> format(<span class="splash-keyword">_</span> value: <span class="splash-type">Double</span>) -&gt; <span class="splash-type">String</span> {
    <span class="splash-keyword">return</span> wrapped.<span class="splash-call">format</span>(value)
}
</code></pre><p>The immediate problem is that since <code>wrapped</code> is an existential, the return type of the format call is not constrained, it returns <code>Any</code>. And since <code>Any</code> is not <code>String</code> it won't compile. The fix here is easy: since we know the only way to create the <code>wrapped</code> property is going through the <code>init</code> that applies the constraints, we can assume the output type is a <code>String</code>, so a force cast should be safe.</p><pre><code><span class="splash-keyword">func</span> format(<span class="splash-keyword">_</span> value: <span class="splash-type">Double</span>) -&gt; <span class="splash-type">String</span> {
    <span class="splash-keyword">return</span> wrapped.<span class="splash-call">format</span>(value) <span class="splash-keyword">as</span>! <span class="splash-type">String</span>
}
</code></pre><p>But now we encounter another problem: <code>Member 'format' cannot be used on value of type 'any FormatStyle'; consider using a generic constraint instead</code>. This error is a bit weirdly explained, but what is happening is that since <code>wrapped</code> is an existential, even though it has the <code>format</code> method defined, the input type of the format call can't be known at compile time and thus the requirement of <code>value: Double</code> being equal to the input type of <code>wrapped</code> is not satisfied.</p><p>Here is where I got stuck. I'm able, thanks to the recent additions to opening existential, to create a generic function that opens the wrapped type. But I haven't figured out a way to relate that with the input type. I was hoping the following worked...</p><pre><code><span class="splash-keyword">private func</span> _format&lt;F: <span class="splash-type">FormatStyle</span>&gt;(
    formatStyle: <span class="splash-type">F</span>,
    value: <span class="splash-type">F</span>.<span class="splash-type">FormatInput</span>
) -&gt; <span class="splash-type">F</span>.<span class="splash-type">FormatOutput</span> {
    formatStyle
        .<span class="splash-call">format</span>(value)
}

<span class="splash-keyword">func</span> format(<span class="splash-keyword">_</span> value: <span class="splash-type">Double</span>) -&gt; <span class="splash-type">String</span> {
    <span class="splash-keyword">return</span> <span class="splash-call">_format</span>(formatStyle: wrapped, value: value)
}

</code></pre><p>... but it can't: <code>Type 'any FormatStyle' cannot conform to 'FormatStyle'</code>. Again, the error is a bit misleading because the issue is really with the second parameter. If the <code>_format</code> function just had 1 parameter <code>formatStyle: F</code> the compiler is able to open the existential at runtime and is all fine. But we can't link the type of the second parameter <code>F.FormatInput</code> to another value and keep the relation with the first one.</p><p>I was confused by this for some time. I even read the proposal that introduced this functionality twice. But in the end, it makes sense. I'm passing a <code>Double</code> as the second parameter, but that has no relation with <code>wrapped</code> whatsoever. I wonder if there is some trick here that I'm not aware of.</p><p>The only way I know of making this compile is to add more force casts. And even though they should be safe since the <code>init</code> constraints the types of the wrapped instance, it feels too much trouble.</p><h2 id="less-generic-alternative">Less generic alternative</h2><p>So I tried to come up with an alternative. The idea of passing the type from the outside is nice, especially because I would have loved to have a generic format style wrapper that could reduce boilerplate; but if that didn't work, I wanted to try a less generic approach.</p><p>Let's still keep the dispatch decision on the dependency system, but specify the types of the formatters we need. Keeping the types concrete would solve the problem we have. For this I decided to switch to an enum with associated types since it felt like the quickest solution.</p><pre><code><span class="splash-keyword">enum</span> WrappedNumberFormatStyle: <span class="splash-type">FormatStyle</span> {
    <span class="splash-keyword">case</span> foundation(<span class="splash-type">FloatingPointFormatStyle</span>&lt;<span class="splash-type">Double</span>&gt;)
    <span class="splash-keyword">case</span> hardcoded(<span class="splash-type">String</span>)
    <span class="splash-keyword">case</span> unimplemented
    
    <span class="splash-keyword">func</span> format(<span class="splash-keyword">_</span> value: <span class="splash-type">Double</span>) -&gt; <span class="splash-type">String</span> {
        <span class="splash-keyword">switch self</span> {
        <span class="splash-keyword">case</span> .<span class="splash-dotAccess">foundation</span>(<span class="splash-keyword">let</span> floatingPointFormatStyle):
            <span class="splash-keyword">return</span> floatingPointFormatStyle.<span class="splash-call">format</span>(value)
        <span class="splash-keyword">case</span> .<span class="splash-dotAccess">hardcoded</span>(<span class="splash-keyword">let</span> string):
            <span class="splash-keyword">return</span> string
        <span class="splash-keyword">case</span> .<span class="splash-dotAccess">unimplemented</span>:
            <span class="splash-keyword">return</span> <span class="splash-type">XCTestDynamicOverlay</span>.<span class="splash-call">unimplemented</span>()
        }
    }
}
</code></pre><p>There are no generics in this enum. All types are concrete, so we don't have any problems with the type system. We exchange a sort of dynamic dispatch with a static and manual dispatch instead. I also took the opportunity to remove the <code>HardcodedNumberFormatStyle</code> type since a <code>String</code> in the <code>hardcoded</code> does the same job, and also add the <code>unimplemented</code> functionality for tests.</p><p>With this, the dependency integration is quite simple:</p><pre><code><span class="splash-keyword">private enum</span> NumberFancyFormatterStyleKey: <span class="splash-type">DependencyKey</span> {
    <span class="splash-keyword">static let</span> liveValue: <span class="splash-type">WrappedNumberFormatStyle</span> = .<span class="splash-call">foundation</span>(<span class="splash-type">FloatingPointFormatStyle</span>&lt;<span class="splash-type">Double</span>&gt;.<span class="splash-property">number</span>.<span class="splash-call">decimalSeparator</span>(strategy: .<span class="splash-dotAccess">always</span>).<span class="splash-call">precision</span>(.<span class="splash-call">integerLength</span>(<span class="splash-number">1</span>)))
    <span class="splash-keyword">static let</span> testValue: <span class="splash-type">WrappedNumberFormatStyle</span> = .<span class="splash-dotAccess">unimplemented</span>
    <span class="splash-keyword">static let</span> previewValue: <span class="splash-type">WrappedNumberFormatStyle</span> = .<span class="splash-call">hardcoded</span>(<span class="splash-string">"hardcoded"</span>)
}
</code></pre><p>This works!</p><p>Now, I admit that seeing <code>    case foundation(FloatingPointFormatStyle&lt;Double&gt;)</code> still makes me want to make it generic but we've been through that rabbit hole so there is no need to repeat it 😂</p><h2 id="locale-for-testing">Locale for testing</h2><p>One of the big benefits of having the dependency system in place is that we can solve one of the annoying parts of formatters: dealing with the locale. It's true that with the code above we can control the format style dependency itself, but if we wanted to still use the real one for testing, we would still have to deal with the locale. A very nice thing we can do is use the <code>@Dependency</code> ourselves in the implementation.</p><pre><code><span class="splash-keyword">func</span> format(<span class="splash-keyword">_</span> value: <span class="splash-type">Double</span>) -&gt; <span class="splash-type">String</span> {
    <span class="splash-keyword">@Dependency</span>(\.<span class="splash-property">locale</span>) <span class="splash-keyword">var</span> locale

    <span class="splash-keyword">switch self</span> {
    <span class="splash-keyword">case</span> .<span class="splash-dotAccess">foundation</span>(<span class="splash-keyword">let</span> floatingPointFormatStyle):
        <span class="splash-keyword">return</span> floatingPointFormatStyle
            .<span class="splash-call">locale</span>(locale)
            .<span class="splash-call">format</span>(value)
</code></pre><p>With this minor change, we now have a formatter that automatically gets the locale, like the default format styles, but with the difference that we can control that dependency.</p><h2 id="a-bit-more-magic">A bit more magic</h2><p>Seeing how we can access the dependencies internally, there is another trick that you can employ. Be ready for some magic 🧙‍♀️ .</p><p>The way that PointFree dependency system decides which value to provide is using a context value, that is itself part of the dependency system 🤯. This is very powerful because it means you can change the context yourself, or read it and leverage the internal logic of the library.</p><p>Thanks to this, we can actually have a type that magically changes.</p><pre><code><span class="splash-keyword">struct</span> MagicNumberFancyFormatStyle: <span class="splash-type">FormatStyle</span> {
    <span class="splash-keyword">func</span> format(<span class="splash-keyword">_</span> value: <span class="splash-type">Double</span>) -&gt; <span class="splash-type">String</span> {
        <span class="splash-keyword">@Dependency</span>(\.<span class="splash-property">context</span>) <span class="splash-keyword">var</span> context
        <span class="splash-keyword">@Dependency</span>(\.<span class="splash-property">locale</span>) <span class="splash-keyword">var</span> locale
        
        <span class="splash-keyword">switch</span> context {
        <span class="splash-keyword">case</span> .<span class="splash-dotAccess">live</span>:
            <span class="splash-keyword">return</span> <span class="splash-type">FloatingPointFormatStyle</span>&lt;<span class="splash-type">Double</span>&gt;.<span class="splash-property">number</span>.<span class="splash-call">decimalSeparator</span>(strategy: .<span class="splash-dotAccess">always</span>).<span class="splash-call">precision</span>(.<span class="splash-call">integerLength</span>(<span class="splash-number">1</span>))
                .<span class="splash-call">locale</span>(locale)
                .<span class="splash-call">format</span>(value)
        <span class="splash-keyword">case</span> .<span class="splash-dotAccess">preview</span>:
            <span class="splash-keyword">return</span> <span class="splash-string">"hardcoded"</span>
        <span class="splash-keyword">case</span> .<span class="splash-dotAccess">test</span>:
            <span class="splash-keyword">return</span> <span class="splash-type">XCTestDynamicOverlay</span>.<span class="splash-call">unimplemented</span>()
        }
    }
}
</code></pre><p>In fact, you can use this trick and expose the format style as an extension, without going through <code>DependencyValues</code> at all! It means that <code>(2.5).formatted(.numberFancy)</code> would look exactly normal, like any other Apple API, but under the hood you made your code fully testable and controllable. This is a huge win in my opinion, and I'm really tempted to use this trick directly without having to deal with the @Dependency in the usage side.</p><blockquote><p>Of course this might be <strong>too much magic</strong>. Analyze the tradeoffs and decide by yourself if it's worth.</p></blockquote><h2 id="where-does-the-path-end?">Where does the path end?</h2><p>Here is where I stopped my exploration. It was fun, and I learned a bunch of things again. We still need to decide if these wrapped types are worth the effort or if we will just keep the function style as the dependency. But for my side project usages I'm very tempted to use the magic solution :)</p><p>As always, thanks for coming with me in this journey, I hope you learned like I did. And if you know of other tricks or solutions that could get me the requirements I want, don't hesitate to tell me 😜</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/the-dark-forest-remembrance-of-earth-s-past-2</guid><title>The Dark Forest review</title><description></description><link>https://alejandromp.com/blog/the-dark-forest-remembrance-of-earth-s-past-2</link><pubDate>Tue, 17 Jan 2023 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>I just finished The Dark Forest, book 2 of the <a href="https://www.goodreads.com/series/189931-remembrance-of-earth-s-past">Remembrance of Earth's Past</a> trilogy.</p><p>Rating: <a href="https://www.goodreads.com/review/show/5069522033">3/5</a></p><p>My feelings about this book are very similar to the first part of the series, and that's no surprise since the story maintains the same tone. I really like the survival puzzles proposed by the story and how humanity reacts and adapts to (maybe) solve them. This book, since it happens a few centuries later, also shows us a possible future for humanity. It was cool to see the new technology and how it affected society.</p><p>But like the first one, it has <em>too much text</em>, and in this case is even worse because the book is longer. The fact that this happens in a more international environment reduces the footnote reading that polluted the first book (for a European reader at least), but the amount of scenes in this book that have very little impact in the overall plot is just too much for me. Some of these scenes are interesting on their own, but the more the book advances, the more these scenes become void.</p><p>But then, like in the first book, the overall plot and story are so enigmatic and the puzzle humanity faces is so complex that it leaves the reader wanting more. And so I had to finish the story, even though I almost leave it multiple times, and I will have to read the last book.</p><p>Overall, I can see how many people love it, but it hasn't clicked for me.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/on-the-new-pointfree-swift-dependencies</guid><title>On the new Point-Free swift-dependencies library</title><description></description><link>https://alejandromp.com/blog/on-the-new-pointfree-swift-dependencies</link><pubDate>Tue, 10 Jan 2023 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>The folks at <a href="https://www.pointfree.co">Point-Free</a> have given us yet again a new tool to improve our Swift development: <a href="https://github.com/pointfreeco/swift-dependencies">swift-dependencies</a>, see their <a href="https://www.pointfree.co/blog/posts/92-a-new-library-to-control-dependencies-and-avoid-letting-them-control-you">announcement</a>. Let me show the journey I've been for the past couple of hours with excitement and discoveries with this new library.</p><blockquote><p>I really love the work Point-Free does and won't tire of recommending them. If you want to invest in your knowledge and support me at the same time use this referral link and <a href="https://www.pointfree.co/subscribe/personal?ref=4Fj20c5I">subscribe to Pointfree</a>, we both get a month free :)</p></blockquote><h2 id="some-context...">Some context...</h2><p>First, a little bit of context.</p><p>I've always been doing dependency injection via init or property with no framework. I find it the best way, no magic, everything is clear and works very well even in a 500k LOC project. Yes, you need to be smart on your architecture to avoid having to carry around dependencies, but it's not rocket science. That's how I've been doing DI for many years.</p><p>The first time I switched strategies was when the guys at Point-Free introduced the global dependency struct technique. I used it sparingly, just to access some system dependencies (calendar, locale...) and it worked really well I have to admit, more than it had the right to for being a global variable 😂</p><p>But then the <a href="https://alejandromp.com/tags/pointfree-composable-architecture/">TCA</a> happened and with it a huge improvement on application architecture. Their most recent update includes a fully fledged and integrated dependency system, akin to SwiftUI's environment. It works very well and does wonders to clean up and modularise your codebase. It's really amazing.</p><h2 id="where-is-the-hype?">Where is the hype?</h2><p>So with that said, I was well aware of how the system worked, and I knew they were intending to break it into a separate package. So when they announced the new library, I was not as hyped as with others. I was using the library (in the TCA) already!</p><p>But then I remembered a question that had been hunting me since I saw the dependency system... I know how it works, and it felt to me that it worked very well for the TCA specifically... but there was something that made it unworkable for a general architecture.</p><p>So the non-hype of the announcement became a curiosity to know what magic, if any, they pulled off. Or to confirm that I didn't understand things as well as I thought, something that I'm always trying to do, makes me stay true.</p><h2 id="how-does-this-work?">How does this work?</h2><p>To understand my doubts about this system working in a general sense you have to understand how it works. Internally it relies on Swift's Task Locals, a new feature of Swift that came with <a href="https://youtu.be/3SX7u5l3CGA">Structured Concurrency</a>.</p><p>Task Locals allow you to set variables in a "context" that is automatically available to your code. But the context modifications are only visible on the <strong>scope</strong> where they changed. This plays nicely with structured concurrency and normal structured programming. As long as you keep calling functions, all the stack has access to the same context.</p><pre><code><span class="splash-keyword">func</span> someFunction() {
  <span class="splash-type">Lib</span>.<span class="splash-property">$taskLocalValue</span>  <span class="splash-comment">// 1 - Outisde the scope</span>
  <span class="splash-type">Lib</span>.<span class="splash-property">$taskLocalValue</span>.<span class="splash-call">withValue</span>(<span class="splash-number">42</span>) {
    <span class="splash-type">Lib</span>.<span class="splash-property">$taskLocalValue</span>  <span class="splash-comment">// 42 - Inside the overwriten scope</span>
    <span class="splash-call">calledFromInside</span>()
  }
  <span class="splash-type">Lib</span>.<span class="splash-property">$taskLocalValue</span>  <span class="splash-comment">// 1 - Outisde the scope</span>
  <span class="splash-call">calledFromOutside</span>()
}

<span class="splash-keyword">func</span> calledFromInside() {
  <span class="splash-type">Lib</span>.<span class="splash-property">$taskLocalValue</span>  <span class="splash-comment">// 42 - Inside the overwriten scope</span>
}

<span class="splash-keyword">func</span> calledFromOutside() {
  <span class="splash-type">Lib</span>.<span class="splash-property">$taskLocalValue</span>  <span class="splash-comment">// 1 - Outisde the scope</span>
}

<span class="splash-keyword">func</span> someOtherUnrelatedFunction() {
  <span class="splash-type">Lib</span>.<span class="splash-property">$taskLocalValue</span>  <span class="splash-comment">// 1 - Outisde the scope</span>
}
</code></pre><p>You can see how this would work very well since the TCA runs everything in reducers that are chained, so they are all in the same scope. That allows the Store to set the dependencies once and run the entire chain.</p><pre><code><span class="splash-type">Action</span> -&gt; <span class="splash-type">Store
Store</span> sets dependencies and calls reduce
<span class="splash-type">Reduce</span> sees the dependencies, next reducer <span class="splash-keyword">is</span> run <span class="splash-keyword">in</span> the same scope...
</code></pre><p>Easy. But when I thought how this could be generalised, I immediately saw problems since in a non-TCA application the scopes of executions are all over the place, there is not a central object that controls the scope.</p><pre><code><span class="splash-type">UI Button</span> calls <span class="splash-type">ViewModel</span>.<span class="splash-property">performAction</span>
<span class="splash-type">Another</span> button calls <span class="splash-type">ViewModel</span>.<span class="splash-property">doSomethingElse</span>
</code></pre><p>There is nowhere you can overwrite the Task Local context for all the scopes. You need to do it on an ad hoc basis.</p><h2 id="the-trick">The trick</h2><p>So then I started reading the new library's documentation. And they <a href="https://pointfreeco.github.io/swift-dependencies/main/documentation/dependencies/overridingdependencies/">quickly make the point</a> that you need to instantiate the "next controller" inside the library's closure.</p><pre><code><span class="splash-keyword">self</span>.<span class="splash-property">onboardingTodos</span> = <span class="splash-call">withDependencies</span>(from: <span class="splash-keyword">self</span>) {
  $0.<span class="splash-property">apiClient</span> = ...
} operation: {
  <span class="splash-type">TodosModel</span>()
}
</code></pre><p>And an important note that explains "It takes an extra argument, <code>from</code>, which is the object from which we propagate the dependencies before overriding some. This allows you to propagate dependencies from object to object."</p><p>Aha! So it all works as long as you instantiate the object inside the scope. This already tells us a bit about the trick that is being employed.</p><p>The above is all well explained in the <a href="https://pointfreeco.github.io/swift-dependencies/main/documentation/dependencies/lifetimes/">Dependency lifetimes</a> section. They even explain how Task Locals work ;)</p><p>Here is the part that opened my eyes:</p><blockquote><p>Accomplishing this can be difficult because models are created in one scope and then dependencies are used in another scope. However, as mentioned above, the library does extra work to make it so that <strong>later referencing dependencies of a model uses the dependencies captured at the moment of creating the model</strong>.</p></blockquote><p>There you go, the confirmation. As long as you instantiate the model in the scope that overwrites the task local, your model will see that overwrite even outside of the scope. You can see the <a href="https://github.com/pointfreeco/swift-dependencies/blob/main/Sources/Dependencies/DependencyValues.swift#L82">code</a> for this, seems like the trick is to keep your own storage so you can overwrite and keep your own "hierarchy" instead of relying simply in the one provided by Task Locals.</p><p>They basically made Task Locals "escape", impressive!</p><h2 id="single-entry-point-systems">Single entry point systems</h2><p>With the understanding of how it worked, I was satisfied. But, in a typical Point-Free fashion, they went the extra mile and actually wrote an article about the specific doubts I had at the beginning of this post. They even gave me the propar vocabulary needed to form the correct mental model.</p><p><a href="https://pointfreeco.github.io/swift-dependencies/main/documentation/dependencies/singleentrypointsystems/">Single entry point systems</a> explains why systems like TCA or SwiftUI are ideal for managing a hierarchy of dependencies since it all funnels through a single entry point; and they compare it <em>Non-single entry point systems</em> like ViewModels or UIKit where is more complicated.</p><p>Ultimately, I think they have accomplished the right levels of ergonomics for a feature like this. If you use a non-single entry point architecture, you get the same benefits on your dependencies overwrites as long as you remember to instantiate the model inside the proper scope. It still leaves the TCA ahead of the game, but is very nice for people that don't want to jump into the future just yet 😜</p><h2 id="and-some-gifts!">And some gifts!</h2><p>As always, Point-Free provides not only a useful library, but a very well done one. Their documentation is gorgeous, full of details about the library itself but also advice on how to design dependencies and architect your app. They even released some extra goodies with the library!</p><p>Some notable details I found interesting even after being using it for a few weeks:</p><ul><li><a href="https://pointfreeco.github.io/swift-dependencies/main/documentation/dependencies/livepreviewtest/#Cascading-rules">Cascading rules</a> gives a nice summary of which "value" will be used in each context if not all of them are provided. Useful to reference until you get used to it.</li><li>I was not expecting to read about <a href="https://pointfreeco.github.io/swift-dependencies/main/documentation/dependencies/concurrencysupport/">Concurrency support</a>! They have split a few very useful types that were in the TCA so we can now use them on any project, nice!<ul><li><a href="https://pointfreeco.github.io/swift-dependencies/main/documentation/dependencies/actorisolated/">ActorIsolated</a> is a very useful generic wrapper to isolate a value in an actor. Great for tests but I've found myself using it in some specific cases where yo don't want an ad hoc actor just to isolate a value.</li><li>I haven't used <a href="https://pointfreeco.github.io/swift-dependencies/main/documentation/dependencies/lockisolated/">LockIsolated</a>, and it seems a bit dangerous but useful if you need to do blocking async code.</li><li><a href="https://pointfreeco.github.io/swift-dependencies/main/documentation/dependencies/uncheckedsendable">UncheckedSendable</a> is one that helps a lot during the transition period for code that hasn't adopted Sendable conformances yet. Another dangerous to use but useful nonetheless. (I wish I had this one a few months back 😂 )</li><li>There are even helpers for AsyncStreams! It feels a bit weird to have these in this library, but in a way it makes sense because you will need them to design your dependencies. I think this will make swift-dependencies a must include on every project of mine.<ul><li>"This allows you to treat the stream type as a kind of “type erased” <code>AsyncSequence</code>." this one feels a bit weird. I'm not going to lie. One would hope that with improvements in the generic system, this wouldn't be necessary but oh well ¯_(ツ)_/¯</li><li>Now, the API for simultaneously constructing a stream and its backing continuation is very useful and something that should come in the standard library.</li><li>There are a few other inclusions so make sure to check it out!</li></ul></li></ul></li></ul><h2 id="consider-me-learned">Consider me learned</h2><p>I love these quick derails my brain takes me into. I was not planning to get deeper into Task Locals at all this week, after all, I thought I already knew pretty much all about them during my <a href="https://alejandromp.com/tags/concurrency/">Concurrency</a> obsessive days; but then curiosity sparked, and feeding it was one of the best joys in life.</p><p>I can't thank enough Point-Free for not only pushing the limits of the Swift community - you know they even got a proposal accepted recently to fix a missing API in Clocks? - but also for making learning so fun!</p><p>Thanks for accompanying in this post and journey.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/why-you-should-care-about-the-future-of-memory-ownership-in-swift</guid><title>Why you should care about the future of Memory Ownership in Swift</title><description></description><link>https://alejandromp.com/blog/why-you-should-care-about-the-future-of-memory-ownership-in-swift</link><pubDate>Mon, 9 Jan 2023 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>I've been very excited about memory ownership improvements to come to Swift, and now that they seem to materialize, I needed to share it with you. Specially because I feel this topic is <em>very complex</em> in people's mind, and many will discard it as something only useful for experts, advanced uses or even "for nobody, Swift is getting too complex".</p><p>So I made this video to pitch you on why Memory Ownership in Swift matters and how it will improve your EXISTING code right away without having to learn too much complicated stuff.</p><p>The benefits will be real and immediately palpable!</p><iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/c6bWSsMO51M" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/tress-of-the-emerald-sea</guid><title>Tress of the Emerald Sea</title><description></description><link>https://alejandromp.com/blog/tress-of-the-emerald-sea</link><pubDate>Sun, 8 Jan 2023 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>I just finished this beautiful book, the first one in The Year of Sanderson.</p><p>From my <a href="https://www.goodreads.com/review/show/4597327338">review on Goodreads</a>:</p><p>5/5</p><p>This book is great at so many levels. After having read Sanderson's all Cosmere books reading this narrative with such a different voice is mesmerising. Being a tale narrated by a character in the Cosmere, who is at the same time a secondary character in the story, brings a different perspective that I enjoyed very much.</p><p>The characters are great, from the girl that embarks on an adventure to each of the named characters. Sanderson is able to take care of real world situations and human characteristics, I loved the deaf character and the one with very bad aim (😉).</p><p>And the plot, oh I loved it! Look, I get bored of a love story told like they do in romance. That's just boring most of the time. Love is just an, albeit important, part of a human live, so it needs to be just a part of a story. For Tress love is what makes her embark on and amazing journey do discover herself and grow. Yes this is not an epic story with armies, but is a romantic journey on the seas, with battles and death! so is not that far &lt;3</p><p>To tip it off, the Cosmere. This book may not be a core story of the Cosmere, but it seems quite important to get to know more about what's going on. I love two things: 1) Sanderson doesn't get shy anymore about including Cosmere things in the story. Things that don't break the immersion if you haven't read the rest (I think), but that are like a juicy fruit for any of us that love this universe. and 2) how this little details are included in such a natural way with the narration. The narrator just mentions it like if they were not important; while as reader I was here screaming of excitement and highlighting lines that gave us more details about an important back story.</p><p>I've loved Tress of the Emerald Sea, a well rounded book in many aspects and a great start of the Year of Sanderson. I think I will be very fond of this story for many years to come.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/year-2022-books-reviews</guid><title>My 2022 in books</title><description></description><link>https://alejandromp.com/blog/year-2022-books-reviews</link><pubDate>Sat, 31 Dec 2022 00:00:00 +0000</pubDate><content:encoded><![CDATA[<h2 id="looking-a-few-years-back...">Looking a few years back...</h2><p>A few years ago I felt back in love with reading again. I've always been a reader, but for a long time I prioritized other hobbies. The social web and easy to digest content occupied most of my leisure time for many years. But the desire nostalgia for experiencing fantasy put me again on the right track.</p><p>Don't get me wrong, I still spent time on YouTube and reading about other stuff, books are only a part of the amount of things I experience in life, but they are a very important one for me. Reading challenges are a fun way to make sure I don't forget this. They are not a mandatory task, but a pleasant reminder of how much I enjoy it.</p><p>Because life is hard, it's tricky sometimes to remember what we should do day-to-day, our mind travels to far places, places that are the total opposite of nice fantastic lands. And when we are in those obscure places, we often forget about the nice things we already have.</p><img src="https://alejandromp.com/blog/year-2022-books-reviews/past-years.jpg" alt="past-years"/><p>Ignoring a very rough 2019, I've been reading more and more every year. This is mostly because I found an author that resonates with me like nothing before, Brandon Sanderson. You can see how the way <a href="https://alejandromp.com/tags/books/">I talked about fantasy</a> changed when I discovered him. When I decided to <a href="https://alejandromp.com/blog/pausing-the-wheel-of-time/">pause The Wheel of Time</a> I was about to enter a hiatus on reading again. But thankfully, I gave Mistborn a try, and oh my, was I lucky discovering <a href="https://alejandromp.com/blog/is-mistborn-my-new-favorite-novel/">my favorite novel</a> yet!</p><p>So after that, I started devouring the Cosmere, the fictional universe where most of Sanderson's fantasy novels happen. That took me from 2021 to 2022 and I can say now that I finally caught up with the Cosmere and I've even been able to enjoy for the first time a new book launch with The Lost Metal!</p><h2 id="2022-in-books-according-to-[goodreads](https://www.goodreads.com/user/year_in_books/2022)">2022 in books according to <a href="https://www.goodreads.com/user/year_in_books/2022">Goodreads</a></h2><p><strong>25 books</strong>! That's quite a lot for me! The number doesn't really matter, everybody reads at different speeds and kinds of books, what matters is how much enjoyment it brought me!</p><p><strong>8,517 pages!</strong> It's funny how that gets to an average of only 340 pages per book. When my impression is that I read way lengthier books, and I do, but I've also read a bunch of short stories that pull that number down. From 25 pages of The Hope of Elantris to the 1248 pages of Oathbringer.</p><p>My average rating is <strong>4.2</strong>/5. That's basically because I only read things that I kinda now I will like, and because I've been reading a lot of Sanderson and, for now, is very rare I don't like something from him.</p><h3>Cosmere</h3><p>It would take me too long to write all my thoughts about the different Cosmere books, so I will only highlight a couple. If you are curious, I keep a <a href="https://twitter.com/alexito4/status/1307633321837555713">thread in Twitter</a> with my Sanderson reading and you can see <a href="https://www.goodreads.com/review/list/75832270-alejandro-martinez?shelf=read">my reviews in Goodreads.</a></p><blockquote><p>As a side note, with everything that has been going on with Twitter, one thing I would love to do is to move all these reading updates and book reviews to my domain. We'll see if I can get that done.</p></blockquote><p><a href="https://www.goodreads.com/book/show/13578175-the-emperor-s-soul">The Emperor's Soul</a> has been, with no doubt, the nicest surprise of all. A short story about art, in the same world as Elantris, that I still keep thinking about.</p><p>All the other smaller stories in the Cosmere (Shadows for Silence in the Forests of Hell, Sixth of the Dusk, etc) are something that many won't bother to read, and you don't really need to, but I love the inter-connected facet of Sanderson's writing so I've put a lot of effort in reading them in what I consider the best order possible for my personal enjoyment. And I have to say that it has paid dividends! I should write about that someday.</p><p>Mistborn Secret History is one of these things that you can only enjoy once in a lifetime. It's a short story that you should know anything about. Really, anything you read or see, by small, it's a major spoiler. And the experience I got while reading it and discovering things... I can't describe it.</p><p>Mistborn Era 2... what can I say about this. I've been able to finish it with the rest of the fanbase and it has been an experience! It's a very distinct style than the first Era, something that put many people out, but I still like it a lot. The mix of western with new tech and humor worked very well for me. And the ending... what an ending! A new era for the Cosmere begins!</p><p>The Stormlight Archive is with no doubt my favorite epic fantasy series of all time. It pulls the best of Sanderson for sure. This year I've continued the series and caught up with it and yes, now I'm waiting the last book of the first half like everybody else. With excitement but also fear. I have no clue how things will go. Well, of course I have many theories like everybody... it's a hot topic of conversion with my friends, BUT Sanderson can pull plot twists that even after paying attention and commenting all potential solutions with friends, nobody saw coming.</p><h3><a href="https://www.goodreads.com/book/show/34726618-diamantes-en-bruto-i--segunda-edici-n-revisada">Diamantes en Bruto</a></h3><p>This is the only non-fiction book I've read this year. I don't really do non-fiction with books since I spent most of my day to day reading it by other means already. But this one was a recommendation to understand better the psychology and mental health of people. It's eye opening to see what others go trough and makes you be more attentive and willing to help.</p><h3><a href="https://www.goodreads.com/series/70323-partials-sequence">Partials Sequence</a></h3><p>From watching Brandon Sanderson and Dan Wells on their podcast I ended up being very curious about Dan work. I picked up Partials as an introduction to his work, and I have to say I enjoyed it. Is a bit too YA for what I was looking for, but it has many interesting details. I still have book 3 pending, which I'm hoping to finish next year.</p><h3><a href="https://www.goodreads.com/book/show/51942569-league-of-legends">League of Legends: Realms of Runeterra</a></h3><p>This is a book about the universe of Runeterra, full of artwork and short-stories. I really loved the stories, and the art is astonishing. Runeterra is probably in my top 3 of fiction worlds and I wish people paid more attention to the multitude of stories and characters in it.</p><p>Many people discards it because it has the League of Legends brand associated with it, "it's just a game". And that might have been true many years ago but Riot has been working on this universe for so long that it has quickly become a rich world that doesn't have to envy anything from others. I mean just look at this <a href="https://map.leagueoflegends.com">beautiful map</a>.</p><p>My favorite part is how nicely in pulls together seemingly incompatible themes and environments. In Runeterra you can find anything you like: Horror and ghosts, pirates, a land of magic and nature, empires at war, ancient dangers in the frozen north, a high-tech city, ancient Egypt like, jungle and elemental magic, and a mountain to ascend to godhood.</p><p>I'm still fascinated by how all of this can match in a very nice and coherent way. That is Runeterra. Seriously, visit their site and discover a new <a href="https://universe.leagueoflegends.com/en_GB/">Universe</a>.</p><h3><a href="https://www.goodreads.com/book/show/22219679-dungeon-master-s-guide">Dungeon Master's Guide</a></h3><p>This year I finished reading the DM's guide to D&amp;D. Of course, being a guide it means I flipped through its pages way more than once, but I still wanted to go trough it in sequence to enjoy the fiction in it.</p><p>Reading tabletop game guides is an enjoyable experience for me. It engages not only with my "game mechanics" brain but also with the fantasy literature part thanks to all the lore and adventure suggestions in them.</p><h3><a href="https://www.goodreads.com/series/295927-sandman-audible-original">Sandman Audible Original Series</a></h3><p>I started Sandman after watching the Netflix tv show and I have to say I enjoyed it a lot, way more than expected. Neil Gaiman storytelling is so peculiar that makes Sandman an incredible experience way beyond what the plot could give.</p><p>I've just finished Act 2, the last thing I will read this year, and there some stories in it I can't wait to see adapted on television. I'm amazed how Gaiman takes folk-tales and religious stories that we all have heard about and gives them a twist integrating them into the Sandman world.</p><h3>The Law - The Dresden Files #17.4</h3><p>Okay, this is a weird one. If anybody did what I did here with the Cosmere I would tell them the big mistake they made. I'm not sure how important is with Dresden but I know I was taking a risk. You see, Amazon Prime gave an offer with free access to their Kindle Unlimited books, and even tho there is a lot of content there was not much that I found interesting to jump into.</p><p>But I've been hearing about The Dresden Files for ages, and is a series I really want to read sometime, so when I saw this short story I just took it. I knew I was risking huge spoilers since is the 17th book of the series, but I risked it anyway.</p><p>And I'm glad, now I'm more curious about Dresden and its world. It seems like a mix that I could enjoy a lot. So it went up on my priority 😜</p><h3>The Three-Body Problem</h3><p>Because it was in Kindle Unlimited and I wanted to change a bit to sci-fi, I jumped in the first book of the Remembrance of Earth's Past Series. I had plenty of good things about this book so I was eager to enjoy it. And I have to say... it was difficult to finish.</p><p>It's true that when I was done, I appreciated the story and its complexity, and I'm curious to see how it continuous. But I don't know if it's because it is too hard sci-fi and is not for me, or because the different author culture (seriously, having to read footnotes every two pages is not good...) but it didn't pull me in the story much.</p><p>I actually started the second book, The Dark Forest, but it's still in progress because is taking me even more to get into. There is simply too much text. I actually switched to Sandman Act 2 to disconnect from it and I finished that one in 2 days 😂 so it's not that I don't want to read! We'll see if I come back to this series.</p><h2 id="a-couple-more...">A couple more...</h2><p>I've read other books that, for one reason or another, are not in Goodreads. I've posted them as "general updates" on the site, but of course that doesn't count as a book.</p><blockquote><p>This is another reason I would love to find an alternative to it.</p></blockquote><h3>Aether of Night, an unpublished novel by Brandon Sanderson</h3><p>After having caught up with the Cosmere I was eager for more and didn't want to wait for The Lost Metal release. So I started looking at what other things Brandon had done around the Cosmere, I knew there was some unpublished work and that seemed like an ideal way to keep the Cosmere alive in my head.</p><p>Aether of Night is an unpublished novel, a draft, that he wrote years ago but never published. He has transformed the ideas in it into other published work. Even knowing that is non-canon and that the writing was in draft form, I really enjoyed the reading.</p><p>Seeing some of the early versions of some things that happened in other books was fascinating to me as a hobbyist writer. And know more about, a version of, the Aeathers, something that we are just starting to see in the Cosmere, was a delightful gift.</p><p><a href="https://www.goodreads.com/user_status/show/543680026">My post in Goodreads about Aether of Night</a>.</p><h3><a href="https://book.micro.blog/">Indie Microblogging</a> by Manton Reece</h3><p>With everything that happened in Twitter this year, and the move to <a href="https://mastodon.alejandromp.com/">Mastodon</a>, I've been paying more attention to the <em>indie-web</em>. I think the social network boom has helped in some aspects to move society to a more connecter world, but I really miss the times of blogs and RSS.</p><p>Manton Reece is part of the indie-web movement that tries to protect the openness of the web. The book talks about his solution, micro.blog, but is not a sell pitch for it. It's very recommended if you are curious about the dangers that are risking the web as we know it.</p><p><a href="https://www.goodreads.com/user_status/show/567739135">My post in Goodreads about Indie Microblogging</a>.</p><h2 id="what's-next?">What's next?</h2><p>My goal for 2023 is to keep enjoying reading as much as I did this year, no matter how many books I read.</p><p>I already have 4 that are clear thanks to The Year of Sanderson that will start on January 1st! After that, I may try to finish some open series and look at others on my pending list.</p><p>Happy new year of reading!</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/limit-swift-concurrency-cooperative-pool</guid><title>Limit Swift Concurrency's cooperative pool</title><description></description><link>https://alejandromp.com/blog/limit-swift-concurrency-cooperative-pool</link><pubDate>Fri, 30 Dec 2022 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>One of the nice things about <a href="https://alejandromp.com/tags/concurrency/">Swift Concurrency</a> is its cooperative thread pool. When writting concurrent code you should not think about threads but is still good to know how things work under the hood.</p><p>In Swift Concurrency all your async code runs in a cooperative thread pool, unless you are using Actors (or in the future custom Executors, but that's a topic for another day). The beauty of the cooperative pool abstraction is that it allows us to not care about thread exhaustion, or even about our code running "on the background", something I still see many developers get wrong.</p><p>You may have seen this cooperative pool while debugging, pay attention to how Xcode shows a label in the debug navigator:</p><img src="https://alejandromp.com/blog/limit-swift-concurrency-cooperative-pool/cooperative_concurrent_thread_example.jpg" alt="Example of how Xcode shows a thread that is part of the cooperative pool"/><p>As you can see the thread is part of the cooperative concurrent queue.</p><p>We can use a bit of <a href="https://gist.github.com/alexito4/549a9c1e634269e1100cf57754e069ed">expensive code</a> to use all the queues and force the runtime to create all possible threads. In my M1 that means 8 threads:</p><img src="https://alejandromp.com/blog/limit-swift-concurrency-cooperative-pool/xcode_8_threads.jpg" alt="Xcode debugger showing 8 threads for the cooperative pool"/><p>It's actually quite nice to see all threads so nice and tidy ^^</p><p>The important thing here is that this is an implementation detail and you should not worry about it, as you should not worry about threads at all.</p><blockquote><p>I know the irony of saying that you shouldn't worry about threads in a post about threads 😂. But if you are having a hard time with Swift Concurrency is probably because you still haven't made the switch to this new way of thinking. There are some legit cases to care about threads, but those are mostly for inter-operation with other systems that are thread based. Free yourself from the threads! 🔥 🧵</p></blockquote><p>In fact this cooperative pool is such a specific implementation detail that it could work totally different in other operative systems or more constrained enviornments. The nice thing about this is that your code should work in the same way, albeit slower and less parallel, in a system with only 1 thread.</p><blockquote><p>Remember that Swift Concurrency doesn't make any promise about parallelism. Most of your code is serial with itself and concurrent with other blocks of code, but you can't make it parallel, that depends on the runtime.</p></blockquote><p>And you can test how your code would behave in such a constrained system thanks to an environment variable that limits the cooperative pool.</p><p>Set <code>LIBDISPATCH_COOPERATIVE_POOL_STRICT=1</code> and see how the runtime will only create 1 thread on the pool.</p><blockquote><p>You can set this in the Scheme editor in Xcode.</p></blockquote><img src="https://alejandromp.com/blog/limit-swift-concurrency-cooperative-pool/xcode_scheme_env.jpg" alt="Xcode scheme editor"/><p>After setting that flag and running the same code that before was spawning 8 threads, we can see now how it only spawns 1.</p><img src="https://alejandromp.com/blog/limit-swift-concurrency-cooperative-pool/xcode_1_threads.jpg" alt="Xcode debugger showing 1 thread for the cooperative pool"/><p>There you have it, a nice utility to force the Swift runtime to use limit the cooperative pool to 1 thread, useful for some debugging situations and for learning purposes.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/github-action-to-create-new-posts</guid><title>GitHub Action to create new posts</title><description></description><link>https://alejandromp.com/blog/github-action-to-create-new-posts</link><pubDate>Tue, 20 Dec 2022 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>Now that I have this site <a href="https://alejandromp.com/blog/generating-this-site-with-netlify-and-github-actions/">building on Netlify</a> I wanted to start writing more far away from my computer. Of course I immediatly found a bit more friction that I had to solve.</p><p>Posts here are just Markdown files, but they do contain a bit of metadata in form of <em>front matter</em> and they must be in a directory with a specific naming convention since I use a <em>bundle</em> format to have the images and the text side by side.</p><p>Since I have a custom CLI tool to build the blog, instead of relying on the default one provided by the static site generator Publish, it's very easy for me to add automatoin to any process. And that's what I had for a long time:</p><pre><code>▶ amp help new
<span class="splash-type">OVERVIEW</span>: <span class="splash-type">Creates</span> a new post

<span class="splash-type">USAGE</span>: cli new &lt;title&gt; [--date &lt;date&gt;] [--disable-auto-<span class="splash-keyword">open</span>]

<span class="splash-type">ARGUMENTS</span>:
  &lt;title&gt;

<span class="splash-type">OPTIONS</span>:
  --date &lt;date&gt;           (default: <span class="splash-number">2022</span>-<span class="splash-number">12</span>-<span class="splash-number">20</span>)
  --disable-auto-<span class="splash-keyword">open</span>
  -h, --help              <span class="splash-type">Show</span> help information.
</code></pre><p>So the only thing I had to do is setup something that triggers that command with some given inputs. I could have build some website that triggered some backend API but there is an easy solution for something so simple: GitHub Actions.</p><p>The action ended up looking like this:</p><pre><code>name: <span class="splash-string">"Create new post"</span>
run-name: <span class="splash-string">"Create new post: ${{ inputs.title }}"</span>

on:
  workflow_dispatch:
    inputs:
        title:
          description: '<span class="splash-type">Post</span> title'
          required: <span class="splash-keyword">true</span>
          type: string

jobs:
  main:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: <span class="splash-type">Setup Swift</span>
        uses: swift-actions/setup-swift@v1.<span class="splash-number">20.0</span>
        with:
          swift-version: <span class="splash-string">"5.7.1"</span>
          
      - name: <span class="splash-type">Cache</span>
        id: cache-alejandromp
        uses: actions/cache@v3
        with:
          path: .<span class="splash-dotAccess">build</span>
          key: ${{ runner.<span class="splash-property">os</span> }}-cachev1-${{ <span class="splash-call">hashFiles</span>('**/<span class="splash-type">Package</span>.<span class="splash-property">resolved</span>') }}
              
      - run: swift run alejandromp new <span class="splash-string">"${{ inputs.title }}"</span> --disable-auto-<span class="splash-keyword">open</span>

      - name: <span class="splash-type">Create Pull Request</span>
        uses: peter-evans/create-pull-request@v4
        with:
          commit-message: <span class="splash-string">"New post ${{ inputs.title }}"</span>
          title: <span class="splash-string">"New post ${{ inputs.title }}"</span>
</code></pre><p>Since I'm just creating files I don't need any macOS specific API so I can run Swift on Ubuntu. I then use the <code>workflow_dispatch</code> in order to be able to trigger it manually from GitHub's UI. I set it up so it asks me for the title so everything is preconfigured by the action itself.</p><p>The action is quite simple, it instllas the correct version of Swift, caches the build folder, runs the command passing the given title and finally creates a PR with the changes.</p><p>Now I can click a button on GitHub, have a new post draft created and start writing from <code>github.dev</code>.</p><img src="https://alejandromp.com/blog/github-action-to-create-new-posts/pr_example.jpg" alt="PR example"/>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/generating-this-site-with-netlify-and-github-actions</guid><title>Generating this site with Netlify and GitHub Actions</title><description></description><link>https://alejandromp.com/blog/generating-this-site-with-netlify-and-github-actions</link><pubDate>Sun, 18 Dec 2022 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>With the whole move to Mastodon, I’ve been thinking a lot about owning my content again and what will happen with all the interesting things I’ve written on Twitter. That’s a topic that is worth its own post, but it got me thinking about focusing more on this blog again.</p><p>That coincided with a technical curiosity. As I talk in my <a href="https://alejandromp.com/tags/meta/">meta</a> <a href="https://alejandromp.com/blog/new-website-redesign-v3-with-publish">post about the site redesign</a> this site is built using Swift’s Publish package and served by Netlify. This gives me a blazing fast static website for free. But until now I’ve been generating the website locally from my computer. Back in the day Netlify didn’t really support running Swift in their servers easily, so I didn’t spend time trying to solve that. When I added <a href="https://alejandromp.com/blog/publish-step-to-generate-social-images-for-your-posts/">automatic image generation</a> to the posts for social sharing I used SwiftUI, which means I need to run on macOS anyway.</p><p>But now time has passed, and I want to have the flexibility to publish in my blog from somewhere that is not my computer. But let’s be honest, it’s mostly a technical curiosity. I’m sure I will still write most of my content from my computer, but that won’t change unless I remove the friction and make it a possibility.</p><h2 id="updating-to-swift-5.7">Updating to Swift 5.7</h2><p>The first order of business was to update the code to Swift 5.7. One of the main reasons I moved out from other site generators in other languages is because every time I had to update anything, it was a mess of dependencies and language issues in languages I didn’t care about.</p><p>Because this is Swift, I’m able to do any update without even thinking about it. But the reality is that this time it took me by surprise.</p><p>The aforementioned image generation that runs in SwiftUI has a requirement, it must run in the main thread. Obviously because is doing UI stuff. But Publish updated some internals to make use of <a href="https://alejandromp.com/tags/concurrency/">Swift Concurrency</a> and that caused problems.</p><p>The short story is that Publish has only adopted concurrency half way. It uses it internally to speed up some things, but it still left the entry point as a normal synchronous function. I imagine that was the best solution when that Publish version was released, but nowadays it is a terrible idea. In order to make the runtime wait Publish uses an internal <a href="https://github.com/alexito4/Publish/commit/d76f9a0492af0038e06c01b6bf584df9b4514736#diff-05322202c2cb552481c629971bc4c96aadb75c26b62c633191ac4a5fcd241187L115">semaphore</a> that blocks the main thread, which as you can imagine it doesn’t play nicely with SwiftUI.</p><p>Since the library doesn’t get much attention, I just forked it and fix it myself. I’m still indecisive on what I will do with this. I don’t want to maintain forks, but if the original library doesn’t get more maintainers, I’m afraid of its future.</p><p>But with that out of the way, the generator run perfectly in Swift 5.7. I also updated some of my Publish plugins (<a href="https://github.com/alexito4/ItemPosterPublishPlugin">Item Poster</a> and <a href="https://github.com/alexito4/ReadingTimePublishPlugin">Reading time</a>) to be up to date with the rest of dependencies.</p><h2 id="running-swift-on-linux-in-netlify">Running Swift on Linux in Netlify</h2><p>The next step was to make sure my code could run on Linux, since is what all servers are based on. Thankfully Netlify makes that very easy.</p><p>First, Swift is now fully supported as a build environment. By default it uses an older version of Swift but, as the <a href="https://docs.netlify.com/configure-builds/manage-dependencies/#swift">docs</a> explains, you just need to set an environment variable with he version you want and it will be automatically installed on the server image. Easy peasy.</p><p>But then we had to update the code to work somewhere else that was not my machine. And one thing I detest of some development workflows is when you can’t try your changes locally. Years ago, I worked a bit on AWS Lambda and the setup that they gave me was so awful that I refused to work more on that project. So of course for this I quickly investigated how to test things locally without waiting for Netlify servers.</p><p>And of course the answer was Docker. It still baffles me that the solution to self-created problems by the industry is packaging entire computers. Is a good idea, don’t get me wrong, but it doesn’t solve the root of our problems. Anyway, Netlify has all the <a href="https://github.com/netlify/build-image/tree/focal">instructions</a> you need to run their image locally. And it was very easy to do, even for myself.</p><p>With that in place, I just had to run the generator and start <em>ifdefing</em> out everything that required macOS and making some hard-coded paths (yes, I’m lazy sometimes when it’s not a critical project).</p><p>Everything seemed to work except, of course, the SASS dependency was not installed in the same way. On macOS I use brew but on Linux I opted to use npm since it was already pre-installed. Took a few tries to get everything setup correctly, but it wasn’t too bad. That said, I despise that my site generation requires non-Swift dependencies. Is such a shame that to do anything on the web you need so many dependencies. In my other site, <a href="https://pulubiworlds.com">Pulubi Worlds</a>, I opted to use tailwind instead, but I’m pretty sure it will be the same mess. Well, a fight for another day.</p><p>And with that I had my site building on Netlify on every push. Nice!</p><h2 id="using-github-actions-for-macos-execution">Using GitHub actions for macOS execution</h2><p>But of course, those pesky posters wouldn’t generate on Linux. I need to run that on macOS remember?</p><p>Until then, the poster generation was part of the site generation, it was just another Publish step. But now I had to look for another solution.</p><p>Thankfully GitHub gives some macOS time for free, not much mind you, with their GitHub Actions. So I opted to make a separate command on my CLI to run only the poster creation. I configured the action to only run if there were changes on the Content folder to avoid wasting those precious macOS minutes.</p><h2 id="conclusion">Conclusion</h2><p>So now I have my site, including social poster generation, running on <em>the cloud</em>, still for free. This means I can write in <strong>my</strong> blog from anywhere which hopefully inspires me to write more.</p><p>I plan to do a couple more things using GitHub actions to reduce the friction. The dream would be to have a CMS that runs on top of GitHub, a CMS for static sites. But for now I can live with some more niceties.</p><p>Another thing I’m interesting in exploring is the whole <a href="https://micro.blog">micro.blog</a>, <a href="https://indieweb.org">indieweb</a> and federation idea. I know static sites don’t play super nice with some of those things, but is interesting to think about nonetheless.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/image-aspectratio-without-frames</guid><title>Image aspectRatio without frames</title><description></description><link>https://alejandromp.com/blog/image-aspectratio-without-frames</link><pubDate>Tue, 13 Dec 2022 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>Today I spent a couple of hours understanding how <a href="https://alejandromp.com/tags/swiftui/">SwiftUI</a> <code>aspectRatio</code> modifiers works and how it interacts with <code>Image</code>. It's a surprisingly simple system, but also one that made me wonder why things worked the way they worked.</p><blockquote><p>Update: <a href="https://mastodon.social/@ole@chaos.social/109524551869334765">Thanks</a> to <a href="https://oleb.net">Ole Begemann</a> I've learned more about how <code>frame</code> works and updated the ideal solution.</p></blockquote><h2 id="streched-images">Streched images</h2><p>It all started when a colleague made a PR to fix an issue that I raised with an image being distorted. While reviewing the PR, I was surprised to see that the old code already was using <code>aspectRatio</code> and the new code was an ugly mess of <code>ZStack</code> and other seemingly unnecessary things.</p><img src="https://alejandromp.com/blog/image-aspectratio-without-frames/stretch image.jpg" alt="Stretch image"/><p>The problem is that using <code>aspectRatio</code> in an <code>Image</code> and giving it a <code>ratio</code> just stretches the image, making it look awful and making the aspect ratio useless.</p><pre><code><span class="splash-type">Image</span>(<span class="splash-string">"christmas"</span>)
  .<span class="splash-call">resizable</span>()
  .<span class="splash-call">aspectRatio</span>(<span class="splash-number">2</span>, contentMode: .<span class="splash-dotAccess">fill</span>)
</code></pre><p>It's interesting how all the search results you find are giving you the solution to the most trivial example without getting deep into how things work. The examples about <code>aspectRatio</code> in images are always without the ratio - <code>.aspectRatio(contentMode: .fill)</code> - and using frame or other combinations that solve the issue at hand.</p><p>What I would love is for this to behave like <code>UIImageView</code> and it scaled the image properly without stretching. I want to use aspect ratio, without a numeric ratio and specifying no manual size, and let the image render properly without stretching.</p><p>But of course that's now what <code>aspectRatio</code> does!</p><p>Of course my curious mind immediately jumped into the code to analyse why there wasn't a better solution. I was sure there was some combination of modifiers that would make it work nicely without <code>ZStack</code> or other hacks. But it seems I was wrong 😑</p><h2 id="aspectratio-and-the-layout-process">aspectRatio and the layout process</h2><p>As with many modifiers in SwiftUI, it is important to realise that they do not really apply any behaviour to the views. It's not like we are telling the Image "object" to respect the aspect ratio. Nope! We are not setting properties to an object here. So don't let your mind complicate things and make you think that you.</p><p>The <code>aspectRatio</code> modifier is a <strong>layout</strong> modifier. That means that it takes part in the layout process of SwiftUI. The layout process is quite simple in reality: proposed sizes go down the hierarchy and taken sizes go up doing the positioning with them.</p><p>Armed with some tools from <a href="https://talk.objc.io">Swift Talk</a> I debugged for a while the behaviour of the modifier to confirm my mental model. This is something I do a lot, even if I think I know how things should work, I want to make sure my mental model is correct. And I dig deeper and deeper until I'm satisfied, when I can't come up with more questions that could shake my mental model.</p><blockquote><p>Note that I'm just giving a frame of 393x400 to avoid the <code>VStack</code> probing multiple times.</p></blockquote><p>Let's start with the problematic example:</p><pre><code><span class="splash-type">Image</span>(<span class="splash-string">"christmas"</span>)
    .<span class="splash-call">resizable</span>()
    .<span class="splash-call">logSizes</span>(<span class="splash-string">"Image"</span>)
    .<span class="splash-call">aspectRatio</span>(<span class="splash-number">2</span>, contentMode: .<span class="splash-dotAccess">fit</span>)
    .<span class="splash-call">logSizes</span>(<span class="splash-string">"Ratio"</span>)
</code></pre><img src="https://alejandromp.com/blog/image-aspectratio-without-frames/example1.jpg"/><p>You can see how the aspect ratio receives a size, it computes an appropriate size respecting the ratio and passes that down to the image. The image accepts that size and <strong>just renders itself in it</strong>. If we change it to <code>fill</code> the behaviour is the same, with the difference that the sizes are bigger.</p><p>Now let's try without giving a ratio at all, just telling the modifier to <code>fill</code>.</p><pre><code><span class="splash-type">Image</span>(<span class="splash-string">"christmas"</span>)
  .<span class="splash-call">resizable</span>()
  .<span class="splash-call">logSizes</span>(<span class="splash-string">"Image"</span>)
  .<span class="splash-call">aspectRatio</span>(contentMode: .<span class="splash-dotAccess">fill</span>)
  .<span class="splash-call">logSizes</span>(<span class="splash-string">"Ratio"</span>)
</code></pre><img src="https://alejandromp.com/blog/image-aspectratio-without-frames/example2.jpg"/><p>Now we can see how the image is correctly filling the available space without stretching. But if you look at the layout logs, you can see what happens in reality. Is not that the image is magically avoiding stretching (like <code>UIImageView</code> did), it's that the image receives a proper size that doesn't make it stretch. The aspect ratio modifier does some probing this time to find the correct size that matches the algorithm. And again, the just renders itself in that size, nothing else.</p><p>So by now I thought that it made sense. The aspect ratio modifier is just changing the proposed size that is passed down and the image just renders itself according to that size, filling all pixels on that space, not caring if that results in stretching at all.</p><p>This explains why so many examples provide a frame and not a ratio, which defeats the purpose of dynamic UIs. So the solution my colleague proposed was on the right track: use aspect ratio to compute a "frame" in which to embed the image, and then let the image fill all the space.</p><p>Despite that, my brain was like "there must be a way of doing that by chaining modifiers!"...</p><h3>Chaining aspect ratios for science!</h3><p>So the idea was to keep the aspect ratio of the image without a specific number, and use another parent modifier to create the correct size:</p><blockquote><p>I'm using a square ratio as an example because it is clear to see that the result is wrong, not squared.</p></blockquote><pre><code><span class="splash-type">Image</span>(<span class="splash-string">"christmas"</span>)
    .<span class="splash-call">resizable</span>()
    .<span class="splash-call">logSizes</span>(<span class="splash-string">"Image"</span>)
    .<span class="splash-call">aspectRatio</span>(contentMode: .<span class="splash-dotAccess">fill</span>)
    .<span class="splash-call">logSizes</span>(<span class="splash-string">"Inner Ratio"</span>)
    .<span class="splash-call">aspectRatio</span>(<span class="splash-number">1</span>, contentMode: .<span class="splash-dotAccess">fit</span>)
    .<span class="splash-call">logSizes</span>(<span class="splash-string">"Outer Ratio"</span>)
</code></pre><img src="https://alejandromp.com/blog/image-aspectratio-without-frames/example3.jpg"/><p>But as you can see that changed nothing.</p><blockquote><p>At this point I added the ratio on the log to see easily if it matched the one I gave.</p></blockquote><p>If you analyze the logs, you can see how the outer modifier changes the size to be a square, but the inner ratio then computes a new size according to its <code>fill</code> rule and is what it uses to probe the image. At the end the result is the same since the image receives that "filled" frame.</p><p>Now is when your brain may say "but I specified an aspect ratio of 1, why is that not respected?" and the answer is the same again. The modifier does nothing else than changing the proposed size down. The child's view is free to ignore that and pick another size, which is reported upwards. And when the layout system goes up, there is no correction. The aspect ratio modifier won't force the reported size of the child to be a ratio of 1.</p><p>You can see it easily if we use a frame instead:</p><pre><code><span class="splash-type">Image</span>(<span class="splash-string">"christmas"</span>)
    .<span class="splash-call">resizable</span>()
    .<span class="splash-call">logSizes</span>(<span class="splash-string">"Image"</span>)
<span class="splash-comment">// .aspectRatio(contentMode: .fill)</span>
    .<span class="splash-call">frame</span>(width: <span class="splash-number">100</span>, height: <span class="splash-number">300</span>)
    .<span class="splash-call">logSizes</span>(<span class="splash-string">"Inner Ratio"</span>)
    .<span class="splash-call">aspectRatio</span>(<span class="splash-number">1</span>, contentMode: .<span class="splash-dotAccess">fit</span>)
    .<span class="splash-call">logSizes</span>(<span class="splash-string">"Outer Ratio"</span>)
</code></pre><img src="https://alejandromp.com/blog/image-aspectratio-without-frames/example4.jpg"/><p>You can see how the frame picks the size ignoring the parent aspect ratio proposed size, and the aspect ratio can't do anything about it. Again, proposed sizes go down, and selected final sizes go up positioning along the way. Nothing more. Is really that simple.</p><h2 id="the-simple-common-scenarios">The simple common scenarios</h2><p>As a side note, let's look at why the common examples used to teach aspect ratio for images work.</p><p>Usually the examples start by showing you how images get stretched:</p><pre><code><span class="splash-type">Image</span>(<span class="splash-string">"christmas"</span>)
    .<span class="splash-call">resizable</span>()
    .<span class="splash-call">frame</span>(height: <span class="splash-number">200</span>)
    .<span class="splash-call">logSizes</span>(<span class="splash-string">"Image"</span>)
</code></pre><img src="https://alejandromp.com/blog/image-aspectratio-without-frames/example5.jpg"/><p>We can see here how the frame proposes a size to the image and this one just takes it and renders itself, resulting in obvious stretching.</p><p>Then the solution proposed is usually to just use the aspect ratio, without a number, to fix it:</p><pre><code><span class="splash-type">Image</span>(<span class="splash-string">"christmas"</span>)
  .<span class="splash-call">resizable</span>()
  .<span class="splash-call">logSizes</span>(<span class="splash-string">"Image"</span>)
  .<span class="splash-call">aspectRatio</span>(contentMode: .<span class="splash-dotAccess">fit</span>)
  .<span class="splash-call">logSizes</span>(<span class="splash-string">"Ratio"</span>)
  .<span class="splash-call">frame</span>(height: <span class="splash-number">200</span>)
  .<span class="splash-call">logSizes</span>(<span class="splash-string">"Frame"</span>)
</code></pre><img src="https://alejandromp.com/blog/image-aspectratio-without-frames/example6.jpg"/><p>This of course fixes the stretching. Now the <code>aspectRatio</code> probes the image to know its aspect ratio, then computes the correct size giving the constraints, and proposes that to the image to just render itself in it.</p><p>But of course you are fixing the sizes which is totally against any modern, adaptable design.</p><p>And just for completeness, try to use <code>fill</code> instead:</p><img src="https://alejandromp.com/blog/image-aspectratio-without-frames/example7.jpg"/><p>That's even more annoying because the image draws out of bounds, you need to clip it. But take the opportunity to understand why that happens. The aspect ratio still probes the image for its desired ratio, and uses it to calculate a correct size using a <strong>filling</strong> algorithm, which makes the size bigger. That report goes up until it find the frame. The frame cannot do anything about it, again the layout process going up is just about positioning, but is stubborn and returns the fix size you gave it. That means the layout outside thinks is 200 but the image rendered way bigger than that.</p><h2 id="image-rendering-is-the-culprit">Image rendering is the culprit</h2><p>At this point I tried many combinations, but I was just distracting myself, learning along the way and reaffirming my mental model yes, but there was no solution on the horizon. Things worked as they should. The aspect ratio modifier just proposes an appropriate size, that's it.</p><p>The issue here is that the image rendering is quite dumb. As soon as you do <code>resizable</code> it just means the image will render all the pixels filling the entire size that is given to it. That makes sense but is annoying given the circumstances. That modifier has a <code>resizingMode</code> that would make you hope it was the solution but no, it's just to change between stretching and tiling. I think that if you could tell that mode to be fitting or filling it would mimic more my expectations.</p><h2 id="solution">Solution</h2><blockquote><p>UPDATE: See <a href="#a-better-solution-with-frames">below</a> for a better solution using frames.</p></blockquote><p>So what's the solution? Sadly, we need to break the hierarchy in two.</p><p>First create a "frame" by constraining the size to a specific desired ratio.</p><pre><code><span class="splash-type">Rectangle</span>()
  .<span class="splash-call">aspectRatio</span>(<span class="splash-number">2</span>, contentMode: .<span class="splash-dotAccess">fit</span>)
</code></pre><img src="https://alejandromp.com/blog/image-aspectratio-without-frames/solution0.jpg"/><p>Then, <strong>embed</strong> the image inside that frame and use another aspect ratio to give it the proper size. We also need to clip the result since using fill will make the image draw of out of bounds as explained above.</p><blockquote><p>Note that I'm using an <code>overlay</code> instead of a <code>ZStack</code>. Prefer to use overlay or background instead of ZStacks when is semantically more appropriate.</p></blockquote><pre><code><span class="splash-type">Rectangle</span>()
  .<span class="splash-call">aspectRatio</span>(<span class="splash-number">2</span>, contentMode: .<span class="splash-dotAccess">fit</span>)
  .<span class="splash-call">overlay</span> {
      <span class="splash-type">Image</span>(<span class="splash-string">"christmas"</span>)
          .<span class="splash-call">resizable</span>()
          .<span class="splash-call">aspectRatio</span>(contentMode: .<span class="splash-dotAccess">fill</span>)
  }
  .<span class="splash-call">clipped</span>()
</code></pre><img src="https://alejandromp.com/blog/image-aspectratio-without-frames/solution1.jpg"/><p>Since this is a bit cumbersome to do, I thought it would be nice to have a reusable modifier for it. But that comes with more questions around API design so feel free to do whatever is more appropriate for your codebase. I just give you my current take as a suggestion:</p><pre><code><span class="splash-keyword">extension</span> <span class="splash-type">View</span> {
    <span class="splash-keyword">func</span> framedAspectRatio(
        <span class="splash-keyword">_</span> ratio: <span class="splash-type">CGFloat</span>? = <span class="splash-keyword">nil</span>,
        contentMode: <span class="splash-type">ContentMode</span>
    ) -&gt; <span class="splash-keyword">some</span> <span class="splash-type">View</span> {
        <span class="splash-type">Color</span>.<span class="splash-property">clear</span>
            .<span class="splash-call">aspectRatio</span>(ratio, contentMode: .<span class="splash-dotAccess">fit</span>)
            .<span class="splash-call">overlay</span> {
                <span class="splash-keyword">self</span>
                    .<span class="splash-call">aspectRatio</span>(contentMode: contentMode)
            }
            .<span class="splash-call">clipped</span>()
    }
}
</code></pre><p>With this modifier at hand the result doesn't seem that bad:</p><pre><code><span class="splash-type">Image</span>(<span class="splash-string">"christmas"</span>)
    .<span class="splash-call">resizable</span>()
    .<span class="splash-call">framedAspectRatio</span>(<span class="splash-number">2</span>, contentMode: .<span class="splash-dotAccess">fill</span>)
</code></pre><h2 id="a-better-solution-with-frames">A better solution with frames</h2><p>After posting this post, Ole Begemann <a href="https://mastodon.social/@ole@chaos.social/109524551869334765">replied on Mastodon</a> with a better solution and some insight on how <code>frame</code> works. It turns out I was not that far when I suspected that there was a way to break the layout in two separate <em>frames</em>. After all, the modifiers in Swift are virtually creating nested views. What I missed is a special behaviour of the <code>frame</code> modifier. It's one of those cases when the answer was in my brain, because I watched <a href="https://talk.objc.io">Swift Talk</a>, but for some reason I didn't think about it, 😞 .</p><p>The documentation of the modifier says this, emphasis mine:</p><blockquote><p>If no minimum or maximum constraint is specified in a given dimension, the frame adopts the sizing behavior of its child in that dimension. If <strong>both constraints are specified in a dimension</strong>, the frame <strong>unconditionally adopts the size proposed</strong> for it, clamped to the constraints.</p></blockquote><p>That's exactly what I wanted!</p><pre><code><span class="splash-type">Image</span>(<span class="splash-string">"christmas"</span>)
    .<span class="splash-call">resizable</span>()
    .<span class="splash-call">aspectRatio</span>(contentMode: .<span class="splash-dotAccess">fill</span>)
		<span class="splash-comment">// this is the magic trick</span>
    .<span class="splash-call">frame</span>( 
        minWidth: <span class="splash-number">0</span>,
        maxWidth: .<span class="splash-dotAccess">infinity</span>,
        minHeight: <span class="splash-number">0</span>,
        maxHeight: .<span class="splash-dotAccess">infinity</span>
    )
    .<span class="splash-call">aspectRatio</span>(<span class="splash-number">2</span>, contentMode: .<span class="splash-dotAccess">fit</span>)
    .<span class="splash-call">clipped</span>()
</code></pre><img src="https://alejandromp.com/blog/image-aspectratio-without-frames/solution-with-frames-logs.jpg" alt="solution with frames"/><p>But I have to admit that I've spend a few hours trying to fully understand the behaviour of <code>frame</code>. When I was happy understanding what passing both constraints does, I found myself confused because when I passed only <code>minHeight: 0</code> the behaviour is still the one I wanted!</p><p>The <a href="https://swiftui-lab.com/frame-behaviors/#altering-behaviors">diagram from SwiftUI Lab</a> was very useful to understand the documentation in a visual form, but even with that the change of behaviour from following the child size to the proposed size is a bit confusing. I understand the common cases, and it always does what you expect it to do, but... I have to think a bit too much, there is still something confusing me.</p><p>Thanks to Ole I now have a better grasp of SwiftUI layout system. I will have to watch some Swift Talk episodes again 😂</p><h2 id="conclusion">Conclusion</h2><p>I love this puzzles! I like to go deep not really to find a solution, but to make sure I understand what's going on. At the end of the journey I'm happy to solidify my mental model of how things work, even if the final answer is not very satisfying.</p><p>Ultimately though, I hope this post serves not only as an explanation of this behaviour but also as an inspiration to make you go deep and make sure you really understand how things work. So please don't just copy the final code from the internet, not even from this post!</p><p>A final thanks for the guys at <a href="https://talk.objc.io">Swift Talk</a> for the useful debugging tools and for the great explanations about SwiftUI layout's system. And to Ole Begemann for giving me not only the solution I desired, but more puzzles to solve. They were crucial to help me form the correct mental model since SwiftUI release ^^</p><p>As usual, I could have totally missed something, or a new version of SwiftUI changes things, so please don’t hesitate to reach out to clarify anything 🙏.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/swiftui-footers-ctas-and-safe-areas</guid><title>Extend a footer outside the Safe Area with SwiftUI</title><description>The safe area is one of the most relevant changes in the UI paradigm of iOS in the recent years. Let's learn how to implement a footer with CTA that respects the safe areas but with a background that extends to the edge.</description><link>https://alejandromp.com/blog/swiftui-footers-ctas-and-safe-areas</link><pubDate>Fri, 30 Sep 2022 00:00:00 +0000</pubDate><content:encoded><![CDATA[<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/gpO1zwgdMlI" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><blockquote><p><a href="https://www.youtube.com/channel/UCfiBFlVY8s-tmJGDMNCd26w?sub_confirmation=1">Subscribe to my channel</a> to be notified when new videos about SwiftUI are released.</p></blockquote><p>The safe area is one of the most relevant changes in the UI paradigm of iOS in the recent years. It unified a bunch of layout ideas into a single API and allowed us to make our UIs adapt to new phones with weird shapes.</p><p>One of the most common design patterns that has to deal with the bottom safe area is having a call to action inside a footer on your screen. The difficulty with this design is that you want your content to respect the safe area, but also you want a background that extends to the edge of the screen. You can see it in action in any <code>TabBar</code>:</p><img src="https://alejandromp.com/blog/swiftui-footers-ctas-and-safe-areas/IMG_928A81A13D6E-1.jpeg" alt="IMG_928A81A13D6E-1"/><p>Implementing this is not as straightforward as it may seem. If you expand your container to the edge, your content will be behind the home indicator. If you fully respect the safe area you will see a different colored background behind the home indicator.</p><p>What you need is a combination of both things.</p><img src="https://alejandromp.com/blog/swiftui-footers-ctas-and-safe-areas/IMG_2729BA01DB1B-1.jpeg" alt="IMG_2729BA01DB1B-1"/><p>Luckily SwiftUI gives us the tools we need to accomplish this.</p><h2 id="solution-for-ios-15">Solution for iOS 15</h2><blockquote><p>Updated solution for iOS 15 using the new API <a href="https://developer.apple.com/documentation/swiftui/presentedwindowcontent/safeareainset(edge:alignment:spacing:content:)-zs3l">safeAreaInset(edge:alignment:spacing:content:)</a></p></blockquote><p>With the new <code>safeAreaInset(edge:alignment:spacing:content:)</code> modifier the way we work with safe areas has changed. Instead of applying a modifier to a view in the main layout making it extend, we apply a modifier to the main view passing another view that we want to extend to the edges.</p><pre><code><span class="splash-type">VStack</span>(spacing: <span class="splash-number">0</span>) {
    <span class="splash-comment">// Your screen content...</span>
}
.<span class="splash-call">safeAreaInset</span>(edge: .<span class="splash-dotAccess">bottom</span>, spacing: <span class="splash-number">0</span>) {
    <span class="splash-type">VStack</span> {
        <span class="splash-comment">// Your footer content or CTA
        // It will respect the safe area</span>
    }
    .<span class="splash-call">padding</span>()
    .<span class="splash-call">frame</span>(maxWidth: .<span class="splash-dotAccess">infinity</span>)
    <span class="splash-comment">// The background will extend automatically to the edge</span>
    .<span class="splash-call">background</span>(<span class="splash-type">Color</span>.<span class="splash-property">green</span>) 
}
</code></pre><img src="https://alejandromp.com/blog/swiftui-footers-ctas-and-safe-areas/simulator_example.jpg" alt="simulator_example"/><p>Note how you can specify a <code>spacing</code> between the main content (the modified view) and the footer view.</p><h2 id="solution-for-ios-14">Solution for iOS 14</h2><blockquote><p>This solution works on iOS 14. SwiftUI behaviour has changed a bit since the first releases. Thanks to <a href="https://twitter.com/mbuchetics/status/1359863185243791366">Matthias for pointing it out</a>.</p></blockquote><p><code>edgesIgnoringSafeArea</code> is a modifier that lets a view ignore the safe areas. We can use this to tell the background of our footer to extend to the edge of the screen.</p><pre><code><span class="splash-type">VStack</span>(spacing: <span class="splash-number">0</span>) {
    <span class="splash-comment">// Your screen content...</span>

    <span class="splash-type">VStack</span> {
        <span class="splash-comment">// Your footer content or CTA</span>
    }
    .<span class="splash-call">padding</span>()
    .<span class="splash-call">frame</span>(maxWidth: .<span class="splash-dotAccess">infinity</span>)
  	<span class="splash-comment">// The background we want to extend</span>
    .<span class="splash-call">background</span>(<span class="splash-type">Color</span>.<span class="splash-property">green</span>.<span class="splash-call">edgesIgnoringSafeArea</span>(.<span class="splash-dotAccess">bottom</span>)) 
}
</code></pre><p>By using the modifier only on the background with still make the rest of the content respect the safe areas which is very important.</p><h2 id="solution-for-ios-13">Solution for iOS 13</h2><p>Watch <a href="https://www.youtube.com/watch?v=rNO0wHc11qM">the original video</a> to check the solution we had back in 2020.</p><iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/rNO0wHc11qM" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/fluent-syntax-extensions-in-swift</guid><title>Fluent syntax extensions in Swift</title><description></description><link>https://alejandromp.com/blog/fluent-syntax-extensions-in-swift</link><pubDate>Wed, 5 Jan 2022 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>In the early days of Swift, one thing I really enjoyed was the focus on properties (bye-bye ivars!) and the unification of stored and computed property syntax. It became very common to define properties that initialized some parts of your view automatically.</p><pre><code><span class="splash-keyword">let</span> label = <span class="splash-type">UILabel</span>()
</code></pre><p>But we all quickly realised that it was not enough. You often want to initialize that label with some defaults set, things like font, color, etc. Swift has a way to do it with immediately-executed closures like so:</p><pre><code><span class="splash-keyword">let</span> label: <span class="splash-type">UILabel</span> = {
  <span class="splash-keyword">let</span> label = <span class="splash-type">UILabel</span>()
  label.<span class="splash-property">textAlignment</span> = .<span class="splash-dotAccess">center</span>
  label.<span class="splash-property">textColor</span> = .<span class="splash-dotAccess">black</span>
  label.<span class="splash-property">text</span> = <span class="splash-string">"Hello, World!"</span>
  <span class="splash-keyword">return</span> label
}()
</code></pre><p>But that is very verbose. You have to repeat the name multiple times and the immediately-executed closure is weird for newcomers.</p><p>The community quickly figured out this need in the early days of Swift Evolution. You can find a bunch of forums posts about the topic through the years, some of them in early days of the mailing list!</p><ul><li><a href="https://gist.github.com/erica/eb32feb22ba99629285a">Adding Method Cascades</a> by <a href="https://github.com/erica">Erica Sadun</a>, one of the early proposals.</li><li><a href="https://forums.swift.org/t/fluent-syntax-replacing-void-with-a-useful-default-return-value/667">Fluent syntax (replacing void with a useful default return value) - Discussion - Swift Forums</a></li><li><a href="https://forums.swift.org/t/circling-back-to-with/2766">Circling back to <code>with</code> - Pitches - Swift Forums</a></li><li><a href="https://forums.swift.org/t/customized-inline-init-closure/882">Customized Inline Init Closure - Discussion - Swift Forums</a></li><li><a href="https://forums.swift.org/t/pitch-scoped-functions/45486">Pitch: Scoped Functions - Pitches - Swift Forums</a></li><li><a href="https://forums.swift.org/t/discussion-here-we-go-again-extension-functions/1568">Discussion Here we go again: Extension Functions - Discussion - Swift Forums</a></li></ul><p>Some of them focus on just adding flexibility to the initialiser syntax and others go beyond that to offer a general solution to these common topics of <em>fluent syntax</em>. The reality is that none of those proposals ever got far, so the language still doesn't offer a pleasant alternative.</p><p>But since the early days <a href="https://github.com/devxoul/Then">devxoul/Then</a> was created and quickly became a standard in the community. I include it by default on all my projects. That's how useful it is! That said, I always missed some functionality and recently I started investigating the topic deeper, which prompted me to write this post and open source a <a href="https://github.com/alexito4/Flow">new package</a>.</p><h2 id="swift-limitations">Swift limitations</h2><p>Accepting that the language doesn't offer the solution we need, let's explore how a library can solve it. It’s important to understand the limitations in the language that limit what a library can do.</p><h3>Any being a non-nominal type</h3><p>The first thing you encounter is the impossibility of <strong>extending non-nominal types</strong>. We rarely think about this distinction in the language, but for the functionality we want is a real blocker. What we would love to do is something like this:</p><pre><code><span class="splash-keyword">extension</span> <span class="splash-type">Any</span> {
  <span class="splash-keyword">func</span> then(...
}
</code></pre><p>But <code>Any</code> is a non-nominal type so we can't extend it! The best alternative to this is to make your own marker protocol (without requirements) and conform all the types you can to it! It's not pretty, but it gets the job done.</p><pre><code><span class="splash-keyword">protocol</span> Flowable {}
<span class="splash-keyword">extension</span> <span class="splash-type">Array</span>: <span class="splash-type">Flowable</span> {}
...
</code></pre><blockquote><p>Note that by extending <code>NSObject</code> to conform to our protocol, we make all Apple frameworks have this new functionality. (if they are in Objective-C and use classes)</p></blockquote><p>With that in place, we can add extension functions to our protocol when the conformant type is a... well, <code>Any</code>!</p><pre><code><span class="splash-keyword">extension</span> <span class="splash-type">Flowable</span> <span class="splash-keyword">where</span> <span class="splash-type">Self</span>: <span class="splash-type">Any</span> {
  <span class="splash-keyword">func</span> then...
</code></pre><p>It's a roundabout way of getting there, but it ends up working.</p><h3>The lack of self rebinding</h3><p>Also known as <a href="https://kotlinlang.org/docs/lambdas.html#function-literals-with-receiver">receiver closures from Kotlin</a>. This functionality allows a closure definition to specify what the "receiver" object in the closure's scope is. The "receiver" is the object that will receive a method call if we don't prefix it with a target object. It's what <code>self</code> is in a method.</p><pre><code><span class="splash-keyword">func</span> methodInAClass() {
   <span class="splash-call">callSomeMethodInThisClass</span>() <span class="splash-comment">// self is implicit, is the receiver object.</span>
}
...

<span class="splash-call">methodWithClosure</span>(<span class="splash-type">SomeObject</span>()) {
  <span class="splash-comment">// This closure could make `SomeObject` the receiver.</span>
  <span class="splash-call">callSomeMethodInSomeObject</span>() <span class="splash-comment">// we don't need $0</span>
}
</code></pre><p>The advantage of this is that you get less boilerplate by avoiding the repeated usage of <code>$0</code>, which is the same reason the language allows us to omit <code>self</code> in methods. It would be very useful to have, since the main purpose of some methods we want is to reduce boilerplate. But alas!</p><h2 id="what-[flow](https://github.com/alexito4/flow)-offers">What <a href="https://github.com/alexito4/Flow">Flow</a> offers</h2><p>Even with these limitations, we can still offer a lot of interesting functionality to improve fluent syntax in Swift.</p><p>As I said, I've been using the <em>Then</em> library for years, but the reality is that on every project I was a bit frustrated by it. It lacks some functionality that I miss on occasions, especially when having interactions with Kotlin code. That meant that I ended up making my own extensions on every project, and eventually switching some names to better match my preferences.</p><p>So after a long time I decided to write my thoughts on it, put together a list of requirements, clean up the methods, unit test them and release it to the world.</p><p>I present you <a href="https://github.com/alexito4/Flow">Flow</a>, 🌊 Let your code flow. A Swift package that includes a bunch of extensions to make fluent syntax better.</p><blockquote><p>What you see is my take on this functionality. It covers my needs for fluent syntax. Of course, other libraries and languages have inspired it. I will document the direct <a href="https://github.com/alexito4/Flow#influences">influences</a> on each method so you can explore the alternative yourself ;)</p></blockquote><p>Below, I summarize all the functionality that I usually want:</p><ul><li>The star of the show is <code>.then</code>. We want this to configure reference and value types. Useful for configuration at the point of initialization.</li></ul><ul><li><code>.mutate</code> in place value types.</li><li><code>.let</code> to transform an object into another.</li><li><code>.do</code> to perform multiple actions with the same object.</li><li>Free function variants, for when you prefer this syntax or don't want to conform to the protocol:<ul><li><code>with</code> (similar to <code>.then</code>)</li><li><code>withLet</code> (similar to <code>.let</code>)</li><li><code>run</code> as an alternative to immediately executed closures.</li></ul></li></ul><h2 id="`.then`"><code>.then</code></h2><p><code>.then</code> let's you perform an object configuration inline. It applies statements in the closure to the object. It's very useful to set the properties of an object when defining it. Is what started this entire discussion many years ago :)</p><pre><code><span class="splash-keyword">let</span> label = <span class="splash-type">UILabel</span>().<span class="splash-call">then</span> {
  $0.<span class="splash-property">text</span> = <span class="splash-string">"Hello"</span>
  $0.<span class="splash-property">textColor</span> = .<span class="splash-dotAccess">red</span>
  $0.<span class="splash-property">font</span> = .<span class="splash-call">preferredFont</span>(forTextStyle: .<span class="splash-dotAccess">largeTitle</span>)
  $0.<span class="splash-call">sizeToFit</span>()
}

<span class="splash-keyword">let</span> size = <span class="splash-type">CGSize</span>().<span class="splash-call">then</span> {
	$0.<span class="splash-property">width</span> = <span class="splash-number">20</span>
}
</code></pre><blockquote><p>There are two overloads of this method provided. One that works on <code>AnyObject</code> (a.k.a. classes) and another that operates on <code>Any</code> (intended for value types). The compiler picks the correct one appropriately.</p></blockquote><ul><li>In the closure you get a reference to <code>self</code> or an <code>inout</code> copy in case of value types.</li><li>It returns the same reference to the object, or the mutated copy for value types.</li></ul><p>Influences:</p><ul><li><a href="https://github.com/devxoul/Then/blob/master/Sources/Then/Then.swift#L42">Then.with</a></li><li><a href="https://kotlinlang.org/docs/scope-functions.html#apply">Kotlin.apply</a> and <a href="https://kotlinlang.org/docs/scope-functions.html#also">Kotlin.also</a></li></ul><h2 id="`.mutate`"><code>.mutate</code></h2><p>Mutates a value <strong>in place</strong>. It s like <code>.then</code> but applies to <code>self</code> instead of a new copy. The value needs to be defined as a <code>var</code>.</p><pre><code>view.<span class="splash-property">frame</span>.<span class="splash-call">mutate</span> {
  $0.<span class="splash-property">origin</span>.<span class="splash-property">y</span> = <span class="splash-number">200</span>
  $0.<span class="splash-property">size</span>.<span class="splash-property">width</span> = <span class="splash-number">300</span>
}
</code></pre><ul><li>In the closure you get an <code>inout</code> reference to <code>self</code> .</li><li>It returns nothing.</li></ul><blockquote><p>This should be used only for value types. For reference types is recommended to use <code>.then</code>.</p></blockquote><h2 id="`.let`"><code>.let</code></h2><p>You can think of <code>.let</code> as a <code>map</code> operation but for all the types (not only for <em>Functors</em>). It lets you transform the object into an object of another type.</p><pre><code><span class="splash-keyword">let</span> dateString: <span class="splash-type">String</span> = <span class="splash-type">Date</span>().<span class="splash-call">let</span> {
    <span class="splash-keyword">let</span> formatter = <span class="splash-type">DateFormatter</span>()
    <span class="splash-keyword">return</span> formatter.<span class="splash-call">string</span>(from: $0)
}
</code></pre><p>It works especially well for type conversions based on initializers:</p><pre><code><span class="splash-keyword">let</span> number: <span class="splash-type">Int</span>? = <span class="splash-string">"42"</span>.<span class="splash-call">let</span>(<span class="splash-type">Int</span>.<span class="splash-keyword">init</span>)
</code></pre><blockquote><p>Don't overuse this when you can use just plain dot syntax. You can use it to access a member of the object <code>Date().let { $0.timeIntervalSince1970 }</code> but that's just the same as <code>Date().timeIntervalSince1970</code>.</p></blockquote><ul><li>You get a reference to <code>self</code> in the closure.</li><li>It returns the object returned in the closure.</li></ul><p>Influences:</p><ul><li>Swift's own <code>let</code> declaration.</li><li><a href="https://kotlinlang.org/docs/scope-functions.html#let">Kotlin.let</a> and <a href="https://kotlinlang.org/docs/scope-functions.html#run">Kotlin.run</a>.</li></ul><h2 id="`.do`"><code>.do</code></h2><p>Use this method to perform multiple actions (side effects) with the same object. It helps to reduce the verbosity of typing the same name multiple times.</p><pre><code><span class="splash-type">UserDefaults</span>.<span class="splash-property">standard</span>.<span class="splash-call">do</span> {
    $0.<span class="splash-call">set</span>(<span class="splash-number">42</span>, forKey: <span class="splash-string">"number"</span>)
    $0.<span class="splash-call">set</span>(<span class="splash-string">"hello"</span>, forKey: <span class="splash-string">"string"</span>)
    $0.<span class="splash-call">set</span>(<span class="splash-keyword">true</span>, forKey: <span class="splash-string">"bool"</span>)
}
</code></pre><p>This behaves like other methods if you discard their return, but is preferred to use <code>do</code> to convey the intention better. It also lets you avoid writing the <code>return</code> on some occasions.</p><ul><li>You get a reference to <code>self</code> in the closure.</li><li>It returns nothing.</li></ul><p>Influences:</p><ul><li><a href="https://github.com/devxoul/Then/blob/master/Sources/Then/Then.swift#L56">Then.do</a></li></ul><h2 id="`.debug`"><code>.debug</code></h2><p>By default, it prints <code>self</code> to the console. This method is useful for debugging intermediate values of a chain of method calls.</p><pre><code><span class="splash-keyword">let</span> result = <span class="splash-type">Object</span>()
   .<span class="splash-call">then</span> { ... }
   .<span class="splash-call">debug</span>(<span class="splash-string">"prefix"</span>)
   .<span class="splash-call">let</span> { ... }
   .<span class="splash-call">debug</span>()
</code></pre><ul><li>You get a reference to <code>self</code> in the closure.</li><li>It returns the same object without touching it.</li></ul><blockquote><p>The following free function variants are mostly there to workaround Swift limitations. But there are also some people that prefer them. Flow gives you both alternatives ;)</p></blockquote><h2 id="free-function-`with`">Free function <code>with</code></h2><p>Executes a closure with the object. This free function it's a substitute for <code>.then</code> when you can't use the method or if you prefer the free function style.</p><pre><code><span class="splash-keyword">let</span> label = <span class="splash-call">with</span>(<span class="splash-type">UILabel</span>()) {
    $0.<span class="splash-property">text</span> = <span class="splash-string">"Hello"</span>
    $0.<span class="splash-property">textColor</span> = .<span class="splash-dotAccess">red</span>
    $0.<span class="splash-property">font</span> = .<span class="splash-call">preferredFont</span>(forTextStyle: .<span class="splash-dotAccess">largeTitle</span>)
    $0.<span class="splash-call">sizeToFit</span>()
}
</code></pre><ul><li>You get a reference to an <code>inout</code> copy of <code>self</code> in the closure.</li><li>It returns the returned object in the closure.</li></ul><p>Influences:</p><ul><li><a href="https://github.com/pointfreeco/swift-overture#with-and-update">Overture.with</a></li><li><a href="https://kotlinlang.org/docs/scope-functions.html#with">Kotlin.with</a></li><li>Many other languages have a <code>with</code> or <code>using</code> function.</li></ul><h2 id="free-function-`withlet`">Free function <code>withLet</code></h2><p>Variant of <code>with</code> that lets you return a different type. It's a free function alternative to <code>let</code>.</p><h2 id="free-function-`run`">Free function <code>run</code></h2><p>Executes a closure of statements, useful to be used when you need an expression. This is like making a closure and invoking immediately, but sometimes is clearer to have a specific name for it.</p><pre><code><span class="splash-keyword">let</span> result = <span class="splash-call">run</span> { ... } <span class="splash-comment">// same as { ... }()</span>
</code></pre><h2 id="conclusion">Conclusion</h2><p>It has been fun to spend the last few days writing down my thoughts on this topic. I read many times Kotlin's documentation and looked at how other languages solved the problems. Ultimately, I compiled a list of the functionality that I wanted and which names should I use for them. I've been using this code in one way or another for many years, so I'm happy to finally have put the time to polish it.</p><p>One of the things I tried was to unify some methods. It worked for <code>then</code> which operates on both reference and value types. I wanted the <code>mutate</code> method to have the same name, but that didn't work out. <code>let</code> is one that I use quite a lot, although I try to not overuse it as the Kotlin community does, in my opinion. <code>do</code> is one that I don't use a lot, but is useful sometimes and since the purpose of this package is to avoid friction, I ultimately decided to include. For the same reason the free functions are included, sometimes I don't want to conform an object to the protocol just for a one of operation, and the free functions are perfect for those occasions. And don't forget about <code>debug</code>, probably the one I use the most ^^.</p><p>Thank you all for reading and remember you can find <a href="https://github.com/alexito4/Flow">Flow</a> on GitHub and try it by yourself.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/unwrap-or-throw-or-die</guid><title>Unwrap Or Throw (or Die)</title><description></description><link>https://alejandromp.com/blog/unwrap-or-throw-or-die</link><pubDate>Tue, 4 Jan 2022 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>Swift's <code>Optional</code> type is one of the biggest hits of the language. Mainly because it's opt-in. Everything is non-optional by default, which solves the old problem of having to deal with nulls everywhere. That said, nulls (or Optional.none) still shows up a decent amount of times, so the second thing Swift did very well was to provide great affordances to work with optional at the language level.</p><blockquote><p>You should read this <a href="https://twitter.com/UINT_MIN/status/1475193503948754947?s=20">Twitter thread</a> from <a href="https://twitter.com/UINT_MIN">Jordan Rose</a> about the decisions of making Optional so convenient.</p></blockquote><p>One of the common operations that you want to do with an optional is to coalesce the nil with a default value. For that, Swift provides the handy <a href="https://docs.swift.org/swift-book/LanguageGuide/BasicOperators.html">nil-coalescing operator</a> <code>??</code>. This operator is so nice that we will use it to improve on the ergonomics of optional later.</p><p>But the reality is that there is still a bunch of behaviour that Swift doesn't make so convenient. For example, another part of the language that is convenient to use is Errors. And the language provides a mechanism to silence errors, to convert a throwing error to an optional. That's what <code>try?</code> does. But there is no convenient way of going the other way around!</p><p>Another important aspect that people often complain about is how force unwrapping <code>!</code> has a very convenient syntax but if leads to opaque logs and crashes with very little information.</p><h2 id="not-invented-here.">Not invented here.</h2><p>The community quickly realised all of this in the early days of Swift. The concern about the lack of proper diagnostics for force unwrapping was put in the table by Erica Sadun on 2017 (see the <a href="https://forums.swift.org/t/pitch-introducing-the-unwrap-or-die-operator-to-the-standard-library/6207">pitch</a>) and it even had a proposed solution (<a href="https://github.com/apple/swift-evolution/blob/master/proposals/0217-bangbang.md">SE-0217: Introducing the <code>!!</code> "Unwrap or Die" operator to the Swift Standard Library</a>) that was eventually rejected. Even tho it was rejected the core team agreed it was something worth discussing and that improvements on the language (Never being a true <a href="https://alejandromp.com/blog/hole-driven-development-swift-fatalerror/">bototm type</a>) could offer alternative better solutions.</p><p>I was never interested in that operator since I barely want to "die" when working with optionals. And when I do <code>!</code> is good enough for me. But what I want often is to throw an error if the optional is nil. Conversations about this also started a while back, <a href="https://forums.swift.org/t/unwrap-or-throw-make-the-safe-choice-easier/14453">Unwrap or Throw - Make the Safe Choice Easier</a> and <a href="https://forums.swift.org/t/introducing-an-unwrap-or-throw-operator/51905">Introducing an “Unwrap or Throw” operator</a>.</p><p>If you read all those conversations, you see that there are multiple ways of solving the same problem and everybody has different opinions and needs.</p><p>What I want to share today results from my gathering of the solutions mentioned over the years and taking the ones I like the most. I've been using this code in my projects for years, so this is maybe not how Swift will solve it eventually, but it's the way I prefer to solve it.</p><h2 id="my-desired-solution">My Desired solution</h2><p>What <a href="https://forums.swift.org/t/introducing-an-unwrap-or-throw-operator/51905/19">I want</a> is to be able to use the existing tools in the language in all the ways I need. That is, use the nil-coalescing operator<code>??</code> but instead of giving a default value, throw an error or even crash.</p><p>That translates to code that should look like:</p><pre><code><span class="splash-keyword">try</span> optional ?? <span class="splash-call">throw</span>(<span class="splash-type">Error</span>())
optional ?? <span class="splash-call">fatalError</span>(<span class="splash-string">"fancy message"</span>)
</code></pre><p>I don't think new operators are needed. The <code>??</code> already provides the semantic definition that we need: unwrap the optional on the left and if it's nil use whatever there is on the right. Usually the right side will have a default value, but it doesn't have to be always like that!</p><h3>Coalescing with <code>raise</code></h3><p>The problem is that if we try to use <code>throw</code> on the right side, we will find a compiler error. That's because Swift's <code>throw</code> is not an expression, so we can't use it in this way.</p><p>We can make a very simple function that throws the given error, call it <code>raise</code>. It’s a very simple function, but it makes it possible to throw errors in places where an expression is needed.</p><pre><code><span class="splash-keyword">try</span> <span class="splash-call">someWork</span>() ?? <span class="splash-call">raise</span>(<span class="splash-type">YourError</span>())
</code></pre><p>Just with this function, you can get very close to the ideal syntax of an "unwrap or throw" operator. Some will even prefer this to the next alternatives, since it doesn't introduce any new operator overloads into the language. This is the solution with less impact.</p><h3>Coalescing with <code>??</code></h3><p>But if you want to have a more succinct syntax, you can overload the coalescing operator. With it, there is no need for the <code>raise</code> function.</p><pre><code><span class="splash-keyword">try</span> <span class="splash-call">someWork</span>() ?? <span class="splash-type">YourError</span>()
</code></pre><p>I think that's all I wanted! ^^</p><h3>Method <code>unwrapOrThrow</code></h3><p>That said, some people don't love overloading operators or even abusing them in this way. For those, it's quite easy to just make an extension in Optional that gives this functionality a proper name: <code>unwrapOrThrow</code>.</p><pre><code><span class="splash-keyword">try</span> <span class="splash-call">someWork</span>().<span class="splash-call">unwrapOrThrow</span>(<span class="splash-type">YourError</span>())
</code></pre><p>You can even make a default error <code>UnwrapError</code>. With that, you can call the method without specifying a custom error.</p><pre><code><span class="splash-keyword">try</span> <span class="splash-call">someWork</span>().<span class="splash-call">unwrapOrThrow</span>()
</code></pre><h3>☠️ Unwrap or die</h3><p>As I said, the "unwrap or die" is not something I ever used. But with the setup we have so far is quite easy to retrofit this functionality. All the same techniques that we use for throwing can apply to <code>fatalError</code>.</p><p>Why fatal error? The common complain about <code>!</code> is that it doesn't give a reason when it crashes. It's like a <code>fatalError()</code>. But if we use <code>fatalError("reason for crashing")</code> we can attach a reason explaining why we thought the optional should have had some value and never nil.</p><p>We can start by just using the <code>raise</code> function.</p><pre><code><span class="splash-keyword">try</span> <span class="splash-call">someWork</span>() ?? <span class="splash-call">raise</span>(<span class="splash-call">fatalError</span>(<span class="splash-string">"reason for crashing"</span>))
</code></pre><p>This works but the compiler will show a warning on this line: <code>Will never be executed</code> . That's because the compiler detects that the raise function itself will never be executed.</p><p>Instead, we can overload <code>??</code> to accept a <code>Never</code> on the right side.</p><pre><code><span class="splash-keyword">try</span> <span class="splash-call">someWork</span>() ?? <span class="splash-call">fatalError</span>(<span class="splash-string">"reason for crashing"</span>)
</code></pre><p>Of course, if you prefer to use the method, it's even easier since it just works.</p><pre><code><span class="splash-keyword">try</span> <span class="splash-call">someWork</span>().<span class="splash-call">unwrapOrThrow</span>(<span class="splash-call">fatalError</span>(<span class="splash-string">"reason for crashing"</span>))
</code></pre><h3>Unwrap or reason?</h3><p>A common request is to have a way to unwrap or pass a String directly for the reason of the crash, instead of using a <code>fatalError(_:)</code>. I barely use the unwrap or die technique, so I don't have the need for further convenience.</p><p>If you want to do that, then you start needed other operators and functions since otherwise you make things ambiguous when the optional contains a String. Is the right String a reason to crash or just a safe default?</p><p>I will leave this as an exercise to the reader.</p><h2 id="wrapping-it-all-together">Wrapping it all together</h2><p>After all this analysis, and years of using some of these solutions, I decided to open source a small Swift package with these conveniences: <a href="https://github.com/alexito4/UnwrapOrThrow">UnwrapOrThrow</a>.</p><p>Unwrap Or Throw (or Die!): 🎁 Unwrap an optional or throw an error if nil (or crash the program).</p><p>There are other solutions out there, but I liked none of them, so this is just yet another one. But is the one I like ^^.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/experimenting-with-a-query-resolver-system</guid><title>Experimenting with a Query Resolver System</title><description></description><link>https://alejandromp.com/blog/experimenting-with-a-query-resolver-system</link><pubDate>Sun, 2 Jan 2022 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>Sometimes some topic gets in my head and doesn't leave until I've gone far enough to satisfy my curiosity. Usually this ends up with me spending days writing some code that just goes to the trash once I'm done with it, but today I decided to share a bit of one of these rabbit holes I went down to.</p><h2 id="what-is-this-even-called?">What is this even called?</h2><p>The weird thing is that I'm not sure what I was trying to do is even called, because to be honest, I'm not even sure what I was trying to do... Is this what it feels to do R&amp;D?</p><p>I think that watching <a href="https://twitter.com/Jonathan_Blow">Jonathan Blow</a> <a href="https://alejandromp.com/tags/jai/">Jai</a> livestreams was what planted the seed. In some of those streams, he talked about how the compiler it's like a game loop that keeps trying to resolve dependencies. This allows the language to be very flexible with declaration order. As long as the information is there, it will eventually solve all the declarations. Or that's what I understood ^^ In my mind, this spawned thoughts about "query resolvers".</p><blockquote><p>At the time of writing this there is no website for Jai so the only knowledge I have is from watching Jon on stream. And I never remember in which one he talked about this topic ^^'</p></blockquote><p>What I wanted to work with was a system where every time there was a query, the answer would come eventually, even if it was not immediately there. The premise is simple, but without a proper framework, it seems quite hard to work with. It's not the usual way of working. What you typically would do is to check in a Dictionary and if the answer is not there, well... bail out. The "try again later" is the tricky part, and I wanted to find a framework for it.</p><p>I'm sure the Jai compiler implements a delightful way of doing it that's very performant (otherwise they couldn't get those below-second compilation times!). But I don't know what I'm doing here and I just wanted to have fun! And play more with <a href="https://alejandromp.com/tags/concurrency/">Swift Concurrency</a>!</p><p>After doing some research, I saw some examples of what I was thinking about, or at least close to it.</p><p>There is a concept called <strong>incremental computation</strong>, see this Rust library <a href="https://github.com/salsa-rs/salsa">Salsa</a> as an example. I'm not exactly sure if it's what I was looking for or not, but seems related. What is not clear to me is if this system solves the "eventually consistent" part of what I was looking for, instead it seems focused on <em>memoizing</em> the results of operations to reuse them, ideal for incremental compilation!</p><p>Talking about compilers, the topic of <a href="https://ollef.github.io/blog/posts/query-based-compilers.html">query-based compiler architectures</a> is a very interesting read. I found out that Rust has a <a href="https://rustc-dev-guide.rust-lang.org/query.html">demand-driven compilation system</a> (<a href="https://github.com/nikomatsakis/rustc-on-demand-incremental-design-doc/blob/master/0000-rustc-on-demand-and-incremental.md">see the docs</a>) and even Swift seems to be moving in this direction with its <a href="https://github.com/apple/swift/blob/main/docs/RequestEvaluator.md">request-evaluator</a> system.</p><p>The good thing about these rabbit holes is that even if I get nothing useful, I definitely learned a ton of interesting things along the way!</p><h2 id="example">Example</h2><p>Let's visualize a bit what kind of problem I was trying to solve with one example I've been playing with. Imagine a toy system of files where each file can contain some <em>text</em>, <em>imports</em> (other files), declarations, and usages (of these declarations).</p><pre><code>[
    <span class="splash-string">"main"</span>: <span class="splash-type">File</span>(contents: [
        .<span class="splash-call">text</span>(<span class="splash-string">"Start of Main"</span>),
        .<span class="splash-call">usage</span>(<span class="splash-string">"A"</span>),
        .<span class="splash-call">usage</span>(<span class="splash-string">"B"</span>),
        .<span class="splash-call">import</span>(<span class="splash-string">"other"</span>),
    ]),
    <span class="splash-string">"other"</span>: .<span class="splash-keyword">init</span>(contents: [
        .<span class="splash-call">text</span>(<span class="splash-string">"Other file."</span>),
        .<span class="splash-call">import</span>(<span class="splash-string">"types"</span>),
    ]),
    <span class="splash-string">"types"</span>: .<span class="splash-keyword">init</span>(contents: [
        .<span class="splash-call">text</span>(<span class="splash-string">"Declaring types:"</span>),
        .<span class="splash-call">declaration</span>(<span class="splash-string">"A"</span>, <span class="splash-string">"Amazing"</span>),
        .<span class="splash-call">declaration</span>(<span class="splash-string">"B"</span>, <span class="splash-string">"Burr!"</span>),
    ]),
]
</code></pre><p>You can see how the <em>main</em> file uses <code>A</code> and <code>B</code> before seeing their declaration. The declaration comes from a chain of imports. The goal then was to code a system that could get the final output (concatenating the strings) of this example without having to keep any state or order dependent code.</p><h2 id="developing-prototypes">Developing Prototypes</h2><p>I started prototyping a Query Resolver where each query would perform a piece of computation. Pretty quickly, I found that the tricky part was how to pause the program when a query was still pending.</p><p>My first approach was to follow a "game loop" like system where on each iteration queries could be added, or answers from it could be obtained. This got quite far, but it had some problems. The loop had to be careful with the order of the queries because if the same query was executed twice before another had responded the system could end up adding more queries ad infinitum ^^ This can of course be solved but the big issue was the usage side since the code was not very nice.</p><pre><code><span class="splash-keyword">func</span> resolve() {
  <span class="splash-keyword">if</span> <span class="splash-comment">// check if the answer you are looking for exists
    // do what you want...</span>
  <span class="splash-keyword">else</span>
    <span class="splash-comment">// enqueue the query that will get you this...</span>
}
</code></pre><p>This is a literal translation of the "try again later" style. But it got tiresome quickly. Plus, now that we have async await in Swift... wouldn't that help? <code>await</code> is literally a way to pause a function until it gets an answer. So I quickly jumped on that!</p><p>That took me down the path of trying how you can pause functions until some data exists. Ultimately, the surface area of async/await doesn't offer low level APIs to control the coroutines easily. <code>Task</code> has a <code>yield()</code> but that doesn't help a lot in this scenario, especially if it's in a hot loop. I eventually end up realising how the <em>continuation</em> API is what I was looking for!</p><p>With a continuation, you can <code>await</code> on a function call and resume it later when you are ready for it. It took me a bit to see how to use it to solve this, since the most common usage of them is to convert from a callback based API:</p><pre><code><span class="splash-keyword">await</span> <span class="splash-call">withCheckedContinuation</span> { continuation <span class="splash-keyword">in</span>
    <span class="splash-call">callbackBasedFunction</span>(onCompletioin: {
      continuation.<span class="splash-property">resume</span>...
    })
}
</code></pre><p>But in this case there are no callbacks, it was just data stored in a cache (Dictionary) that eventually shows up. The solution is to keep around the continuation, but that's easier said than done. Eventually I ended up making a small <code>AsyncChannel</code> type that took care of that. Read more here <a href="https://alejandromp.com/blog/building-a-channel-with-swift-concurrency-continuations">Building a Channel with Swift Concurrency Continuations</a>.</p><p>With that piece solved, implementing the Resolver was quite straightforward.</p><blockquote><p>One independent piece of the Resolver is the <code>AsyncStorage</code> type. It's the core part of the system that uses <code>AsyncChannel</code> to await for the data to be in the Dictionary. It may be useful for other scenarios.</p></blockquote><h2 id="usage">Usage</h2><p>The basic idea is to represent computations with queries that have a key associated:</p><pre><code><span class="splash-keyword">struct</span> ProcessFile: <span class="splash-type">Query</span> {
    <span class="splash-keyword">var</span> key: <span class="splash-type">String</span> { fileName }
    <span class="splash-keyword">let</span> fileName: <span class="splash-type">String</span>
    <span class="splash-keyword">func</span> resolve(<span class="splash-keyword">_</span> resolver: <span class="splash-type">AsyncResolver</span>) <span class="splash-keyword">async throws</span> {
        <span class="splash-keyword">let</span> contents = <span class="splash-keyword">try</span> fs.<span class="splash-call">readFile</span>(fileName)
        <span class="splash-keyword">let</span> textParts: [<span class="splash-type">String</span>] = <span class="splash-keyword">await</span> contents.<span class="splash-property">content</span>.<span class="splash-call">concurrentMap</span> { c <span class="splash-keyword">in</span>
            ...
            <span class="splash-keyword">let</span> content = <span class="splash-keyword">await</span> resolver.<span class="splash-call">query</span>(
                <span class="splash-type">ProcessFile</span>(fileName: dependency),
            )
        }
        <span class="splash-keyword">await</span> resolver.<span class="splash-call">save</span>(textParts.<span class="splash-call">joined</span>(separator: <span class="splash-string">" || "</span>), for: key)
    }
}
</code></pre><p>You can see some points on the example:</p><ol><li>The <code>key: String</code> identifies this query. The resolver uses this to return a previously computed output of the same query if available. <em>It could be used for more things but I didn't get that far...</em></li><li>The <code>resolve</code> function is where you implement the computation.</li><li><code>await resolver.query(...)</code> will add the query to the system and wait for its resolution.</li><li><code> await resolver.save(..., for: key)</code> saves the result of the computation.</li><li>There is a <code>await resolver.addQuery(...)</code> that just adds the query without waiting for its resolution. In fact, <code>query(...)</code> is a combination of both <code>addQuery</code> and <code>read</code>.</li></ol><p>The important bit is to understand that a query doesn't have to know how to get the answers for the entire chain. As long as some query in the system has the answer, it will work.</p><p>When the result of a computation is saved, every other query in the system that depended on that key would get resolved and computation will continue.</p><p>Another important piece here is the <code>concurrentMap</code>. If a computation has dependencies in other queries, it should try to request the results concurrently. This unlocks the power of resolving queries out of order. If you ask for otherwise independent computations in series, you won't get much benefit.</p><h2 id="function-like-syntax">Function like syntax</h2><p>Having to do <code>query(Query)</code> feels a bit cumbersome. Following the goal of making this as "normal" as possible, I ended up wrapping these calls in functions. This allowed for a much more pleasant syntax:</p><pre><code><span class="splash-keyword">let</span> result = <span class="splash-keyword">await</span> resolver.<span class="splash-call">processFile</span>(name: <span class="splash-string">"main"</span>)
</code></pre><p>From the usage side, the only unusual thing is the resolver. The rest seems like a normal async call. You still need to reach for the direct calls for when you want to add a query without waiting for the result, or when you just want to provide results to the system. I'm sure better APIs could be built around that.</p><blockquote><p><a href="https://github.com/salsa-rs/salsa">Salsa</a> uses Rust's powerful meta-programming capabilities to create these functions for you.</p></blockquote><h2 id="further-improvements">Further improvements</h2><p>So the system works, at least for the toy examples I tried 😂 But if this was a real project there would be plenty of improvements to make. For example, cycles are not detected, so if you add a cycle in the data, the program will halt for ever. I <em>think</em> that this is usually solved by keeping track of which queries add other queries.</p><p>I recommend you to read the linked articles above if you are curious what a proper system is capable of.</p><h2 id="curiosity-satisfied!">Curiosity satisfied!</h2><p>So that's all! You can check the code on the <a href="https://github.com/alexito4/QueryResolverSystem">Query Resolver System repository</a>, including the <a href="https://github.com/alexito4/QueryResolverSystem/tree/main/QueryResolverPrototypes">prototypes</a>. Don't expect high-quality code ^^'</p><p>I love getting lost in these experiments and this one got quite far. I didn't expect I could follow through it until the point where I was satisfied with the usage of it and it worked! But I did ^^. I would still love to work on detecting cycles, but I have other interesting things on the to-do list, so I will just leave it here for now.</p><p>If you have gotten this far, thank you! 🙏 I hope you found this experiment interesting.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/building-a-channel-with-swift-concurrency-continuations</guid><title>Building a Channel with Swift Concurrency Continuations</title><description></description><link>https://alejandromp.com/blog/building-a-channel-with-swift-concurrency-continuations</link><pubDate>Sat, 25 Dec 2021 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>Following <a href="https://www.youtube.com/watch?v=3SX7u5l3CGA">Structured Concurrency</a> was one of the best decisions Swift could have made when introducing concurrency into the language. The impact of that decision on all the code written with concurrency in mind can't be underestimated.</p><p>But the other day I needed a tool that, while allowing me to stay in a structured concurrency system, it internally could leverage unstructured techniques. The exact situation is not really relevant besides understanding that I have a system that needs to read a value from some storage with the quirk that the value may not be there yet and thus it should wait for it.</p><pre><code><span class="splash-keyword">let</span> value = <span class="splash-keyword">await</span> storage.<span class="splash-call">value</span>(for: key)
</code></pre><p>I want to follow the structured concurrency principles on the reading side. But we can’t implement this without escaping the confines of this structure. That's because reading the value is not what starts the work of generating it. Instead, it’s another independent subsystem, at another time, that will end up saving the value into the storage.</p><p>To accomplish this, we need a way to pause the execution and resume it when another system tells us the value is available.</p><blockquote><p>Consider this a proof of concept and an excuse for me to dig deeper into these topics. You can <a href="https://github.com/alexito4/AsyncChannel">read the source</a> but if you really need a solution like this for production, I recommend you to review it carefully and maybe look for other tools.</p></blockquote><h2 id="discarded-solutions">Discarded solutions</h2><ol><li>Future/Promise: I want to stay as much as possible in Swift Structured Concurrency, so this is a no go, although the Channel we're implementing looks a lot like a Future.</li><li>Combine <code>PassthroughSubject</code>: this is more akin to what we're looking for. A way to pass values from one place to another. But I want to use the tools in the language, not an Apple-only framework. Also, I just want to pass one value.</li><li><code>Task</code>: Nope! People still treat this as a Future and I have a lot to say against that (<em>I should have written already about this 😢 </em>). Suffices to say that it won't work because you need to feed data from the outside and Task doesn't have an API for that, because it shouldn't!</li><li><code>AsyncStream</code>: we could use this since it is using just the language tools. But you will still need to write something to keep its continuations (which are slightly different that the ones we're using). Also, I just want to pass one value so this is an overkill.</li></ol><h2 id="building-the-asyncchannel">Building the AsyncChannel</h2><p>Now that we understand our problem, let's build our own solution! I call it <code>AsyncChannel</code>, although is probably not the best name for it 😂</p><blockquote><p>The following code shows a simplified implementation for illustration purposes. Handling cancellation adds a bunch of verbosity so I left it out of the article. You can read the <a href="https://github.com/alexito4/AsyncChannel">full source</a> for more details.</p></blockquote><p>Let's start by looking at what we eventually need:</p><pre><code><span class="splash-comment">// In one side...</span>
<span class="splash-keyword">let</span> value = <span class="splash-keyword">try await</span> channel.<span class="splash-property">value</span>

<span class="splash-comment">// In the other side...</span>
channel.<span class="splash-call">send</span>(<span class="splash-number">42</span>)
</code></pre><p>From this usage, we can already see a couple of important details:</p><ol><li>We need to be able to await for getting the value (the whole point of this!)</li><li>We need to be able to send a value without awaiting (we don't want to force other systems to be async)</li></ol><p>With this in mind, let's create a <code>class</code> with the methods we need:</p><pre><code><span class="splash-keyword">final class</span> AsyncChannel&lt;T&gt; {
    <span class="splash-keyword">var</span> value: <span class="splash-type">T</span> {
        <span class="splash-keyword">get async</span> {
            ...
        }
    }

    <span class="splash-keyword">func</span> send(<span class="splash-keyword">_</span> v: <span class="splash-type">T</span>) {
        ...
    }
}
</code></pre><p>To make sure we avoid concurrency problems, we will put the bulk of the implementation in an internal type, called <code>Buffer</code>, that will be an <code>Actor</code>. In this way, we can keep a simple class interface to the outside but ensure we don't have concurrency issues.</p><p>To understand what the buffer will do, first let's look at a simplified implementation for the <code>value</code> computed property.</p><pre><code><span class="splash-keyword">var</span> value: <span class="splash-type">T</span> {
    <span class="splash-keyword">get async</span> {
        <span class="splash-keyword">await</span> <span class="splash-call">withCheckedContinuation</span> { continuation <span class="splash-keyword">in</span>
            <span class="splash-type">Task</span> {
                <span class="splash-keyword">await</span> buffer.<span class="splash-call">addContinuationIfNeeded</span>(continuation, id)
            }
        }
    }
}
</code></pre><p>Here is the main point of the solution. The Continuation APIs! You can think of them as a hook into the concurrency runtime, a sort of low-level tool that lets you control the execution of a function. With them, you can pause the execution of the function while having control of when resumption happens. The common usage of these APIs involved calling a callback based function and resuming on its completion, but here we keep hold of the continuation, passing it to our buffer which will resume it at a later point.</p><blockquote><p>A proper implementation should handle cancellation of the current Task to make sure the continuations are released properly. You can see how the <a href="https://github.com/alexito4/AsyncChannel">full source</a> uses a <code>UUID</code> to identify each <code>value</code> call and makes sure to cancel it appropriately.</p></blockquote><p>The <code>send</code> method is very simple since it just forwards the call to the internal buffer:</p><pre><code><span class="splash-keyword">func</span> send(<span class="splash-keyword">_</span> v: <span class="splash-type">T</span>) {
    <span class="splash-type">Task</span> {
        <span class="splash-keyword">await</span> buffer.<span class="splash-call">send</span>(v)
    }
}
</code></pre><p>Since it’s calling an actor isolated method, we need to perform the call asynchronously. It's important to note that the method itself pretends to be synchronous so we don't pollute systems that don't need to be async.</p><p>The buffer implementation is not that much more complicated. It keeps the current value and a list of continuations and provides a safe interface to managing them.</p><p>The <code>addContinuationIfNeeded</code> checks if the value is already there and resumes the continuation immediately. If it's not there yet, it keeps the continuation around to resume it later.</p><pre><code><span class="splash-keyword">func</span> addContinuationIfNeeded(<span class="splash-keyword">_</span> continuation: <span class="splash-type">CheckedContinuation</span>&lt;<span class="splash-type">T</span>&gt;) {
    <span class="splash-keyword">if let</span> value = state.<span class="splash-property">value</span> {
        continuation.<span class="splash-call">resume</span>(returning: value)
        <span class="splash-keyword">return</span>
    }

    continuations.<span class="splash-call">append</span>(continuation)
}
</code></pre><p>Finally, the <code>send</code> method saves the value and resumes and releases all the continuations:</p><pre><code><span class="splash-keyword">func</span> send(<span class="splash-keyword">_</span> v: <span class="splash-type">T</span>) {
    value = v
    continuations.<span class="splash-property">values</span>.<span class="splash-call">forEach</span> { $0.<span class="splash-call">resume</span>(returning: v) }
    continuations.<span class="splash-call">removeAll</span>()
}
</code></pre><p>And that’s most of it. The <a href="https://github.com/alexito4/AsyncChannel">implementation</a> performs extra checks to ensure the channel doesn’t already have a value, or it’s cancelled.</p><h2 id="conclusions">Conclusions</h2><p>As you can see, the trick relies on keeping the continuations around and resume them later. The complicated part is managing the continuations themselves since they are a delicate object to manage manually.</p><p>You need to resume the continuations only once. And if you forget to resume them at all, the piece of code that is waiting for them will hang. And you also need to make sure they are released when no longer needed, especially when Tasks are cancelled, otherwise you may leak resources from other Tasks. That's why you always need to handle cancellation properly.</p><p>Think of them as a low level implementation of concurrency. They give you great power and you know what happens with great power ;)</p><p>You can read the <a href="https://github.com/alexito4/AsyncChannel">full source code</a> to see how the cancellation is handled and how the continuations are managed. I will advise against running this code in production since it's just a proof of concept for a very specific need I had.</p><p>I hope you found this useful and learned something new!</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/ios-app-architecture-in-2022</guid><title>iOS App Architecture in 2022</title><description></description><link>https://alejandromp.com/blog/ios-app-architecture-in-2022</link><pubDate>Wed, 15 Dec 2021 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>Since we're about to start a new year, I thought it would be good to write about what I think it's the best approach for building iOS apps nowadays.</p><p>For the past couple of years the iOS landscape has changed dramatically and I finally feel like we're in a proper position to enjoy making apps again, something I didn't feel since the early days of the platform.</p><p>In this article, I want to describe what I think is the best way to build iOS apps. This ranges from how to make UIs to how to structure the overall project, of course touching on the subject of architecture.</p><p>These ideas come out directly from my experience over the years building and maintaining applications. Everything I'm suggesting here are things I've tried myself.</p><blockquote><p>As a side note, pretty much all these recommendations apply as well to Android development. I've successfully deployed these ideas to both platforms with excellent results. Some things are trickier in Android due to do nature of the frameworks, but they are totally doable and very desirable.</p></blockquote><p>Suffices to say that I'm not a guru that writes this to spread a dogma. This is just my opinion, my recommendation born from my experience. If there is one thing that everybody needs to learn is to analyse things from themselves, so don't follow this blindly, heck, follow nothing blindly!</p><p>Another thing I want to address is the first reaction some will have about this tech stack. If you think that I have decided this tech stack because these are the new shiny things, I encourage you to reconsider and look past that. I'm not one to jump on everything new and compromise the future of my projects. I don't think any good engineering lead should do that. But I'm also not going to pretend the world is not moving forward. When I see that something new I tried for myself to make sure I understand the tradeoffs that it proposes.</p><p><strong>Table of Contents:</strong></p><ol><li><a href="#goals">Goals</a></li><li><a href="#modularised-structure">Modularised structure</a></li><li><a href="#ui">UI</a></li><li><a href="#architecture">Architecture</a></li><li><a href="#concurrency">Concurrency</a></li><li><a href="#go-first-party">Go first party</a></li><li><a href="#conclusion">Conclusion</a></li></ol><h2 id="goals">Goals</h2><p>Before talking about the different points that make my ideal architecture is important to have some goals in mind. We need to have a clear solution space that we can analyse our decisions on.</p><p>One of the crucial points to get right is <strong>developer experience</strong> with fast <strong>iteration cycles</strong>. In a rapid development environment, these two characteristics help a lot to keep up with new product features in a timely manner.</p><p>Another very important aspect is the <strong>maintainability</strong> and evolution of our codebase. Whatever system we use it needs to allow us to change code rapidly and, most importantly, get rid of it when it’s no longer required. I directly relate this to the desire to facilitate the <strong>independent evolution</strong> of the different parts of the app and make it simple to have <strong>system integration</strong>.</p><p>One thing to keep in mind too is how these decisions affect <strong>hiring</strong>. Most people will very soon want to work only on modern tech stacks and the onboarding ramp is something that we need to pay attention to.</p><p>With these goals in mind, let's look at the specific points that make a desirable architecture in today's world.</p><h2 id="modularised-structure">Modularised structure</h2><p>A key part of the tech stack is having a fully modularised application structure. I'm not talking about having files in different folders, but about enforcing strict boundaries between the different systems in your application.</p><blockquote><p>This has never been easier in iOS! I remember having different project frameworks years ago, hacking Xcode to support them on iOS before any official support. It was crazy pants. But nowadays the Swift Package Manager makes this trivial.</p></blockquote><p>The aim is to have the code separated in multiple small independent packages that are combined by an “application”. This facilitates the <strong>maintainability</strong> of each package and their <strong>independent evolution</strong>. Having small packages and a clean dependency graph also improves compile times and unlocks a bunch of improvements in <strong>iteration cycles</strong> and <strong>developer experience.</strong></p><p>The important thing to understand is that we're not just talking about modularising helpers or utilities. The goal here is to modularise the distinct features of your app. That, in turn, will force you to think about your structure and modularise the rest.</p><blockquote><p>Many of the ideas you will read in this section have been directly inspired by <a href="https://www.pointfree.co/subscribe/personal?ref=4Fj20c5I">Pointfree</a>. Make sure you check it out!</p></blockquote><p>An idealistic goal is to have your Xcode project just have the app entry point and immedatly start the code from a feature package. Yes, this makes 99% of your code live in Swift Packages! 🎉</p><h3>The Mindset</h3><p>For me, one of the most important aspects of adopting modularisation is the change of mindset that forces on the developers. It’s very important that you get into the mindset of proper modularization. This will break some existing preconceptions that you have about relationships in your code, but it is crucial to embrace them in order to get all the benefits of this approach.</p><p>Simple dependency injection and inversion of control becomes crucial. Your package may need to do some work, and it may be tempting to put the code directly in the same package. But you need to have clear responsibilities for each package and know <strong>where the walls need to be built</strong>. Another way of looking at it is to not just think about the dependencies and the graph (there are always ways to force it to do what you want) but about <strong>the knowledge (or lack of thereof) that each package should have</strong>.</p><blockquote><p>I use physical metaphors often when describing these concepts. I found they help visualise where the limits of each module are. Everybody knows you can't cross through walls unless there is a door, or what's the difference between your home and the outside. I recommend you to use the same when you are trying to explain some of these concepts.</p></blockquote><p>A very common example is when a package needs something that doesn’t really need to be known to it. It must provide callbacks or customisation points to the outside world. Its responsibility is just to call those hooks - not to know what happens in them. But if the packages just calls back (delegates) to the outside world to do this work, who is then doing the actual work?</p><p>That’s where the hierarchy comes in. When a communication needs to be established between two otherwise independent packages, a <strong>third package</strong> is introduced to depend on both and provide the communication channel between them (see example below). Usually this package ends up being the App target, which will import all features and link them together appropriately. But sometimes it may be beneficial to make these “parent” packages to bring other kinds of functionality together.</p><blockquote><p>This solution has come up so frequently and can solve so many issues that I ended up calling "The third package rule". Making a third package that pulls together two other packages is always a valid solution. Nonetheless you should try to find other solutions to avoid an explosion of this type of package.</p></blockquote><h3>Example</h3><p>Imagine that feature A may want to open a screen that lives in feature B. It may be tempting to make A depend on B, after all you want to open its screen. But that’s the wrong mindset!</p><p>Feature A shouldn’t know anything about what happens outside itself. It shouldn’t know anything about that other screen, since is part of B. It should just provide a callback, a hook, to let somebody else decide what to do. Who is that somebody else? A third <em>parent</em> package that will pull together feature A and B, usually the App.</p><p>This third package, C, will depend on both A and B. It will hook into A’s callback, and when that callback executes, it will open B’s screen. A and B know nothing about each other. C is the one connecting them together. <em>It’s like an</em> <a href="https://www.google.es/search?q=switchboard+operator&sxsrf=AOaemvJ-jgvbWb8R-uoa976HlkD_GNMhGg:1636369924035&source=lnms&tbm=isch&sa=X&ved=2ahUKEwi-zquA0Yj0AhWE8OAKHf-tCQkQ_AUoAXoECAEQAw&biw=1440&bih=800&dpr=2"><em>old telephone operator</em></a><em>.</em></p><h3>The hierarchy</h3><p>Having multiple modules in a project is very beneficial, but can quickly get out of hand if they depend on each other. When that happens, you just moved the spaghetti mess of your code up one level. That's why I designed some guidelines (rules for my team ^^) to help facilitate the decisions when finding these dependencies.</p><p>It is important to realise that not all modules are equal. Even tho all of them just have some code their purpose is different and they take part in different ways on the dependency graph of the project.</p><img src="https://alejandromp.com/blog/ios-app-architecture-in-2022/Modules structure hierarchy.png" alt="Modules structure hierarchy"/><p>The diagram tries to illustrate the different levels in the modules hierarchy.</p><p><strong>Apps</strong> are the topmost modules. This is where your <strong>main app</strong> belongs, but also other "feature preview apps" or other targets like widgets and other system integrations. They <strong>Can import</strong> any other module but <strong>Can’t be imported</strong> by any other module.</p><p><strong>Features</strong> are the modules that represent the different features of your app (user profile, feed, ...). This is the most crucial aspect of the graph, and the one that benefits most from this approach. It's important to remember that they can't depend on other modules at the same level or above. They <strong>Can only import non-feature modules.</strong></p><p><strong>Dependencies</strong> are other <em>library like</em> modules. Things like API layers or other subsystems. I like to think about this as my own "first party libraries", so they are not necessarily third party packages. One important detail is that if they depend on heavy third-party libraries, you should break them down in interface and implementation. And if you need to use third-party libraries directly on features, they should receive the same treatment. The <strong>Interface</strong> module will just contain the interface and dependencies needed. This is the module that will be imported on feature modules. The <strong>Live</strong> module will contain a live implementation of the dependency. This will only be imported by final apps (top layer). This has the benefit of being able to create fake implementations very easily, directly in the interface module or on their own one if required.</p><p>The bottom layer is what I like to call <strong>Foundation</strong> modules. These are special libraries that are at the bottom of the hierarchy and provide the foundational functionality needed everywhere. They <strong>Can’t import</strong> any other module and <strong>Can be imported</strong> by any other module. This one is sometimes hard to grasp since it seems like a lot of things could go here, and is quite the opposite. Usually I just end up having a couple of modules at this layer: Foundation extensions and common UI building blocks. It's important to realise that if something is needed in a lot of places but has dependencies or specific requirements, that’s not a foundational library. Don’t be afraid of making as many specific library modules as needed!</p><h3>Other app modules</h3><p>Having this modularisation gives you flexibility to have apps other than your main product. For example, feature preview applications are very useful for rapid development on real devices of a specific feature. They avoid having to go through your entire navigation every time.</p><p>But you can think about Playgrounds as another kind of application. It's very useful to have playgrounds to play with some business logic or some subsystem of the application without having to deal with everything else. For example, I made a small playground to play with API calls that has turned out to be quite useful! You could even make CLI applications that reuse your business logic!</p><h2 id="ui">UI</h2><p>It won't come as a surprise that I think a modern iOS app should be using a modern UI framework like SwiftUI. Not because is modern, but because a <strong>declarative UI framework</strong> has real benefits.</p><p>It's not because SwiftUI is the new shiny thing (is not even new anymore 😂 ) but because I truly believe that a declarative UI system reduces a lot of the friction and <strong>maintenance</strong> burden that you get from more classical imperative systems (UIKit). As you may know, I've been <a href="https://alejandromp.com/tags/wwdc/">wishing</a> for a declarative UI framework on Apple platforms for years before SwiftUI was announced.</p><blockquote><p>My <a href="https://www.youtube.com/watch?v=p8q5ANt-22o&t=681s">video about the announcement</a> is still my most watched video, not because of its quality but because I was so excited about that I published it in record time and was the only video about SwiftUI in YouTube for hours.</p></blockquote><p>SwiftUI directly helps with <strong>iteration cycles</strong>, not only thanks to the Xcode Preview system, but because changing things in views is way faster than with imperative code. The fact that the only thing you write are mappings from data to view makes working with UI as easy as manipulating data. The beauty of which has been lost through the years. I know SwiftUI comes with a change of mentality that not everybody is comfortable with, but it's totally worth it.</p><blockquote><p>I won't elaborate more about the reasons to use SwiftUI here because I sound like a broken record 😆 Feel free to read some of my posts on <a href="https://alejandromp.com/tags/swiftui/">#SwiftUI</a> or watch my <a href="https://www.youtube.com/playlist?list=PL2HXX-dkWqS1PeWo1e-NbHaXb8BV9BISF">SwiftUI playlist</a>.</p></blockquote><p>But I won't hide the fact that SwiftUI is still young and sometimes you need to fall back to UIKit. I just don’t consider that a tremendous problem! The integration works very well and thanks to the modularisation, you can provide APIs that the rest of the project uses without knowing that UIKit is still there, just like Apple does. The recommendation to my team is to be comfortable integrating UIKit, but try to avoid it like the plague.</p><p>I would also recommend that you keep under control the amount of factorization you do for your views. Coming from an OOP framework we feel like we should avoid DRY to the extreme, but composing views in a declarative framework is so easy that sometimes I much rather prefer duplicated code in conceptually different views than not tie them together too early for no reason. I like to delay that decision until it's clear that they are the same view but just with minor differences, and not force that into the code. Refactoring view code is so easy that I don't think is worth risking doing it too early.</p><h2 id="architecture">Architecture</h2><p>In terms of architecture, the decision is clear, a modular uni-directional data flow architecture is the desired choice. This type of architecture it's the most crucial aspect for an <strong>easy to understand</strong> and <strong>maintainable</strong> codebase.</p><p>The more classical approaches (MVC and even MVVM) can quickly become out of hand and hard to grasp. Is not immediately obvious where a change in the application's state happens or where it comes from. It feels to me like those architectures are tied to their OOP roots and show the same defects as that paradigm. Instead, a uni-directional data flow architecture benefits from some functional programming concepts that make things way more controllable and easy to understand.</p><p>I've seen the benefits of this approach in other ecosystems for years, but since it's quite a radical departure from what the iOS community is used to do I've never felt that we had a proper library for it. For years, I've been watching this space, and I always had issues with all the candidates so I have a judgemental eye and know what to ask. But then Pointfree started designing <a href="https://github.com/pointfreeco/swift-composable-architecture">The Composable Architecture</a> on their videos. At the start of every episode, I saw the same issues I always had with architectures like this, but by the end of the episode, they answered with brilliant solutions. That's something that never happened to me before! Seeing how everything fitted together so well, and not the fact that was new and shiny, was what made me a big fan of the library and <a href="https://alejandromp.com/blog/pointfree-composable-architecture-showcase/">started using</a> it even before it was released officially.</p><p>I don't want to make this post longer by elaborating on why the TCA is great, but let me give you a few pointers by touching on the different aspects of the architecture quickly:</p><ul><li>Having the <strong>State</strong> of your app (and UI!) in a plain struct makes it super clear why the app is showing what is showing in every moment. Makes it incredible <a href="https://www.youtube.com/watch?v=113bOxNHlUk">debuggable</a> and even <a href="https://www.youtube.com/watch?v=ASsjhyzwBR4">reproducible</a>.</li><li>Every single event that the user or other systems perform on the app is encapsulated in an <strong>Action</strong>. This means you can know every single event that the entire app reacts to.</li><li>Most systems fall apart when you start talking about dependencies. But the TCA comes with an integrated solution thanks to its <strong>Environment</strong>. Forget about using bulky dependency injection frameworks, the environment is just a plain struct with dependencies. It makes it incredibly easy to switch dependencies on test without having to rely on sub-classing or classical mocks that just cause issues.</li><li>In the same way that SwiftUI makes building UIs easier thanks to its declarative nature (Data -&gt; UI), the <strong>Reducer</strong> gives us similar benefits to our business logic. It's a <strong>pure function</strong> that lets us convert the state of the app based on what actions has received. Swift makes this incredibly nice thanks to <code>inout</code> because you feel like you are writing mutable code but you are not. Finally, the <strong>Effects</strong> are controlled so the purity of the function is kept intact.</li><li>The final piece is what brings everything together, the <strong>Store</strong>. It's the responsible for keeping the flow of data going and interpreting the managed effects that come out from your reducers. It's a part of the architecture that you barely touch but for me it's crucial because it follows the "interpreter pattern" that I've grown to love so much.</li></ul><blockquote><p>The importance of Swift on the beauty of this architecture can't be underestimated. Having so aproachable value types, that even give us mutable value semantics is incredible. But also more advanced features like KeyPaths make it possible to build elegant APIs. Swift is an amazing language and libraries like this make it very clear.</p></blockquote><p>You can see here the main bullet points of the architecture. But for me, the most important concept that sets this apart from any other architecture is the composability of the domains.</p><h3>Domain</h3><p>I use the word domain a lot when talking about features and the TCA because it defines a clear separation between different parts of the code. In my own words, a <strong>Domain</strong> refers to a specific area of the program that can be reasoned about independently. It can be as small or as big as necessary. For example, a “feed feature” is a domain for an entire feature, but the “list of posts” is the domain for just one screen, or part of. You can go even further and talk about the "post" domain, which represents a single row in the list. Is a useful word to use because it helps describe the structure of the code when we want to break down or compose domains.</p><p>The beauty of the TCA is in how easy it makes it to compose different domains. This translates into making it trivial to break down domains into smaller domains. Usually you have 1 domain per screen, but if the screen is too complex, or part of it is repeated in multiple places, you are free to break them down into its own domain and share it between the screens.</p><p>I like to classify these domains to facilitate the conversation:</p><ul><li><strong>Embedded</strong> domains are those that provide functionality by embedding it into your own domain. This is often what you do when composing different screens in a flow, or when separating a reusable piece of UI. This is particularly useful for navigation or to make a domain for each individual item in a list.</li><li><strong>Generic</strong> domains. Domains can be built to reuse generic functionality across the application, for example, the <a href="https://github.com/pointfreeco/swift-composable-architecture/blob/main/Examples/CaseStudies/SwiftUICaseStudies/04-HigherOrderReducers-ReusableFavoriting.swift">reusable favoriting case study</a>. These are often accomplished thanks to <em>high order reducers</em>, which represent the same concept as high order functions. In my mind, these generic domains come in two forms: <em>polluting</em> and <em>transparent</em> (not very good names I know).<ul><li><strong><em>Polluting</em></strong> generic domains are those where the types of the store changes. These happen when you need to include domain specific actions and state. They are very powerful but can complicate a bit the types you need to write.</li><li><strong><em>Transparent</em></strong> generic domains on the other hand are those that are made out of high order reducers that just add functionality without altering the types of the store. Things like <code>debug()</code>.</li></ul></li></ul><h3>The Feature level domain</h3><p>It's important to give a special mention to the domain that encompasses an entire feature. It's the domain that provides the public interface of the feature and all the other reducers and views are hidden internally. You can think of it as the entry point of a feature.</p><blockquote><p>Take a look at <a href="https://alejandromp.com/blog/observe-actions-in-the-composable-architecture/">Observe actions in The Composable Architecture</a> which provides a nice little tool to hook this feature domains with the rest of the application.</p></blockquote><h2 id="concurrency">Concurrency</h2><p>Concurrency is a big topic right now in the community since we finally got Swift Concurrency. It's a topic that I've been following for months and one for which I have <a href="https://alejandromp.com/tags/concurrency/">many things to say</a>. But for what relates to this post, I would just say that in a modern iOS app you should use Swift Concurrency as much as possible before looking at more complex alternatives. And if you really need to use a full-fledged FRP framework, I recommend you to stick with Combine instead of using a third party library.</p><p>My advice is that you really try to learn and embrace <a href="https://www.youtube.com/watch?v=3SX7u5l3CGA&t=1s">Structured Concurrency</a>. You may be tempted to follow the same patterns and techniques you are used to with FRP or Futures, but you will hurt your codebase and future maintainability if you do that.</p><p>Swift Concurrency is a game changer and something you should embrace fully. It will make all your async code more <strong>maintainable</strong>.</p><h2 id="go-first-party">Go first party</h2><p>Finally, I just want to touch a bit on the topic of dependencies. This is something that sets aside our ecosystem from others. We have a "first party" provider, Apple. The relation we have with them is not always perfect, but it's very wise to follow their recommendations as close as you can.</p><p>For many years we've had to look to outside libraries for things integral to how we code (things like RxSwift, other Databases or wrappers, etc) and tools (third party package managers). But nowadays I think the situation is much better and for many things you should choose to use a first party solution instead.</p><p>We've already seen how this approach fully embraces SPM and Swift Concurrency. But besides that I would also recommend sticking with vanilla Core Data (although <a href="https://github.com/groue/GRDB.swift">GRDB</a> is my preference). Don't confuse this with refusing to use any third party code (TCA is not first party after all!) but about realising that Apple frameworks have come along way and more often than not they provide the tools that you need. You just have to look closely ;)</p><h2 id="conclusion">Conclusion</h2><p>To summarise, in my opinion an iOS application in 2022 should:</p><ul><li>Be written in Swift (of course I didn't mention that because is obvious coming from me).</li><li>Be fully modularised project structure.</li><li>Use SwiftUI (a declarative UI framework).</li><li>Use a modern uni-directional data flow architecture that is composable (TCA).</li><li>Stick to system frameworks when possible.</li><li>Use all these points to improve the developer experience and iteration cycles.</li></ul><p>And these recommendations are not just empty words, but things that I've been actually putting into practice in the main application that my team maintains. An app with ~350k LOC that was born in 2013. I'm thrilled about how nice is to work with, but it's time to move it to modern times.</p><p>And here you have a couple of slides that I presented in our engineering gathering before ending the year. ^^ (as you can see, this system is followed by both platforms)</p><img src="https://alejandromp.com/blog/ios-app-architecture-in-2022/Highlights of the year.png" alt="Highlights of the year"/><img src="https://alejandromp.com/blog/ios-app-architecture-in-2022/New tech stack.png" alt="New tech stack"/>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/observe-actions-in-the-composable-architecture</guid><title>Observe actions in The Composable Architecture</title><description></description><link>https://alejandromp.com/blog/observe-actions-in-the-composable-architecture</link><pubDate>Fri, 3 Dec 2021 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>One of the beautiful things about Pointfree's Composable Architecture is how you can start using it on a smaller part of your app. It makes it very easy to improve a codebase without having to <em>stop the press</em>, which is something that I always require of any new technology.</p><p>One inconvenience is that the principal object of the architecture, the <code>Store</code>, doesn't have a way to observe the actions that it receives from the outside, the only one that gets actions is the reducer and that is part of your TCA domain. This makes sense since the star of the show is the state.</p><p>The state should drive everything and that's why the library comes with a <code>StorePublisher</code> that will provide a stream of changes to the state. With that you can use TCA in UIKit for example, and is very easy to use. But sadly, there is no affordance to observe the actions themselves.</p><h2 id="the-problem-with-observing-state">The problem with observing state</h2><p>Observing the state is totally the right thing to do in features that use the TCA, but it comes with some problems when you want to use it to interact with the exterior world. Having to listen to the state means that you need boilerplate to check if the change that you cared actually happened, furthermore you probably will need an action to reset the state once you've done what you wanted with it. These things are not an issue in a fully declarative world but on the ugly outside it's a big annoyance.</p><p>But the big issue is how this usually means polluting your state just so something can be observed from the outside. This may seem not that important, but in my opinion is a big negative point for this solution.</p><p>What we really care in these cases are the events that happen inside the feature. In other words, we need to know what <strong>actions</strong> are passing through the Store.</p><h2 id="relay">Relay</h2><p>The goal then is to hook into the Store to get the actions, but we want to do that without modifying the library. With that limitation, there is only one place we can use to get callbacks when actions are sent, and that's the reducer.</p><p>This means that we need to extend the reducer we use for the specific feature on the fly. Something like this would work:</p><pre><code><span class="splash-keyword">let</span> store = <span class="splash-type">Store</span>(
        initialState: ...,
        reducer: featureReducer.<span class="splash-call">combined</span>(with: .<span class="splash-keyword">init</span>({ <span class="splash-keyword">_</span>, action, <span class="splash-keyword">_ in</span>
                <span class="splash-comment">// switch on the action that you want to listen to and run some code</span>
                <span class="splash-keyword">case</span> .<span class="splash-dotAccess">someAction</span>:
                      <span class="splash-call">runSomeCallback</span>()
                      <span class="splash-keyword">return</span> .<span class="splash-dotAccess">none</span>
            }))
...
</code></pre><p>This works fine and is all you need, but is worth discussing the disadvantages of this approach.</p><p>If you look at it with a TCA mindset, you immediately see how we're performing uncontrolled side effects. In a way, it makes sense. That's exactly what we wanted after all! But my fear when I was approaching this was mainly from a teaching point of view. The rest of my team was still learning the TCA, and I was afraid that looking at code like this would pollute their minds.</p><p>To cleanup this I followed a <a href="https://github.com/pointfreeco/swift-composable-architecture/discussions/851#discussioncomment-1469781">good advice</a> and made a high order reducer explicitly for this. This high order reducer gives an explicit name to this operation, <code>relay</code>. Besides this, it makes the closure cleaner since the only thing it receives is the action and it doesn't have to return any Effect. This may feel like a minor detail, but making the closure look different from a normal reducer makes it more clear that what you are doing in the closure has nothing to do with TCA.</p><p>So the result looks like this:</p><pre><code><span class="splash-keyword">let</span> store = <span class="splash-type">Store</span>(
        initialState: ...,
        reducer: featureReducer.<span class="splash-call">relay</span> { action <span class="splash-keyword">in
          switch</span> action {
            <span class="splash-keyword">case</span> .<span class="splash-dotAccess">someAction</span>:
              <span class="splash-call">runSomeCallback</span>()
          }
        },
  ...
</code></pre><p>Much nicer!</p><p>Thanks to this, we can easily integrate TCA features with the rest of the application that relies in a more typical architecture.</p><blockquote><p>You can read my original <a href="https://github.com/pointfreeco/swift-composable-architecture/discussions/851">GitHub discussion</a> on the topic.</p></blockquote><h2 id="relaystore">RelayStore</h2><p>The <code>relay</code> method works well when you create the store in a class (a <code>UIViewController</code>, a Coordinator...) but it breaks down very quickly when you want to use it in SwiftUI.</p><p>For example, if you want to use this in a pure SwiftUI App you may start with this code:</p><pre><code><span class="splash-keyword">@main
struct</span> FeaturePreviewApp: <span class="splash-type">App</span> {
    <span class="splash-keyword">let</span> store = <span class="splash-type">Store</span>(
        initialState: .<span class="splash-keyword">init</span>(),
        reducer: featureReducer,
        environment: .<span class="splash-keyword">init</span>(...)
   )
   <span class="splash-keyword">var</span> body: <span class="splash-keyword">some</span> <span class="splash-type">Scene</span> {
        <span class="splash-type">WindowGroup</span> {
            <span class="splash-type">FeatureView</span>(store: store)
        }
    }
}
</code></pre><blockquote><p>You may wonder what's the point of this, why not use the TCA fully then. The answer is "Preview Apps". We have tiny apps that run only a specific feature. We don't want to overcomplicate the code in the app itself and we want to use a SwiftUI app since they require so little setup.</p></blockquote><p>Then you may add a local state gets assigned when something happens in the feature. That local state will drive an alert so you can show that something happened on the preview app.</p><pre><code><span class="splash-keyword">@main
struct</span> FeaturePreviewApp: <span class="splash-type">App</span> {
  <span class="splash-keyword">let</span> store = <span class="splash-type">Store</span>(
      initialState: .<span class="splash-keyword">init</span>(),
      reducer: featureReducer,
      environment: .<span class="splash-keyword">init</span>(...)
  )
  <span class="splash-keyword">@State var</span> someLocalStateVariable: <span class="splash-type">String</span>?

  <span class="splash-keyword">var</span> body: <span class="splash-keyword">some</span> <span class="splash-type">Scene</span> {
      <span class="splash-type">WindowGroup</span> {
          <span class="splash-type">FeatureView</span>(store: store)
      }
      .<span class="splash-call">alert</span>(isPresented: <span class="splash-property">$someLocalStateVariable</span>.<span class="splash-call">hasValue</span>(), content: {
          <span class="splash-type">Alert</span>(title: <span class="splash-type">Text</span>(someLocalStateVariable!))
      })
  }
}
</code></pre><p>Now it's time to use the <code>relay</code>...</p><pre><code>   <span class="splash-keyword">let</span> store = <span class="splash-type">Store</span>(
      initialState: .<span class="splash-keyword">init</span>(),
      reducer: featureReducer.<span class="splash-call">relay</span> { action <span class="splash-keyword">in
        switch</span> action {
          <span class="splash-keyword">case let</span> .<span class="splash-call">something</span>(value):
          	someLocalStateVariable = value <span class="splash-comment">// NOPE!</span>
          ...
        }
      },
      environment: .<span class="splash-keyword">init</span>(...)
  )
  <span class="splash-keyword">@State var</span> someLocalStateVariable: <span class="splash-type">String</span>?


</code></pre><p>As soon as you try to access the local state, the compiler will complain that you are trying to access <code>self</code> too soon. And since this is a <code>struct</code> you can't use the trick of making <code>store</code> a <code>lazy var</code>.</p><p>What you need is to use the <code>relay</code> in the <code>body</code> of the View. But if you try to move the store to it, you will end up with issues since SwiftUI will recompute the body of the View and that will recreate the entire store!</p><pre><code>   <span class="splash-keyword">var</span> body: <span class="splash-keyword">some</span> <span class="splash-type">Scene</span> {
      <span class="splash-type">WindowGroup</span> {
          <span class="splash-type">FeatureView</span>(store: <span class="splash-type">Store</span>( <span class="splash-comment">// store will be created on every sate change!</span>
            initialState: .<span class="splash-keyword">init</span>(),
            reducer: featureReducer.<span class="splash-call">relay</span> { action <span class="splash-keyword">in
              switch</span> action {
                <span class="splash-keyword">case let</span> .<span class="splash-call">something</span>(value):
                  <span class="splash-keyword">self</span>.<span class="splash-property">someLocalStateVariable</span> = value <span class="splash-comment">// this is fine now</span>
                ...
              }
            },
            environment: .<span class="splash-keyword">init</span>(...)
        ))
      }
</code></pre><p>So we need the Store as a local property but the relay on the body... what a conundrum.</p><p>The solution to the problem is what I call the <code>RelayStore</code>, not only is not very original but is also a bit of a lie since is not a <code>Store</code> 🙈.</p><p>With it, you can write exactly what you need:</p><pre><code><span class="splash-keyword">@main
struct</span> FeaturePreviewApp: <span class="splash-type">App</span> {
  <span class="splash-keyword">let</span> relayStore = <span class="splash-type">RelayStore</span>( <span class="splash-comment">// local property 👍</span>
      initialState: .<span class="splash-keyword">init</span>(),
      reducer: featureReducer,
      environment: .<span class="splash-keyword">init</span>(...)
  )
  <span class="splash-keyword">@State var</span> someLocalStateVariable: <span class="splash-type">String</span>?

  <span class="splash-keyword">var</span> body: <span class="splash-keyword">some</span> <span class="splash-type">Scene</span> {
      <span class="splash-type">WindowGroup</span> {
          <span class="splash-type">FeatureView</span>(store: relayStore.<span class="splash-call">storeWithRelay</span> { action <span class="splash-keyword">in
            switch</span> action {
                <span class="splash-keyword">case let</span> .<span class="splash-call">something</span>(value):
                	<span class="splash-keyword">self</span>.<span class="splash-property">someLocalStateVariable</span> = value <span class="splash-comment">// access to self 👍</span>
                ...
              }
          })
      }
      .<span class="splash-call">alert</span>(isPresented: <span class="splash-property">$someLocalStateVariable</span>.<span class="splash-call">hasValue</span>(), content: {
          <span class="splash-type">Alert</span>(title: <span class="splash-type">Text</span>(someLocalStateVariable!))
      })
  }
}
</code></pre><p>The trick here is that this fake store doesn't initialise the real store on the init. Instead, it just keeps the parameters (initial state, reducer and environment) as local properties. It's only when you call <code>storeWithRelay</code> where a real store is created, using the injected closure as the relay to extend the reducer and, very importantly, keep that real store around so is not recreated in the next refresh.</p><h2 id="conclusion">Conclusion</h2><p>The TCA is superb, but it has a shortcoming when you want to observe the actions of the Store to integrate it with an external non declarative system. The <code>relay</code> solution is decent and I like it, but it needed a bit of experimentation and help from the <code>RelayStore</code> to get the polish it needed.</p><p>You can find the code for this in the <a href="https://github.com/alexito4/RelayStore">RelayStore GitHub repo</a>.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/swift-s-default-literal-types</guid><title>Swift's default literal types</title><description></description><link>https://alejandromp.com/blog/swift-s-default-literal-types</link><pubDate>Thu, 2 Dec 2021 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>Today I want to show you a rather obscure feature of Swift. You will learn a bit about Swift's type system, type inference and other nice powers that the language has.</p><h2 id="type-inference">Type Inference</h2><p>We know Swift is a strongly typed programming language, that means that every variable you declare has a type defined at compile time.</p><pre><code><span class="splash-keyword">let</span> name: <span class="splash-type">String</span> = <span class="splash-string">"Kelsier"</span>
</code></pre><p>The <code>name</code> variable has a specific type: <code>String</code>. But, as with any modern language, having to define the types of every single variable can be tedious and so the compiler <em>infers</em> the types for us.</p><p>So you can leave them out in most places:</p><pre><code><span class="splash-keyword">func</span> someAge() -&gt; <span class="splash-type">Int</span> {
    <span class="splash-keyword">return</span> <span class="splash-number">1</span>
}
<span class="splash-keyword">let</span> age = <span class="splash-call">someAge</span>() <span class="splash-comment">// inferred to be Int</span>
</code></pre><p>The compiler can see that the function <code>someAge</code> returns an <code>Int</code> and thus the variable <code>age</code> must be of type <code>Int</code>. Something that any Swift programmer is used to.</p><h2 id="literals">Literals</h2><p>But let's go back to the original example and rewrite it to use type inference:</p><pre><code><span class="splash-keyword">let</span> name = <span class="splash-string">"Kelsier"</span>
</code></pre><p>Now the type of <code>name</code> is not explicitly declared by the programmer. Which means that the compiler needs to infer it from the right side of the assignment, a string literal.</p><p>Now the type of <code>name</code> is not explicitly declared by the programmer. So the compiler needs to infer it from the right side of the assignment, a string literal.</p><p>And of course the compiler is going to define the variable as a <code>String</code>. Or will it?</p><p>The peculiarity of string literals is that they don't have an intrinsic type on their own. The context defines their type. For example, let's look at the number literals.</p><pre><code><span class="splash-keyword">func</span> iWantAnInt(<span class="splash-keyword">_</span> i: <span class="splash-type">Int</span>) {}
<span class="splash-keyword">func</span> iWantADouble(<span class="splash-keyword">_</span> d: <span class="splash-type">Double</span>) {}
<span class="splash-call">iWantAnInt</span>(<span class="splash-number">42</span>)
<span class="splash-call">iWantADouble</span>(<span class="splash-number">42</span>)
</code></pre><p>Here you can see how the literal <code>42</code> is inferred to be an <code>Int</code> or a <code>Double</code> depending on how it's used.</p><h2 id="expressible-by-literal">Expressible By Literal</h2><p>Another interesting feature of the language is that it allows us to make our own types be used with literals. Every literal in the language has an associated protocol in the form of <code>ExpressibleBy*Literal</code>. If your type conforms to that protocol, a literal can be used to initialise it.</p><p>For example, let's make our own number:</p><pre><code><span class="splash-keyword">struct</span> MyNumber: <span class="splash-type">ExpressibleByIntegerLiteral</span> {
    <span class="splash-keyword">init</span>(integerLiteral value: <span class="splash-type">IntegerLiteralType</span>) {
        <span class="splash-comment">// ...</span>
    }
}

<span class="splash-keyword">func</span> iWantMyNumber(<span class="splash-keyword">_</span> d: <span class="splash-type">MyNumber</span>) {}
<span class="splash-call">iWantMyNumber</span>(<span class="splash-number">42</span>)
</code></pre><p>We can see how our type behaves the same as the standard library types in terms of inference. That's very powerful!</p><h2 id="default-literal-types">Default literal types</h2><p>So now that we understand how type inference, let's refer to the original example <em>again</em> and ask, which is the type of <code>name</code>?</p><pre><code><span class="splash-keyword">let</span> name = <span class="splash-string">"Kelsier"</span>
</code></pre><p>For this, the language needs to base the inference in the context, and since we're not passing the variable to a function that has an explicit parameter type, the compiler must use some safe default instead. And of course, the best default for a string literal is the type <code>String</code>. So we have the answer!</p><p><code>name</code> is of type <code>String</code>.</p><p>... or is it?</p><p>One of the best things about Swift's design is to have as much as possible on user land, as opposed to specifically coded in the compiler. I just told you that <code>String</code> is the default type for the string literal, and that's true, but that knowledge is defined in the standard library. Is not a hard-coded decision in the compiler.</p><p>So how does the standard library define the default types for literals? Look for <code>*LiteralType</code>. In the string case <a href="https://developer.apple.com/documentation/swift/stringliteraltype">StringLiteralType</a> is defined as:</p><pre><code><span class="splash-keyword">typealias</span> StringLiteralType = <span class="splash-type">String</span>
</code></pre><p>This means that we can define our own <code>typealias</code> with the same name and change the default literal in our context.</p><pre><code><span class="splash-keyword">typealias</span> StringLiteralType = <span class="splash-type">MyString</span>

<span class="splash-keyword">struct</span> MyString: <span class="splash-type">ExpressibleByStringLiteral</span> {
    <span class="splash-keyword">init</span>(stringLiteral value: <span class="splash-type">String</span>) { 
      <span class="splash-comment">// ....</span>
    }
}
</code></pre><p>And now, for the last time, what's the type of <code>name</code>?</p><pre><code><span class="splash-keyword">let</span> string = <span class="splash-string">"hola"</span>
<span class="splash-call">print</span>(<span class="splash-call">type</span>(of: string)) <span class="splash-comment">// MyString</span>
</code></pre><p>Since the compiler sees our definition of <code>StringLiteralType</code> (since is in the same module) from now on, every literal string in our code will be of type <code>MyString</code>.</p><h2 id="conclusion">Conclusion</h2><p>In this post I explained a rather obscure feature of the Swift language. It's not something you will see being used pretty much anywhere, but is good to know we can change the default types of literals. It makes the language very powerful. Of course we need to be careful with over using a power, unless is to prank your coworkers for a bit 😉</p><p>Tell me, have you used this in a real codebase?</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/the-matrix-in-swiftui</guid><title>The Matrix in SwiftUI</title><description></description><link>https://alejandromp.com/blog/the-matrix-in-swiftui</link><pubDate>Sat, 20 Nov 2021 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>Today I want to share a weekend experiment where I built the classic Matrix effect in SwiftUI. It all started after seeing <a href="https://mobile.twitter.com/curiousnikhyl/status/1459232842093719553?s=12">this tweet</a> of the effect implemented in Compose. I immediately wondered what would it take me to build that in SwiftUI, so when I had some spare time in a weekend I gave it a go.</p><p>I like to do this kind of small experiments from now and then. It satisfies my curiosity, but doesn't force me to focus on a single thing for a long time. I finish it before it gets boring :) Because of this you won't see the most perfect code in here, but if you have some interesting improvements or alternative implementations share them ^^.</p><img src="https://alejandromp.com/blog/the-matrix-in-swiftui/matrixmac.jpg" alt="Matrix"/><p>You can find the code in <a href="https://github.com/alexito4/Matrix-SwiftUI">GitHub</a>. Note that the linked tweet code uses a port of p5 for Compose. I've talked about something like this for Swift before in <a href="https://alejandromp.com/blog/processing-p5-swift/">Processing and p5 in Swift</a>, but I'm just using vanilla SwiftUI in this experiment.</p><p>A first idea for implementing this it’s using a <code>Canvas</code> view. But, for some reason I don’t remember, I opted to use views for this, although I'm pretty sure using a <code>Canvas</code> would be better. After all, the only layout I'm using is the <code>VStack</code> for the columns. I’m calculating myself the layout of everything else so I don't think I would lose much just dropping to the lower drawing level.</p><p>One of the nicest things about building something like this in SwiftUI is the <code>TimelineView</code>. This view recomputes the provided view, providing an up to date <code>Date</code> value, based on the refresh interval you specify. You don’t have to hook into any timer to do this, the view takes care of it for you. From the date, it's quite easy to get a number (<code>TimeInterval</code>) from any reference date. It doesn't really matter which reference you use, since the only thing you care about is to have a number that is incremented as time passes. This is very reminiscent of how game engines work.</p><p>One thing I do often when working on these experiments is to try to drive the UI from data as much as possible. By this I mean to not use view state or anything like that. It makes it easier to write algorithms to compute the UI instead of having to mess around with the views themselves. That's why I have a <code>ColumnData</code> struct that has all the properties from the columns that I need to render.</p><pre><code><span class="splash-keyword">struct</span> ColumnData: <span class="splash-type">Identifiable</span> {
    <span class="splash-keyword">let</span> id = <span class="splash-type">UUID</span>()
    <span class="splash-keyword">let</span> characters: [<span class="splash-type">Character</span>]
    <span class="splash-keyword">let</span> glyphSize: <span class="splash-type">Int</span>
    <span class="splash-keyword">let</span> x: <span class="splash-type">Double</span>
    <span class="splash-keyword">let</span> speed: <span class="splash-type">Double</span>
}
</code></pre><p>I also have a function that creates the data for all the columns that need to be rendered in a given width.</p><pre><code><span class="splash-keyword">static func</span> columns(<span class="splash-keyword">_</span> proxy: <span class="splash-type">GeometryProxy</span>) -&gt; [<span class="splash-type">ColumnData</span>] {
    <span class="splash-keyword">let</span> estimatedColumnWidth = <span class="splash-number">26.0</span>
    <span class="splash-keyword">let</span> width = proxy.<span class="splash-property">size</span>.<span class="splash-property">width</span>
    <span class="splash-keyword">let</span> count = <span class="splash-type">Int</span>(width / estimatedColumnWidth)
    <span class="splash-keyword">return</span> (<span class="splash-number">0</span>..&lt;count).<span class="splash-call">map</span> { i <span class="splash-keyword">in</span>
        <span class="splash-type">ColumnData</span>(
            proxy,
            x: (<span class="splash-type">Double</span>(i) * estimatedColumnWidth) + (estimatedColumnWidth / <span class="splash-number">4</span>)
        )
    }
}
</code></pre><p>Well, I lied a bit. The <code>ColumnData</code> doesn't contain all the data needed to render the column. There are a couple of pieces that are decided on the UI on the fly, and that's because I want to change them during the lifetime of the animation.</p><p>This mix of approaches worked out nicely, but I really don't recommend it for anything serious. I'm abusing SwiftUI's lifecycle here. I generate the data inside the body function of the root view, which won't be recomputed again.</p><pre><code><span class="splash-keyword">struct</span> ContentView: <span class="splash-type">View</span> {
    <span class="splash-keyword">var</span> body: <span class="splash-keyword">some</span> <span class="splash-type">View</span> {
        <span class="splash-type">GeometryReader</span> { proxy <span class="splash-keyword">in
            let</span> columnsData = <span class="splash-type">ColumnData</span>.<span class="splash-call">columns</span>(proxy)
            <span class="splash-type">Matrix</span>(data: columnsData, fullHeight: proxy.<span class="splash-property">size</span>.<span class="splash-property">height</span>)
        }
        .<span class="splash-call">clipped</span>()
    }
}
</code></pre><blockquote><p>Technically, this is recomputed if the window size changes. Which you can see happening on macOS.</p></blockquote><p>This means that all the random generation is only run once. This makes up for the constant part of the data needed to draw the views. The part of the data that can't change during the animation. But be careful because this is relying on internal decisions of the framework. If SwiftUI recomputes bodies I'm not expecting, the data won't be stable anymore and you will see weird jumps on the screen.</p><p>The other parts, the dynamic bits that need to change, are all calculated inside the <code>TimelineView</code> . Things like the <code>y</code> coordinate of the column as shown here. Note how the <code>x</code> position is defined in the constant data, but the <code>y</code> is driven by a <em>tick</em> and the speed of the animation.</p><pre><code>.<span class="splash-call">offset</span>(x: data.<span class="splash-property">x</span>)
.<span class="splash-call">offset</span>(y: (tick * data.<span class="splash-property">speed</span>).<span class="splash-call">truncatingRemainder</span>(dividingBy: fullHeight + columnHeight) - columnHeight)
</code></pre><p>Another part that changes outside the column data is the glyph. The column draws the provided list of glyphs except that sometimes one of the characters is changed for another random one. For fun.</p><pre><code><span class="splash-type">TimelineView</span>(.<span class="splash-call">animation</span>(minimumInterval: <span class="splash-number">0.5</span>, paused: <span class="splash-keyword">false</span>)) { <span class="splash-keyword">_ in
    let</span> pickRandom = <span class="splash-type">Int</span>.<span class="splash-call">random</span>(in: <span class="splash-number">0</span>...<span class="splash-number">100</span>) &lt; <span class="splash-number">2</span>
    <span class="splash-type">Text</span>(<span class="splash-type">String</span>(pickRandom ? glyphs.<span class="splash-call">randomElement</span>()! : character))
}
</code></pre><p>You can see how I'm using yet another <code>TimelineView</code>, this one with its own interval. It's quite a powerful technique to be able to compose views that have their own independent refresh intervals.</p><p>One thing that keeps getting me every time is how the <code>offset</code> modifier is purely a rendering modifier. By that I mean it doesn't affect the layout computation at all. It's a quick way of moving things on the screen, but if you rely on layout considering those positions, you will be in trouble.</p><p>And that's it. I just wanted to share this little and fun experiment with you. Some techniques are not desirable in production environments but they are quite fun to use in a weekend project ^^</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/the-importance-of-cooperative-cancellation</guid><title>The importance of cooperative cancellation</title><description></description><link>https://alejandromp.com/blog/the-importance-of-cooperative-cancellation</link><pubDate>Sun, 13 Jun 2021 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>One of the most important aspects to understand about <a href="https://alejandromp.com/blog/swift-concurrency/">Swift Concurrency</a> is how cancellation of async tasks works. You may expect that when a task is cancelled, it immediately stops, like when you kill a process. But that's not at all how it works, cancellation in Swift is <strong>cooperative</strong>.</p><blockquote><p>Updated 06/01/2022: <code>Task.sleep</code> now respects cancellation. Improved the timeout example. Linked to Baggins package.</p></blockquote><h2 id="cooperative-cancellation">Cooperative cancellation</h2><p>A cooperative system is one where all the involved parts need to cooperate in order to accomplish a goal. Here, the goal is cancellation, and the parts are all the async tasks involved. This means that when a parent task is cancelled, its responsibility is to <strong>tell</strong> all the children that they have been cancelled.</p><p>When a parent task does this, it sets the <code>Task.isCancelled</code> flag to true, and that's it! That's where the work of the parent task finishes. At this point is when cooperation is needed and is up to the children to check for that flag and <strong>stop their work early</strong>.</p><blockquote><p>Note that API there is another way of checking for cancellation, <code>try Task.checkCancellation()</code> which will immediately throw a <code>CancellationError</code> up the call stack. This is a convenient way of handling cancellation if your function is already throwing.</p></blockquote><p>In other words, if the child Tasks never check for cancellation, it's like the system doesn't support cancellation at all.</p><p>This is an important aspect of <strong>Structured Concurrency</strong> since it ensures that tasks are never terminated without letting them cleanup their resources and also that there is no task that is left hanging on the ether, since the <strong>parent task always waits for all children to finish</strong>.</p><blockquote><p>Another aspect where cooperation is necessary is to avoid resource starvation on long running tasks. But that's a topic for another day.</p></blockquote><h2 id="good-citizens">Good citizens</h2><p>Cooperative cancellation has its benefits, but it also means that we need to be conscious about implementing async functions that cooperate. Let's take a look at what impact it has.</p><p>I want to show you how to use the tools that Swift Concurrency gives us to implement of a couple of common requirements when dealing with asynchronous work: timeouts and races. I think they are an excellent example of how important cooperative cancellation is since this functionality relies a lot on early cancellation.</p><h3>Timeout</h3><p>One of the significant advantages of structured concurrency is that it provides a way to pass context down the tree of tasks. One thing that the context can help with is timeouts.</p><p>Right now that's not something that is part of the Swift's standard library, but we can imagine a function that would provide that functionality:</p><pre><code><span class="splash-keyword">func</span> withTimeout(
    <span class="splash-keyword">_</span> seconds: <span class="splash-type">Double</span>,
    <span class="splash-keyword">_</span> work: <span class="splash-keyword">@escaping</span> () <span class="splash-keyword">async throws</span> -&gt; <span class="splash-type">Void</span>
) <span class="splash-keyword">async throws</span> {
    <span class="splash-comment">// ...</span> 
}
</code></pre><p>The way I've implemented this with the existing tools is by using the <code>Task.sleep()</code> functionality to have a way to know when the timeout has passed. Because we need to run both things concurrently, we need to use a <code>TaskGroup</code>:</p><pre><code>     <span class="splash-keyword">try await</span> <span class="splash-call">withThrowingTaskGroup</span>(of: <span class="splash-type">TimeoutResult</span>.<span class="splash-keyword">self</span>) { group <span class="splash-keyword">in</span>
        group.<span class="splash-call">addTask</span> {
          <span class="splash-keyword">try await</span> <span class="splash-call">work</span>()
        }
        group.<span class="splash-call">addTask</span> {
            <span class="splash-keyword">try await</span> <span class="splash-type">Task</span>.<span class="splash-call">sleep</span>(seconds: seconds)
        }
        <span class="splash-comment">// ...</span>
    }
</code></pre><p>To get the behaviour we want, we add a <em>child</em> task to the group and another "control" task. Both will run concurrently thanks to the <code>TaskGroup</code> and the group scope won't end until both finish. The trick then is to have a <code>sleep</code> in the control task, so it ends at the moment our timeout is reached.</p><p>Finally, we just need to <code>await</code> for one of the tasks to finish and cancel the other one.</p><pre><code>         <span class="splash-keyword">try await</span> group.<span class="splash-call">next</span>()
        group.<span class="splash-call">cancelAll</span>()
</code></pre><p>If the first one that finishes is the timeout, it means we are cancelling early that the given work function. If the passed function finishes first, then we just cancel the sleep.</p><p>Now we can use this function:</p><pre><code><span class="splash-keyword">await</span> <span class="splash-call">withTimeout</span>(<span class="splash-number">5</span>) {
    <span class="splash-keyword">await</span> <span class="splash-call">busyWork</span>()
}
</code></pre><p>This will make sure that <code>busyWork</code> is cancelled after 5 seconds if it's still running.</p><h3>Cooperation</h3><p>Now let's imagine that the <code>busyWork</code> function is not very cooperative and doesn't check for cancellation:</p><pre><code><span class="splash-keyword">func</span> busyWork() <span class="splash-keyword">async</span> {
    <span class="splash-call">print</span>(<span class="splash-string">"Starting busyWork"</span>)
    <span class="splash-keyword">for</span> i <span class="splash-keyword">in</span> <span class="splash-number">0</span>...<span class="splash-number">100</span> {
        <span class="splash-call">print</span>(i)
        <span class="splash-keyword">await</span> <span class="splash-call">nonCooperativeWork</span>()
    }
}
</code></pre><p>As you can see, this function doesn't check for cancellation, and if we assume that <code>nonCooperativeWork</code> doesn't check either, we have a dangerous scenario for cooperative cancellation. Running this will cause the following output:</p><pre><code><span class="splash-type">Starting</span> busyWork
<span class="splash-number">0</span>
...
<span class="splash-number">5</span>
cancel finished first
<span class="splash-number">6</span>
...
<span class="splash-comment">// until a 100!</span>
</code></pre><p>This is not ideal. So let's make sure our function checks for cancellation when appropriate:</p><pre><code><span class="splash-keyword">func</span> busyWork() <span class="splash-keyword">async</span> {
    <span class="splash-call">print</span>(<span class="splash-string">"Starting busyWork"</span>)
    <span class="splash-keyword">for</span> i <span class="splash-keyword">in</span> <span class="splash-number">0</span>...<span class="splash-number">100</span> {
      	<span class="splash-comment">// Let's check for cancellation on every iteration</span>
        <span class="splash-keyword">if</span> <span class="splash-type">Task</span>.<span class="splash-property">isCancelled</span> { <span class="splash-keyword">return</span> }
        <span class="splash-call">print</span>(i)
        <span class="splash-keyword">await</span> <span class="splash-call">nonCooperativeWork</span>()
    }
}
</code></pre><p>Now, if we run this, we see that the timeout has the effect we desire:</p><pre><code><span class="splash-type">Starting</span> busyWork
<span class="splash-number">0</span>
...
<span class="splash-number">5</span>
cancel finished first
<span class="splash-type">Program</span> ended with exit code: <span class="splash-number">0</span>
</code></pre><p>I hope that this illustrates the importance of being a good citizen in a world of cooperative cancellation.</p><blockquote><p>Note that this is a very simplistic implementation of the timeout. To start, a real implementation would let you return a value from the closure, but besides that it would handle edge cases and inheriting the timeout through the call stack. You can see my implementation of it in <a href="https://github.com/alexito4/Baggins/blob/main/Sources/Baggins/Concurrency.swift">Baggins/Concurrency</a>.</p></blockquote><h3>Race</h3><p>Let's try another example to illustrate a bit more how important this is. Imagine that we want to implement a <code>race</code> function. A function that given a couple of async functions runs them both concurrently and returns the result of the first one, cancelling the other because it lost the race. This is a very common operation, for example, if you want to show something to the user and you don't care if it's from a local database or a network call.</p><pre><code><span class="splash-keyword">func</span> firstOf&lt;R&gt;(
    <span class="splash-keyword">_</span> f1: <span class="splash-keyword">@escaping</span> () <span class="splash-keyword">async</span> -&gt; <span class="splash-type">R</span>,
    or f2: <span class="splash-keyword">@escaping</span> () <span class="splash-keyword">async</span> -&gt; <span class="splash-type">R</span>
) <span class="splash-keyword">async</span> -&gt; <span class="splash-type">R</span> {
    <span class="splash-keyword">await</span> <span class="splash-call">withTaskGroup</span>(of: <span class="splash-type">R</span>.<span class="splash-keyword">self</span>) { group <span class="splash-keyword">in</span>
        group.<span class="splash-call">addTask</span> {
            <span class="splash-keyword">await</span> <span class="splash-call">f1</span>()
        }
        group.<span class="splash-call">addTask</span> {
            <span class="splash-keyword">await</span> <span class="splash-call">f2</span>()
        }
        <span class="splash-keyword">guard let</span> first = <span class="splash-keyword">await</span> group.<span class="splash-call">next</span>() <span class="splash-keyword">else</span> {
            <span class="splash-call">fatalError</span>()
        }
        group.<span class="splash-call">cancelAll</span>()
        <span class="splash-keyword">return</span> first
    }
}
</code></pre><p>As before, we use a TaskGroup to run the two functions concurrently and respecting Structured Concurrency. The only difference is that the function that we are running now is not our own timeout, but a passed in function. And we just return the result from the first one that finishes.</p><p>You can see how this works very well if the given functions cooperate for the cancellation. Otherwise, even if one wins the race, everybody needs to wait for the others to finish. Which may be nice in a real world race, but definitively not what we want in our programs.</p><blockquote><p>It may be interesting to have a <code>select</code> operation that works with unstructured concurrency and leaves detached tasks dangling.</p></blockquote><h2 id="standard-cooperation">Standard Cooperation</h2><p>One thing to note is that in these examples, it seems quite tiresome that we need to be checking for cancellation ourselves all the time. And that if we forget, the system won't behave as desired. This is true, but in reality it is less of an issue that it may seem.</p><p>In this toy example, we were just performing an iteration without really calling any system function. So it makes sense that the responsibility is on us. But in real code, it is very likely that you always end up calling a system function, and is expected that those functions handle cancellation properly. That said, if you are building some library of async functions, make sure you respect cooperative cancellation too.</p><h3>Task.sleep</h3><p><code>Task.sleep</code> respects cooperative cancellation. That is, it will throw a cancellation error and finish early if its current task is cancelled.</p><blockquote><p>During the initial betas of Swift Concurrency, Task.sleep was non-throwing, and it didn't cancel early. I personally raised this in a WWDC Lab and <a href="https://forums.swift.org/t/se-0304-3rd-review-structured-concurrency/48847/36">in the forums</a>. It got fixed before the official release.</p></blockquote><h3>URLSession</h3><p>The new URLSession async functions follow cooperative cancellation and as soon as the Task is cancelled they also cancel the underlying request. This is very nice since is probably one of the major use cases for async that people will use.</p><h2 id="conclusion">Conclusion</h2><p>I hope you understand a bit more how cancellation works in Swift Concurrency. I don't think you should worry about it too much since the system frameworks will handle that, like the URLSession case, but it is still important that we all have a clear picture of it so the packages we create behave nicely on the wider ecosystem.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/use-spm-collections-to-have-easy-access-to-your-favourite-packages</guid><title>Make a Swift Package Collection with your favorites</title><description></description><link>https://alejandromp.com/blog/use-spm-collections-to-have-easy-access-to-your-favourite-packages</link><pubDate>Thu, 10 Jun 2021 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>WWDC21 has brought <a href="https://alejandromp.com/blog/wwdc21-notes/">many cool things</a> and there is one that will facilitate a lot the creation of new projects with dependencies. Until now it was a bit of a pain to remember which packages you wanted to add on almost every new project. It was such an inconvenience that I even have my small CLI to create new Swift packages. But I think now there is a better way!</p><blockquote><p>Note that SPM may have soon a way of creating packages from templates. That's not what I'm talking about here but it will be an even better addition to our toolbelt. See the pitch for a <a href="https://forums.swift.org/t/pitch-new-command-for-package-creation-and-package-templates/47874">package creation</a> command.</p></blockquote><h2 id="package-collections">Package Collections</h2><p>A package collection is nothing more than a json file describing a collection of packages. SPM interprets those and they are stored locally on your computer so it's easier to add packages from those collections into your projects.</p><p>This new feature came trough Swift Evolution in <a href="https://github.com/apple/swift-evolution/blob/main/proposals/0291-package-collections.md">SE-0291</a>. The nice thing is that not only SPM supports it but Apple also added integration directly into Xcode!</p><img src="https://alejandromp.com/blog/use-spm-collections-to-have-easy-access-to-your-favourite-packages/xcode spm collections.png" alt="xcode spm collections"/><p>Xcode comes with a default collection containing all Apple's Swift Packages. Many of them feel like part of the standard library so it's very nice to have them available with just one click.</p><p>One click?</p><p>Yes, because Xcode now can offer a fix-it when you are trying to import a module, and if the module is in a collection you are just one click away!</p><img src="https://alejandromp.com/blog/use-spm-collections-to-have-easy-access-to-your-favourite-packages/xcode spm collection suggest import.png" alt="xcode spm collection suggest import"/><h2 id="author-collections">Author collections</h2><p>The folks at the Swift Package Index have just released their first feature using the new collections: <a href="https://blog.swiftpackageindex.com/posts/launching-swift-package-collections/">Author Collections</a>. That is great for adding collections from your favorite authors.</p><p>Of course the first thing I did was to add the <a href="https://swiftpackageindex.com/pointfreeco">collection</a> from <a href="https://www.pointfree.co/subscribe/personal?ref=4Fj20c5I">pointfree</a>!</p><h2 id="your-own-collection">Your own collection</h2><p>But since a collection is just a JSON you shouldn't be afraid of having your own. And that's the nice thing about this. I think that making and maintaining your own collection is great for helping your future self bootstrap new projects and packages easily!</p><p>I recommend you to watch WWDC21 <a href="https://developer.apple.com/wwdc21/10197">Discover and curate Swift Packages using Collections</a> for a great introduction and step-by-step guide on how to do it. Is very easy!</p><p>Just use the <a href="https://github.com/apple/swift-package-collection-generator">generator</a> to convert a simple JSON to the expected format. Look at my <a href="https://github.com/alexito4/spm-collection/blob/main/input.json">input.json</a> as an example:</p><pre><code>{
    <span class="splash-string">"name"</span>: <span class="splash-string">"Alexito's favorite packages"</span>,
    <span class="splash-string">"overview"</span>: <span class="splash-string">"This collection contains my favorite Swift packages."</span>,
    <span class="splash-string">"keywords"</span>: [
        <span class="splash-string">"favorite"</span>
    ],
    <span class="splash-string">"packages"</span>: [
        {
            <span class="splash-string">"url"</span>: <span class="splash-string">"https://github.com/nicklockwood/SwiftFormat.git"</span>
        },
        ...
    ],
    <span class="splash-string">"author"</span>: {
        <span class="splash-string">"name"</span>: <span class="splash-string">"Alejandro Martinez"</span>
    }
}
</code></pre><p>You can specify more things on the JSON but if you pass a GitHub <code>--auth-token</code> to the generator it will automatically get all the information that it needs from every repository. I find that very convenient.</p><p>Once you have your <a href="https://github.com/alexito4/spm-collection/blob/main/collection.json">output json</a> you just need to host it on some server. A GitHub repo is good enough for your own use.</p><p>Mine is already on GitHub: <a href="https://github.com/alexito4/spm-collection">Alexito's favorite packages</a>. This will make it easier so much easier to import the packages that I need when prototyping ideas.</p><p>Now it's your time! Go, create and share collections of your favorite packages!</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/swiftui-and-structured-concurrency</guid><title>SwiftUI and Structured Concurrency</title><description></description><link>https://alejandromp.com/blog/swiftui-and-structured-concurrency</link><pubDate>Wed, 9 Jun 2021 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>We're just in the week of <a href="https://alejandromp.com/blog/wwdc21-first-impressions/">WWDC</a> and it's clear that <a href="https://alejandromp.com/blog/swift-concurrency">Swift's Concurrency</a> it's the biggest topic that will change how we develop. I've been following its evolution for months now and I'm happy to see how Apple talks about it on their sessions, it helps us see how much they really believe in this new langauge feature.</p><p>One of the things that I was not sure about is how the frameworks will integrate with certain aspects of the concurrency story. Things like how the UI frameworks would integrate with <a href="https://www.youtube.com/watch?v=IWd83J1rcLY">Global Actors</a> were very clear, but how things would integrate with Structured Concurrency was still a question mark.</p><p>Lately I've been looking a lot into Kotlin's decisions and how they compare with Swift's. And one thing I'm was not sure is how nice it would be to work with "coroutine contexts" in Swift. Well now at least we have an answer on how SwiftUI is doing it.</p><h2 id="scopes">Scopes</h2><p>Up until now the best thing you could do was to start gathering the data for your view with <code>.onAppear</code>. That was a fine way of hooking into the view's lifecycle but once you have <a href="https://www.youtube.com/watch?v=3SX7u5l3CGA&t=1s">Structured Concurrency</a> that's not enough.</p><p>To follow the rules of Structured Concurrency your async task must run in a defined scope. In small sample code that scope is defined statically by your source code.</p><pre><code><span class="splash-keyword">func</span> someAsyncFunction() <span class="splash-keyword">async</span> {
    <span class="splash-keyword">await</span> <span class="splash-call">longRunningTask</span>()
}
</code></pre><p><code>longRunningTask</code> lives in the scope defined by <code>someAsyncFunction</code> and ties both functions together. The latter won't outlive the former. If the parent function is cancelled it will cancel the child and wait for it to finish. That's Structured Concurrency in a nutshell.</p><p>But in a context of a UI app, there is a runloop going. The scope is not as static as our source code. So, how can we attach tasks into a view lifecycle and ensure that when the view goes away all its linked structured tasks go away too?</p><h2 id="swiftui-lifecycle">SwiftUI lifecycle</h2><p>SwiftUI introduces a new view modifier called <code>.task</code>. In its closure you can start async work that will be linked to the view's lifecycle.</p><pre><code><span class="splash-keyword">struct</span> DetailView: <span class="splash-type">View</span> {
    <span class="splash-keyword">@State var</span> list = <span class="splash-type">Array</span>(<span class="splash-number">1</span>...<span class="splash-number">10</span>)
    <span class="splash-keyword">var</span> body: <span class="splash-keyword">some</span> <span class="splash-type">View</span> {
        <span class="splash-type">List</span>(list, id: \.<span class="splash-keyword">self</span>) { n <span class="splash-keyword">in</span>
            <span class="splash-type">Text</span>(<span class="splash-string">"-&gt;</span> \(n)<span class="splash-string">"</span>)
        }
        .<span class="splash-call">task</span> {
            <span class="splash-keyword">await</span> <span class="splash-call">longOperation</span>()
        }
    }
}
</code></pre><p>This means that the <code>longOperation</code> will be implicitly cancelled if the <code>DetailView</code> goes away. No need to manually manage its lifecycle, or store <em>cancellables</em> so ARC can do it for you. Nope! Structured Concurrency takes care of everything! 🎉</p><video controls=true preload="auto" src="https://alejandromp.com/blog/swiftui-and-structured-concurrency/swiftui task.mov"></video><h2 id="other-swiftui-callbacks">Other SwiftUI callbacks</h2><p>One thing you need to be careful is that other callbacks like <code>.refreshable</code> don't seem to follow the rules of structured concurrency very well. In this case the refresh control will wait for your task to finish, but it won't cancel it if the view goes away.</p><p>I have an open radar about this: FB9139963</p><h2 id="conclusion">Conclusion</h2><p>Structured Concurrency is a clear improvement to the current status quo of concurrent programming. It's not just about the nice async/await syntax, but about the structure that brings into asyncronous programming. I'm very happy to see SwiftUI offer some affordances for this style and I hope we see all frameworks do the same.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/wwdc21-first-impressions</guid><title>WWDC21 first impressions</title><description></description><link>https://alejandromp.com/blog/wwdc21-first-impressions</link><pubDate>Wed, 9 Jun 2021 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>And here we are again! A new year, a new <a href="https://alejandromp.com/tags/wwdc/">WWDC</a>! I'm writting this after the first day of video sessions so there is still a bunch of cool things to unpack, but I think is alraedy a good point to sit down a bit and reflect.</p><p>As a general sentiment I don't think this has been a WWDC with a lot of new and revolutionary things. It for sure seems like a year of refined, and that's welcomed! That said the more sessions I watch the more little nuggets I find that are a big deal. Check out my <a href="https://alejandromp.com/blog/wwdc21-notes">raw session notes</a> to keep up with that.</p><h2 id="did-my-wishes-come-true?">Did my wishes come true?</h2><p>First, let me talk about the first impressions I had after the keynote and the SOTU. All that matters at that point is if you got what you were wishing ^^</p><iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/HcPvLSUxteo" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><p>As expected the more revolutioanry thing this year it's <a href="https://alejandromp.com/blog/swift-concurrency/">Swift Concurrency</a>. As I said, this was not new, thanks to Swift Evolution I already knew it was coming and spent the recent weeks fully focused on that. I learned a lot, made videos about it and tried many things. I definetly feel like I was ready for it. What is very fun is to see the rest of the community being so excited about it!</p><blockquote><p>It feels like I can finally share with everybody an awesome toy that I've been playing with for a while. ❤️</p></blockquote><p>It's not with a mix feeling if I'm honest. Now that Apple has done official documentation and amazing sessions, is inevitable that my content will become obsolete. Especially when every other content creator will be focusing on that topic. But it's also true that I don't mind very much (a little, yes, for sure) because I do share my knoweldge because I love doing it! I love making those videos explaining technical details that probably nobody else cares about. That's my jam!</p><p>We didn't see any <strong>System Themes</strong> like on Android. It would have been a huge change for iOS so I'm not surprised it's nto here this year.</p><p>What is a bit more unfortunate is to not have a <strong>Core Data replacement</strong>. I know this is not very likely since Core Data is battle tested and ditching it entirely would be a mistake, but some improvements to make it feel right at home in Swift are really needed. Anyway, in the wishlist for next year ^^</p><p>We got <strong>Xcode CI</strong>! That's a positive one. Although I'm still hesitent about its utility and scared about Apple monopolising this sector with their strict rules. Right now the CI industry for mac is kinda screwed, and that just affects developers like us. We'll see how this develops. But not only that, the new Xcode has many cool new features! Although I still wish they ditched the project file.</p><p><strong>SwiftUI</strong> has tons of very welcomed improvements (<a href="https://alejandromp.com/blog/wwdc21-notes">see my raw session notes for a list</a>). I'm very excited for the new possibilities and to get used to the refinements very quickly! Sadly there is still no guidance on <strong>navigation architecture</strong>. And every year that passes it becomes more and more necessary. With the amount of system technologies taht rely on deep linking into your app it feels like Apple is droping the ball here.</p><p>So besides the CI I don't think any other wish has been granted ^^'</p><p>Let's keep a list for next year!</p><ul><li><a href="https://alejandromp.com/blog/wwdc-2020-wishes/%23navigation">Navigation architecture</a> - <a href="https://alejandromp.com/blog/wwdc-2019-wishes/%23better-deep-linking-integration">Better deep linking integration</a></li><li><a href="https://alejandromp.com/blog/wwdc-2019-wishes/%23cloudkit-functions">CloudKit functions in Swift</a></li><li><a href="https://alejandromp.com/blog/wwdc-2019-wishes/%23swiftcore">SwiftCore</a></li><li><a href="https://alejandromp.com/blog/wwdc-2019-wishes/%23scripting-with-swift">Scripting with Swift</a></li><li><a href="https://alejandromp.com/blog/wwdc-2019-wishes/%23custom-watch-faces">Custom Watch faces</a></li><li><a href="https://alejandromp.com/blog/wwdc-2019-wishes/%23custom-view-controller-and-non-ui-extension-providers">Custom View Controller and Non-UI Extension Providers</a></li><li><a href="https://alejandromp.com/blog/wwdc-2019-wishes/%23custom-view-controller-and-non-ui-extension-providers">Custom View Controller and Non-UI Extension Providers</a></li><li><a href="https://alejandromp.com/blog/wwdc-2019-wishes/%23more-control-on-app-version-updates">More control on App version updates</a></li></ul>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/wwdc21-notes</guid><title>WWDC21 notes</title><description></description><link>https://alejandromp.com/blog/wwdc21-notes</link><pubDate>Wed, 9 Jun 2021 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>As <a href="https://alejandromp.com/blog/wwdc20-session-notes/">last year</a> I decided to share my <strong>unedited</strong> notes from the sessions I'm watching. The difference is that this time I've focued more on the topics and not on the sessions themselves. I've found this way more approachable this time.</p><p>Note that I haven't taken many notes about concurrency because is a topic that I'm already well versed since it was avilalbe for months thanks to Swift Evolution. If you want to know my take on that watch my <a href="https://alejandromp.com/blog/swift-concurrency/">Concurrency talks</a>.</p><p>I will keep updating this notes as I watch more sessions.</p><blockquote><p>Updated: 2021-06-09</p></blockquote><hr><h2 id="swift">Swift</h2><ul><li><code>#if ... #endif</code> can now surround explicit member expression suffixes. (51690082)</li><li>You can now apply property wrappers to function and closure parameters. (<a href="https://github.com/apple/swift-evolution/blob/main/proposals/0293-extend-property-wrappers-to-function-and-closure-parameters.md">SE-0293</a>, 66866426, 78029226)</li><li>Xcode has a new Optimize Object Lifetimes build setting, under Swift Compiler - Code Generation. Enabling this performs more aggressive ARC optimization and shortens object lifetimes, which can help reduce the memory your app uses. This option also helps you find bugs where code makes invalid assumptions about object lifetimes.</li><li>The <code>lazy</code> keyword now works in local contexts. (78028578)</li><li>Whenever a reference to <code>Self</code> doesn’t impede the usage of a protocol as a value type, or a protocol member on a value of protocol type, the same is now true for references to <code>[Self]</code> and <code>[Key : Self]</code>. (78028842)</li><li>It is now possible to use leading-dot syntax in generic contexts to access static members of protocol extensions where <code>Self</code> is constrained to a fully concrete type. (78029041)</li></ul><p>Apple Packages: ![[apple swift packages.png]]</p><p>Static linking on Linux, good for server apps. Better JSON performance on Linux. Better AWS Runtime lambda performance.</p><h3>Concurrency</h3><ul><li><a href="https://developer.apple.com/documentation/swift/swift_standard_library/concurrency">Apple Developer Documentation</a></li><li><a href="https://forums.swift.org/t/concurrency-in-swift-5-and-6/49337">Concurrency in Swift 5 and 6 - Discussion - Swift Forums</a></li><li>Maybe it will be backwards deployed?!?!?! <a href="https://forums.swift.org/t/swift-concurrency-feedback-wanted/49336/6">Swift Concurrency: Feedback Wanted! - #6 by tkremenek - Discussion - Swift Forums</a></li><li>Integrated with [[#SwiftUI]] callbacks<ul><li><code>.task</code> modifier is a task linked to the view lifecycle.<ul><li>use for in here and you have a lot of the things you want from Rx/Combine for free!</li></ul></li><li>but the <code>refreshable</code> doesn't follow the lifecycle.</li><li>BUT CANCELLATION DOESN'T SEEM TO BE TIED TO THE LIFETIME!</li><li>SDK changes!:</li><li>UIImage thumbnails</li><li>URLSession</li><li>URL line by line</li><li>FileHandle.bytes</li><li>NotificationCenter</li><li>Core Data<ul><li>await context.perform</li><li>but still, that makes it dangerous to return managedObjects.</li><li>MainActor.run {} is useful if you want to group multiple calls to the main actor without suspending (await) in between them. Types of concurrency with tasks. ![[Screenshot 2021-06-08 at 18.00.45.png]]</li></ul></li></ul></li></ul><p>Integrated with XCTest.</p><h2 id="swiftui">SwiftUI</h2><p><a href="https://developer.apple.com/documentation/swiftui/building_a_great_mac_app_with_swiftui">Building a Great Mac App with SwiftUI</a> <a href="https://developer.apple.com/documentation/swiftui/add_rich_graphics_to_your_swiftui_app">Add Rich Graphics to Your SwiftUI App</a></p><ul><li>TimelineView<ul><li>Schedules updates to your view automatically (outside of State changes)</li><li>Periodic</li><li>Explicit</li><li>Animation framerate</li><li>Custom</li><li>AsyncImage <a href="https://developer.apple.com/documentation/swiftui/asyncimage">AsyncImage | Apple Developer Documentation</a></li><li>Focus areas, <a href="https://developer.apple.com/documentation/SwiftUI/FocusState"><code>FocusState</code></a></li><li>can be a boolean for 1 case</li><li>or a hashable (enum) to pick which area to focus on</li><li><a href="https://developer.apple.com/documentation/SwiftUI/Table"><code>Table</code></a></li><li><a href="https://developer.apple.com/documentation/SwiftUI/Canvas"><code>Canvas</code></a></li><li><a href="https://developer.apple.com/documentation/SwiftUI/Material"><code>Material</code></a></li><li>use them as background so the content on top takes the correct vibrancy to be legible.</li><li>Lists:</li><li>swipe actions</li><li>Pull down to refresh <a href="https://developer.apple.com/documentation/swiftui/texteditor/refreshable(action:)?changes=latest_minor">Apple Developer Documentation</a></li><li>Swipe actions <a href="https://developer.apple.com/documentation/swiftui/texteditor/swipeactions(edge:allowsfullswipe:content:)?changes=latest_minor">Apple Developer Documentation</a></li><li>separators</li><li>ScrollView.safeAreaInset modifier to keep the scroll inside the safe area but let the content be visible outside the area.</li><li>content is passed in the closure of the modifier.</li><li><code>badge</code></li><li>.searchable</li><li>is passed trough the environment, if no view does anything with it, defaults kick in</li><li>NavigationView puts the searchbar in the navigation bar</li><li>Environment .isSearching to show results.</li><li>Use an overlay to show the results so the list behind stays there.</li><li>optional viewbuilder closure to offer suggestions<ul><li>searchCompletion modifier handles the typical case by converting a non interactive view into a button and changing the searchable text to the suggested.</li></ul></li><li>use .onSubmit(.search) {} to perform the search when the user submits the search query.</li><li>Landscape previews</li><li>[[#SF Symbols 3]]</li><li>Default set colors</li><li>Accessibilty:</li><li>Rotor:<ul><li>header: from Section or with accessibilityAddTrais(.isHeader)</li><li>custom rotors: for example if a visual user can see icon alerting on each cell, a blind user would have to go to each cell to know if there is an alert. instead make a custom rotor that goes trough the alerts only.</li></ul></li><li><code>.accessibilityRepresentation</code> use the accessibility representation from one view to define the accessibility of another.</li><li><code>.accessibilityChildren</code> modifier to convert a accessibility view into a container with children.<ul><li>nice trick to use a shapes (rectangle) with accessibility</li></ul></li><li><code>accessibilityEleemnt(children. contain)</code> in horizontal carousel of cells, the reading order is top-left -&gt; bottom-right so it would read all top views, then go down to the next element. instead you can mark each "cell" as a container so it reads an entire cell first instead of going to the next. need to understand the id of a view, and use namespace if there is mulitple views with the same id.</li><li><code>accessibilitySortPriority(-1)</code>` to read a view last</li><li><code>accessibilityElement(children: .combine)</code> to make the entire cell 1 single element, keeping the chidlren's properties.</li><li>![[accessibility child behaviour.png]]</li><li><code>accessibilityFocusState</code> to control programatically the focus of voiceover</li><li>better performance on macos</li><li>Debugging helper: &gt; <a href="https://twitter.com/luka_bernardi/status/1402045202714435585">https://twitter.com/luka_bernardi/status/1402045202714435585</a> &gt; Call `Self._printChanges()` inside the body of a view to print out the changes that have triggered the view update.</li><li>Text</li><li>now supports Markdown strings.</li><li>with custom attributes in the markdown</li><li>tapable links</li><li>dynamicTypeSizes to restrict the range .</li><li>textSelection modifier to allow it</li><li>date.formatted()</li><li>person.nameComponents.formatted() and support for textField bindings too.</li><li>TextField</li><li>prompt</li><li>onSubmit</li><li>submitLabel</li><li>ToolbarGroup placement: .keyboard</li><li>Button</li><li>.bordered style on iOS!</li><li>.tint</li><li>.controlSize (large gives you the typical full with buttons)</li><li>.controlProminence</li><li>role: .destructive</li><li>Confirmation dialogs</li><li>menuIndicator(.hidden) to make Manu buttons (dropdowns) appear as just a normal button.</li><li>Menu primary action to allow a one click action, with a context menu as a secondary action.</li><li>Toggle .button style to make a button that toggles.</li><li>ControlGroup groups related controls.</li><li>Core Data fetch request property wrapper now gives binding to sort propery.</li><li>Core Data sectioned fetch request.</li><li>importItemProviders modifier to accept data from other apps.</li><li>exportItemProviders modifier to share data from your app. Nice to integrate it with shortcuts!</li><li>Mac: ImportFromDevicesCommands() as commands in the window group to add functionity to get images from an iPhone.</li><li>privateSensitive to redact UI when in private modes like watch always on mode, or widgets on the lock screen.</li><li>Accessibility modifiers visible in the Xcode inspector.</li><li>Accessibility preview tab.</li></ul></li></ul><p>Thanks to property wrappers in function parameters we can pass a binding to an array in List and ForEach.</p><h2 id="widgets">Widgets</h2><p>New extra large size for iPad. Donate to the system so it can show the widget to the user on smart rotating stacks:</p><ul><li>INRelevantShortcut, from the app, to suggest a widget</li><li>TimelineEntryRelevante, from widget extension, to rotate</li><li>INInteraction, from the app, to suggest and rotate</li></ul><h2 id="shareplay,-groupactivities-framework">SharePlay, GroupActivities Framework</h2><p>Activities. CoreMedia + Group Activities coordinate the video playback across all devices. It plays locally on your app on everybody's device. Based on URLs/Deeplinks. Reliable Data channel, e2e encrypted. For any kind of experience, realtime.</p><h2 id="ipad-swift-playgrounds">iPad Swift Playgrounds</h2><p>...</p><h2 id="uikit">UIKit</h2><ul><li>UISheetPresentationController <a href="https://developer.apple.com/documentation/uikit/uisheetpresentationcontroller">Apple Developer Documentation</a> UITooltips</li><li>keyboard layout guide <a href="https://developer.apple.com/documentation/uikit/uikeyboardlayoutguide?changes=latest_minor">Apple Developer Documentation</a> UIImage resizing thumbnail creation.</li><li>bars are now transparent. if is not appropiate make a custom barappearance.</li><li>vc.setcontentscrollviewforedge lets you tell uikit which scroll to handle.</li><li>New UIList<ul><li>lists styles: prominentInsetGrouped and extraProminentInsetGrouped for lists with rich content so headers are not lost.</li><li>separator configuration</li><li>DatePicker wheel is back, but can type on the dates.</li><li>Button</li><li>New configuration API</li><li>popup and pulldown menu buttons</li><li>Button now supports multiple lines of text.</li><li>subtitle configuration property.</li><li>setNeedsUpdateConfiguration with the configuration closure to update the button. button own properties (highlight) will call the closure automatically.</li><li>incorporated activity indicator!</li><li>toggle buttons that keep the selected state. <code>changesSelectionAsPrimaryAction = true</code></li><li>pop-up buttons (similar to pull-down buttons with <code>showMenuAsPrimaryAction</code>) but with only 1 selection. works via menus by adding <code>changesSelectionAsPrimaryAction</code>. pre assign the default by setting <code>state: .on</code> in the <code>UIAction</code>.</li><li>cells and buttons configuration can be applied with a closure based api. no need to subclass cells anymore.</li><li>[[#SF Symbols 3]]</li><li>restrict dynamic type sizes.</li><li>system colors are the same on all platforms.</li><li><a href="https://developer.apple.com/documentation/corelocationui"><code>CoreLocationUI</code></a></li><li>Scenes:</li><li>saving state by giving a user activity to persist</li><li>and with a new delegate method to restore.<ul><li>can request some extended time to perform async restoration. but don't use this for long tasks like api requests!</li></ul></li><li>textField and textView have a <code>interactionState</code> property that gives you the restoration state of the field, but not the text content.</li><li>uiscene "share this" api</li><li>iPad center prominent scene like mail.</li><li>ActivationAction to put on menus and AcitvationInteraction to put on cells or views do use the gesture.</li><li>customise the preview by giving it a view</li><li>use QLPreviewSceneActivationConfiguration to use a system provided preview scene.</li><li>iPad Keyboard support has many improvements for menu and shortcuts.</li><li>automatic localisation for shortcuts</li><li>iPad: uibandselectioninteraction (drag a rectangle to select multiple things). automatic support on non-list collection views.</li><li>iPad pointer:</li><li>accessory vies that follow the pointer.</li><li>latching axis so the pointer stays transformed when the view is moving.</li><li>UIFocus system across all platforms.</li><li>reconfigure cells without recreating them</li><li>&gt; <a href="https://twitter.com/smileyborg/status/1402056034416398338">https://twitter.com/smileyborg/status/1402056034416398338</a> Do you use diffable data source? &gt; If so, there are some big changes in iOS 15: &gt; - applySnapshot(_: animatingDifferences: false) now diffs &amp; only performs minimal updates to UI &gt; - New API applySnapshotUsingReloadData if you want reloadData &gt; - New API to efficiently reconfigure items! &gt; Generally speaking, you should continue to use applySnapshot() — whether animating or not — whenever possible, and avoid using reloadData (as that's a big hammer that resets everything, it throws away all your existing cells and more). &gt; But there are some cases where reloadData does make sense, e.g. if you are applying a completely different set of data, or recycle the collection/table view for use on an entirely different screen, or have a huge set of changes and want to skip diffing/updates. &gt; You might find that this behavior change for animatingDifferences:false exposes some issues.The simple quick fix to get the old behavior back is just to use applySnapshotUsingReloadData instead of animatingDifferences:false.But, be aware that may just paper over real bugs. &gt; @jesse_squires Before iOS 15: animatingDifferences:true --&gt; diff + updates (animate) animatingDifferences:false --&gt; reloadData iOS 15: animatingDifferences:true --&gt; diff + updates (animate) animatingDifferences:false --&gt; diff + updates (no animation) applySnapshotUsingReloadData --&gt; reloadData</li><li>collectionview prefetch changes?</li><li>drag and drop across apps works on iphone.</li><li>Location button</li><li>doesn't ask permission, is a one time only thing</li><li>customise look</li><li>ios ensures is always visible and can be used to trick the user</li><li>The pasterboard banner won't appear if it comes from a user command or if they come from standard paste acitons: paste, paste and go, paste and search, paste and match style.</li><li>pasteboard data detectors.</li><li>don't gran access to the data but tell you if it could be a type of data you are interested in.</li></ul></li></ul><h2 id="xcode">Xcode</h2><p>PR comments inline the code. Vim mode Run tests repeatedly to find issues. Better diff and code review Crashlogs into the Organiser in minutes, with user comments in crash reports. Cloud signing based on keys stored in connect. Editing:</p><ul><li>Auto import frameworks as needed</li><li>if let name = name auto completed.</li><li>suggestions go inside intermetiate objects. <code>text.corn</code> -&gt; <code>text.layer.cornerRadius</code></li><li>switch cases autocompletion without having to click on the fix it.</li><li>for X in array automaitcally gives a singlar name to X based on the array.</li><li>expansion of multiple closures follows the nice new syntax. Column breakpoints, nice to stop only inside a closure.</li></ul><p>With package collections Xcode can find modules you want to important and show them so you are one click away.</p><p>Alternate app icons in the asset catalog. You can now use platform filters in build phases and target dependencies for all supported platforms.</p><h3>Instruments</h3><ul><li>Analyse network traffic</li></ul><h3>DocC</h3><p>Build, view and share documentation for Swift packages using DocC. <a href="https://developer.apple.com/documentation/Xcode/documenting-a-swift-framework-or-package">Documenting a Swift Framework or Package | Apple Developer Documentation</a> The documentation works in Xcode doc viewer and as a web page. Add extra pages like index, articles and even tutorials. Xcode's Quick Help now uses DocC to present project documentation and renders links to your project’s documentation in the documentation window Open sourced later this year.</p><h2 id="xcode-cloud">Xcode cloud</h2><p>For all Apple platforms. Paralleized testing Static analysis Build results and screenshoots in Xcode and App Store Connect. Auto deploy to testlfihg REST apis. Code signing automatically handledssxx. Needs changes to support Cocoapods, a build script. Seems like there is no way to customise the execution, it only runs Xcode stuff. But if you have them in Git is fine. <a href="https://developer.apple.com/documentation/xcode/making-dependencies-available-to-xcode-cloud">Apple Developer Documentation</a></p><h2 id="ios">iOS</h2><p>iOS 15 doesn't drop any device! <a href="https://twitter.com/JoshHrach/status/1401986459645530114">https://twitter.com/JoshHrach/status/1401986459645530114</a></p><p>JSON5 supported, so Comments in JSON!</p><h2 id="foundation">Foundation</h2><p>-Attributed String value type to <a href="https://developer.apple.com/documentation/foundation/attributedstring">Apple Developer Documentation</a>	- with Markdown support!	- full Swift, doesn't rely on NSAttributedString <a href="https://twitter.com/jmschonfeld/status/1402038729850585090">https://twitter.com/jmschonfeld/status/1402038729850585090</a>	- supports attributes and even user defined ones <a href="https://developer.apple.com/documentation/foundation/attributescopes">Apple Developer Documentation</a>	- compatible with Swift String counting	- fully localizable	- AttributeContainer to hold attributes without the string	- Scopes to securely define what attributes are accepted.</p><ul><li>New formatting API!<ul><li>extensions on Date, Numbers...</li><li>so no more worry about creating custom formatters and cashing them!</li><li>get an attributed string so you can customise parts of it!</li><li>the same formats are strategies to parse dates. custom strategies use string interpolation</li><li>Morphology</li><li>System wide user's pronoun.</li><li>Grammer engine to Expand loaclisation with plurals, gender, et</li><li>JSON 5 support</li><li>comments</li></ul></li></ul><h2 id="notifications">Notifications</h2><p>Focus Notifications different alert levels:</p><ul><li>passive: silent, don't awake the device.</li><li>active</li><li>- time sensitive: skips the summary, stay a bit longer, siri speaks it out loud on headphones</li><li>critical: health concerns, requires entitlement.</li><li>message / call Notification summary:</li><li>what shows up is based on relevancy, thumbnail size, amount of notifications... but untimely is user customized.</li></ul><h2 id="sf-symbols-3">SF Symbols 3</h2><p><a href="https://developer.apple.com/sf-symbols/">SF Symbols - Apple Developer</a> 600+ new symbols new color rendering modes workflow optimisation custom symbol improvements more localisation options</p><ul><li>variants (fill) will automatically be picked by swiftui (tabs filled on iOS but outlined on macOS)</li><li>hierarchical: monocrhome but with multiple levels of opacity</li><li>palette: customise the colors of each layer pick styles programatically</li></ul><h2 id="watchkit">WatchKit</h2><h2 id="mailkit">MailKit</h2><h2 id="textkit-2">TextKit 2</h2><p>TextKit 1 it's there since the NextStep days. TextKit 2 still leverages Foundation, Quartz and CoreText.</p><ul><li>Correctness: abstract away glyph handling. Necessary for international text.</li><li>Safety: value semantics (immutable classes)<ul><li>Element: paragraph, attachment, custom!</li><li>Performance: viewport-based layout and rendering</li><li>Non contiguous text layout. More performant for large documents.</li></ul></li></ul><h2 id="shazamkit">ShazamKit</h2><p><a href="https://developer.apple.com/documentation/shazamkit"><code>ShazamKit</code></a> Audio recognition for our Apps, not only Music. Matches audio to an existing catalog. Is not Sound Analysis classification, use ML for that.</p><ul><li>Shazam catalog recognition: for song identification.</li><li>Custom catalog recognition: device matching of arbitrary audio.</li><li>Library management</li></ul><h2 id="healthkit">HealthKit</h2><ul><li>Move minutes</li><li>Alcohol consumption (number of drinks)</li><li>Pregnancy tests</li><li>Walking steadiness</li></ul><h2 id="ar">AR</h2><p><a href="https://developer.apple.com/documentation/realitykit/creating_3d_objects_from_photographs">Creating 3D Objects from Photographs</a></p><h2 id="metal">Metal</h2><p>...</p><h2 id="game">Game</h2><p>New game controller HUD</p><h2 id="screen-time-api">Screen Time API</h2><p>100% Swift and SwiftUI code. Parent control apps: needs Family Control capability. Only works on a child's device.</p><ul><li>Managed settings: access to the same restriction that Screen Time has.<ul><li>restriction of apps, custom branding screen when locked.</li><li>limit access and provided custom actions.</li><li>Family controls: authorization.</li><li>allow parents to chose the apps for the kids</li><li>the app doesn't get the bundle IDs, just tokens, so only the parents know which apps are</li><li>Device activity: usage.</li><li>with the tokens from the family controls.</li><li>register time windows and completion events so your app can react, sending alerts or blocking apps.</li><li>system calls your extension.</li></ul></li></ul><h2 id="shortcuts">Shortcuts</h2><p>On mac. Imports Automator flows. Supports shell scripts and applescript. Uses siri intents like in iOS. Exposes a CLI and scripting interface, with ScriptingBridge framework you can run shortcuts from an app. Sharable via files.</p><p>![[types-nouns-actions-verbs-intents.png]]</p><p>Intents should be:</p><ul><li>Useful<ul><li>Handles a task</li><li>Not too immersive</li><li>Repeatable</li><li>Modular</li><li>Composable</li><li>Useful standalone</li><li>Customizable with parameters</li><li>Offer outputs so shortcuts can be build</li><li>Useful ones: Create, edit, delete, get, pick a thing, open app</li><li>Multimodal:</li><li>Compatible with UI and Siri</li><li>Configurable in editor</li><li>Visually represented in snippets (siri UI)</li><li>Clear (in the editor)</li><li>summarised in a sentence</li><li>consistent between suummary and title</li><li>include default values</li><li>Discoverable</li><li>icloud links</li><li>add to siri</li></ul></li></ul><h2 id="app-store-/-storekit">App Store / StoreKit</h2><blockquote><p><a href="https://developer.apple.com/documentation/storekit">StoreKit</a> 2 introduces a modern Swift-based API that takes advantage of new language features like Swift concurrency. Use this API to load product information, display in-app purchases in your store, allow customers to make purchases, manage access to content and subscriptions, and receive transaction information signed by the App Store in JSON Web Signature (JWS) format</p></blockquote><h2 id="other">Other</h2><p>Human Interface Guidelines with Inclusion in mind <a href="https://developer.apple.com/design/human-interface-guidelines/inclusion/overview/">Inclusion - Technologies - Human Interface Guidelines - Apple Developer</a></p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/swift-concurrency</guid><title>Swift Concurrency Videos</title><description></description><link>https://alejandromp.com/blog/swift-concurrency</link><pubDate>Tue, 25 May 2021 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>Swift is about to get its Concurrency features. Their development is going very well, with many proposals actively reviewed and a lot of the work already available in recent snapshots. The story is big and with many moving pieces interlinked with each other. That makes it a bit hard to wrap your head around the entire thing. Specially for those that don't read Swift Evolution as a hobby ^^.</p><p>But it has hooked me up. There are so many interesting conversations and so much to learn! I've written a big number of notes about the topic and decided that it was worth making a video series to help the community understand what really Swift Concurrency entails.</p><p>That's what this series of videos is trying to do. I explain to you parts of the Concurrency story, making it clear how they relate to each other. Some of these concepts can be quite new to a lot of developers so you will also find the theory and story behind them. As always, my goal is not to make tutorials, but to explain to you what things are and why they are how they are. To give you the tools so you can dive deeper into those topics. I just want you to be ready for when all of this lands officially into the language. The Swift programming language inspires these videos, and the examples use it to drive the point home. But the theory and principles widely apply to any other programming language. So I hope that this helps other communities too.</p><h2 id="first-look-at-async-await">First look at async await</h2><iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/Xf9HfHUb-cM" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><p>This first video serves as an introduction to the whole Concurrency story, focusing on the new keywords, what they are and what they are not. I also explore how we can bridge between an existing callback system and this new world of async functions, and how this will affect our codabases.</p><h2 id="actors">Actors</h2><iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/IWd83J1rcLY" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><p>This second video is fully focused on the <strong>Actor System</strong>. This system is not new, but is not very well known either. That's why I thought it would be very good to explain what Actors are, what's the theory behind them, what problems they solve and what things we need to be careful about.</p><h2 id="structured-concurrency">Structured Concurrency</h2><iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/3SX7u5l3CGA" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><p>Structured Concurrency is the underlying topic that pulls the entire Swift Concurrency story together, it brings very important fundamentals that help design the rest of features. But is not something that the everyday programmer has heard about. This video goes into the story and theory behind it, hopefully making it clear to everybody why Swift is going in this direction.</p><h2 id="asyncsequence">AsyncSequence</h2><iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/SNGjIb7gRL8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><p>AsyncSequence is a new protocol that aims to cover those cases were we need more than one value to be computed asynchronously. This will remind you to RxSwift and Combine and that's because the principles behind it are the same. How will this be integrated with those frameworks? All of this and more in the video!</p><h2 id="...-more">... more</h2><p>Right now these are the four videos of the series. I have a couple of more drafted but with WWDC21 approaching fast I'm not sure I will have enough time to finish them.</p><p>If there is any interest in other concurrency topics, feel free to reach out :)</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/swiftui-read-preference-helper</guid><title>SwiftUI read preference helper</title><description></description><link>https://alejandromp.com/blog/swiftui-read-preference-helper</link><pubDate>Mon, 22 Mar 2021 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>SwiftUI's layout system is very nice to get started with. Combining stacks and modifiers you can get very far very quickly, but at some point you will need to pass information up the view hierarchy. Thankfully SwiftUI has a solution for that: <strong>preferences</strong>.</p><p>To make a preference you need to create a type that conforms to <code>PreferenceKey</code>. That can sometimes get repetitive but today I don’t want to solve that part. The bit that bothers me more is what comes next. With that new type written you then start a dance of boilerplate that gets boring very quickly. Let's explore how we can make our lives a little bit easier.</p><h1 id="reading-a-preference">Reading a preference</h1><p>The first thing you need to do is make the child view write to the preference.</p><pre><code>childView
	.<span class="splash-call">preference</span>(key: <span class="splash-type">MyPreferenceKey</span>.<span class="splash-keyword">self</span>, value: value) }
</code></pre><p>This will make <em>value</em> available to the parent views. Next step is reading that, and it’s where the boilerplate gets too much repetitive for me.</p><pre><code><span class="splash-keyword">@State private var</span> childValue: <span class="splash-type">String</span>? = <span class="splash-keyword">nil
var</span> body: <span class="splash-keyword">some</span> <span class="splash-type">View</span> {
    <span class="splash-type">VStack</span> {
        <span class="splash-type">Text</span>(childValue ?? <span class="splash-string">""</span>)
        <span class="splash-type">MakeChildView</span>()
            .<span class="splash-call">onPreferenceChange</span>(<span class="splash-type">MyPreferenceKey</span>.<span class="splash-keyword">self</span>) { value <span class="splash-keyword">in</span>
            		childValue = value
        		}
    }
}
</code></pre><p>Declare a <code>@State</code> property to store the value read from the preference, use a <code>onPreferenceChange</code> modifier that needs the type and a closure. A closure that it's usually doing the same thing: storing the read value into the state property.</p><p>This API is very flexible. If you are doing something different on that closure every time it makes sense to use it, but most of the time we just need to mutate some local state to trigger a redraw. In that case, the API turns out to be too flexible.</p><p>So... what if we could simplify this a bit?</p><p>Reducing this boilerplate to the core of what we need is really easy. We just need an alternative method that reads the preference and stores it directly into the property that we want. Thankfully doing that is very easy.</p><pre><code><span class="splash-keyword">extension</span> <span class="splash-type">View</span> {
    <span class="splash-keyword">func</span> readPreference&lt;K&gt;(
        <span class="splash-keyword">_</span> key: <span class="splash-type">K</span>.<span class="splash-type">Type</span> = <span class="splash-type">K</span>.<span class="splash-keyword">self</span>,
        to binding: <span class="splash-type">Binding</span>&lt;<span class="splash-type">K</span>.<span class="splash-type">Value</span>&gt;
    ) -&gt; <span class="splash-keyword">some</span> <span class="splash-type">View</span> <span class="splash-keyword">where</span> <span class="splash-type">K</span> : <span class="splash-type">PreferenceKey</span>, <span class="splash-type">K</span>.<span class="splash-type">Value</span> : <span class="splash-type">Equatable</span> {
        <span class="splash-call">onPreferenceChange</span>(key) { value <span class="splash-keyword">in</span>
            binding.<span class="splash-property">wrappedValue</span> = value
        }
    }
}
</code></pre><p>With this we can rewrite the previous code to get rid of the closure.</p><pre><code><span class="splash-keyword">@State private var</span> childValue: <span class="splash-type">String</span>? = <span class="splash-keyword">nil
var</span> body: <span class="splash-keyword">some</span> <span class="splash-type">View</span> {
    <span class="splash-type">VStack</span> {
        <span class="splash-type">Text</span>(childValue ?? <span class="splash-string">""</span>)
        <span class="splash-type">MakeChildView</span>()
      			.<span class="splash-call">readPreference</span>(<span class="splash-type">MyPreferenceKey</span>.<span class="splash-keyword">self</span>, to: <span class="splash-property">$childValue</span>)
    }
}
</code></pre><p>The new modifier reads very nicely and does its job without asking us for custom logic every single time. Note how the method accepts a binding, which means we could use other things to store the preference other than a state property.</p><h1 id="conclusion">Conclusion</h1><p>As you can see, there is nothing revolutionary in this idea. Is just a simple method extension that implements a default behaviour. But that's the whole point that I wanted to transmit. Sometimes we get stuck into repeating the same boilerplate over and over without realising that it's very easy to get rid of it. Specially when the code is well architectured and the language provides you with the right tools.</p><p>This is not the only place where a small amount of boilerplate shows up when writing SwiftUI. With this post I want to show how reducing it is not very hard thanks to the architecture and the language. So keep an eye open and build your own library of little modifiers that get rid of the boring parts!</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/better-dictionary-literals-with-swift-result-builders</guid><title>Better Dictionary literals with Result Builders</title><description></description><link>https://alejandromp.com/blog/better-dictionary-literals-with-swift-result-builders</link><pubDate>Tue, 9 Mar 2021 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>Swift is well known for its lean syntax that helps newcomers understand the code relatively quickly. But it's also a language with advanced and powerful features. Sometimes this makes part of the community wonder if it is going too far. In this post, I'm glad to merge these two worlds and use an "advanced" feature of the language to improve the base syntax. Of course I'm talking about <strong>Result Builders</strong> and a DSL for Dictionary literals.</p><h2 id="dictionary-literals">Dictionary literals</h2><p>One place where we've grown accustomed to a nice and simple syntax is literals. You can create a dictionary literal with keys and values easily. If you don't have experience with other languages, you may not realise how nice it is.</p><pre><code>[
    <span class="splash-string">"key"</span>: value,
    <span class="splash-string">"hello"</span>: <span class="splash-string">"world"</span>
]
</code></pre><p>But often you may need to only add keys to the dictionary based on some condition, like if the value is not nil. And when that happens, the literals don't make the cut anymore.</p><p>You need to start using the Dictionary API to add values after its original creation. But that means that you need to have a variable to mutate. And not only that, but now you need to put the constant values on the literal init and anything that requires logic after that. This is quite annoying when you want to define the dictionary with a specific order to make it easier to read.</p><pre><code><span class="splash-keyword">var</span> dictionary = [
    <span class="splash-string">"key"</span>: value
]
<span class="splash-keyword">if let</span> welcome = optionalMessage {
    dictionary[<span class="splash-string">"hello"</span>] = welcome
}
...
</code></pre><p>Of course, this is not a big deal with such a simple example. But in reality, the function where this code lives is probably more complex and having to keep a variable just for this adds extra complexity. What if we could just make the literal initialisation support conditions?</p><h2 id="result-builders">Result builders</h2><p>Result builders is a Swift feature introduced by SwiftUI and officially added to the language on <a href="https://github.com/apple/swift-evolution/blob/main/proposals/0289-result-builders.md#result-builders"><strong>Swift 5.4</strong></a>. I talked about it in the context of the <a href="https://youtu.be/YG5u0aFgGQI">SwiftUI DSL</a> but also as a <a href="https://youtu.be/LKFVcc_uC60">deep dive on result builders</a> feature on itself. Because this feature is much more than just an implementation detail of SwiftUI. It allows us to make very nice DSLs.</p><p>People in our community always have a tendency to look bad at these more advanced, Swift features. This one specifically is always countered with the question of what utility does it have outside SwiftUI. And it's true that the typical examples are all about a very similar use case, like building HTML. But there are other interesting applications of it and the one I'm proposing here is not even to improve a separate framework, but the language itself. You can't get more useful than that!</p><h2 id="dictionarybuilder">DictionaryBuilder</h2><p>Let's build a result builder that helps us make dictionaries. And the nice thing is that is pretty easy.</p><blockquote><p>I won't go into much detail of how Result Builders work. I recommend you to <a href="https://youtu.be/LKFVcc_uC60">watch my deep dive video</a> to get a better understanding.</p></blockquote><pre><code><span class="splash-keyword">@resultBuilder
struct</span> DictionaryBuilder&lt;Key: <span class="splash-type">Hashable</span>, Value&gt; {
  ...
}
</code></pre><p>To start, we just define a type and annotate it with the special attribute <code>@resultBuilder</code>. This tells the compiler that this type can be used as an annotation of its own to enable the special DSL syntax in the body of a function.</p><p>Then we need to make the builder do something useful. We do this by adding special functions.</p><pre><code><span class="splash-keyword">static func</span> buildBlock(<span class="splash-keyword">_</span> dictionaries: <span class="splash-type">Dictionary</span>&lt;<span class="splash-type">Key</span>, <span class="splash-type">Value</span>&gt;...) -&gt; <span class="splash-type">Dictionary</span>&lt;<span class="splash-type">Key</span>, <span class="splash-type">Value</span>&gt; {
    dictionaries.<span class="splash-call">reduce</span>(into: [:]) {
        $0.<span class="splash-call">merge</span>($1) { <span class="splash-keyword">_</span>, new <span class="splash-keyword">in</span> new }
    }
}
</code></pre><p>This will make the builder accept dictionaries. But with this we gain very little. We could merge multiple dictionaries easily, but that's not our goal. To support conditionals, we need to add another special function.</p><pre><code><span class="splash-keyword">static func</span> buildOptional(<span class="splash-keyword">_</span> dictionary: <span class="splash-type">Dictionary</span>&lt;<span class="splash-type">Key</span>, <span class="splash-type">Value</span>&gt;?) -&gt; <span class="splash-type">Dictionary</span>&lt;<span class="splash-type">Key</span>, <span class="splash-type">Value</span>&gt; {
    dictionary ?? [:]
}
</code></pre><p>With these two simple functions, we have unlocked a huge potential of this feature. There are way more things a function builder can do but for now lets stick to the scenario that we want to solve.</p><h2 id="using-the-new-builder">Using the new builder</h2><p>Now we have a new annotation available: <code>@DictionaryBuilder&lt;Key, Value&gt;</code>. To use it one approach is to make a new Dictionary initialiser that let's use use this new DSL.</p><pre><code><span class="splash-keyword">extension</span> <span class="splash-type">Dictionary</span> {
  <span class="splash-keyword">init</span>(<span class="splash-keyword">@DictionaryBuilder</span>&lt;<span class="splash-type">Key</span>, <span class="splash-type">Value</span>&gt; build: () -&gt; <span class="splash-type">Dictionary</span>) {
      <span class="splash-keyword">self</span> = <span class="splash-call">build</span>()
  }
}
</code></pre><p>This is quite simple. The only thing we're doing is to mark the closure parameter as a builder. This indicates the compiler that the body of that closure will have super powers.</p><pre><code><span class="splash-keyword">let</span> dictionary = <span class="splash-type">Dictionary</span>&lt;<span class="splash-type">String</span>, <span class="splash-type">String</span>&gt; {
    [
        <span class="splash-string">"id"</span>: <span class="splash-string">"1"</span>,
        <span class="splash-string">"name"</span>: <span class="splash-string">"alex"</span>,
    ]
    <span class="splash-keyword">if let</span> welcome = optionalMessage {
        [<span class="splash-string">"hello"</span>: welcome]
    }
    [
        <span class="splash-string">"more"</span>: <span class="splash-string">"values"</span>
    ]
}
...
</code></pre><p>This allows us to use a <code>let</code>, which simplifies our code. It also lets us mix literal dictionaries with keys that require some logic, which lets us keep the order of the keys like we want it. This may seem like a trivial thing, but in some occasions it helps tremendously to improve the readability of the dictionary construction.</p><p>But there is another way of using the builder. If you have watch my <a href="https://www.youtube.com/watch?v=_VKGEEITeYY">AnyView vs. @ViewBuilder</a> video you probably know what I'm talking about. The dictionary initialiser is very useful if you are in the middle of a bigger function, but if your function is just there to return the resulting dictionary you can't skip the initialiser altogether and use the DSL directly!</p><pre><code><span class="splash-keyword">@DictionaryBuilder</span>&lt;<span class="splash-type">String</span>, <span class="splash-type">String</span>&gt;
<span class="splash-keyword">func</span> makeMeADictionary() -&gt; <span class="splash-type">Dictionary</span>&lt;<span class="splash-type">String</span>, <span class="splash-type">String</span>&gt; {
    [
        <span class="splash-string">"id"</span>: <span class="splash-string">"1"</span>,
        <span class="splash-string">"name"</span>: <span class="splash-string">"alex"</span>,
    ]
    <span class="splash-keyword">if let</span> welcome = optionalMessage {
        [<span class="splash-string">"hello"</span>: welcome]
    }
    [
        <span class="splash-string">"more"</span>: <span class="splash-string">"values"</span>
    ]
}
</code></pre><h2 id="conclusion">Conclusion</h2><p>We have seen how this Swift feature is not only there to make SwiftUI nice to use, but it can unlock a huge potential to improve our code. DictionaryBuilder is not just making the syntax nicer, but is helping to make our code easier to understand thanks to avoiding variables and letting us define the keys in the order we want.</p><p>And this is just the tip of the iceberg. Function builders are even more powerful than this, and I'm sure we will find more incredible applications. I think we need to stop complaining about the complexity of new features as long as the learning curve is not impacted. Some of this features are crucial to make Swift a better language and even to simplify the barrier of entry. Keep your mind open folks ;)</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/apple-s-swiftui-tutorial-series</guid><title>Apple's SwiftUI tutorial series</title><description></description><link>https://alejandromp.com/blog/apple-s-swiftui-tutorial-series</link><pubDate>Sun, 7 Mar 2021 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>When Apple released its own <a href="https://developer.apple.com/tutorials/app-dev-training">SwiftUI tutorial</a> I decided to give it a try. This was not a simple tutorial introducing the basics of SwiftUI, but a more overarching training to know how to create a real application in SwiftUI. From custom UI to sharing data between and interacting with frameworks.</p><p>You can find all 13 videos on my <a href="https://youtube.com/playlist?list=PL2HXX-dkWqS3tvmECY0cmTT-vmpIZu2UM">Apple's SwiftUI tutorial playlist</a>. You can start watching the first one to know what was my purpose with these videos.</p><iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/P3g-0WPBN4s" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><p>When I started doing the tutorials, I already knew SwiftUI. The framework is still young, so I'm by no means an expert, but I've been working with it since its release. So I was not going with the mentality of learning how to build an app. My intention was to take an analytical approach at the tutorial to know how good it is and if I would recommend it to others.</p><p>During the series, you can see me complain about some details and praise other decisions. I'm well aware this is not entertaining for everybody, but I find this kind of content very interesting, so it's what I want to create. I find really enjoyable watch other people's mental process, it’s the best way to learn!</p><p>If you are even just a bit like me, I recommend you watching the videos, but if you just want to know how good are the tutorials from my point of view, you can just skip to the last episode.</p><iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/cqlgM3BgEqw" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><p>Overall, I'm thrilled with the series, specially because now I have a better idea of what to answer when people ask me what to do to learn SwiftUI.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/graphql-modeling-domain-backend-driven-ui</guid><title>GraphQL and modeling domains</title><description></description><link>https://alejandromp.com/blog/graphql-modeling-domain-backend-driven-ui</link><pubDate>Thu, 25 Feb 2021 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>I've been a big fan of what Apollo is doing for a while, and recently they have been doing various interesting talks and interviews. In this post I want to review and share my notes about the conversation that happened on February 24th 2021 around GraphQL modeling and backend driven UI.</p><iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/hw-pEWzVD7E" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><p>Yes, I know that's now what the title of the video says. But I think there is not very much to take out from that video about federation. They mention a bit about organisation structure, but nothing that caught my attention. Instead, there are some important things to learn about modeling and designing systems.</p><p>Let me share my experience and views on the topic.</p><h2 id="modeling">Modeling</h2><p>At Lifeworks we've been using GraphQL for over two years now. So one could say I have a bit of experience with it. During all this time there is one thing that just keeps coming back: the most important part of GraphQL is knowing how to model your domain.</p><p>Seems quite obvious, right? After all, you are defining a graph of entities for your domain. But often we get lost in other more fancy things like how nice is having a schema for your API, types, an amazing cache, subscriptions, etc. But none of that matters if your schema design is not ideal.</p><p>If you want to focus on something important, that will help you be good at GraphQL, my advice is to learn how to model domains. It’s not specific to GraphQL, but is a skill that often developers ignore. Luckily for me I had excellent teachers at University that reiterated the importance of it.</p><p>The nice thing that is discussed in the video is about understanding that the graph is something that can evolve. And I agree with that sentiment. Defining your graph is an iterative process that benefits from experimentation. You don't have to be afraid of taking some decision that is now correct for your product and later deprecate it and evolve it in another direction. That's a nice thing about GraphQL, it understands deprecations. This is often important if you're trying to sell managers on GraphQL. It's likely that it involves a migration and you can't "stop the press" for it. So focus on delivering value and do a migration bit by bit.</p><p>This is how we did it at Lifeworks. We started our schema as a proof of concept for a new and shiny new feature. After that we started migrating the rest of features that are related to the first one (they belong to the same feature team). And nowadays we are undergoing a migration of the rest of features using Federation.</p><p>Being able to do it bit by bit and keep growing the schema is important. But this shouldn't be used as an excuse to have a poorly design graph. Think about it properly and try to do it properly sooner rather than later. Make every step a correct step. Yes, you can deprecate things and perfect it over time, but it won’t be without friction. Know how to model and you will do yourself a favour. 😉</p><h2 id="backend-driven-ui">Backend driven UI</h2><p>Another interesting topic that the video talks about is backend driven UIs. This is another thing I introduced in the product years ago. I implemented a simple backend service that returned a JSON structure for a landing page build out of components. In fact, this is where the beginning of HubKit started, a homegrown UI component framework.</p><p>Having a system like this is super cool when you want to have a dynamic screen that can adapt and change a lot. For me the goal was to improve our Perks home screen. It's also interesting because you can slowly build up the system. You can start with a simple backend returning a hardcoded JSON. Then you can introduce dynamic elements, eventually linking it to a CMS or even some fancy AI.</p><p>But then enters GraphQL, which in people’s mind contradicts this completely since GQL is all about giving the power to the frontend. But in reality, it can totally be done. You just have to design your graph based on some component entities. The FE still benefits from being the one in control. For example, the component library can grow without breaking changes.</p><p>Some slides from the video to illustrate the point:</p><img src="https://alejandromp.com/blog/graphql-modeling-domain-backend-driven-ui/Screenshot1.jpg" alt="Screenshot1"/><p>Yes, you need to have components and a proper design system to do this. But you should have that anyway nowadays.</p><img src="https://alejandromp.com/blog/graphql-modeling-domain-backend-driven-ui/Screenshot2.jpg" alt="Screenshot2"/><h2 id="conclusion">Conclusion</h2><p>The video is very interesting. I really recommend it if you want to see how GraphQL is used in production and how a company migrates from old technology to a modern graph.</p><p>If you need to take one thing out from all of this, it should be: learn how to model a domain. That will help you in so many aspects, not only on GQL but also in any other product development.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/publish-step-to-generate-social-images-for-your-posts</guid><title>Publish step to generate social images for your posts</title><description></description><link>https://alejandromp.com/blog/publish-step-to-generate-social-images-for-your-posts</link><pubDate>Fri, 22 Jan 2021 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>In this post I want to show you a little behind the curtain. As you may have noticed if you follow me on Twitter, recently the tweets with links to this post got a little fancier. What you may not know is that these images are generated using SwiftUI.</p><img src="https://alejandromp.com/blog/publish-step-to-generate-social-images-for-your-posts/twitter_card_example.jpg" alt="Twitter card example"/><p>I've wanted to have fancy poster images on my posts for a while, but I didn’t want to have to make them manually, or even manage them at all. Since this website is built using <a href="https://alejandromp.com/tags/publish/">Publish</a> it means I already have all the power of Swift available. And because I run the generation on macOS, it means I also have access to <a href="https://alejandromp.com/tags/swiftui/">SwiftUI</a>. So why not take advantage of that and use SwiftUI to generate the images for every post?</p><h2 id="from-swiftui-views-to-images">From SwiftUI views to images</h2><p>Getting images from a SwiftUI view is the first problem to solve. I will not discuss it much here because I already wrote a whole <a href="https://alejandromp.com/blog/swiftui-views-to-images/">post</a> about it. I also made a Swift Package that encapsulates this functionality so we can skip directly into how to bend Publish to our needs.</p><h2 id="vanilla-publish">Vanilla Publish</h2><p>To start this process, I will assume we're working with a vanilla installation of Publish. I have some tweaks and changes on the tool to facilitate some things, that I need for this website. But I will stick to the basics for this post.</p><p>The first thing to understand is that Publish already comes with support incorporate this type of images on your post. The Item has an <code>imagePath</code> property and if you check the provided Plot components; you see that the default <code>head</code> adds the twitter card as follows:</p><pre><code>.<span class="splash-call">twitterCardType</span>(location.<span class="splash-property">imagePath</span> == <span class="splash-keyword">nil</span> ? .<span class="splash-dotAccess">summary</span> : .<span class="splash-dotAccess">summaryLargeImage</span>),
</code></pre><p>That is very good! It means we just want to worry about generating the images and setting that path.</p><h2 id="the-step">The step</h2><p>To avoid having to make the images manually we will add a step that creates all the images for our posts.</p><pre><code>additionalSteps: [
    .<span class="splash-call">generatePosters</span>()
]
</code></pre><p>The structure of the step is quite typical in any Publish step:</p><pre><code><span class="splash-keyword">try</span> context.<span class="splash-call">mutateAllSections</span> { section <span class="splash-keyword">in
		try</span> section.<span class="splash-call">mutateItems</span> { item <span class="splash-keyword">in</span>
				...
</code></pre><p>We need to iterate over all items of all sections to perform the work. Note that we are using the mutating variants because once we have the poster generated we want to set its path to the item <code>imagePath</code> property so the theme can pick it up.</p><p>The rough plan for the work is as follows:</p><ol><li>Skip the generation when appropriate</li><li>Generate the poster image</li><li>Save the image</li><li>Assign the path to the item's image property</li></ol><h2 id="avoid-the-work">Avoid the work</h2><p>We want to avoid doing the work for multiple reasons. The first check we should do is to detect if the item already has an <code>imagePath</code> set. That indicates that the item already has an image associated, we don't want to overwrite that.</p><pre><code><span class="splash-keyword">guard</span> item.<span class="splash-property">imagePath</span> == <span class="splash-keyword">nil else</span> {
    <span class="splash-keyword">return</span>
}
</code></pre><p>The second reason to avoid doing the work is performance. Generating views and rendering an image out of them can be costly, especially if the site contains many posts. That's why it should only be done once and just change the image if the data used on the view changes.</p><p>Unfortunately, I haven't found a pleasant way of doing this in vanilla Publish. The context has a method to create or retrieve a cached file <code>cacheFile(named:)</code> but I haven't found a convenient way of knowing if the file was just created or already existed.</p><blockquote><p>In my website I don't use the cache because I persist the images in a different way. See below.</p></blockquote><h2 id="generate-the-image">Generate the image</h2><p>Since we already have a package to generate the image, the only thing we need is to build the actual SwiftUI view. This is what everybody can customise to best fit the style of the website. For this exercise, I’ve just created a very basic view that displays the title of the post.</p><pre><code><span class="splash-keyword">struct</span> Poster: <span class="splash-type">View</span> {
    <span class="splash-keyword">let</span> title: <span class="splash-type">String</span>
    
    <span class="splash-keyword">var</span> body: <span class="splash-keyword">some</span> <span class="splash-type">View</span> {
        <span class="splash-type">Text</span>(title)
            .<span class="splash-call">font</span>(.<span class="splash-call">system</span>(size: <span class="splash-number">200</span>))
            .<span class="splash-call">bold</span>()
            .<span class="splash-call">background</span>(<span class="splash-type">Color</span>.<span class="splash-property">gray</span>)
    }
}
</code></pre><p>The view needs to accept the data that it needs, usually data from the post or the website. In this example I'm just using the title of the post but you can use the date, tags, etc.</p><p>I recommend you to design your view to be rendered at big sizes, this will give more resolution to the final image. In the example I use a big font size to accomplish that.</p><p>With the SwiftUI view created, we can just use <a href="https://github.com/alexito4/Raster">Raster</a> to make an image out of it.</p><pre><code><span class="splash-keyword">let</span> size = <span class="splash-type">CGSize</span>(width: <span class="splash-number">1600</span>, height: <span class="splash-number">840</span>)
<span class="splash-keyword">let</span> image: <span class="splash-type">NSBitmapImageRep</span> = <span class="splash-type">Poster</span>(title: item.<span class="splash-property">title</span>).<span class="splash-call">rasterizeBitmap</span>(at: size)
<span class="splash-keyword">let</span> data = image.<span class="splash-call">representation</span>(using: .<span class="splash-dotAccess">jpeg</span>, properties: [:])
</code></pre><h2 id="save-the-image">Save the image</h2><p>This is probably the most problematic step of all. It should be simple, after all we just have to save the Data in disk. But the question is, where exactly?</p><p>In my site I treat the posters as Content and that's why I save them alongside the markdown file. That works nicely because I don't have the markdown files all in the same folder. Instead, each post has its own folder with its own resources, what we often call a "bundle". After many years of working with static site generators, I definitely think this is the best approach. That's why I just save the file in the post bundle and everything is packaged nicely.</p><p>But in a vanilla Publish installation we probably don't want that. The more basic scenario is to just save the file directly in the output directory. That's easy since we just have to combine the item path with a name for the poster image. But keep in mind that this will slow down generation.</p><pre><code><span class="splash-keyword">let</span> posterPath = item.<span class="splash-property">path</span>.<span class="splash-call">appendingComponent</span>(<span class="splash-string">"poster.jpg"</span>)
<span class="splash-keyword">let</span> file = <span class="splash-keyword">try</span> localContext.<span class="splash-call">createOutputFile</span>(at: posterPath)
<span class="splash-keyword">try</span> file.<span class="splash-call">write</span>(data)
</code></pre><h2 id="use-the-poster">Use the poster</h2><p>To use the poster we just have to assign the path of the image to the item, a supported property of Publish's Item type.</p><pre><code>item.<span class="splash-property">imagePath</span> = posterPath
</code></pre><p>And because we're using the mutate APIs they will propagate this change to the next steps of the pipeline. That's going to let the theme use this path to create the proper HTML.</p><h2 id="conclusion">Conclusion</h2><p>As you can see, the work is not very complex once you have a way to create an image from a view. The rest is working with Publish API to get the desired effect. For some things the API is a bit too restricted and you need to workaround it, but it's all possible.</p><p>If you want to use this system on your own site, you can check out the plugin that I open sourced: <a href="https://github.com/alexito4/ItemPosterPublishPlugin">ItemPosterPublishPlugin</a>. By default the plugin works as explained on this post, but it's fully customisable with closures in order to be as flexible as posible. This allows me to use the same plugin on my site, which has a different behaviour.</p><p>I would love for Publish to support officially bundled posts, a better way to detect the local path of an item and better cache interaction. With these things I could make the plugin way better by default. I understand that all of these may be requirements for a narrow use case but these things are almost the only ones that forced me to maintain my own fork of the tool.</p><p>In any case I hope you enjoyed this post and the Plugin. If you integrate this on your website be sure to <a href="https://twitter.com/alexito4">mention me on Twitter</a> so I can see your fancy post images!</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/viewbuilder-vs-anyview</guid><title>ViewBuilder vs. AnyView</title><description></description><link>https://alejandromp.com/blog/viewbuilder-vs-anyview</link><pubDate>Sun, 17 Jan 2021 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>One of the major benefits of SwiftUI is its amazing DSL. A feature that not only makes it nice to read but also makes it possible to use the type system to unlock tremendous performance benefits. <code>AnyView</code> is a view that defies all of this, and although useful in very specific circumstances, you should always try to use a better alternative.</p><p>Let's explore how all this ties together.</p><iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/_VKGEEITeYY" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><h2 id="swiftui-and-the-type-system">SwiftUI and the Type System</h2><p>One major difference of SwiftUI with other declarative UI frameworks is how it uses the power of Swift at its maximum. Swift is a statically typed language, and that opens the door to a lot of interesting techniques with real benefits.</p><p>When you create a view hierarchy in SwiftUI, it is not only encoded at runtime with a tree of instances, it's also encoded on the type system. The framework uses views with generic type parameters to define the view hierarchy.</p><blockquote><p>Watch <a href="https://youtu.be/YG5u0aFgGQI">What's behind SwiftUI DSL? - Swift Function Builders</a> to know more about SwiftUI DSL.</p></blockquote><p>Having the view hierarchy encoded in the type system lets the framework do a better job at diffing. Diffing happens when the UI needs to change. A declarative UI frameworks takes the new state of the UI, compares it with the previous one, and just performs the smaller amount of changes necessary.</p><p>It's easy to imagine how having more information available can help with this. If each decision point on a hierarchy has its own type, it means that the framework only needs to do runtime checks for the ones that can change, and even in those cases having a specific type for each case makes it easier to optimise.</p><p>To illustrate this behaviour, let's define a simple view and analyse its type.</p><pre><code><span class="splash-keyword">var</span> body: <span class="splash-keyword">some</span> <span class="splash-type">View</span> {
    <span class="splash-type">VStack</span> {
        <span class="splash-type">Text</span>(<span class="splash-string">"Hello"</span>)
        <span class="splash-type">Image</span>(systemName: <span class="splash-string">"square"</span>)
    }
}
</code></pre><p>To easily see the type, you can just change the return type to an Int and read the compiler error.</p><pre><code><span class="splash-type">Cannot</span> convert <span class="splash-keyword">return</span> expression of type '<span class="splash-type">VStack</span>&lt;<span class="splash-type">TupleView</span>&lt;(<span class="splash-type">Text</span>, <span class="splash-type">Image</span>)&gt;&gt;' to <span class="splash-keyword">return</span> type '<span class="splash-type">Int</span>'
</code></pre><p>You can see how the view hierarchy is encoded in the view's type using generic parameters. We have a <code>VStack</code> with a <code>TupleView</code> that has a <code>Text</code> and an <code>Image</code>. We can imagine how with this information the framework could be able to know with no runtime check that the hierarchy is not going to change, just the content of the leaf views.</p><p>That's nice, but having to provoke an error to see the type is quite annoying. We can implement a small extension to print out the type of a view.</p><pre><code><span class="splash-keyword">extension</span> <span class="splash-type">View</span> {
    <span class="splash-keyword">func</span> debugType() -&gt; <span class="splash-keyword">some</span> <span class="splash-type">View</span> {
        <span class="splash-call">print</span>(<span class="splash-call">type</span>(of: <span class="splash-keyword">self</span>))
        <span class="splash-keyword">return self</span>
    }
}
</code></pre><p>Adding this let us see the type of the view in the console. Much better.</p><p>But let's focus again on the return type. That <code>some View</code>. That's Swift's opaque return types feature being tremendously useful. Without that, having a framework like SwiftUI that creates such complex types would be impossible to work with.</p><blockquote><p>Watch <a href="https://youtu.be/EH8QQyCP8Oc">Swift Opaque Result Types</a> to learn more about this feature.</p></blockquote><p><code>some View</code> makes it so we don't have to know any of this internal view types and avoids a lot of boilerplate. But is crucial to understand that the type is fixed at compile time, and it must be one concrete type. You can't have multiple returns with different types, it must be always one type. In other words, opaque types don't add dynamism into the system. The function has a static type as always, it's just that you don't have to write it yourself.</p><p>And this is problematic on some occasions, for example, when you want to return two different views based on some condition.</p><pre><code><span class="splash-keyword">func</span> labelOrText() -&gt; <span class="splash-keyword">some</span> <span class="splash-type">View</span> {
    <span class="splash-keyword">if</span> showLabel {
        <span class="splash-keyword">return</span> <span class="splash-type">Label</span>(<span class="splash-string">"Bye"</span>, systemImage: <span class="splash-string">"circle"</span>)
    } <span class="splash-keyword">else</span> {
        <span class="splash-keyword">return</span> <span class="splash-type">Text</span>(<span class="splash-string">"Bye"</span>)
    }
}
</code></pre><p>This code will give you the following compiler error:</p><blockquote><p>Function declares an opaque return type, but the return statements in its body do not have matching underlying types</p></blockquote><h2 id="type-erasers-and-anyview">Type erasers and AnyView</h2><p>If you really want to have multiple types in a such a strongly typed system, there is always a scape hatch: type erasers. This is a technique that deserves its own post but suffices to say that they are quite common in Swift. The type eraser for SwiftUI views is called <code>AnyView</code>.</p><p>By wrapping a view in an <code>AnyView</code> we erase the underlying genuine type of the view. The compiler doesn't know anymore what was there, a <code>Text</code>? an <code>Image</code>? No way to know. That may seem bad, but it gives us the benefit of mixing different views.</p><pre><code><span class="splash-keyword">func</span> labelOrText() -&gt; <span class="splash-type">AnyView</span> {
    <span class="splash-keyword">if</span> showLabel {
        <span class="splash-keyword">return</span> <span class="splash-type">AnyView</span>(<span class="splash-type">Label</span>(<span class="splash-string">"Bye"</span>, systemImage: <span class="splash-string">"circle"</span>))
    } <span class="splash-keyword">else</span> {
      	<span class="splash-keyword">return</span> <span class="splash-type">AnyView</span>(<span class="splash-type">Text</span>(<span class="splash-string">"Bye"</span>))
    }
}
</code></pre><p>Although this works, it is far from ideal. By using type erasure, we're denying useful information to the framework.</p><p>So let's look at an alternative!</p><h2 id="function-builders-with-conditions">Function builders with conditions</h2><p>Wanting to return multiple views based on a condition often required to use <code>AnyView</code> in the beginning of SwiftUI. Thankfully, since Swift 5.3 function builders, the Swift feature that makes the DSL possible, added support for multiple control flow statements, including if conditions.</p><blockquote><p>Watch <a href="https://youtu.be/LKFVcc_uC60">Swift Function Builders deep dive for Swift 5.3</a> to see all the amazing things this feature can do.</p></blockquote><p>Thanks to that you can use <code>if</code> conditions in SwiftUI <code>body</code> with no problem.</p><pre><code><span class="splash-keyword">var</span> body: <span class="splash-keyword">some</span> <span class="splash-type">View</span> {
    <span class="splash-keyword">if</span> showLabel {
        <span class="splash-type">Label</span>(<span class="splash-string">"Bye"</span>, systemImage: <span class="splash-string">"circle"</span>)
    } <span class="splash-keyword">else</span> {
        <span class="splash-type">Text</span>(<span class="splash-string">"Bye"</span>)
    }
}
</code></pre><p>But we're still using <code>some View</code> as the return type. So you may ask, how are we able to have multiple types? And that's the magic, there are no multiple types, there is only a single return type. SwiftUI is using function builders to use another of its internal types, to encode the hierarchy in the type system, just as we saw before.</p><p>In this case the hierarchy has a condition, so it has a special view type for that:</p><pre><code><span class="splash-type">_ConditionalContent</span>&lt;<span class="splash-type">Label</span>&lt;<span class="splash-type">Text</span>, <span class="splash-type">Image</span>&gt;, <span class="splash-type">Text</span>&gt;
</code></pre><h2 id="use-it-in-your-own-methods">Use it in your own methods</h2><p>Being able to use <code>if</code> in the <code>body</code> is nice, but as you can see, our previous problematic example was using a separate method. That's when most people use <code>AnyView</code> or move the code into the main body property. But there is a better way.</p><p>To use SwiftUI DSL a method must be marked with a special annotation: <code>@ViewBuilder</code>. By default, a view's <code>body</code> property is marked with it, that's why we can use the DSL without by default.</p><p>But when we make our own function, we're outside the DSL world. That's why we were forced to write the <code>return</code> statements and why the power of the <code>if</code> didn't work. But we can solve it easily! Just add the annotation yourself and you are back into the DSL world.</p><pre><code><span class="splash-keyword">@ViewBuilder
func</span> labelOrText() -&gt; <span class="splash-keyword">some</span> <span class="splash-type">View</span> {
    <span class="splash-keyword">if</span> showLabel {
        <span class="splash-type">Label</span>(<span class="splash-string">"Bye"</span>, systemImage: <span class="splash-string">"circle"</span>)
    } <span class="splash-keyword">else</span> {
        <span class="splash-type">Text</span>(<span class="splash-string">"Bye"</span>)
    }
}
</code></pre><h2 id="conclusion">Conclusion</h2><p>SwiftUI uses Swift's powerful type system at its fullest. <code>some View</code> helps us not to have to write the complicated types, but it doesn't give us dynamism. Using <code>AnyView</code> denies that, so it's better to avoid it if possible. Just use <code>@ViewBuilder</code> when you are outside a view's <code>body</code> and you will be ready. That said, sometimes is still needed, so don't be afraid of it. Just know the tools you have at your disposal and pick the best for the job.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/swiftui-views-to-images</guid><title>SwiftUI views to images</title><description></description><link>https://alejandromp.com/blog/swiftui-views-to-images</link><pubDate>Sat, 9 Jan 2021 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>SwiftUI is an amazing tool to create all sorts of views in our applications. But many times we want that ease of use to generate graphics that can be used outside of apps, usually as simple image files. That's why is so useful to know how to generate images from SwiftUI views. This power unlocks a new world of possibilities!</p><p>Sadly, SwiftUI doesn't provide a native way of generating images from its views. We need to resort to tricks used in its ancestor frameworks.</p><p>The main use case that I have for this is to generate images from a command line tool, that means we need to use AppKit since the code will run in a macOS machine. You can do a very similar thing in iOS with UIKit, for example, if you want to share something via share sheets.</p><h1 id="rasterize-swiftui-views">Rasterize SwiftUI views</h1><p>SwiftUI provides a very good interoperability with AppKit. You can display SwiftUI views in AppKit views and vice versa. We can use that capability to use AppKit APIs.</p><p>First, we need to create a <code>NSHostingView</code> with the SwiftUI view that you want to create the image from.</p><pre><code><span class="splash-keyword">let</span> nsView = <span class="splash-type">NSHostingView</span>(rootView: swiftUIView)
</code></pre><p>With an <code>NSView</code> in hand, the rest of the process is no different that what you would do to rasterize a native AppKit view.</p><pre><code><span class="splash-keyword">let</span> bitmapRep = nsView.<span class="splash-call">bitmapImageRepForCachingDisplay</span>(in: nsView.<span class="splash-property">bounds</span>)!
bitmapRep.<span class="splash-property">size</span> = nsView.<span class="splash-property">bounds</span>.<span class="splash-property">size</span>
nsView.<span class="splash-call">cacheDisplay</span>(in: nsView.<span class="splash-property">bounds</span>, to: bitmapRep)
</code></pre><p>This code gives you a bitmap representation of the view. This is already an image, but one that can hardly be used. If you want to use the image in any other software is very likely that you want to convert it to a common format and save it to disk.</p><pre><code><span class="splash-keyword">let</span> data = image.<span class="splash-call">representation</span>(using: .<span class="splash-dotAccess">jpeg</span>, properties: [:])
<span class="splash-keyword">try</span> data?.<span class="splash-call">write</span>(to: path)
</code></pre><p>And that's it. Now you have a jpeg image of your SwiftUI view stored on disk. With it, you can do whatever you please! So much power!</p><h1 id="raster-package">Raster package</h1><p>I've packaged up this code in a Swift Package. You can find it on <a href="https://github.com/alexito4/Raster">GitHub</a> and even in the <a href="https://swiftpackageindex.com/alexito4/Raster">Swift Package Index</a>. If you have any suggestions or improvements, feel free to open a PR. It's not like I'm an expert on AppKit!</p><blockquote><p>If you want to know how to share a package in the Swift Package Index make sure you <a href="https://youtu.be/xRZv2AhPnBQ">watch this video</a>.</p></blockquote>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/how-to-update-swiftlint</guid><title>How to update SwiftLint</title><description></description><link>https://alejandromp.com/blog/how-to-update-swiftlint</link><pubDate>Thu, 24 Dec 2020 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>Having a good process to update your tools is very important, specially for those that affect directly your code. I've talked about <a href="https://alejandromp.com/blog/how-do-i-update-swiftformat/">how I update swiftformat</a> and this post will discuss my update process for <a href="https://github.com/realm/SwiftLint">SwiftLint</a>.</p><p>At a high level the process is very similar since the goals are the same: to have <strong>full control</strong> of what rules are run over our code.</p><h1 id="the-process">The process</h1><p>The process starts very similar as with swiftformat. First, I check and track the time it takes to run the current version of the tool to detect big regressions. Second, I check the changelog and take a quick look at what changes I will have to work trough. Then I update the binary and start the process.</p><p>In this case, I rarely go one version at a time. This is because the linter never touches our code, so I'm less afraid of regressions on a specific version.</p><p>One important detail is that I have the linter configured to only run the rules I enable manually, by using the <code>only_rules</code> option. This means that not even the default ones will run without my approval. As with the previous post, I keep <strong>all rules</strong> in the configuration, including the disabled ones, which have a friendly comment explaining why they are disabled.</p><p>To see what changes have happened, I run this command:</p><pre><code>./swiftlint rules --config ./swiftlint.<span class="splash-property">yml</span> &gt; ./swiftlinttable.<span class="splash-property">txt</span>
</code></pre><p>This saves a table with all the rules in our git repo. The git diff makes it really easy to see the new rules, and because they are all disabled, I can easily go one by one and check them out.</p><h1 id="conclusion">Conclusion</h1><p>That's it. As you can see, this one is a little more straightforward thanks the keeping a list committed in gif.</p><p>The two important things from this system are:</p><ol><li>Use <code>only_rules</code> to manually enable rules instead of relying on defaults.</li><li>Commit the list of rules in git to make use of the diff.</li></ol><p>I hope you learned a bit from reading my process and if you have a better one, make sure to reach out 😉.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/how-do-i-update-swiftformat</guid><title>How do I update swiftformat</title><description></description><link>https://alejandromp.com/blog/how-do-i-update-swiftformat</link><pubDate>Sun, 20 Dec 2020 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>Talking about how one updates a tool may seem a bit nonsensical, after all, what dificutlies can you have when updating a tool? Well, you would be surprised! But no, this post is not about issues when updating <a href="https://github.com/nicklockwood/SwiftFormat">swiftformat</a>. Quite the opposite!</p><p>I just have praises for swiftformat, it's an amazing tool. This post is just a description of the process I follow when I have to update it. The way I want to configure the tool seems to be a little out of the ordinary, so after the years I've developed a specific process with various steps. As with many things, I just have this process interiorised and I do it automatically every time I'm working on an update. But once you sit down and write it down, something I did for the internal documentation of my team, you realise that is quite involved.</p><p>The principal reason for such as process is because I want to have full control of the options and changes of the tool, something that is usually the opposite of what authors want. And that's not something bad. A tool needs to be easy to use, it needs to be ready in a couple of steps. And that works fine for most people, but I want to know exactly what rules are being applied at all times. That's why I check the changes on every update and have the configuration the way I have it.</p><h1 id="the-process">The process</h1><h2 id="configuration">Configuration</h2><p>The configuration file is set up in a way that allows me to have <strong>full control</strong> of the rules and makes it easier to update. This allows me to know exactly what will happen when formatting and don’t let new versions touch code without explicit consent.</p><p>Thankfully, swiftformat has a way to make all the rules opt-in. Which is great because this means I must specify all the rules I want, even if they would be enabled by default.</p><p>Another important point is that <strong>all the rules are listed</strong>, the ones I don’t want are commented with a <strong>reason of why they are not enabled</strong>. This helps a lot when in a future update the reason is no longer valid, because of a fix or a new option.</p><p>I also keep the <strong>list of rules ordered alphabetically</strong>, this makes it easier to detect if you already have a rule or not. In theory it shouldn't be necessary since all rules are listed, but it wouldn't be the first time I missed one!</p><p>After all the rules, there is a list of options. As with the rules, this list is ordered and contains all options, with the ones I don’t want commented and with a reason.</p><p>It’s very important that this configuration is kept with these rules, to summarise:</p><ul><li>First rules, then options.</li><li>Ordered alphabetically.</li><li>All are present, the ones I don’t want are commented with a reason.</li></ul><h2 id="update-process">Update process</h2><h3>1. Check the time it takes tor run</h3><p>Before changing the version or the configuration is necessary to record the time it takes to run in order to detect vast increases. This is quite important since with our big codebase any process takes quite a bunch of time, so I want to keep an eye to make sure it doesn't get disproportionally worse.</p><p>I use <a href="https://github.com/sharkdp/hyperfine">hyperfine</a> to benchmark command-line tools.</p><h3>2. Check the changelog</h3><p>First, I check the version that is installed by running:</p><pre><code>./swiftformat --version
</code></pre><p>Then I go to the <a href="https://github.com/nicklockwood/SwiftFormat/releases">releases page</a> and check how many releases have been since last time. At this point I take a first glance at the changes to detect any major breaking things that could block me later.</p><h3>3. Update each version</h3><p>Yes, I update each version one at a time. This is very important since I want to see what changes every version introduces and go step by step. Sometimes fixes in a version change the way things look and is very hard to detect where is the problem if you change multiple versions at once.</p><h4>3.1 Update the binary</h4><p>On each release page there is a binary attached. This is very convenient because I like to keep the binaries in the project to make sure everybody is running the same version of the tool.</p><h4>3.2 Give it a try</h4><p>I then run <code>sh format.sh</code> (a small script that runs the formatter) to see changes. Ideally nothing would have changed between versions, but sometimes there are changes that are actually desirable, due to a bugfix on the tool.</p><p>If everything looks good, I keep going.</p><p>Otherwise, if the format changes to an undesirable state, there are multiple things that I often do:</p><ul><li>Check the changelog for related fixes in upcoming versions. If there is a newer version with a potential fix I just finish the update for this version and go to the next one.</li><li>Check if a new rule or option has been added that would allow me to keep the old format.</li><li>If the format is broken after trying the recent version, I raise an issue on the repo and don’t update yet. The author is so responsive than usually there is a fix pretty quick.</li></ul><h4>3.3 Update rules</h4><p>I then check the changelog of that version for any mention of rules and options.</p><p>If there is a new rule or option, I give it a try and decide with the team what we want to do with it. If the team decides to add the rule, I make a note and do it in a separate PR (unless doesn’t affect much code). Remember that no matter if is enabled or disabled, the rule needs to be added to the config file (with explanation if disabled).</p><p>If there is an existing rule or option mentioned, I check if I have it disabled. If the changes on the rule would fix the reasons I had to disable it, I talk with the team to decide if we want to enable it now.</p><h4>3.4 Commit the changes</h4><p>This helps the PR review by having a trace of which changes were done in each version.</p><h1 id="conclusion">Conclusion</h1><p>I follow this process step by step so I know exactly what are the new changes and I can take proper decisions. It takes a bit more time that just updating willy-nilly but for me is totally worth.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/runeterra-wallpapers-downloader-tool-released</guid><title>Runeterra Wallpapers Downloader tool released</title><description></description><link>https://alejandromp.com/blog/runeterra-wallpapers-downloader-tool-released</link><pubDate>Thu, 26 Nov 2020 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p><a href="https://playruneterra.com/en-us/">Legends of Runeterra</a> has become one of my favourite games. I started playing it since the beta was available and haven't stopped since. It caught me by surprise, but it's been one of the few games that I've played for so long. It was just a question of time that I found some little project to mix the passion for this game with the passion for coding.</p><img src="https://alejandromp.com/blog/runeterra-wallpapers-downloader-tool-released/01DE012T1-full.jpg" alt="01DE012T1-full"/><p>LoR is a great card game with many good things that I could talk about for a while. I've played other collectible card games before but, apart from MtG in university, I didn't like any of them that much. But the quality of the game, its mechanics, its great pricing model it is not what I want to talk about it today. Today is all about the amazing art it has.</p><p>The first thing you see when you open the game is a stunning animated art piece of one character and region. From that point on, you just keep being more impressed by the art on every card. And not only that, but that art is telling you a story, the story of Runeterra.</p><p>Inevitably, I wanted all those amazing art pieces as wallpapers for my device. And that's why I made this little tool: <a href="https://github.com/alexito4/RuneterraWallpapersDownloader">Runeterra Wallpaper Downloader</a>.</p><img src="https://alejandromp.com/blog/runeterra-wallpapers-downloader-tool-released/03PZ001-full.jpg" alt="03PZ001-full"/><p>This tool downloads the <a href="https://developer.riotgames.com/docs/lor#data-dragon">official card assets</a> from Legends of Runeterra and copies the card full screen art into the desired location. I built this to help me keep up to date the wallpapers every time a new set is released. Doing it manually takes too much time since the assets come organised in folders that have together the card images and the full screen art, also those folders contain images for the spells which don't have big images that can be used as wallpapers.</p><p>The tool is of course built with <strong>Swift</strong> following the typical SPM structure for CLI tools: there is a package with the core code and an executable target with just the CLI. It makes it super nice to work with, and it allows the core code to be used in other projects.</p><p>As always, I have some more ideas for improvements that could be nice to do at some point. But as it is right now is usable, so there is no reason to hold it back. I want everybody to enjoy the amazing art of Runeterra!</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/swift-s-optional-equitability</guid><title>Swift's Optional equitability</title><description></description><link>https://alejandromp.com/blog/swift-s-optional-equitability</link><pubDate>Tue, 27 Oct 2020 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>Optional equitability is one of those aspects of Swift that seems simple at a first glance but that makes you stop and think twice when you encounter it in actual code. The good thing is that once you pause and look at it you realise is trivial.</p><p>As always, let's start with an example type:</p><pre><code><span class="splash-keyword">struct</span> Object {
    <span class="splash-keyword">let</span> flag: <span class="splash-type">Bool</span>
}
</code></pre><p>Let's pretend that your code receives an optional instance of this type: <code>Object?</code>. Optional equitability becomes important when in your code you want to do something with the flag directly like so:</p><pre><code><span class="splash-keyword">if</span> object?.<span class="splash-property">flag</span> {
    ...
}
</code></pre><p><code>flag</code> is a boolean so you may expect that to work, and in other languages it might, with some rules you have to learn of it behaviour and its corner cases. But in Swift the compiler will forbid this dangerous code giving you this error message:</p><pre><code><span class="splash-type">Optional</span> type '<span class="splash-type">Bool</span>?' cannot be used <span class="splash-keyword">as</span> a boolean; test <span class="splash-keyword">for</span> '!= <span class="splash-keyword">nil</span>' instead
</code></pre><p>That's an unfortunate error message because its suggestion has nothing to do with what you want. Yes, you could bind the object to a new variable with <code>if let</code> but that introduced new names into your code that only increase the cognitive overload while reading the code.</p><p>But don't worry, you can convince the compiler to treat that expression as a boolean. You just need to explicitly use the equitability operator <code>==</code>:</p><pre><code><span class="splash-keyword">if</span> object?.<span class="splash-property">flag</span> == <span class="splash-keyword">true</span> {
    ...
}
</code></pre><p>The best way to understand how this works is to analyse all the cases that this interaction has. Remember that you are not dealing with a boolean here, but with an optional boolean. This means you have three cases: <code>true</code>, <code>false</code> and <code>nil</code>.</p><p>If we declared the cases as variables they would look like this:</p><pre><code><span class="splash-keyword">let</span> oT:    <span class="splash-type">Object</span>? = <span class="splash-type">Object</span>(flag: <span class="splash-keyword">true</span>)
<span class="splash-keyword">let</span> oF:    <span class="splash-type">Object</span>? = <span class="splash-type">Object</span>(flag: <span class="splash-keyword">false</span>)
<span class="splash-keyword">let</span> oNil:  <span class="splash-type">Object</span>? = <span class="splash-keyword">nil</span>
</code></pre><p>Now let's try all the equalities and see their results:</p><pre><code>oT?.<span class="splash-property">flag</span> == <span class="splash-keyword">true</span>			<span class="splash-comment">// true</span>
oF?.<span class="splash-property">flag</span> == <span class="splash-keyword">true</span>			<span class="splash-comment">// false</span>
oNil?.<span class="splash-property">flag</span> == <span class="splash-keyword">true</span>			<span class="splash-comment">// false</span>

oT?.<span class="splash-property">flag</span> == <span class="splash-keyword">false</span>			<span class="splash-comment">// false</span>
oF?.<span class="splash-property">flag</span> == <span class="splash-keyword">false</span>			<span class="splash-comment">// true</span>
oNil?.<span class="splash-property">flag</span> == <span class="splash-keyword">false</span>			<span class="splash-comment">// false</span>

oT?.<span class="splash-property">flag</span> == <span class="splash-keyword">nil</span>				<span class="splash-comment">// false</span>
oF?.<span class="splash-property">flag</span> == <span class="splash-keyword">nil</span>				<span class="splash-comment">// false</span>
oNil?.<span class="splash-property">flag</span> == <span class="splash-keyword">nil</span>			<span class="splash-comment">// true</span>
</code></pre><p>With these examples in mind I hope you can now see how it works. A good mental model to follow is to think that what the compiler is doing is <em>promoting</em> the literal to an optional and just comparing those.</p><p>In our case we could rewrite the example to make it more obvious:</p><pre><code><span class="splash-keyword">if</span> object?.<span class="splash-property">flag</span> == <span class="splash-type">Optional</span>(<span class="splash-keyword">true</span>) {
    ...
}
</code></pre><p>Once you realise that you are dealing with optionals, and not boolean, in both sides and that you have three cases instead of two, the results become obvious.</p><p>But even so, I would like you to take a closer look at one specific combination:</p><pre><code>oNil?.<span class="splash-property">flag</span> == <span class="splash-keyword">false</span>			<span class="splash-comment">// false</span>
</code></pre><p>This just says that <code>nil</code> is different than <code>false</code>. This is obvious because they are two different cases of the three we have available. But if you are used to other languages, this may trip you out since you could imagine that <code>false</code> and <code>nil</code> are equivalent. Be careful with this one.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/how-to-capture-a-reference-that-doesn-t-exist-yet</guid><title>How to capture a reference that doesn't exist yet</title><description></description><link>https://alejandromp.com/blog/how-to-capture-a-reference-that-doesn-t-exist-yet</link><pubDate>Mon, 19 Oct 2020 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>Sometimes when writing Swift code you want to reference an instance before its creation. It's not a very common, which is why I'm writing this post so I can easily remember it next time it happens.</p><p>To have an example to work with, let's pretend we want to link a custom <code>UIViewController</code> with its <code>ViewModel</code>. This is a typical scenario when building UIKit apps, but the same can apply to any other scenario that involves two classes, inits and closures.</p><h2 id="the-ingredients-for-a-problematic-cycle">The ingredients for a problematic cycle</h2><p>One ingredient for this scenario to occur is that you want to inject all dependencies through the initialiser of an object. Yes, there are other ways of injecting dependencies, and if we use any of them this problem would go away. The most common, that you can use in any codebase, is doing injection via a property. But I don't like that at all since it forces your class to deal with optionals (or implicitly unwrapped optionals if you're brave enough) and that just introduces more burden.</p><p>The second ingredient you need is a dependency to a closure. This is not typically a problem unless during the creation of the closure you need to reference an uninitialised object.</p><p>And that's the third ingredient you need, a cycle. The cycle appears when the object you need in the closure needs the object you're initialising with the closure itself. You can't have one without the other, so you must find a way to break the cycle.</p><p>Put in a concrete example:</p><pre><code><span class="splash-keyword">class</span> ViewController {
    <span class="splash-keyword">let</span> viewModel: <span class="splash-type">ViewModel</span>
    
    <span class="splash-keyword">init</span>(viewModel: <span class="splash-type">ViewModel</span>) {
        <span class="splash-keyword">self</span>.<span class="splash-property">viewModel</span> = viewModel
    }
    
    <span class="splash-keyword">func</span> run() {
        viewModel.<span class="splash-call">closure</span>() <span class="splash-comment">// for example</span>
    }
}

<span class="splash-keyword">class</span> ViewModel {
    <span class="splash-keyword">let</span> closure: () -&gt; <span class="splash-type">Void</span>
    
    <span class="splash-keyword">init</span>(<span class="splash-keyword">_</span> closure: <span class="splash-keyword">@escaping</span> () -&gt; <span class="splash-type">Void</span>) {
        <span class="splash-keyword">self</span>.<span class="splash-property">closure</span> = closure
    }
}

<span class="splash-keyword">func</span> create() -&gt; <span class="splash-type">ViewController</span> {
    <span class="splash-keyword">let</span> viewModel = <span class="splash-type">ViewModel</span> {
        <span class="splash-comment">// access viewController here</span>
    }
    <span class="splash-keyword">let</span> viewController = <span class="splash-type">ViewController</span>(viewModel: viewModel)  
    <span class="splash-keyword">return</span> viewController
}
</code></pre><p>As you can see, the <code>ViewController(viewModel: viewModel)</code> needs the <code>viewModel</code>. But <code>let viewModel = ViewModel { ... }</code> needs the <code>viewController</code>. Congratulations, you just cooked a problematic cycle.</p><h2 id="reference-the-future">Reference the future</h2><p>The fix for the problem is quite obvious at a first glance. You just need to have a reference to a variable that will be set later.</p><pre><code><span class="splash-keyword">let</span> viewController: <span class="splash-type">ViewController</span>
<span class="splash-keyword">let</span> viewModel = <span class="splash-type">ViewModel</span> {
    viewController...
}
viewController = <span class="splash-type">ViewController</span>(viewModel: viewModel)  
<span class="splash-keyword">return</span> viewController
</code></pre><p>But that's easier said that done. Because the compiler, caring so much for our safety, won't let us declare a variable and use it before it's initialised. And capturing it in the closure counts as a usage.</p><img src="https://alejandromp.com/blog/how-to-capture-a-reference-that-doesn-t-exist-yet/Screenshot 2020-10-19 at 17.55.26.png" alt="Screenshot 2020-10-19 at 17.55.26"/><p>To have an uninitialised variable we need to use an Optional, but then you also need to use a <code>var</code>, otherwise you will be forced to assign it before usage.</p><pre><code><span class="splash-keyword">var</span> viewController: <span class="splash-type">ViewController</span>?
<span class="splash-keyword">let</span> viewModel = <span class="splash-type">ViewModel</span> {
    viewController?.<span class="splash-call">run</span>()
}
viewController = <span class="splash-type">ViewController</span>(viewModel: viewModel)
<span class="splash-keyword">return</span> viewController!
</code></pre><p>Now this works, as in, you can access the instance inside the closure and the compiler is happy about it. But... congratulations! You just created a reference cycle.</p><h2 id="avoiding-the-reference-cycle">Avoiding the reference cycle</h2><p>We can easily see the reference cycle that is created from the above code:</p><img src="https://alejandromp.com/blog/how-to-capture-a-reference-that-doesn-t-exist-yet/ViewController.png" alt="ViewController"/><p>If we focus on the closure, this is not a new issue, Swift developers are used to keep an eye for reference cycles on closures. Typically, we need to be careful with <code>self</code> but in this case we need to be careful with <code>viewController</code>. So let's do the obvious thing and add a capture list that weakifies the instance.</p><pre><code><span class="splash-keyword">var</span> viewController: <span class="splash-type">ViewController</span>?
<span class="splash-keyword">let</span> viewModel = <span class="splash-type">ViewModel</span> { [<span class="splash-keyword">weak</span> viewController] <span class="splash-keyword">in</span>
    <span class="splash-call">print</span>(<span class="splash-string">"access viewController here:</span> \(viewController?.<span class="splash-property">viewModel</span>)<span class="splash-string">"</span>)
}
viewController = <span class="splash-type">ViewController</span>(viewModel: viewModel)
<span class="splash-keyword">return</span> viewController!
</code></pre><p>This indeed breaks the cycle, but if you run it will see this output:</p><pre><code>access viewController here: <span class="splash-keyword">nil</span>
</code></pre><p>What is happening here is that the capture list is creating a new weak variable that points to the same memory as the original one. Yes, <strong>a new variable</strong>. That means that what the closure is capturing is a pointer to <code>nil</code> and that won't change no matter what we do later. So when we're assigning the instance later, we are not changing the variable inside the closure, only the one outside.</p><p>To solve this problem, we need to cook the weak variable manually.</p><h2 id="manual-weak">Manual weak</h2><p>Since we can use the capture list, we must reference the original variable. And to avoid the retain cycle, we must have a weak reference. Luckily for us we can declare a local weak variable (something <a href="https://forums.swift.org/t/best-way-to-approach-a-cycle-between-two-classes-and-a-closure-at-init/41294">I forgot</a>).</p><pre><code><span class="splash-keyword">weak var</span> viewController: <span class="splash-type">ViewController</span>?
<span class="splash-keyword">let</span> viewModel = <span class="splash-type">ViewModel</span> {
    <span class="splash-call">print</span>(<span class="splash-string">"access viewController here:</span> \(viewController?.<span class="splash-property">viewModel</span>)<span class="splash-string">"</span>)
}
viewController = <span class="splash-type">ViewController</span>(viewModel: viewModel)
</code></pre><p>We just need to add <code>weak</code> on the declaration and remove the capture list.</p><p>But now we have yet another problem. Since the variable is weak, it means nobody is retaining the instance and keeping it in memory. As soon as the method execution ends the <code>viewController</code> will get deallocated.</p><img src="https://alejandromp.com/blog/how-to-capture-a-reference-that-doesn-t-exist-yet/Screenshot 2020-10-19 at 18.25.35.png" alt="Screenshot 2020-10-19 at 18.25.35"/><p>To solve this, we need to make sure we keep a strong reference to the instance. We need to have two variables, a weak one for the closure and a strong one to retain it. And we need to assign the instance to both of them.</p><pre><code><span class="splash-keyword">weak var</span> weakViewController: <span class="splash-type">ViewController</span>?
<span class="splash-keyword">let</span> viewModel = <span class="splash-type">ViewModel</span> {
    <span class="splash-call">print</span>(<span class="splash-string">"access viewController here:</span> \(weakViewController?.<span class="splash-property">viewModel</span>)<span class="splash-string">"</span>)
}
<span class="splash-keyword">let</span> viewController = <span class="splash-type">ViewController</span>(viewModel: viewModel)
weakViewController = viewController
</code></pre><p>And this is the result. We successfully got a reference to an object that still doesn't exist and we made sure there were no retain cycles.</p><p>If your code is more complex than this simple snippet, I recommend you to drop an assertion to make sure your future self doesn't forget to assign the instance, without an assert this would silently fail.</p><img src="https://alejandromp.com/blog/how-to-capture-a-reference-that-doesn-t-exist-yet/Screenshot 2020-10-19 at 18.28.04.png" alt="Screenshot 2020-10-19 at 18.28.04"/><h2 id="conclusion">Conclusion</h2><p>Mostly, Swift lets us forget about memory management and references but it's always good to know what's going on under the hood to be able to solve these scenarios when they inevitably occur.</p><p>It's also very nice how the compiler has give us errors and warnings on <em>almost</em> every step of this process.</p><p>Next time I won't forget I can use <code>weak</code> in local variables ^^</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/is-mistborn-my-new-favorite-novel</guid><title>Is Mistborn my new favorite novel?</title><description></description><link>https://alejandromp.com/blog/is-mistborn-my-new-favorite-novel</link><pubDate>Sun, 20 Sep 2020 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>Last night I finished Mistborn, The Final Empire. And I have to say: I loved it! If it’s not my new favorite story it’s very close.</p><p>As I teased last time, this is my entrance into Brandon Sanderson’s Cosmere. On March 2019 I tried with The Way of Kings, but I was not mentally at the right time to take an epic fantasy story. So that year I went for something lighter. When I decided that it was time to start with Brandon’s books again, I preferred to avoid its bigger piece. After putting on pause The Wheel of Time I wanted something smaller, more approachable.</p><p>I’ve always had a curiosity for Mistborn. I think it’s the name that attracted me first. It makes my imagination fly. But then when i heard it was a fantasy heist plot, I got overly excited. Ocean’s Eleven, but with magic? Heck yes! And now that I’ve finished the first book, I annoyed that I didn’t read it sooner!</p><p>As my first Sanderson’s book I have to say that I really like how he writes. I’m sure the style will vary from book to book, but I found Mistborn’s prose very good but approachable. Something that as a non-native speaker I really appreciate.</p><p>The characters are lovely. Not only the main two but also the rest of the crew. Vin is arguably the principal character of the story and it has been very enjoyable to see her grow, from the first chapter to the last. She has learned and changed a lot, but you can still see her past self in her. It’s so well done.</p><p>The plot makes you flip pages like there was no tomorrow. There are no slow parts. Even the chapters with less action, there is still something very interesting happening. There is no filling. The plot moves page after page. If there is one detail to comment is that the heist itself takes a bit of a back sit, but it’s to focus on the characters and make them shine, so it’s all for a good purpose. And don’t get me wrong, the heist is still there. Is the main driver of the story. It’s just not a one hour film where everything that matters is how to rob the bank. It’s way more than that!</p><p>And the setting? Well, well well. The setting is so vivid in my mind. It’s so different that I really feel like I was running through the mists at night with our protagonists. And the best thing is that it doesn’t take much time boring you with explanations of it. Sanderson is able to sell us this world with very little. No filling.</p><p>But let’s get to what had me more curious. The magic system. A hard magic system. Pretty much everything I read has been soft magic systems, and I was very expectant to see what everything was praising Brandon for, the king of magic systems. Well, people were not mistaken. He delivered. Now, if you don’t get pumped up by details about how magic works, this may not excite you as much. And it’s truth that there is a bunch of word count dedicated to the magic by necessity. But even if you are not a fan of this style I think you will like it because it’s so well woven into the character development and action scenes that I don’t think there is a single paragraph where you will be bored.</p><p>And those action scenes! Between the characters, the big plot behind each scene and the spectacular magic, I would say that Mistborn has some of the best action scenes I’ve ever read. And there are a lot of them.</p><p>Finally, the world building. As I said the, setting is magnificent, but it doesn’t stop there. The wider world and universe are what interests me the most. Being able to finish this book and step into the bigger world of the Cosmere is something I’ve wanted to do for a while. And just with this book, I can already see glimpses of what could be. I’m eager to enjoy the discovery.</p><p>So yes, I don’t know if this is my favorite novel, but it is. And the best thing is that Brandon is a machine, and he keeps writing and writing. So I signed up for an amazing long ride!</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/pausing-the-wheel-of-time</guid><title>Pausing The Wheel of Time</title><description></description><link>https://alejandromp.com/blog/pausing-the-wheel-of-time</link><pubDate>Sun, 30 Aug 2020 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>This year I got into <a href="https://alejandromp.com/blog/getting-into-the-wheel-of-time/">The Wheel of Time</a> series. I wanted to get a test of this well renown epic fantasy before the TV show aired. I’m sure the show will be good, but is going to differ from the books for sure. You can’t adept fourteen thousand pages book without cutting corners.</p><p>So I went for the first and thought it was fine, but not amazing. It was the first one and seemed like an introduction to the world with not a lot of interesting action. So I kept going. Now I finished the fifth entry on the series, The Fires of Heaven. And I’m still with this weird sensation of missing something.</p><p>The book is wonderful, but I don’t think is such as amazing as the huge fans say. And that’s normal. They wouldn’t be fans otherwise. But I’m talking about myself here.</p><p>The characters are very well realised, and there are a lot of them. Which maybe is the big problem for me? Too many characters. I know their stories and interwoven, but I can’t avoid the feeling of being lost every time the scene changes. That’s probably my fault. To read epic fantasy, you need to be well versed on novels, so maybe I’m just not there yet.</p><p>The magic is very, very interesting. It’s not a hard magic system by any means, but the combination of different sources of magic and styles in the same story is super interesting. It’s something that is very close to my fantasy world. Maybe I should have read this long ago!</p><p>The plot is also very, very interesting. Is an epic fantasy after all. The world is at risk of being destroyed by the evil overlord, and our main characters need to stop it. But that’s not it, there are a lot of subplots happening constantly. Each character pursuing their own motivations without forgetting about the big picture.</p><p>When you read that it seems like the best thing in the world. And I keep thinking about that. Or at least about the promise of that. But after finishing every book, I can’t stop feeling that not much has happened. Yes, the plot has moved forward and the characters have grown, but the proportion of that with the number of pages is way too low for my taste.</p><p>And for other people that may be fine, since all those extra pages are dedicated and making us feel like part of the world. This immense world with very detailed cultures. But I guess I want a bit less of that and more action. And I FEEL BAD for saying that about world-building, which is one of my passions. But really, I don’t need hundreds of pages to tell me how Aiel are.</p><p>As the Spanish meme says...</p><img src="https://alejandromp.com/blog/pausing-the-wheel-of-time/maxresdefault.jpg" alt="maxresdefault"/><p>I still like the books. And I still want to keep reading and finish it. But is a daunting task. With the feeling of not much happening on every book and still nine books to go. Without mentioning that apparently on the seventh one there is a big depression where the pacing slows down, even the fans have trouble with those. So I’m scared. I don’t want to leave it, but it won’t be easy.</p><p>So my plan is to pause it before I burn out of it. I want to go back to it after the first season of the show airs, and I’m hooked by the story and the characters again. But for now, I want to disconnect for a bit.</p><p>So what’s next?, you may ask. Well, it is time to taste a hard magic system.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/my-new-and-old-hobby</guid><title>My New and Old hobby</title><description></description><link>https://alejandromp.com/blog/my-new-and-old-hobby</link><pubDate>Thu, 20 Aug 2020 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>When I was younger, I loved fantasy so much that I always wanted to make a world of my own. When I was around fourteen, I started doing it. Yes, I started writing a novel. I still have it in my hard drive. It’s very cheesy, but I find in there the dreams of a younger me. And the interesting thing is that those dreams never died off.</p><p>When I decided to pursue a career on software development is not just because of the technical aspect of it, but also because I was a very creative person. If have never written code you may not relate it to creative thinking, but it is. Think about it this way: you are literally creating something, whatever you want, from nothing. That’s what made me go to university to study computer science. The freedom and limitless creative possibilities of it.</p><p>Those old word documents of mine got lost between a plethora of other hobbies and life. But one of the major reasons for my younger self to stop writing was that was not a good writer. We wrote and shared our text with a group of close friends, yes we had a writing group even without knowing that was a thing, and their prose was much better than mine. So I knew that pursuing a professional career in writing was out of my reach.</p><p>And that was the big mistake.</p><p>No. I’m still convinced I don’t have enough skill to be a good writer. You won’t see my novel in a bookshelf. I was correct in that. The mistake was about thinking writing <em>had to be</em> a professional career. Nobody had ever told me that writing could be just a hobby. And that’s something that is very rotten in our society. We all played on some sports team. As a hobby, nobody was pursuing being a pro realistically. It was just fun and healthy. I even did drawing and painting classes. As a hobby. But writing? When you think about writing you immediately think about those authors that have been blessed with enough skill to be in a bookshelf.</p><p>So I didn’t write for many years.</p><p>I, and my friends, made a similar mistake with D&amp;D. We heard it was too hard, and since we didn’t have examples, we just accepted it was too difficult for us. So we never played. But then in my late twenties I discovered FATE, Critical Role and the D&amp;D renaissance. Suddenly role-playing seemed something we could enjoy doing, but now with a friend on each corner of the world not that easy. Too late.</p><p>But that didn’t stop me of organizing some sessions when we were together. And we had fun. Or at least I had. I went from never playing to being the dungeon master, skipping the player position completely. And I loved it! For the first time in years, I could externalise somehow the world that my mind has been creating for twenty years.</p><p>And finally, early this year, I started being curious again. It all started by being hooked up with fantasy again. When I decided to read <a href="https://alejandromp.com/blog/getting-into-the-wheel-of-time">The Wheel Of Time</a> I started hearing more and more about Mr. Sanderson and his part in finishing the series. I’ve heard about him before and I still have on my list getting into his world. But his charisma made me follow him, even reading nothing from him yet.</p><p>Then is when I discovered he had a complex inter-winded world of fantasy, the Cosmere. Something very exciting because an inter-connected fantasy world is something that excites me a lot. And then I found out he does university classes about writing fantasy and sci-fi and, more importantly, they are available online. So one night, alone, during the pandemic, I decided to take a look.</p><p>And it changed my perception on writing.</p><blockquote class="twitter-tweet" data-dnt="true" data-theme="dark"><p lang="en" dir="ltr">I finished watching <a href="https://twitter.com/BrandSanderson?ref_src=twsrc%5Etfw">@BrandSanderson</a> 2016 lectures and now 2020 show up! :D The introduction is great, I wish somebody had told me &quot;writing can be JUST a hobby&quot; 15 years ago. Funny how when I was on my 14/15 I actually wrote half a book, and started another<br>But I stoped.</p>&mdash; Alejandro Martinez (@alexito4) <a href="https://twitter.com/alexito4/status/1220475593260720129?ref_src=twsrc%5Etfw">January 23, 2020</a></blockquote><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script><p>Are you saying that I can write just for fun? Without having to suffer because not fulfilling expectations? SAY WHAAAT?</p><p>So I opened Scrivener. Recovered the old documents of my novels, pulled the world-building from my D&amp;D sessions and started writing.</p><p>Even at that point I was not convinced that I could write a novel, I’m still not sure to be honest. So I just started with the mission of keeping memories. As I said before, I’ve been building this fantasy world with dozens of stories in my head for many years. Of course not everything is good material, but my brain has been an imagination machine for a long time. But I’m a human that is getting old, and those memories from fantastic worlds, creatures and battles will fade away at some point. So my task was just to write a list of what my imaginary characters have gone trough. Keep a list of the major story lines, how they connect and the peculiarities of my world.</p><p>But you can guess what happened.</p><p>That sparked a wave of inspiration in me again. With everything that has been happening this year, and spending so much time alone enclosed at home with my girl int he other side of the world the fantasy realm was a more comfortable place to be. So I took the present story that my brain was developing and started writing it down.</p><p>Of course things have to change a bit when you put them on paper, but overall I’m excited about it. My plan is to finish it before my next birthday. I don’t want to leave other parts of my leave behind, but I think I will dedicate a bunch of time to this.</p><p>We’ll see how it goes. There is no pressure. Is just for fun.</p><p>It’s my new old hobby.</p><blockquote class="twitter-tweet" data-dnt="true" data-theme="dark"><p lang="en" dir="ltr">I&#39;ve had this in the back of my head for too long so I decided to do something about it. Last year I promised to myself to ship a new app just for myself to have fun again. So this year I will try to finally write a novel, I&#39;ve been ignoring this passion of mine for too long. <a href="https://t.co/5xFnImJAUS">https://t.co/5xFnImJAUS</a></p>&mdash; Alejandro Martinez (@alexito4) <a href="https://twitter.com/alexito4/status/1296356166235193346?ref_src=twsrc%5Etfw">August 20, 2020</a></blockquote><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/mocks-protocols-and-boilerplate</guid><title>The Dogma of Mocks and Protocols</title><description></description><link>https://alejandromp.com/blog/mocks-protocols-and-boilerplate</link><pubDate>Tue, 4 Aug 2020 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>This post is a personal opinionated piece around unit testing and the dogmas of our industry. Be sure to come here with an open mind and respectul toughts. I will also link to some <a href="https://www.pointfree.co/subscribe/personal?ref=4Fj20c5I">Pointfree</a> content so make sure you check them out.</p><h2 id="the-abstraction-dogma">The abstraction dogma</h2><p>We all know that unit testing the logic of your code is important. Over the years the industry has created tons of material explaining how abstracting your types with protocols (a.k.a. interfaces) is the best way to accomplish maintainable and testable code.</p><p>Although some of it is objectively true. There is a lot of dogma and close mindedness in a lot of the narrative surrounding tests and architecture. I've personally always been in two minds on this topic (and many others, which is hard in today's extremist world).</p><p>Yes, I do love a good unit testing suite but no, I don't want to force my code into a <strong>complex net</strong> of systems <strong>just</strong> to make unit testing easier.</p><p>Many will argue that unit testing is a tool that helps shaping and designing good code, and again, I agree partially. When they teach you how to do unit testing and use interfaces they often forget to tell you that every interface you add to your code increases its complexity. There is more stuff to keep in your head, and more files you need to click trough to finally read the code that really matters.</p><p>The more code I need to maintain the more I appreciate simplicity. As a young engineer I bought into the OOP dogma and tended to implement <em>future proof</em> systems with protocols and <em>abstractions</em> all over the place. I was so naive.</p><p>We've seen this attitude get into the mindset of iOS developers with things like VIPER that are so overly complicated that everybody runs away just by hearing its name. And again, I'm pretty sure there are places where deploying a system like this is worth the complexity that it adds.</p><p>Personally, nowadays, if I can use a concrete type and avoid having protocols all over the place I'm a much happier programmer, and so is the rest of the team.</p><h2 id="the-useless-abstraction">The useless abstraction</h2><p>Abstractions are good when they are good abstractions. When they create a new language that helps us talk in a higher level way about a problem. In those occasions a protocol becomes a good abstraction, when it emerges from the design of a solution to a problem. But that's not what protocols required by unit testing are. And in Swift we tend to make a lot of those since runtime hackery is not at the level that we need to fully mock all objects.</p><p>That's why I'm so happy to see an impactful site like Pointfree talk about this. I'm not gonna put words on their mouth, maybe I interpreted too much on their words, but their current series of episodes felt like a liberating chant. Finally!</p><blockquote><p>But, just because it’s popular doesn’t mean it can’t be improved. - PointFree about <a href="https://www.pointfree.co/episodes/ep110-designing-dependencies-the-problem#t1693">protocol-oriented problems.</a></p></blockquote><p>The problem with the protocols that show up from unit testing is that they are only necessary for unit testing. If you have a very complex piece of software that require multiple implementations that can be used trough a single interface, then yes, by all means, use protocols!</p><p>I'm gonna leave here a quote from Pointfree's video about <a href="https://www.pointfree.co/episodes/ep110-designing-dependencies-the-problem">dependencies</a>. It summaries very well the thoughts that I've been having for years but that are so hard to merry with the dogma that permeates our industry.</p><blockquote><p>There is something a little strange about what we have come up with so far. We created a protocol to abstract away the interface of getting weather results, but only created two conformances: a live one that makes an API request and a mock one that synchronously returns mocked data. - PointFree about <a href="https://www.pointfree.co/episodes/ep110-designing-dependencies-the-problem#t1693">protocol-oriented problems.</a></p></blockquote><p>It has always smelled badly to me the fact that we're so happy just making a protocol to make unit testing happy.</p><blockquote><p>A protocol that only has two conformances is not a strong form of abstraction. There is not a single protocol that Apple gives us that is meant to only have two conformances. For example, the <code>Sequence</code> and <code>Collection</code> protocols have dozens of conformances. - PointFree about <a href="https://www.pointfree.co/episodes/ep110-designing-dependencies-the-problem#t1693">protocol-oriented problems.</a></p></blockquote><h2 id="when-reality-strikes-again">When reality strikes again</h2><p>But of course, as with many topics that I talk about in this blog, reality is here to stay. It's very likely that you are working in a codebase that requires this unit testing protocols because there is no other way of doing it. Even if adopting some of Pointfree's ideas wouldn't take too long we already have work to do and we can't stop the printing press just for this.</p><p>So here's my tip, something that I've been doing recently.</p><p>Embrace that those protocols must exist and accept that, on their own, they don't add anything valuable to your codebase. They are just there for unit testing. They are just there to create boilerplate. And what do we do with boilerplate? We summon a sorcerer!</p><img src="https://alejandromp.com/blog/mocks-protocols-and-boilerplate/sorcerer.gif" alt="sorcerer"/><p>I used <a href="https://github.com/krzysztofzablocki/Sourcery">Sourcery</a> to generate all the boilerplate necessary to have nice unit tests.</p><pre><code><span class="splash-comment">// sourcery: AutoProtocol, AutoMockable</span>
<span class="splash-keyword">final class</span> AuthenticationDataManager
</code></pre><p>Just with that annotation you get a protocol that reflects the public interface of the type and a mock implementation with a lot of helpers to know what method has been called, to fake return values, etc.</p><p>I haven't invented anything here. <a href="https://github.com/krzysztofzablocki/Sourcery/blob/master/Templates/Templates/AutoMockable.stencil">AutoMockable</a> comes with Sourcery and AutoProtocol is a modification of this <a href="https://github.com/AliSoftware/SourceryTemplates#autointerface">AutoInterface</a> template. What I've done has been tweak a little both of them.</p><p>First because AutoInterface naming is too close to Java for my taste. I don't want to see <strong>I</strong>Type in a Swift codebase. We prefer to use <code>Protocol</code> as a suffix.</p><p>And second, because these templates are thought to be used individually. You can get a protocol from a class. And you can generate a mock from a protocol. But what I wanted is that from a concrete type that I write, to first get a protocol for it, and from that protocol get a mock. This is not hard to do but it requires modifications and some duplication in the templates.</p><p>This is not perfect. You still need to be aware of the existence of the protocol because that's what you need to use on your consuming types. But at least you don't have to write the boilerplate and it makes sure that everything is always in sync.</p><p>I leave the templates that I'm using in this <a href="https://gist.github.com/alexito4/75a085b2cb54a7969c036efa65e74c3f">Gist</a>.</p><h2 id="conclusion">Conclusion</h2><p>As usually, just have an open mind and don't follow dogmas blindly. Just with that you will be a much happier programmer, and human being ^^.</p><p>Protocols are nice and powerful but don't over use them. Especially if they don't add any value as an abstraction.</p><p>And finally <a href="https://www.pointfree.co/subscribe/personal?ref=4Fj20c5I">check out Pointfree</a>. I'm in no way affiliated to them (apart from that link being an affiliate link LUL) but their content is so good that I can't miss any opportunity to recommend it.</p><p>Thanks for reading.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/goodprogress-release</guid><title>GoodProgress has been released</title><description></description><link>https://alejandromp.com/blog/goodprogress-release</link><pubDate>Sat, 25 Jul 2020 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>My birthday is the middle of July, seven days from now, which has always made me consider summer as the division between years. That mentality was reaffirmed when as a teenager I got hooked up on TV Shows. Those shows are broken down in seasons, and usually summer was that weird space between seasons without much interesting content to watch.</p><p>Last year, at the start of my new season, I made myself a promise: release a new iOS app. I've been an iOS developer for many years now. But at some point I stopped making apps for myself. I was busy with work and life, and the time that I had I put it in experiments to learn and explore new things. Swift has been a big topic on this space, but also the blog, making videos... I never stop learning or creating, but it's true that finishing a personal project is not something I'm very good at.</p><p>So here I am. One year later with an App on the Store. I present to you <a href="https://apps.apple.com/us/app/id1518492878">GoodProgress</a>!</p><img src="https://alejandromp.com/blog/goodprogress-release/goodprogress_appstore.jpg" alt="goodprogress_appstore"/><p>GoodProgress was born from necessity and curiosity.</p><p>Since I'm recovering the love for reading and fantasy I needed to build an app to help me keep track of the progress of books. You know that I love tracking progress, remember WishFilms? Well, for books Goodreads is basically the go to website. There is very little to no competition. And it's noticeable because the web and apps are quite bad.</p><p>Without exaggerating: between navigating the confusing interface, waiting for pages to load and fighting the constants bugs it can take you up to a minute to update the progress of your book. I wanted something quick and fast.</p><p>And that's how this app idea took shape. I just needed a single screen with the book I'm reading and a big fat button to update the progress. That was my primary motivation.</p><p>SwiftUI and the promise of WWDC showing us a more polished version of it was exciting too. So I decided, after working with <a href="https://alejandromp.com/tags/swiftui/">SwiftUI</a> for a year, to put something on the store with it, combined with <a href="https://alejandromp.com/tags/pointfree-composable-architecture/">The Composable Architecture</a>.</p><p>But making an app like that would be too easy, right? Well, yes, except that the Goodreads API is worse than their app. Just read this: XML. Yes, in 2020. And the format of the responses is not such a big deal as so many developers on the community forum pretend to be. The real problem here is that the API is not maintained at all. The documentation is worse than generated docs. API calls missing or not working at all. And the worse, in my opinion, is that the entity organisation and relationships are so much more confusing that they should be.</p><p>But I was determined. I started listening to audiobooks with Overcast because of its Smart Speed feature. That meant that I didn't know the progress or even the page. I just had the number of the chapter I was in. So one of the most useful features of the App for me is the chapter update progress screen.</p><img src="https://alejandromp.com/blog/goodprogress-release/4_APP_IPHONE_58_4.jpg" alt="4<em>APP</em>IPHONE<em>58</em>4"/><p>Design wise is not a piece of art. But I'm not disappointed. As always design is one skill I need to improve but I like the color contrast and full screen cover art. It makes it stand out for a simple stock list of books.</p><p>That's it, I just wanted to leave some thoughts for posterity on the release of my new App. More features are planning so hopefully I will write another post about it at some point.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/home-screen-quick-actions-with-the-composable-architecture</guid><title>Home Screen Quick Actions with the Composable Architecture</title><description></description><link>https://alejandromp.com/blog/home-screen-quick-actions-with-the-composable-architecture</link><pubDate>Sun, 5 Jul 2020 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>iOS offers the ability for applications to add quick actions to the home screen icons. Implementing this feature often requires things that are not easy to access in most common App architectures. In this post I want to show you how <a href="https://alejandromp.com/tags/pointfree-composable-architecture">The Composable Architecture</a> makes it very easy to implement without sacrificing your code.</p><img src="https://alejandromp.com/blog/home-screen-quick-actions-with-the-composable-architecture/ios quick actions example.png" alt="ios quick actions example"/><h2 id="ios-home-screen-quick-actions">iOS Home Screen Quick Actions</h2><p>Implementing <a href="https://developer.apple.com/design/human-interface-guidelines/ios/system-capabilities/home-screen-actions/">Quick Actions</a> is quite straightforward from an API perspective. <code>UIApplication</code> has a <code>shortcutItems</code> array property that you just need to assign when you want to set the quick actions. It really doesn't get simpler than that.</p><blockquote><p>Note that you can also define quick actions statically in your Info.plist. But here we're focusing on dynamically updating them which is the most common case.</p></blockquote><p>The shortcut item itself is a simple object with an initialiser where you pass the data you want to display: title, subtitle and icon. You need to define a type so you can later differentiate between different kinds of actions. And finally, as many other iOS APIs, it offers a <code>userInfo</code> dictionary where you can set any custom data that you want.</p><p>As you can see the API itself is quite simple to use. The inconvenience of is given by the your specific use case and architecture of choice. As any good architecture out there you probably have multiple features or screens completely decoupled between them. What one screen does shouldn't affect any other random screen. And that glorious benefit is a small issue to overcome on these situations.</p><p>To know when to update the quick actions, and which ones to display, you need to detect some changes on the data of the user. These changes can happen from different features of your application and thus complicating a bit this code that needs to know about all of them.</p><p>If you're lucky you may have a database. And then you can make sure that any change that provokes the quick actions to be updated is saved into database. Or at least that you inform the system with a notification. And then you also need to make sure to never forget about those things when adding more features!</p><p>As you can see, there are solutions of course, but you start relying on external systems or compromises on your architecture.</p><p>The beauty of the composable architecture is that its centralised design of state and actions makes implementing features like this a breeze. But it's also fully composable so you are not sacrificing the decoupling between features. And by using functional concepts like high order reducers you can plug and play this functionality without affecting the rest of your app.</p><p>To show case this I'm gonna use one of the amazing example projects that comes with the composable architecture library: <a href="https://github.com/pointfreeco/swift-composable-architecture/tree/main/Examples/Todos">Todos</a>.</p><h2 id="updating-the-shortcuts">Updating the shortcuts</h2><p>Let's start by creating a new file called <code>QuickActions.swift</code>. I like to have everything that is needed for a feature like this to work in a single file.</p><pre><code><span class="splash-keyword">import</span> UIKit
<span class="splash-keyword">import</span> ComposableArchitecture
</code></pre><p>The first thing we need to add in the file is a definition for a new high order reducer.</p><p>High order reducers are like any other reducer you make in your application with the difference that work generically. They're just like a high order function.</p><pre><code><span class="splash-keyword">extension</span> <span class="splash-type">Reducer</span> {
    <span class="splash-keyword">func</span> quickActionable() -&gt; <span class="splash-type">Reducer</span> {
        ...
    }
}
</code></pre><p>But this reducer is completely generic. We don't have any information about the state or the actions. To solve that we need to use Swift's <a href="https://alejandromp.com/blog/swift-where-clause-in-generic-contexts">generic constraints</a> to restrict this reducer to our application.</p><pre><code><span class="splash-keyword">extension</span> <span class="splash-type">Reducer</span> <span class="splash-keyword">where</span> <span class="splash-type">State</span> == <span class="splash-type">AppState</span>, <span class="splash-type">Action</span> == <span class="splash-type">AppAction</span>, <span class="splash-type">Environment</span> == <span class="splash-type">AppEnvironment</span> {
</code></pre><blockquote><p>We could definitely make this reducer fully generic and make it work with any application. Read the <a href="#alternative">section below</a> for some words about that.</p></blockquote><p>Now that we have a reducer that has access to our application state we can just chain it in our main reducer.</p><pre><code><span class="splash-keyword">let</span> appReducer = <span class="splash-type">Reducer</span> {
  ...
}
.<span class="splash-call">quickActionable</span>()
</code></pre><p>Just with that single line we've added a full set of functionality to our app!</p><p>Well, now we need to implement it ^^'</p><p>Our new function needs to return a new <code>Reducer</code> that adds the work you want. When implementing a high order reducer usually the first thing you want to do is let the reducer chain run and do their normal work. For that we just need to call <code>self</code> and keep the resulting effect around to return it later.</p><pre><code><span class="splash-keyword">func</span> quickActionable() -&gt; <span class="splash-type">Reducer</span> {
    <span class="splash-type">Reducer</span> { state, action, environment <span class="splash-keyword">in
        let</span> effect = <span class="splash-call">self</span>(&amp;state, action, environment)
        ...
        <span class="splash-keyword">return</span> effect
    }
}
</code></pre><p>Before we write any code for the quick actions we need to tweak the enviornment to give us access to the iOS API. Yes, you could access <code>UIApplication.shared</code> from the reducer but that breaks the pure function nature of a Reducer. It's a big NO NO.</p><p>Since we're hooking into the <code>appReducer</code> we need tweak its <code>AppEnvironment</code>. You could pass an instance of <code>UIApplication</code> but the best practice is to have closures as properties in your environment. That makes it easier to mock with anything you want. For example you could <code>fatalError()</code> in tests that you want to make sure don't touch the quick actions, that's way harder to do if you just inject an object directly.</p><pre><code><span class="splash-keyword">struct</span> AppEnvironment {
    ...
    <span class="splash-keyword">var</span> updateQuickActions: ([<span class="splash-type">UIApplicationShortcutItem</span>]?) -&gt; ()
}

<span class="splash-comment">// when initialising the environment</span>
updateQuickActions: { <span class="splash-type">UIApplication</span>.<span class="splash-property">shared</span>.<span class="splash-property">shortcutItems</span> = $0 }
</code></pre><p>With that scaffolding in place we can add our quick actions functionality.</p><p>We reach into the state to get the pending tasks and create <code>UIApplicationShortcutItem</code>s from them. For now we only care about passing the description of the task and, since we're not gonna have multiple types of actions, a hardcoded type.</p><pre><code><span class="splash-keyword">let</span> quickActions = state.<span class="splash-property">todos</span>.<span class="splash-property">elements</span>
    .<span class="splash-call">filter</span> { $0.<span class="splash-property">isComplete</span> == <span class="splash-keyword">false</span> }
    .<span class="splash-call">map</span> { todo <span class="splash-keyword">in</span>
        <span class="splash-type">UIApplicationShortcutItem</span>(
            type: <span class="splash-string">"MarkTodoAsDone"</span>,
            localizedTitle: todo.<span class="splash-property">description</span>,
            localizedSubtitle: <span class="splash-keyword">nil</span>,
            icon: <span class="splash-keyword">nil</span>,
            userInfo: <span class="splash-keyword">nil</span>
        )
    }
environment.<span class="splash-call">updateQuickActions</span>(quickActions)
</code></pre><p>And with this we can now add some todos and see how they appear as a quick action.</p><img src="https://alejandromp.com/blog/home-screen-quick-actions-with-the-composable-architecture/todos list.png" alt="todos list"/><img src="https://alejandromp.com/blog/home-screen-quick-actions-with-the-composable-architecture/todos quick actions.png" alt="todos quick actions"/><h2 id="handling-a-quick-action">Handling a quick action</h2><p>When a user taps in a quick action the system notifies your application in two different ways.</p><p>If the app was already launch the <code>SceneDelegate</code> will receive a call to the following method:</p><pre><code><span class="splash-keyword">func</span> windowScene(<span class="splash-keyword">_</span> windowScene: <span class="splash-type">UIWindowScene</span>, performActionFor shortcutItem: <span class="splash-type">UIApplicationShortcutItem</span>, completionHandler: <span class="splash-keyword">@escaping</span> (<span class="splash-type">Bool</span>) -&gt; <span class="splash-type">Void</span>)
</code></pre><p>Instead, if the app was closed and the user opened it via a quick action, the information of the shortcut comes as part of the options <code>UIScene.ConnectionOptions</code>.</p><p>No matter from which method we get the <code>shortcutItem</code> we can forward it to a private helper method.</p><pre><code><span class="splash-keyword">private func</span> handleQuickAction(<span class="splash-keyword">_</span> shortcutItem: <span class="splash-type">UIApplicationShortcutItem</span>) -&gt; <span class="splash-type">Bool</span> {
</code></pre><p>This method's purpose is to send an action to the <code>Store</code> so our reducers can handle it. For that we need to tweak the <code>SceneDelegate</code> in order to have a property that lets us access the store. We also need to add a new action to our <code>AppAction</code> enum.</p><pre><code><span class="splash-keyword">enum</span> AppAction: <span class="splash-type">Equatable</span> {
    ...
    <span class="splash-keyword">case</span> handleQuickAction(todoId: <span class="splash-type">UUID</span>)
}
</code></pre><p>As you can see the new action has an associated value indicating the identifier of the todo that the user selected. To know this information we need to give it to the system when we create the <code>UIApplicationShortcutItem</code>, that's what the <code>userInfo</code> property is for.</p><pre><code>userInfo: [
    <span class="splash-string">"todoId"</span>: todo.<span class="splash-property">id</span> <span class="splash-keyword">as</span> <span class="splash-type">NSSecureCoding</span>
]
</code></pre><p>But to avoid having to work with string keys from different places of our app, let's extend <code>UIApplicationShortcutItem</code> to add a computed property that gives us the todo id.</p><pre><code><span class="splash-keyword">extension</span> <span class="splash-type">UIApplicationShortcutItem</span> {
    <span class="splash-keyword">static let</span> todoIdKey = <span class="splash-string">"todoId"</span>

    <span class="splash-keyword">var</span> todoId: <span class="splash-type">UUID</span>? {
        (userInfo?[<span class="splash-type">Self</span>.<span class="splash-property">todoIdKey</span>] <span class="splash-keyword">as</span>? <span class="splash-type">String</span>).<span class="splash-call">flatMap</span>(<span class="splash-type">UUID</span>.<span class="splash-keyword">init</span>(uuidString:))
    }
}
...
userInfo: [
    <span class="splash-type">UIApplicationShortcutItem</span>.<span class="splash-property">todoIdKey</span>: todo.<span class="splash-property">id</span>.<span class="splash-property">uuidString</span> <span class="splash-keyword">as</span> <span class="splash-type">NSSecureCoding</span>
]
</code></pre><p>Now that we're passing the todo id trough the shortcut item we can extract it in the scene delegate and send the appropriate action to the Store.</p><pre><code><span class="splash-keyword">private func</span> handleQuickAction(<span class="splash-keyword">_</span> shortcutItem: <span class="splash-type">UIApplicationShortcutItem</span>) -&gt; <span class="splash-type">Bool</span> {
    <span class="splash-keyword">if let</span> todoId = shortcutItem.<span class="splash-property">todoId</span> {
        <span class="splash-type">ViewStore</span>(store).<span class="splash-call">send</span>(.<span class="splash-call">handleQuickAction</span>(todoId: todoId))
        <span class="splash-keyword">return true</span>
    } <span class="splash-keyword">else</span> {
        <span class="splash-keyword">return false</span>
    }
}
</code></pre><p>The next step is handling the new action. We could add this logic into our main app reducer but, as I said in the beginning, I prefer to have everything related to this feature in a single place. So instead, let's ignore the action in the main reducer</p><pre><code><span class="splash-keyword">case</span> .<span class="splash-dotAccess">handleQuickAction</span>:
    <span class="splash-keyword">return</span> .<span class="splash-dotAccess">none</span>
</code></pre><p>and implement it in our <code>quickActionable</code> reducer.</p><pre><code><span class="splash-keyword">let</span> effect = <span class="splash-call">self</span>(&amp;state, action, environment)

<span class="splash-keyword">if case let</span> <span class="splash-type">AppAction</span>.<span class="splash-call">handleQuickAction</span>(todoId: id) = action {
    <span class="splash-keyword">return</span> .<span class="splash-keyword">init</span>(value: .<span class="splash-call">todo</span>(id: id, action: .<span class="splash-dotAccess">checkBoxToggled</span>))
}

...
</code></pre><p>To handle the action in this case is quite simple since we just want to mark the task as done. We just forward the id into an already existing action. We also stop the function here because there is no need to update the quick actions since they will be updated as soon as the task is marked as done.</p><img src="https://alejandromp.com/blog/home-screen-quick-actions-with-the-composable-architecture/todos.gif" alt="todos"/><h2 id="tests">Tests</h2><p>The first thing worth mentioning is how the tests still pass. We've added all this new functionality just by extending our app features without modifying any of them.</p><p>Let's start by preparing a <code>TestStore</code></p><pre><code><span class="splash-keyword">func</span> testQuickActions() {
    <span class="splash-keyword">let</span> store = <span class="splash-type">TestStore</span>(
        initialState: <span class="splash-type">AppState</span>(),
        reducer: appReducer,
        environment: <span class="splash-type">AppEnvironment</span>(
        mainQueue: <span class="splash-keyword">self</span>.<span class="splash-property">scheduler</span>.<span class="splash-call">eraseToAnyScheduler</span>(),
        uuid: <span class="splash-type">UUID</span>.<span class="splash-property">incrementing</span>,
        updateQuickActions: { ? }
        )
    )
</code></pre><p>To track what changes we do to the shortcut items we can have a history array keeping track of them. This not only will allow us to check if the correct items are given to the system, but also how many times we change them.</p><pre><code>     <span class="splash-keyword">var</span> quickActionsHistory: [[<span class="splash-type">UIApplicationShortcutItem</span>]?] = []

    <span class="splash-keyword">let</span> store = <span class="splash-type">TestStore</span>(
        ...
        updateQuickActions: { quickActionsHistory.<span class="splash-call">append</span>($0) } <span class="splash-comment">// &lt;--</span>
        )
    )
</code></pre><p>Now we can just write a series of events that exercise our new functionality.</p><p>First we add a new task and check how the quick actions has been modified:</p><pre><code>store.<span class="splash-call">assert</span>(
    .<span class="splash-call">send</span>(.<span class="splash-dotAccess">addTodoButtonTapped</span>) {
        $0.<span class="splash-property">todos</span>.<span class="splash-call">insert</span>(
            <span class="splash-type">Todo</span>(
                description: <span class="splash-string">""</span>,
                id:  id,
                isComplete: <span class="splash-keyword">false</span>
            ),
            at: <span class="splash-number">0</span>
        )
    },
    .<span class="splash-call">do</span> {
        <span class="splash-call">XCTAssertEqual</span>(quickActionsHistory.<span class="splash-property">count</span>, <span class="splash-number">1</span>)
    },
</code></pre><p>Now we change the description of the task and check that is reflected correctly in the quick actions.</p><pre><code>     .<span class="splash-call">send</span>(.<span class="splash-call">todo</span>(id: id, action: .<span class="splash-call">textFieldChanged</span>(<span class="splash-string">"Cookies"</span>))) {
        $0.<span class="splash-property">todos</span>[<span class="splash-number">0</span>].description = <span class="splash-string">"Cookies"</span>
    },
    .<span class="splash-call">do</span> {
        <span class="splash-call">XCTAssertEqual</span>(quickActionsHistory.<span class="splash-property">count</span>, <span class="splash-number">2</span>)
        <span class="splash-call">XCTAssertEqual</span>(quickActionsHistory[<span class="splash-number">1</span>]?[<span class="splash-number">0</span>].localizedTitle, <span class="splash-string">"Cookies"</span>)
    },
</code></pre><p>Finally we ask the store to handle a quick action and check how it doesn't change the history immediately, but instead it forwards the job to another action.</p><pre><code>     .<span class="splash-call">send</span>(.<span class="splash-call">handleQuickAction</span>(todoId: id)) { <span class="splash-keyword">_ in</span>
        <span class="splash-call">XCTAssertEqual</span>(quickActionsHistory.<span class="splash-property">count</span>, <span class="splash-number">2</span>)
    },
    .<span class="splash-call">receive</span>(.<span class="splash-call">todo</span>(id: id, action: .<span class="splash-dotAccess">checkBoxToggled</span>)) {
        $0.<span class="splash-property">todos</span>[<span class="splash-number">0</span>].isComplete = <span class="splash-keyword">true</span>
    },
    .<span class="splash-call">do</span> {
        <span class="splash-call">XCTAssertEqual</span>(quickActionsHistory.<span class="splash-property">count</span>, <span class="splash-number">3</span>)
        <span class="splash-call">XCTAssertTrue</span>(quickActionsHistory[<span class="splash-number">2</span>]!.isEmpty)
    },
    .<span class="splash-call">do</span> { <span class="splash-keyword">self</span>.<span class="splash-property">scheduler</span>.<span class="splash-call">advance</span>(by: <span class="splash-number">1</span>) },
    .<span class="splash-call">receive</span>(.<span class="splash-dotAccess">sortCompletedTodos</span>)
)
</code></pre><p>And with this set of steps we have fully tested our quick actions integration.</p><img src="https://alejandromp.com/blog/home-screen-quick-actions-with-the-composable-architecture/code coverage.png" alt="code coverage"/><blockquote><p>One thing to note is that we're not refreshing the quick actions when the app starts. In theory this wouldn't be a problem if the example persisted the tasks. But since the example is not doing it, when the app starts it doesn't have any todos while the system still keeps the old shortcut items. This is left as an exercise to the reader.</p></blockquote><h2 id="alternative">Alternative</h2><p>Fully reusable high order reducers open the door to a great deal of reusability. Plug and 'play features that can be shipped as packages. You can see how this would work in the <a href="https://github.com/pointfreeco/swift-composable-architecture/blob/main/Examples/CaseStudies/SwiftUICaseStudies/04-HigherOrderReducers-ReusableFavoriting.swift">reusable favourites example</a>.</p><p>For the feature we have in hand there may be a generic design that could work on any application, but I haven't found a nice one. If you look at our resulting code you will notice that there is very little generic code in there. Almost everything is tailored to our needs. Yes, you can make a generic reducer. But then you need to inject so much functionality from the outside, that you ended up with a more complex system for very little gain.</p><p>That's why I hope this article shows that there is nothing bad about writing <em>adhoc</em> functionality, even if at first glance one could imagine and desire a more generic approach.</p><p><em>Write the usage code first.</em></p><h2 id="conclusion">Conclusion</h2><p>With this example I wanted to illustrate how nice it is to add functionality to an application even when it requires to have access to any feature. And all of it without impacting any of the existing apps logic.</p><p>Keep in mind that even if we have access to the entirety of our app state, the composable architecture allows us to break it down in features and compose them into one. So we don't lose any separation of concerns. In the example you can see how managing the entire list of tasks is separate from managing a single task. It doesn't get more separated than that!</p><p>I hope you enjoyed this article and learned a little bit. If you are curious about the code you can check this <a href="https://github.com/pointfreeco/swift-composable-architecture/compare/main...alexito4:quick-actions?expand=1">diff in GitHub</a>.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/wwdc20-session-notes</guid><title>WWDC20 session notes</title><description></description><link>https://alejandromp.com/blog/wwdc20-session-notes</link><pubDate>Wed, 24 Jun 2020 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>WWDC week is here and with it the usual post with all my notes about the sessions.</p><p>This year I've changed the format and I will keep the notes grouped by their topic instead of session. Over the years I've come to realise that different sessions repeat a bunch of the same content so a topic based system seems more appropriate.</p><blockquote><p>This post will be kept up to date with information with my notes as I keep watching the sessions. Check out other <a href="https://alejandromp.com/tags/wwdc">WWDC</a> posts. Last Update: Saturday.</p></blockquote><p>You can find my notes separated by topic below. The sessions in bold are those that I think are a <strong>must watch</strong>. If you have any other suggestion or comment feel free to <a href="https://twitter.com/alexito4">reach out</a> to me.</p><h2 id="swiftui">SwiftUI</h2><ul><li><strong>10041: What's new in SwiftUI</strong></li><li>10048: Build complications in SwiftUI</li><li><strong>10119: Introduction to SwiftUI</strong></li><li>10042: Build SwiftUI apps for tvOS</li><li>10037: App essentials in SwiftUI</li><li>10185: Visually edit SwiftUI views</li><li>10649: Add custom views and modifiers to the Xcode Library</li><li><strong>10031: Stacks, Grids, and Outlines in SwiftUI</strong></li><li>10039: Build document-based apps in SwiftUI</li><li>10149: Structure your app for SwiftUI previews</li><li>10033: Build SwiftUI views for widgets</li><li>10040: Data Essentials in SwiftUI</li></ul><p>I recommend to start with the introduction to SwiftUI. Even if you're already an expert in the framework is a good refresh of the cool technology we have in our hands.</p><p>There is a lot of new things in SwiftUI, it definitely feels like the improvements that we were all expecting. I plan to make a proper deep dive once I've watched all the sessions. I don't want to release something that may be wrong, so I will wait for the end of the week. For now here's a summary of what's new!</p><ul><li>New API for Scenes and Apps :<ul><li><code>WindowGroup</code>, create new windows in iPad, macOS (automatically gives a <em>New</em> comment)</li><li><code>SettingsGroup</code></li><li><code>DocumentGroup</code>, document based apps (automatically gives a <code>Save</code> command)</li></ul></li></ul><ul><li><code>@StateObject</code> lets SwiftUI manage the lifecycle of the model, its tied to the View (not the struct) lifecycle. As opposed to <code>@ObservedObject</code> that doesn't manage the lifecycle for you (a.k.a. will be recreated every time). <code>@SceneStorage</code> keeps and restores the state for a Scene. <code>@AppStorage</code> does it for an entire app (user defaults). Use this just to persist the UI state of your app, your data should still be persisted as part of your model layer.</li></ul><img src="https://alejandromp.com/blog/wwdc20-session-notes/swiftui_source_truth.png" alt="SwiftUI source of truth lifetime"/><ul><li>Event sources: User interaction, onReceive, onChange, onOpenURL, onContinueUserActivity, closures run on the main thread.</li></ul><ul><li><code>.commands</code> modifier</li></ul><ul><li>and <code>.keyboardShorcuts</code> that can be used with <code>Button</code>s too!</li></ul><ul><li>Launch Screen with just the Info.plist. Bye bye storyboards!</li></ul><ul><li>Lists become outlines by using the children <code>KeyPath</code> para meter.</li></ul><ul><li>LazyGrids are composed with ScrollView (not with List)</li></ul><ul><li><code>Toolbar</code> and <code>ToolbarItem</code><ul></ul></li></ul><ul><li>semantic placements and positional placements</li></ul><ul><li><code>Label</code> adds semantics to Text + Image, but you can use any other views.</li></ul><ul><li><code>help</code> tooltips on macOS, accessibility hint for the rest of platforms.</li></ul><ul><li><code>ProgressView</code>, linear and circular styles.</li></ul><ul><li><code>Gauge</code> only watchOS. I don't get why they don't ship the same UI everywhere :(</li></ul><ul><li>Other system frameworks provide SwiftUI views <img src="https://alejandromp.com/blog/wwdc20-session-notes/swiftui_system_frameworks.png" alt="SwiftUI in system frameworks"/></li></ul><ul><li><code>matchedGeometryEffect</code> lets you animate a view between “screens”. This is amazing.</li></ul><ul><li>.clipShape(ContainerRelativeShape().</li></ul><ul><li>Custom fonts supported in text that automatically scales. You can even specify a <code>relativeTo</code> parameter to scale int he same way that a specific system style, by default is relative to body style.</li></ul><ul><li><code>@ScaledMetric</code> scales other numbers based on the dynamic type accessibility settings. You can pass a relative to like with custom fonts.</li></ul><ul><li><code>Text</code> now can interpolate <code>Image</code>s and other <code>Text.</code></li></ul><ul><li><code>ContainerRelativeShape()</code> takes the closer shape from the parent including corner radius. Very useful to make sure your radius is the same as the system you're running on, ideal for widgets.</li></ul><ul><li><code>accentColor</code> for macOS and <code>AppAccentColor</code> in the asset catalog for all the platforms. <code>listItemTint</code> for list items or sections. <code>Switch</code> and other control styles now support specific custom accent colors.</li></ul><ul><li><code>Link</code> opens the url with Safari or universal links. Ideal to use in Widgets to open the App. The environment now has a <code></code>openUrl` that lets you open a URL manually.</li></ul><ul><li>New UTType framework. It helps with drag and drop support.</li></ul><ul><li><code>CardButtonStyle</code> for tvOS effects.</li></ul><ul><li>tvOS has a bunch of new focus APIs for SwiftUI.</li></ul><ul><li><code>LibraryContentProvider</code> protocol to include your views in the Xcode Library.</li></ul><ul><li>One cool thing about <code>@StateObject</code> in an <code>App</code> struct is that Xcode knows about it and doesn't initialise the model when running under previews.</li></ul><ul><li>If you want assets or tests data only for previews use Xcode's Development Assets option.</li></ul><ul><li>Xcode previews work on device and update immediately. And you can have previews in multiple devices at the same time. You even have an icon on Springboard to go back to the last preview.</li></ul><ul><li>One thing I'm very glad the SwiftUI team says clear: your view struct initialisation should be cheap. Don't perform heavy work in there, use events to trigger those side effects.<img src="https://alejandromp.com/blog/wwdc20-session-notes/swiftui_avoid_slow_updates.png" alt="SwiftUI avoid slow updates"/></li></ul><h2 id="swift">Swift</h2><ul><li><strong>10170: What's new in Swift</strong></li><li>10169: Explore logging in Swift</li><li>10165: Embrace Swift type inference</li><li>10217: Explore numerical computing in Swift</li><li>10648: Unsafe Swift</li><li>10167: Safely manage pointers in Swift</li></ul><p>What's new in Swift is worth watching but it doesn't add anything that we didn't know about the language, the beauty of open source! If you're interested in some deep dives check out my <a href="https://www.youtube.com/playlist?list=PL2HXX-dkWqS230T7I1FuSebggDjL4HvB8">Following Swift Evolution videos</a>.</p><p>Lots of nice improvements for the language coming with Xcode 12 (Swift 5.3)</p><img src="https://alejandromp.com/blog/wwdc20-session-notes/swift_proposals.png" alt="Swift 5.3 SE numbers"/><p>Something that was not clear from the session is if the new SwiftSystem framework would be part of Swift.org or a private Apple framework. <a href="https://forums.swift.org/t/open-sourcing-swiftsystem/37830/7?u=alejandro_martinez">Ted has confirmed</a> that it will be part of the open source project.</p><p>New Swift logging APIs on Xcode 12. It uses compiler integration to be really performant. Numeric types are redacted by default. use <code>privacy: .public</code> in string interpolation to disable that. It includes log levels. Logs can be retrieved on the console app or streamed live, also in Xcode. String interpolation has many things like fixed with with padding and formatting capabilities.</p><p>Xcode 12 brings a bunch of better error reporting capabilities from Swift type inference engine. The presentation does a great job of explaining what the compiler does to resolve all the type constraints of your code.</p><p>Float16 is new to the standard library. The Numerics package introduced a Real protocol that you can use to write generic numeric code. It adds a Complex type that conforms to Real, useful for complex numbers.</p><p>I'm so glad that the "Unsafe Swift" exists. It clearly states what safe means in Swift, which is often misunderstood by programmers that have not spend a lot of time with the language. The session slides have very nice tables with the correspondence of C pointers and Swift unsafe API.</p><h2 id="xcode,-swift-package-manager-and-playgrounds">Xcode, Swift Package Manager and Playgrounds</h2><ul><li>10169: Swift packages: Resources and localization</li><li>10096: Explore Packages and Projects with Xcode Playgrounds</li><li>10654: Create Swift Playgrounds content for iPad and Mac</li><li>10091: Write tests to fail</li><li>10164: XCTSkip your tests</li><li>10687: Triage test failures with XCTIssue</li><li>10643: Build a SwiftUI view in Swift Playgrounds</li><li>10221: Get your test results faster</li><li>10147: Distribute binary frameworks as Swift packages</li><li>10644: Use Swift on AWS Lambda with Xcode</li></ul><p>The new features of SPM are the missing parts that we've waiting for to fully replace other dependency managers. It has been part of the open evolution so no new surprised there. I can't wait to have all of this in Xcode!</p><p>Swift Playgrounds is fully integrated with Xcode build system. That allows them to support:</p><ul><li>Swift Packages</li><li>Frameworks in the same project</li><li>Other resources (including machine learning models that need to be compiled).</li></ul><p>Build logs from playgrounds are now displayed in Xcode.</p><p>XCTSkip for when you want to skip specific tests, even conditionally. Xcode has a third state "skipped" so distinguish from Pass and Error.</p><p>New setup and tearDown "with error" functions that can throw.</p><p>XCTIssue encapsulates the failure message, file path, line number and others. It now keeps the stack trace of the failure so you can follow it until the point of the assert. Much better than passing #file and #line around, although you may still want to keep that to improve clarity. You can overwrite <code>record(issue)</code> on the test class to do whatever you want with it. This seems like a very nice thing for testing frameworks.</p><p>The new option execution time allowance lets you add a timeout to tests so they fail instead of hanging the suite for ever. By default is 10 minutes.</p><p>It's pretty cool to see a session about AWS Lambda. The fact that the library comes with a solution for local development out of the box is huge. In my limited experience with lambdas this was a big pain. It's great to work with these technologies from our familiar tools.</p><h2 id="uicollectionview">UICollectionView</h2><ul><li><strong>10097: Advances in UICollectionView</strong></li><li>10045: Advances in diffable data sources</li><li>10026: Lists in UICollectionView</li><li>10027: Modern cell configuration</li></ul><p>The new additions on UICollectionView look amazing. They continue with the modern APIs included last year. Unfortunate I haven't been able to look too much into them since for old projects you can use it and for new ones I've been using SwiftUI.</p><p>What I'm more interesting in is the configuration pattern making it into UIKit. I will have to look again at it when new sessions are released, because for now I don't see how it will work with custom views.</p><h2 id="widgets">Widgets</h2><ul><li>10028: Meet WidgetKit</li><li>10034: Widgets Code-along, part 1: The adventure begins</li><li>10035: Widgets Code-along, part 2: Alternate timelines</li><li>10036: Widgets Code-along, part 3: Advancing timelines</li></ul><p>The best thing about WidgetKit is how it's fully using SwiftUI. They use the declarative nature of the framework (your UI is just data) to serialise that and make sure the home screen always has a valid UI to show without loading screens.</p><p>Key takeaways:</p><ul><li>Widgets are not mini-apps, they just project your content on the home screen.</li><li>Widget bundles to have different widgets on the same app.</li><li>You should support as many sizes as make sense.<ul><li>supportedFamilies: systemSmall, medium, large.</li><li>Configuration system is based on intents. The system makes the UI from them.</li><li>static configuration</li><li>intent configuration</li><li>You provide a placeholder view that is used as the default content, without user data. This is usually only used on environment changes.</li><li>In small widgets the entire view is one tappable area ( <code>.widgetURL</code>). In medium and large you can have different subviews deep links to different parts of the app (<code>Link</code>).</li><li>Snapshots are used in the gallery so what you see there is your real UI, no mock designs.</li><li>You can perform reloads by:</li><li>widgetcenter.reloadtimeline to force a reload from in the app</li><li>background url session</li><li>timeline api (similar to the old complications API on the watch)</li><li>Use <code>previewContext(WidgetPreviewContext)</code> in your SwiftUI previews.</li><li>Use <code>.isPlaceholder(true)</code> to get a placeholder UI for free. AMAZING.</li><li>Environment has a <code>.widgetFamily</code></li><li>URL Background session completion is handled in the widget itself. <code>onBackgroundURLSessionEvents</code></li></ul></li></ul><h2 id="app-clips">App Clips</h2><ul><li>10174: Explore app clips</li></ul><p>App Clips are really interesting and I'm curious to see if they become a common feature on iOS Apps.</p><ul><li>App clip experiences are based on URLs.</li><li>Invocation methods: Safari, Messages, Maps, NFC Tag, QR Code and Location.</li><li>They are like universal links URLs handled by app clips instead of a browser. Registered in App Store Connect instead of the existing associated domains file.</li><li>They are mutually exclusively with apps. When the app is installed you need to handle the app clips URLs.</li><li>They are just a standalone app (target) that has access to all iOS APIs (with some privacy restrictions).</li></ul><h2 id="intelligence,-siri-and-shortcuts">Intelligence, Siri and Shortcuts</h2><ul><li>10068: What's new in SiriKit and Shortcuts</li><li>10086: Design for intelligence: Apps, evolved</li><li>10087: Design for intelligence: Make friends with "The System"</li><li>10088: Design for intelligence: Discover new opportunities</li><li>10200: Design for intelligence: Meet people where they are</li></ul><p>Intelligent system experience. "How the operative system works with apps that people use everyday to make the everyday easier for people." It's a platform convention.</p><img src="https://alejandromp.com/blog/wwdc20-session-notes/system_integrations.jpg" alt="intelligence integrations"/><ul><li>Intents.framework<ul><li>Define, learn and execute.</li><li>Donations.</li></ul></li></ul><h2 id="location">Location</h2><ul><li>10660: What's new in location</li></ul><p>More privacy controls.</p><ul><li>(iOS 13) Never, Ask Next Time, While Using, Always. The flow from 13.4 has changed!</li><li>Let's the user select precise or approximately.</li><li>This is fully controlled by the user, the app needs to adapt.</li><li><code>authorizationStatus</code> class function becomes a property.</li><li>A new property to know the accuracyAuthorization.</li><li>New didChanteAuthorization method that covers both dimensions.</li><li>Reduced locations still come on the same delegate but with low accuracy and updated only four times per hour. They contain the user true location but not the exact point.</li><li>Significant location changes API doesn't change much. The amount of deliveries are the same. The timestamps are still accurate, but the location is more approximate.</li><li>Bacons and regions need accurate access.</li><li>New constant to ask only for reduced precision.</li><li>If the user only shares approximatly location but you need full you can:<ul><li>send user to settings</li><li>prompt for temporary full accuracy. The purpose must be in a new dictionary of the Info.plist.</li><li>asking only when is needed is better for the user.</li></ul></li></ul><h2 id="ios">iOS</h2><ul><li>10668: Meet Nearby Interaction</li><li>10052: Build with iOS pickers, menus and actions</li></ul><p>The U1 chip is accessible by devs with the Nearby Interaction framework.</p><ul><li>Both devices need to grant permission.</li><li>Get distance and direction.</li><li>Have different sessions with different devices at the same time.</li><li>You need to share the discovery token on your own, with multi-peer connectivity or a backend service.</li><li>It works in the simulator with different simulator windows.</li></ul><p>Minor UIKit design updates across standard controls. Menus may be a replacement for UIPicker in many contexts. UIPageControl supports unlimited pages and custom icons. New color picker. UIDatePicker has a compact style and a full calendar. Menus <code>UIMenu</code> on controls triggered by a long press, or you can trigger the menu directly with <code>showsMenuAsPrimaryAction = true</code>. Navigation back button now has menu with the history. UIAction menus can be added to bar button items.</p><h2 id="macos">macOS</h2><ul><li>10104: Adopt the new look of macOS</li><li>10056: Optimize the interface of your Mac Catalyst app</li></ul><p>I really like the new macOS design. Some details need to be polished IMO but the new style feels very fresh.</p><ul><li>Full height sidebars.</li><li>Accent color tint fully supported in sidebars.</li><li>Unified toolbar style.</li><li>New search bar item that collapses when there is no space.</li><li>New multicolor accent color that lets app use their own tint. Specified in Info.plist and Asset Catalog.</li><li>Large control size.</li><li>Text Styles come to macOS!</li><li>SF Symbols come to macOS!</li></ul><p>Enabling the optimised mode for Mac on catalyst apps seems to be a very nice way of migrating your iPad app for the mac.</p><h2 id="ipad">iPad</h2><ul><li>10206: Design for iPad</li></ul><p>Make your apps profit from the iPad size, don't just make it a halfway product between iPhone and Mac.</p><ul><li>Show more content: Sidebars help you fill the screen with content, faster navigation and easy drag and drop. Tweak the density to better use the screen space.</li><li>Keep the context: keep people in context, keep controls at the same level instead of overlays.</li><li>Immersive experience: big display but with only your content so you can focus on it with custom layouts.</li><li>Keyboard shortcuts, pointer/trackpad/pen/scribble. Combine multiple inputs, like keyboard with touch or pencil and touch.</li><li>Sidebars with 3 column layout in all iPads.</li><li>Keep tabbars for compact mode and iPhone. Don't just move the tabs into a sidebar, enrich the sidebar with shortcuts to the most important content, but don't overload it with everything.</li><li>Don't mix sidebars and tabbars.</li></ul><h2 id="symbols-and-fonts">Symbols and fonts</h2><ul><li>10207: SF Symbols 2</li><li><strong>10175: The details of UI typography</strong></li></ul><p>SF Symbols supported on macOS! The app lets you now organise in custom categories. Check the app for the names. Some symbols have changed the names to be consistent.</p><p>SymbolConfiguration/.imageScale lets you change the scale of the symbol independent of the size of the text/icon. <code>Label</code> is handy for combining text and image in one go or even interpolating Image in Text string.</p><p>Some symbols are localised automatically.</p><p>Symbols are now multicolor. isTemplate false to have the multicolor variant.</p><p>Apple is moving to a single font SFPro instead of having to download multiple files for all the variants. Thanks to variable fonts. Design tools will let you tweak granularly the weight and optical size. In code is all automatic.</p><p>If you need to make letters close together don't use kerning, is better to use tracking for that. But is just better to enable <code>allowsTightening</code>. The font has tables that use the proper tracking based on size, etc.</p><p>Use text styles, this year macOS has support for them too (although without dynamic type).</p><p>And if you need a little more visual difference you can get their descriptor and apply a symbolic trait.</p><img src="https://alejandromp.com/blog/wwdc20-session-notes/system_font_bold.png" alt="make system font bolder"/><p>The system automatically adds more leading (space between lines) to locales that have a lot of vertical letters, like arabic. You can see how the default controls get taller. Or in watchOS the leading is reduced to show more content. You can apply the same variations to your text if needed.</p><img src="https://alejandromp.com/blog/wwdc20-session-notes/system_font_leading.png" alt="System font leading"/><p>And you can use SF rounded, NY or SF mono with these traits too. You can also use these font styles on webkit.</p><img src="https://alejandromp.com/blog/wwdc20-session-notes/system_font_designs.png" alt="System font designs"/><h2 id="watchos">watchOS</h2><ul><li>10046: Create complications for Apple Watch</li></ul><p>Complications are complicated.</p><h2 id="healthkit">HealthKit</h2><ul><li>10182: What's new in HealthKit</li><li>10661: Getting started with HealthKit</li></ul><p>Very short video. I really like the new format!</p><ul><li>Symptoms support.</li><li>Electrocardiogram exposed to HealthKit.</li><li>Mobility data types.</li></ul><h2 id="appstore-and-in-app-purchases">AppStore and In-App Purchases</h2><ul><li>10659: Introducing StoreKit Testing in Xcode</li><li>10651: What's new in App Store Connect</li></ul><p>It's pretty cool how testing can be when Apple gives us a proper framework. It completely changes the development flow for in-app purchases.</p><p>iOS 14 has a separate account slot for sandbox user accounts.</p><p>Family sharing for subscriptions and other in-app purchases.</p><p>App Metadata and analysis tools are now part of the App Store Connect API!</p><h2 id="web">Web</h2><ul><li>10665: Meet Safari Web Extensions</li></ul><p>Safari has extensions again, based in standard web technologies so people can use the same code they use for other browsers. More privacy controls and being able to be sold on the App Store. I still find weird that you have to use Apps to distribute extensions, especially when the App doesn't do anything.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/wwdc-20-day-two-enjoying-the-new-session-format</guid><title>WWDC 20 day two, enjoying the new session format</title><description></description><link>https://alejandromp.com/blog/wwdc-20-day-two-enjoying-the-new-session-format</link><pubDate>Tue, 23 Jun 2020 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>After having <a href="https://alejandromp.com/blog/wwdc20-day-one-getting-ready-for-the-week-ahead">absorbed the keynote and SotU</a> the wait for the sessions started. But with patience, and thanks to the constant flow of time, California o'clock arrived and, after a little delay, we got the first batch of WWDC20 sessions!</p><p>First of all, I love the new format.</p><p>Seeing the presenters in a "real" environment, so beautiful as is Apple's campus, is way more engaging than dark rooms and slides. And the fact that they can now be flexible with time is so welcomed. If they don't have one hour of content they just cut it short. It feels like <a href="https://alejandromp.com/blog/how-to-watch-wwdc">my 2x technique</a> is not that necessary this year.</p><p>Looking at the announcements and session titles it feels like there was not too many <a href="https://alejandromp.com/blog/wwdc20-day-one-getting-ready-for-the-week-ahead">new things</a>. At least I don't have the feeling that there are a lot to keep track of.</p><p>Because of that, and because of the new format and short videos, this year I took a slightly different approach for my note taking.</p><p>In previous years I was taking notes of <a href="https://alejandromp.com/blog/wwdc-18-session-notes/">every little detail</a> and I ended up being overwhelmed. This time I'm just taking notes about what I find really important. Even for new frameworks I think their usage is quite obvious and not many notes are needed. And with the videos being so short rewatching them is not a big deal. We'll see how it goes!</p><p>I've created <a href="https://alejandromp.com/blog/wwdc20-session-notes">WWDC20 session notes</a> post that will be updated constantly with the new things I find interesting.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/wwdc20-day-one-getting-ready-for-the-week-ahead</guid><title>WWDC20 day one, getting ready for the week ahead</title><description></description><link>https://alejandromp.com/blog/wwdc20-day-one-getting-ready-for-the-week-ahead</link><pubDate>Mon, 22 Jun 2020 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>WWDC Monday finished! And what an evening! For the first time I was able to stay awake to watch the SotU live and it was great ^^ The problem is how then I spend a couple of hours playing with SwiftUI and time flew by.</p><p>And this morning I've woken up very early to reflect on the announcements and give my view of the keynote. You can watch the following video to get the full picture.</p><iframe width="560" height="315" src="https://www.youtube.com/embed/yEhxo2TALYY" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><p>I'm very happy with the keynote. There has not been much revolutionary things, apart from the start of a new Mac era of course. I'm fine with a year of evolution, having to deal with revolution every year is too much. And we already had <a href="https://alejandromp.com/blog/swiftui-and-the-best-wwdc-ever">last year for that</a>.</p><p>What I was more grateful for was the format of the keynote. I was very afraid they wouldn't make a good show. During the pandemic I've seen other major companies do a very poor job with their conferences, and I didn't want that to happen to Apple. Why? Because for me WWDC is all about the show. It's not just about the material. New frameworks, documentation, etc. All of that is nice but can happen any day for any technology. What makes this week special is how I enjoy watching all of this unfold from my couch <a href="https://twitter.com/alexito4/status/1275111595144884224">with popcorn</a>.</p><p>And I have to say, I really enjoyed this new format. The high quality production makes up for the fact that is not live. And I think it's even better in some aspects. It lets the presentation get straight to the point and be free to make cuts and edits that make sense for the flow.</p><p>Furthermore, now everybody has realised that watching the keynote from home has its advantages. I've been having fun seeing how everybody was excited for a "remote WWDC" when for me (and the majority of people) it's always been like that. Nothing has changed this year for us, except the got a much better format.</p><p>Now I need to start preparing my J.O.B. for the summer and wait for the sessions to show up at Californian time. I can't wait!</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/shared-swiftui-previews-for-prototyping</guid><title>Shared SwiftUI previews for prototyping</title><description></description><link>https://alejandromp.com/blog/shared-swiftui-previews-for-prototyping</link><pubDate>Mon, 15 Jun 2020 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>The introduction of SwiftUI and previews changed completely my process of developing applications. Having such an easy way of quickly prototyping UI ideas affected the rest of my process. But as much as I love Xcode previews, they are not perfect. In this post I want to share with you a small trick that can improve a lot your iteration cycles.</p><p>One small inconvenience (well, not so small since I'm writing about it) is the amount of places you need to change the code to make it compile after a change.</p><p>As an example lets take a look at the code that is given to us by Xcode's default templates.</p><p>The <code>SceneDelegate</code> has code to initialise the root view of your application:</p><pre><code>...
<span class="splash-keyword">let</span> contentView = <span class="splash-type">ContentView</span>()
...
</code></pre><p>And the same code can be found in the <code>PreviewProvider</code> of that <code>ContentView</code>:</p><pre><code><span class="splash-keyword">struct</span> ContentView_Previews: <span class="splash-type">PreviewProvider</span> {
    <span class="splash-keyword">static var</span> previews: <span class="splash-keyword">some</span> <span class="splash-type">View</span> {
        <span class="splash-type">ContentView</span>()
    }
}
</code></pre><p>This can become quite an annoyance since every time that you change your <code>ContentView</code> initialiser, or any other change that affects the shape of your view types, you have to tweak the code in the scene delegate <strong>and</strong> in the preview provider.</p><p>In early stages of development, while you're still discovering your application, this can happen quite often. My personal recommendation is that you change this structure until you're comfortable enough with your app that you don't do such foundational changes that often.</p><p>The trick is simple. Just treat your preview code as the source of truth.</p><p>Change the line on your scene delegate to:</p><pre><code><span class="splash-keyword">let</span> contentView = <span class="splash-type">ContentView_Previews</span>.<span class="splash-property">previews</span>
</code></pre><p>In this way, every change that your view needs will only need to be done in the preview code. This makes the iteration cycles even faster, which is crucial on that discovery phase.</p><img src="https://alejandromp.com/blog/shared-swiftui-previews-for-prototyping/simulator_previews.png" alt="Screenshot"/><p>If you want to make sure that you don't ship preview code to your users you can just surround that line with an <code>#if DEBUG</code> and use the real view initialiser on release.</p><p>I hope this little trick serves you well ;)</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/wwdc-2020-wishes</guid><title>WWDC 2020 wishes</title><description></description><link>https://alejandromp.com/blog/wwdc-2020-wishes</link><pubDate>Mon, 1 Jun 2020 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>It's that time of the year again! WWDC 2020 is <a href="https://www.apple.com/newsroom/2020/03/apples-wwdc-2020-kicks-off-in-june-with-an-all-new-online-format/">around the corner</a>. As <a href="https://alejandromp.com/tags/wwdc/">every year</a> around this time I start thinking about my wishes for this version of WWDC and solidifying them in words.</p><p>As I'm starting to write this piece I have to admit that the excitement levels are not even close to what they were in the previous edition. Last year was the most important WWDC since Swift's release, not only for SwiftUI, but also for Dark Mode and Catalyst.</p><p>Reflecting on it a year after I still feel the same: last year's WWDC was the <a href="https://alejandromp.com/blog/swiftui-and-the-best-wwdc-ever/">start of a new era</a>. I don't expect this year to be anything close to that, but still, there are some things that one always expects.</p><h2 id="swiftui...-2?">SwiftUI... 2?</h2><p>Last year <a href="https://alejandromp.com/blog/wwdc-2019-wishes/%23declarative-ui-framework">we got SwiftUI</a>, the declarative UI framework that I've been waiting for years. And it was much more that what I expected.</p><p>"SwiftUI 2" is a name that has been thrown around lately. I don't get why suddenly we have decided to add numbers to frameworks. Maybe people adds a number to indicate they really want a big change?</p><p>Of course I want improvements on SwiftUI, but I just want evolution not revolution. Some people complain about things that are just how the system should work. I understand that it's still early days and we need to adapt, but I want to give a big kudos to the Apple folks because the framework is very well done.</p><p>But of course there are things that need improving! The first of them, cleaning up some bugs. There are things that are just broken, specially around navigation. You can workaround with ugly alternatives but that's not ideal. I hope Apple has put effort on polishing this rough edges so we can enjoy this amazing framework without worrying about its problems.</p><p>In terms of API surface I hope they add some of the missing pieces that anybody coming from UIKit/AppKit would miss. It's true that they did an amazing work around interoperability with UIKit/AppKit. You can reach into those worlds and use any existing UI from there. But having to do this work should be reserved by edge cases, the basic building blocks that already exist should be available directly in SwiftUI.</p><p>The TextField is a good example. The new API is very nice and fits well in a declarative paradigm. But it's also missing quite a lot of functionality. I don't really mind about the look'n'feel, SwiftUI lets you customise things quite easily. But what we can't do is add functionality. For example, there is no way to focus programatically a textfield, we can't make something a first responder. And to be honest, I don't really want the complexity of the responder chain, we can leave that in the past. I just want a way to indicate via state that a text field should be focused.</p><p>A <code>UICollectionView</code> like component is the other necessary thing. A lot of people argues that there is no reason for it, which I completely disagree with. It's true that you can roll your own grid layout, but a collection view is not <em>just</em> a gird layout. The magic of that class is that it handles all the reusing for you. Is the same reason why SwiftUI has a <code>List</code> when you can do the same with a <code>ScrollView</code> and a <code>ForEach</code>. The former deals with reusing each item in the list, the latter is just scrollable content. And not only that, but last year's additions to <code>UICollectionView</code> were too great, giving, finally, an answer to a common UI pattern in many Apps. Is probably the only reason why I look back at UIKit with envy eyes. We should have that facility in SwiftUI too, without having to roll your own.</p><p>As a side note, I was quite disappointed when I saw the <code>List</code> view to be honest. In UIKit land <code>UICollectionView</code> superseeds <code>UITableView</code> in everything. There is practically no reason for the later one to exist. Many of us were for the day they deprecate <code>UITableView</code> and just move any functionality into an improved flow layout. So I'm quite sad they repeated the same <em>mistake</em> in a brand new UI framework.</p><p>We'll see what they have been cooking for a year ^^</p><h2 id="navigation">Navigation</h2><p>Better integration with deep linking support is something I already <a href="https://alejandromp.com/blog/wwdc-2019-wishes/%23better-deep-linking-integration">wished for last year</a>. I hope is something that Apple is actively working on. Nowadays is a crucial part of any medium complex application.</p><p>SwiftUI actually makes navigation way more simple than ever before (when it works without bugs of course). You don't really need any complex <em>flow controllers</em>/<em>coordinators</em>/<em>whatever you call them</em>.</p><p>The fact that your entire UI, including its navigation, is a pure function of simple objects makes it really easy. You just need to drive it from your state. It's hard to make it simpler than that.</p><p>That said, it would still be nice to have some reusable functionality to incorporate this fully into the OS with deep linking, user activity, etc. I'm open to be surprised.</p><h2 id="tooling">Tooling</h2><p>Tooling is one of the aspects that I wish got better, much better. Swift it's part of that but I talk about Swift constantly so I don't want to repeat myself here. The future we're expecting with <a href="https://alejandromp.com/blog/road-to-swift-6-video/">Swift 6</a> covers a lot of my desires so I prefer to focus on other things.</p><p>One interesting thing I'm waiting for is to see if Apple has something new around Swift being secretly developed. Recently there has been some, unfounded in my opinion, feelings about the Swift Core team accepting features just because Apple needs them internally, ignoring the community's feedback. That's a big topic that I don't want to get into, but I just want to see the discussion resolve.</p><p>One thing I do want to see Apple taking more seriously is open source tooling. Since the Swift project was open sourced a lot of tooling is being developed on the open. But because Xcode is still close source it's quite hard to notice. It also doesn't help that the IDE, the main tool we use, is released with such a long cadence. This all contributes to the feeling that we don't really see any of those improvements and we can't even try what's coming easily.</p><p>Toolchains help a bit with trying new Swift versions, but they have many issues with Xcode. Every time I want to work on a video about new Swift features I spend hours fighting Xcode and Playgrounds. That said it would be very nice it we could try pre-release version of other tools like SPM integration.</p><p>And of course, one can wish for Xcode being open sourced and having a decent plugin system. Let's keep hoping :)</p><p>Apart from that I just hope performance and bug-fixing is a priority for the tools team.</p><h2 id="icloud-and-swift">iCloud and Swift</h2><p>As I said <a href="https://alejandromp.com/blog/wwdc-2019-wishes/%23cloudkit-functions">last year</a> I really want to be able to run Swift functions on iCloud. Every year that passes this becomes a more obvious missing feature.</p><p>The improvements on the Swift project that are happening recently and that are planned for this year have a very positive impact on Swift on the server. We're seeing other companies offer ways of running Swift very easily so it's a shame that Apple hasn't done the same yet.</p><p>Apple should do something more to contribute to this space.</p><h2 id="old-classics">Old classics</h2><p>There are many things that I'm still hoping for, you can read more about them in older posts.</p><ul><li><a href="https://alejandromp.com/blog/wwdc-2019-wishes/%23swiftcore">SwiftCore</a>, <a href="https://alejandromp.com/blog/wwdc-2019-wishes/%23scripting-with-swift">Scripting with Swift</a> and the usage in <a href="https://alejandromp.com/blog/wwdc-2019-wishes/%23better-shortcuts-integration">Shortcuts</a>.</li><li><a href="https://alejandromp.com/blog/wwdc-2019-wishes/%23custom-watch-faces">Custom watch faces</a></li><li><a href="https://alejandromp.com/blog/wwdc-2019-wishes/%23custom-view-controller-and-non-ui-extension-providers">Custom View Controller and Non-UI Extension Providers</a></li><li><a href="https://alejandromp.com/blog/wwdc-2019-wishes/%23more-control-on-app-version-updates">More control on App version updates</a></li></ul><h2 id="conclusion">Conclusion</h2><p>Having low expectations before a WWDC is nothing bad, quite the opposite. I'm gonna be pleasantly surprised with any new thing they announce, and that's exciting by itself :D</p><p>What are your feelings about WWDC'20? Are you waiting for something not mentioned here? Are you hyped? <a href="https://twitter.com/intent/tweet?in_reply_to=1268179972549722112">Tell me more!</a></p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/swift-where-clause-in-generic-contexts</guid><title>Swift where clause in generic contexts</title><description></description><link>https://alejandromp.com/blog/swift-where-clause-in-generic-contexts</link><pubDate>Fri, 15 May 2020 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>Swift type system is quite powerful and the <code>where</code> clause is a very important part of how developers interface with it. This keyword allows developers to constraint code to a set of conditions. Swift 5.3 frees this keyword to be used in more contexts.</p><iframe width="560" height="315" src="https://www.youtube.com/embed/Y6v89qJ3YqI" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><blockquote><p><a href="https://www.youtube.com/channel/UCfiBFlVY8s-tmJGDMNCd26w?sub_confirmation=1">Subscribe to my channel</a> to be notified when new videos about Swift Evolution are released.</p></blockquote><h2 id="generic-constraints">Generic constraints</h2><p>To understand the changes introduced by Swift 5.3 we first need to understand the power of the <code>where</code> clause. This keyword is mostly used to apply constraints to generic types. So let's start by defining one of such types.</p><pre><code><span class="splash-keyword">struct</span> Wrapper&lt;T&gt; {
    <span class="splash-keyword">let</span> value: <span class="splash-type">T</span>
}
</code></pre><p><code>Wrapper</code> is a simple type that wraps a value of any type. The wrapper itself is generic over the type of the wrapped value.</p><p>In Swift you can add methods to a <code>struct</code> without any problem:</p><pre><code><span class="splash-keyword">struct</span> Wrapper&lt;T&gt; {
    <span class="splash-keyword">let</span> value: <span class="splash-type">T</span>
  
    <span class="splash-keyword">func</span> someFunc() { ... }
}
</code></pre><p>This method is gonna be available to all instances of that type, doesn't matter which specific type we use. But more often than not, the ability of having a generic type opens the doors to offer functions <strong>only</strong> when the wrapped value is of a specific type.</p><p>For example, lets suppose we wanted to have a function that requires <code>Equatable</code> conformance. We can add this functionality to our type only when the wrapped value is equatable.</p><pre><code><span class="splash-keyword">extension</span> <span class="splash-type">Wrapper</span> <span class="splash-keyword">where</span> <span class="splash-type">T</span>: <span class="splash-type">Equatable</span> {
    <span class="splash-keyword">func</span> equatable(other: <span class="splash-type">T</span>)  {
        <span class="splash-comment">// value == other</span>
    }
}
</code></pre><p>In the body of that function you're free to use <code>==</code> because the type system knows that <code>self.value</code> and <code>other</code> are equatable, because T is constrained to conform to that protocol.</p><p>That's what <code>where T: Equatable</code> does.</p><p>Of course we can do the same with another protocol.</p><pre><code><span class="splash-keyword">extension</span> <span class="splash-type">Wrapper</span> <span class="splash-keyword">where</span> <span class="splash-type">T</span>: <span class="splash-type">Comparable</span> {
    <span class="splash-keyword">func</span> compare(other: <span class="splash-type">T</span>)  {
        <span class="splash-comment">// value &lt; other</span>
    }
}
</code></pre><h2 id="the-limitations">The limitations</h2><p>One of the limitations of this system is already visible in the previous snippets. The <code>where</code> clause can't be applied to the function definition itself. We need to create an extension that contains our function and apply the constraint to that extensions. This is not a major limitation in most cases, but conceptually it would be very nice if you could express exactly what you want.</p><pre><code><span class="splash-keyword">extension</span> <span class="splash-type">Wrapper</span>  {
    <span class="splash-keyword">func</span> equatable(other: <span class="splash-type">Wrapper</span>) <span class="splash-keyword">where</span> <span class="splash-type">T</span>: <span class="splash-type">Equatable</span> {
        <span class="splash-comment">// value == other</span>
    }

    <span class="splash-keyword">func</span> compare(other: <span class="splash-type">Wrapper</span>) <span class="splash-keyword">where</span> <span class="splash-type">T</span>: <span class="splash-type">Comparable</span> {
        <span class="splash-comment">// value &lt; other</span>
    }
}
</code></pre><p>The above snippet is equivalent to the previous ones. The difference is that we moved the generic constraints to the function definitions themselves. So we can have all the functions in one extensions with their requirements specified individually.</p><p>Another advantage of this is that you can still add the constraints to the extension itself, which gives a lot of flexibility in terms of reusing them.</p><p>For example we could add a third constraint to the above system just by adding it to the extension:</p><pre><code><span class="splash-keyword">extension</span> <span class="splash-type">Wrapper</span> <span class="splash-keyword">where</span> <span class="splash-type">T</span>: <span class="splash-type">Hashable</span>  {
  ...
</code></pre><p>Now this constraint applies to the entire extensions and is an added requirement to the individual constraints specified on each function.</p><h2 id="conclusion">Conclusion</h2><p>As you can see Swift's type system is quite powerful and with this addition on Swift 5.3 it becomes even more flexible. This seminally small addition lets us express our type requirements in the most appropriate way for our use case.</p><p>You can watch the video to see more examples of how this can be used and how it impacts the usage side of your types.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/synthesized-comparable-conformance-for-enums</guid><title>Synthesized Comparable conformance for enums</title><description></description><link>https://alejandromp.com/blog/synthesized-comparable-conformance-for-enums</link><pubDate>Tue, 12 May 2020 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>Swift 5.3 comes with a nice addition for enums: it will synthesize the required implementation to conform to the <code>Comparable</code> protocol. This reduces a lot the boilerplate needed to make your enums comparable.</p><iframe width="560" height="315" src="https://www.youtube.com/embed/fWce9_7M4oE" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><blockquote><p><a href="https://www.youtube.com/channel/UCfiBFlVY8s-tmJGDMNCd26w?sub_confirmation=1">Subscribe to my channel</a> to be notified when new videos about Swift Evolution are released.</p></blockquote><p>Up until now there were multiple ways of adopting conformance to this protocol, each one with different degrees of inconvenience.</p><p>Even if Swift 5.3 solves all of them, it's still useful to know these techniques for the rare cases when you want to implement the conformance manually in order to customise some behaviour.</p><h2 id="comparable-raw-values">Comparable Raw Values</h2><p>The first trick and the one that requires less code is to bake your <code>enum</code> with a comparable raw value, like an <code>Int</code>.</p><pre><code><span class="splash-keyword">enum</span> Priority: <span class="splash-type">Int</span>, <span class="splash-type">Comparable</span> {
    <span class="splash-keyword">case</span> low
    <span class="splash-keyword">case</span> medium
    <span class="splash-keyword">case</span> high
</code></pre><p>Having access to an integer makes it really easy to implement the comparison function.</p><pre><code>     <span class="splash-keyword">static func</span> &lt; (lhs: <span class="splash-type">Self</span>, rhs: <span class="splash-type">Self</span>) -&gt; <span class="splash-type">Bool</span> {
       <span class="splash-keyword">return</span> lhs.<span class="splash-property">rawValue</span> &lt; rhs.<span class="splash-property">rawValue</span>
   }
}
</code></pre><p>The problem with this is that now the users of your type will be able to treat it like an integer by accessing its raw value. This is something that you rarely want and it should be avoided.</p><h2 id="private-raw-value">Private Raw Value</h2><p>The alternative is to keep the raw value private. This can't be done automatically so it adds some boilerplate.</p><pre><code><span class="splash-keyword">private var</span> comparisonValue: <span class="splash-type">Int</span> {
    <span class="splash-keyword">switch self</span> {
    <span class="splash-keyword">case</span> .<span class="splash-dotAccess">low</span>:
        <span class="splash-keyword">return</span> <span class="splash-number">0</span>
    <span class="splash-keyword">case</span> .<span class="splash-dotAccess">medium</span>:
        <span class="splash-keyword">return</span> <span class="splash-number">1</span>
    <span class="splash-keyword">case</span> .<span class="splash-dotAccess">high</span>:
        <span class="splash-keyword">return</span> <span class="splash-number">2</span>
    }
}

<span class="splash-keyword">static func</span> &lt; (lhs: <span class="splash-type">Self</span>, rhs: <span class="splash-type">Self</span>) -&gt; <span class="splash-type">Bool</span> {
    <span class="splash-keyword">return</span> lhs.<span class="splash-property">comparisonValue</span> &lt; rhs.<span class="splash-property">comparisonValue</span>
}
</code></pre><p>This lets you keep the comparison function simple and without opening the type to misuse.</p><h2 id="hardcore-comparison">Hardcore comparison</h2><p>Another alternative, and probably the most correct one, is to implement the comparison without using any proxy value, by just checking the cases themselves.</p><pre><code><span class="splash-keyword">private static func</span> minimum(<span class="splash-keyword">_</span> lhs: <span class="splash-type">Self</span>, <span class="splash-keyword">_</span> rhs: <span class="splash-type">Self</span>) -&gt; <span class="splash-type">Self</span> {
    <span class="splash-keyword">switch</span> (lhs, rhs) {
    <span class="splash-keyword">case</span> (.<span class="splash-dotAccess">low</span>, <span class="splash-keyword">_</span>), (<span class="splash-keyword">_</span>, .<span class="splash-dotAccess">low</span>):
        <span class="splash-keyword">return</span> .<span class="splash-dotAccess">low</span>
    <span class="splash-keyword">case</span> (.<span class="splash-dotAccess">medium</span>, <span class="splash-keyword">_</span>), (<span class="splash-keyword">_</span>, .<span class="splash-dotAccess">medium</span>):
        <span class="splash-keyword">return</span> .<span class="splash-dotAccess">medium</span>
    <span class="splash-keyword">case</span> (.<span class="splash-dotAccess">high</span>, <span class="splash-keyword">_</span>), (<span class="splash-keyword">_</span>, .<span class="splash-dotAccess">high</span>):
        <span class="splash-keyword">return</span> .<span class="splash-dotAccess">high</span>
    }
}

<span class="splash-keyword">static func</span> &lt; (lhs: <span class="splash-type">Self</span>, rhs: <span class="splash-type">Self</span>) -&gt; <span class="splash-type">Bool</span> {
    <span class="splash-keyword">return</span> (lhs != rhs) &amp;&amp; (lhs == <span class="splash-type">Self</span>.<span class="splash-call">minimum</span>(lhs, rhs))
}
</code></pre><h2 id="conclusion">Conclusion</h2><p>As you can see the automatic synthesis of Swift 5.3 it's very welcomed. Without it we can't avoid adding some boilerplate and even hurting the API of our type. You also have to consider that if your enum has associated values it adds another layer of complexity.</p><p>So use Swift 5.3 features when possible, but keep these techniques on your toolbelt for those rare cases where they may be necessary.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/swiftui-macos-color-picker</guid><title>SwiftUI macOS color picker</title><description></description><link>https://alejandromp.com/blog/swiftui-macos-color-picker</link><pubDate>Mon, 4 May 2020 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>A couple of weekends ago I was reading my Twitter timeline and I, don't know how, ended up in this old tweet.</p><blockquote class="twitter-tweet"><p lang="en" dir="ltr">&quot;This isn&#39;t a Louie Mantia color.&quot;<br><br>(That means it isn&#39;t 5° increment for Hue or ⅛ of 100% increment for Saturation and Brightness.)</p>&mdash; Louie (@Mantia) <a href="https://twitter.com/Mantia/status/570687359328645120?ref_src=twsrc%5Etfw">February 25, 2015</a></blockquote><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script><p>I immediately thought that it would be a cool little project to build a color picker with SwiftUI that followed those rules. I just wanted to have some fun and practice a bit.</p><img src="https://alejandromp.com/blog/swiftui-macos-color-picker/screenshot.png" alt="screenshot"/><p>That ended up being one of the things I worked on <a href="https://www.twitch.tv/alejandromp4">my streams</a> for a couple of sessions. Now it's in a decent state and it does what I wanted it to do. So I'm done :)</p><p>But before I move on to something else I wanted to open source the code for demonstration purposes. Is not a production ready application but I think it serves as a simple example of what SwiftUI can do.</p><p>One thing I like about this little application is that it is so simple that it doesn't need any complex architecture, not even a view model! It's really nice to do simple things sometimes.</p><p>You can check the code on <a href=" https://github.com/alexito4/mantia-color-picker">GitHub alexito4/mantia-color-picker</a>.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/pointfree-composable-architecture-showcase</guid><title>PointFree Composable Architecture showcase</title><description></description><link>https://alejandromp.com/blog/pointfree-composable-architecture-showcase</link><pubDate>Sun, 3 May 2020 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p><a href="https://www.pointfree.co">PointFree</a> <a href="https://github.com/pointfreeco/swift-composable-architecture">has released</a> a library with their <strong>Composable Architecture</strong> and I've been showing it a little bit on livestreams and videos. This page wants to serve as an index and a summary for this content.</p><blockquote><p>I want to thank <a href="https://www.twitter.com/mbrandonw">Brandon</a> and <a href="https://www.twitter.com/stephencelis">Stephen</a> for giving me early access to the library. That has allowed me to get my hands dirty with the code and to make this content in order to hype more people ^^</p></blockquote><p>If you want in-depth material their <a href="https://www.pointfree.co/collections/composable-architecture">videos</a> will do a better job than me. Consider this a <strong>What's the point?</strong> from an outsiders perspective.</p><h1 id="building-a-macos-app-with-tca">Building a macOS App with TCA</h1><p>The streamings I've been doing are about developing a <strong>macOS</strong> application with <strong>SwiftUI</strong> and the <strong>composable architecture</strong>. I've focused more on showing what the architecture can do than on the app itself so it should be a good way of seeing what the library is capable to do.</p><p>You can see next a list of the <strong>livestreams</strong> I've done, together with <strong>clips</strong> from them showcasing specific things.</p><h2 id="livestreams">Livestreams</h2><ul><li><a href="https://www.youtube.com/embed/x7OMRjHBOZE">Building Six! App PART 1</a></li><li><a href="https://www.youtube.com/embed/C4B8GRr0xng">Building Six! App PART 2</a></li></ul><p>Part 1 serves as an introduction to the application I want to make, some SwiftUI and main concepts behind the architecture. I had some connection issues so we had to stop short.</p><p>Part 2 continues with the development of the application but focusing more on 3 things that I wanted to showcase. I've made clips of those examples so you can watch directly how the architecture gives us elegant solutions.</p><h2 id="unit-testing-example">Unit testing example</h2><iframe width="560" height="315" src="https://www.youtube.com/embed/b2EDNgkLFIc" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><p>This clip shows how unit testing with this architecture is not only more simple but also more powerful and fun. And making unit tests fun to write is a huge endeavour.</p><h2 id="high-order-reducers-and-debugging">High order reducers and debugging</h2><iframe width="560" height="315" src="https://www.youtube.com/embed/113bOxNHlUk" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><p>This clip serves as an introduction to the concept of high order reducers. It also shows a specific high order reducer that makes it really easy to debug your application and to get a feeling of how a feature works without looking at the code.</p><h2 id="building-time-travel-from-scratch-under-1h">Building Time Travel from scratch under 1h</h2><iframe width="560" height="315" src="https://www.youtube.com/embed/ASsjhyzwBR4" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><p>When I announced that I wanted to build time travel into the application I was not really convinced I would pull it off in a livestream. But it was totally possible! This only speaks to how great are the powerful concepts behind TCA and how flexible it is. I can't wait to have a more polished version of this on every application!</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/protocol-extensions-and-subclasses</guid><title>Protocol extensions and subclasses</title><description></description><link>https://alejandromp.com/blog/protocol-extensions-and-subclasses</link><pubDate>Wed, 29 Apr 2020 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>Protocol extensions are one of the most powerful features in Swift, but they also come with a bit of danger. In this post I will explore how this feature interacts with class inheritance and how dangerous it can be.</p><h2 id="method-dispatch">Method Dispatch</h2><p>Method dispatch is the system of the language that is used to decide what method implementation should be used in a polymorphic scenario. Swift has multiple dispatch systems that are used depending on the kind of type and the knowledge the compiler has about it.</p><p><em>Static dispatch</em> is used when the compiler knows at compile time the concrete type being used and exactly which method implementation to use. This is fast at runtime and easy to understand.</p><p><em>Message dispatch</em> is used when Swift needs to interact with the Objective-C runtime. Objective-C uses message passing to invoke all the methods so Swift needs to follow the same pattern when it needs to bridge to code that comes from that language.</p><p><em>Dynamic dispatch</em> is used when he compiler can't know at compile time the specific method implementation that needs to be used. This is commonly seen on class hierarchies and protocols were the concrete type is not known until runtime.</p><p>This is the scenario we are interested in today.</p><h2 id="protocols-with-default-implementations">Protocols with default implementations</h2><p>To examine the issue we first need to prepare some examples. We need a protocol with a method requirement that is implemented in an extension.</p><pre><code><span class="splash-keyword">protocol</span> Model {
    <span class="splash-keyword">func</span> execute()
}

<span class="splash-keyword">extension</span> <span class="splash-type">Model</span>  {
    <span class="splash-keyword">func</span> execute() {
        <span class="splash-call">print</span>(<span class="splash-string">"Default implementation"</span>)
    }
}
</code></pre><p><em>Note that the method we implement on the extension is part of the protocol definition. We could add methods that are not part of the protocol but that behaves in a <a href="https://alejandromp.com/blog/swift-protocol-extensions-dispatch/">different way</a>.</em></p><p>This is easily one of the most powerful features of the language. Thanks to the combination of protocols and extensions we can provide functionality for free, while still allowing those types to implement custom more specific code. This is a design that is very common on the standard library.</p><p>To illustrate the part where the compiler can't know until runtime the specific types we're using let's make a class that calls the method on a property defined with the protocol type:</p><pre><code><span class="splash-keyword">class</span> Controller {
    <span class="splash-keyword">let</span> model: <span class="splash-type">Model</span>
    
    <span class="splash-keyword">init</span>(model: <span class="splash-type">Model</span>) {
        <span class="splash-keyword">self</span>.<span class="splash-property">model</span> = model
    }
    
    <span class="splash-keyword">func</span> execute() {
        <span class="splash-keyword">self</span>.<span class="splash-property">model</span>.<span class="splash-call">execute</span>()
    }
}
</code></pre><p>As you can see when <code>execute</code> is run, <code>Controller</code> only has access to a property of type <code>Model</code>. The compiler can't know what specific type we're using, it just knows is a type that conforms to that protocol.</p><p>Now let's prepare two conforming types that illustrate Swift dispatching behaviour:</p><pre><code><span class="splash-keyword">class</span> ClassUsingDefault: <span class="splash-type">Model</span> {}

<span class="splash-type">Controller</span>(model: <span class="splash-type">ClassUsingDefault</span>()).<span class="splash-call">execute</span>() <span class="splash-comment">// prints Default implementation</span>
</code></pre><p>This first type doesn't implement the method itself, instead it relies on the default implementation provided by the extensions.</p><pre><code><span class="splash-keyword">class</span> ClassWithImplementation: <span class="splash-type">Model</span> {
    <span class="splash-keyword">func</span> execute() {
        <span class="splash-call">print</span>(<span class="splash-string">"ClassWithImplementation"</span>)
    }
}

<span class="splash-type">Controller</span>(model: <span class="splash-type">ClassWithImplementation</span>()).<span class="splash-call">execute</span>() <span class="splash-comment">// ClassWithImplementation</span>
</code></pre><p>This time we have a type that is implementing its own version of the protocol requirement. We want this implementation to take precedence over the default implementation and indeed that's how Swift behaves.</p><p>This is the behaviour we want and expect from dynamic dispatch. Thanks to Swift's runtime we're able to use default or concrete implementations whenever we want.</p><h2 id="the-danger-of-inheritance">The danger of inheritance</h2><p>Now let's take a look what happens when you include class inheritance into the mix.</p><pre><code><span class="splash-keyword">class</span> SubclassOfSuperclassThatHasImplementation: <span class="splash-type">ClassWithImplementation</span> {
    <span class="splash-keyword">override func</span> execute() {
        <span class="splash-call">print</span>(<span class="splash-string">"SubclassOfSuperclassThatHasImplementation"</span>)
    }
}

<span class="splash-type">Controller</span>(model: <span class="splash-type">SubclassOfSuperclassThatHasImplementation</span>()).<span class="splash-call">execute</span>() <span class="splash-comment">// SubclassOfSuperclassThatHasImplementation</span>
</code></pre><p>This time our type is subclassing a superclass that has a concrete method implementation. As expected the compiler dynamically finds the correct method to execute.</p><p>Pay attention to the method definition. The compiler is forcing us to write <code>override</code> because we're not only implementing a method required by a protocol, we're also overriding a method implemented on the superclass.</p><p>This all makes sense and works as expected.</p><p>Now let's implement a class that inherits from a superclass that relies on the default method implementation from the extension.</p><pre><code>

<span class="splash-keyword">class</span> SubclassOfSuperclassThatUsesDefault: <span class="splash-type">ClassUsingDefault</span> {
    <span class="splash-keyword">override func</span> execute() { <span class="splash-comment">// ERROR: Method does not override any method from its superclass</span>
        <span class="splash-call">print</span>(<span class="splash-string">"SubclassOfSuperclassThatUsesDefault"</span>)
    }
}
</code></pre><p>When writing this you can already see something weird. The compiler tells you that using <code>override</code> is not allowed. This is correct because the superclass doesn't implement that method.</p><p>But even if it makes sense it's a little weird. You know the superclass conforms to a protocol, so the method must be on the superclass set of callable methods. That is correct but still Swift doesn't consider that you are overriding the method because is not specifically defined on the superclass.</p><p>And this is were the problem resides.</p><p>Let's trust the compiler error and remove the <code>override</code>. We still want a custom implementation of the method but let's agree with the compiler that we're not overriding anything from the superclass.</p><pre><code><span class="splash-keyword">class</span> SubclassOfSuperclassThatUsesDefault: <span class="splash-type">ClassUsingDefault</span> {
    <span class="splash-keyword">func</span> execute() {
        <span class="splash-call">print</span>(<span class="splash-string">"SubclassOfSuperclassThatUsesDefault"</span>)
    }
}
</code></pre><p>Now the compiler is happy. So let's try to use this and see what dispatching behaviour we get.</p><pre><code><span class="splash-type">Controller</span>(model: <span class="splash-type">SubclassOfSuperclassThatUsesDefault</span>()).<span class="splash-call">execute</span>() <span class="splash-comment">// Default implementation !!!!</span>
</code></pre><p>🚨 💣</p><p>We get the default implementation. Even if we've written a concrete method on our type, in the same way we've done on all previous cases, we still get the default implementation.</p><p>This is because Swift only checks the superclass when deciding if a type has concrete implementations of a protocol requirement. Since our superclass doesn't have that, it relies on the default implementation, the compiler doesn't even check the subclasses.</p><p>The worse part is that from a user's perspective there is no way to fix this. You can't stick a fancy keyword on your method and expect it to work. It's also really subtle and if you're not paying attention it's very easy to introduce bugs with this. The good part is that you can't break it by removing a superclass implementation since the compiler will warn you about the <code>override</code> keyword.</p><p>This is considered a limitation of Swift (as of 4.2) and is tracked as a <a href="https://bugs.swift.org/browse/SR-103">bug</a>. There are also conversations on the <a href="https://forums.swift.org/t/default-protocol-implementation-inheritance-behaviour-the-current-situation-and-what-if-anything-should-be-done-about-it/28049/7">forums</a> that discuss a nice solution for this scenario.</p><h2 id="conclusion">Conclusion</h2><p>Protocols are very nice in Swift, and together with default implementations on extensions they become an amazing feature of the language. Almost like a superpower. And you know what they say about that.</p><img src="https://alejandromp.com/blog/protocol-extensions-and-subclasses/peter.parker.uncle.ben.jpg" alt="peter.parker.uncle.ben"/>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/new-website-redesign-v3-with-publish</guid><title>New website redesign, v3 with Publish</title><description></description><link>https://alejandromp.com/blog/new-website-redesign-v3-with-publish</link><pubDate>Wed, 22 Apr 2020 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>Welcome to <code>alejandromp3</code>. As you may have noticed this website has a totally new design! Not only that, but is now using a different static site generator purely in Swift!</p><p>This was a tough decision. Since I <a href="https://alejandromp.com/blog/Rebuilding-my-website-with-GatsbyJS">moved to Gatsby</a> almost two years ago I realised that it was not a good investment of my time to just rebuild websites for the sake of it. I would much rather prefer to sit down and spend that time writing articles.</p><p><a href="https://alejandromp.com/tags/gatsbyjs/">Gatsby</a> was great and I <a href="https://alejandromp.com/blog/experience-GatsbyJS-modern-web-development">learned a lot</a>, so there is nothing bad about that. But, for me, it has the same issue that the previous generators that I used had. All these site generators are build on ecosystems that change at a fast pace. That may not be an issue if you are part of the ecosystem and keep up with it, but for me, as an outsider, it's always been a problem. For example, months after I released that version of my site <a href="https://alejandromp.com/blog/tales-of-updating-to-gatsby-20/">Gatsby 2</a> came out and I had to spend some time updating it. It was not a big deal since I still had some fresh knowledge about the system, but it was not a walk in the park either.</p><p>For a long time after that I was subconsciously afraid of touching the site. I knew I would have to lear again the ecosystem just to have an up to date code before I could add any new functionality, because after some time of not updating <em>nothing works</em>. This resulter in almost 2 years of no updates on the site.</p><p>This is not a critique to Gatsby, the same happened with Jekyll before. Is just an observation of how fast things move in certain ecosystems and how software breaks if you are not on top of it almost daily.</p><p>So that's why I finally took the decision of migrating the site once again. This time to <a href="https://github.com/JohnSundell/Publish">Publish</a> a static site generator made in Swift. How is that gonna be different? Well, I'm in this ecosystem. I breath Swift. I keep up to date with the language evolution, write posts and make videos about it. Software would probably break anyway, but I will know how to fix it without even thinking about it.</p><p>I took some time before starting the migration <a href="https://www.youtube.com/watch?v=Qju4l48M_A4&list=PL2HXX-dkWqS2-Jq1j1wp_mu-u6ItcuG08&index=4&t=0s&ab_channel=Alexito%27sWorld">exploring Publish</a>. I know its internals and I'm comfortable with them. I feel more in control of the situation now than ever before.</p><h1 id="new-features">New features</h1><p>This change has allowed me to finally develop some new features that I wanted for a while. My site has always had some special requirements with a taxonomy system. This is because one very important thing to me is that this is NOT a site about one exclusive topic, even if that's the worse decision for marketing purposes ^^'</p><blockquote class="twitter-tweet" data-conversation="none" data-theme="dark"><p lang="en" dir="ltr">This is very important to me since I like to share things about different topics and thus is hard to keep it interesting for everybody. __This is a personal site after all__. It&#39;s something I always struggle as a *content creator ™️*. Dedicated Pages offer a good balance.</p>&mdash; Alejandro Martinez (@alexito4) <a href="https://twitter.com/alexito4/status/1249280972295634945?ref_src=twsrc%5Etfw">April 12, 2020</a></blockquote><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script><p>But thanks to Publish flexibility and a little Swift love I've been able to fully integrate my custom taxonomy system into the site and I'm very happy with the results, which in turn has allowed me to create specific Topic pages.</p><p>For example you can see a page only about <a href="https://alejandromp.com/swift/">Swift</a>. That's probably the main topic of this site so it was really important to me to have a URL to which to point to. But if you don't want to focus only on Swift, you also look at the broader <a href="https://alejandromp.com/development/">Development</a> page. Even more, I was able to create a page to show case my <a href="https://alejandromp.com/videos/">companion articles to my videos</a>.</p><p>Hopefully this helps you a bit to navigate the site and focus on the topics you are interested in.</p><p>There are other small features across the site that I will be detailing a bit more on future posts so stay tuned for more Publish articles ^^</p><h1 id="deployment">Deployment</h1><p>This is still a static site so the deployment keeps being straightforward. I keep using <a href="https://alejandromp.com/blog/using-netlify-for-gatsby-deployment">Netlify</a> because it has given me great results without any problem.</p><p>One thing to note is that Netlify still doesn't officially support running Swift during deployment (they have a PR for that) but it is not a big deal since you can generate the code locally and just push the Output folder.</p><p>One great thing is that to switch the DNS to the new site I just had to change one configuration on their site and that's it, everything worked in seconds. And thanks to their redirect system I've been able to switch the slugs of my site (they don't contain dates anymore) while keeping all the previous links working!</p><p>I can’t recommend Netlify enough, the service is great and with all the basics that you need for free.</p><h1 id="conclusion">Conclusion</h1><p>The switch as taken a couple of weeks to complete (mostly fighting CSS) and it has been really enjoyable without any major roadblocks. I’m more comfortable with the current setup than ever before and I'm really happy with that.</p><p>There are some improvements that I expect to be releasing soon and some articles explaining some specific custom parts of the site in hopes to help everybody that wants to use Publish. You can check the <a href="https://alejandromp.com/tags/publish/">Publish tag</a> or even the <a href="https://www.youtube.com/playlist?list=PL2HXX-dkWqS2-Jq1j1wp_mu-u6ItcuG08">Youtube playlist</a> to know more.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/debugging-superpowers-with-flex</guid><title>Debugging superpowers with FLEX</title><description></description><link>https://alejandromp.com/blog/debugging-superpowers-with-flex</link><pubDate>Sat, 18 Apr 2020 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>I’ve been using <a href="https://github.com/Flipboard/FLEX">FLEX</a> for years and I just realised the little I’ve done to promote this great tool among the iOS community. So here is my attempt at giving some love to the project and show you the superpowers you can get with it.</p><h2 id="an-in-app-debugging-tool">An in-app debugging tool</h2><p>FLEX is a library that adds an in-app debugging menu with a bunch of tools into your project. This is really helpful when you’re on the wild and want to check something on a real device. As developers, we’re probably more comfortable using other tools like LLDB, but this is for another context. An in-app debugging tool is way easier to use so it opens the gates of debugging to other people, like your QA and design teams or other stakeholders.</p><img src="https://alejandromp.com/blog/debugging-superpowers-with-flex/flex.png" alt="FLEX"/><p>The library has constant activity with many developers using it and with improvements coming constantly.</p><blockquote><p>Before you go and integrate the library make sure you read <a href="https://github.com/Flipboard/FLEX#excluding-flex-from-release-app-store-builds">one important detail</a>. This library is not designed to be released to the App Store so you need to make sure your installation process doesn't include it for release builds.</p></blockquote><p>I personally think that FLEX is one of the best libraries for this. In-app debugging libraries should offer a basic set of tools that are generally helpful, but also offer a powerful API to extend it with custom tools that are easy to write and feel as integrated as the default ones.</p><p>The list of <a href="https://github.com/Flipboard/FLEX#give-yourself-debugging-superpowers">tools included by default</a> with FLEX is not short, I won't go over them one by one but there are some that I would like to give special mention since they are the most useful to me.</p><h2 id="included-tools">Included tools</h2><p>One of the most used tools that FELX includes is the network debugging utility. It’s something that you use constanly if your App connects to an API. Of course you can use more sophisticated tools like Charles, but having the ability to debug network calls in the app itself without requiring any external setup is invaluable.</p><img src="https://alejandromp.com/blog/debugging-superpowers-with-flex/flex network.png" alt="flex network"/><p>Not only you can see all the information of a request, but also its contents and even copy a <em>curl</em> request to easily send it to other developers. It makes debugging API related issues so much easier!</p><p>Another really powerful tool is its UI hierarchy introspection. You can see all the views that are on the screen and explore the classes and data behind them. For example, this allows you to easily check that the content of labels or margins are what you expect. This is specially useful to allow designers to double check your work directly in a device.</p><p>But the UI introspection tools not only lets you check your UI, it also lets you change it! This is really interesting when somebody without access to developer tools wants to do some tweaks into the UI to see how it would look.</p><img src="https://alejandromp.com/blog/debugging-superpowers-with-flex/flex ui.gif" alt="flex ui"/><p>This ability of changing data at runtime is not only available for the UI, you can use it in many other tools offered by FLEX. For example the Database and NSUserDefaults exploration tools benefit a lot from this, letting you tweak on the fly user's data.</p><p>There is a tool for pretty much anything you want to do on your iOS App. And thanks to the Heap Explorer if there is some object that doesn't have a special menu, you can just search it yourself and tweak it.</p><h2 id="customisation">Customisation</h2><p>But of course every app is unique and it’s very likely that you have some set of data or information that you want to expose to QA or other alpha testers. You can probably access that data with the existing tools but sometimes is much better to build some simple custom UI that shows your data in the way it makes more sense.<br><br>I’ve been using custom tools with FLEX for years and recently decided to open a <a href="https://github.com/Flipboard/FLEX/issues/396">GitHub issue</a> with some feedback on how the API could be improved. If it was good enough I can’t wait for it to be even better!</p><p>The nice think about extending FLEX is that the only thing you need to do is create your custom <code>UIViewController</code> and register it to the menu. That's it.</p><pre><code><span class="splash-type">FLEXManager</span>.<span class="splash-call">registerGlobalEntry</span>(withName: <span class="splash-string">"Fancy custom tool"</span>) { hostViewController <span class="splash-keyword">in
    let</span> viewController = ...
    hostViewController.<span class="splash-call">present</span>(viewController, animated: <span class="splash-keyword">true</span>)
}
</code></pre><p>Another powerful thing you can do is register custom keyboard shortcuts than can speed up a lot some flows. For example you can bind the key <code>o</code> (out) to an action that logs out the user from the App. Really useful for when you are working on a feature that forces you to switch accounts often.</p><p>But not everything you want to do may need a custom screen. Sometimes is useful enough to just have a button that triggers some code. For that you can register custom actions on the menu. They look the same as other entries but don't open a screen, they just let you execute code.</p><blockquote><p>To do this I had an ugly workaround for years. But now (<a href="https://github.com/Flipboard/FLEX/pull/411">still in PR</a>) this functionality is exposed with an official API.</p></blockquote><h2 id="my-tools">My tools</h2><p>I imagine that by now you already have some ideas on how to help your peers with amazing tools. But, just in case, let me show you some of the tools I've developed over the years to help my team.</p><img src="https://alejandromp.com/blog/debugging-superpowers-with-flex/flex custom tools.png" alt="flex custom tools"/><p>On our app we have feature fences that allow us to merge changes that are still in progress without the risk of impacting our users in production, but still letting testers try them. To toggle those fences on and off we build a simple screen that lists them and updates the local device flags.</p><img src="https://alejandromp.com/blog/debugging-superpowers-with-flex/fences.png" alt="fences"/><p>One thing I developed around 2018 was an in-house UI component framework, it improved the team's UI development flow so much that is one of the things I'm most proud off. But something I didn't anticipate is the lack of discoverability. When you want to make sure that components are reusable and avoid making new similar ones all the time is crucial to have a way too easily see the ones we already have. To help with this an improvement was made to the components to support examples with the different states so it was easy to have a catalog with all of them. So the <em>HubKit examples</em> entry you see on the menu is a screen that is automatically generated via a combination of protocols and code generation.</p><img src="https://alejandromp.com/blog/debugging-superpowers-with-flex/hubkit example.png" alt="hubkit example"/><p>Analytics tracking libraries are always a pain to work with. And even if they sell realtime updates on the Dashboards that's rarely the case. To help us implement and test events I added a screen that shows the events and screens the App is capturing. This helps testers discard issues on our side very easily.</p><img src="https://alejandromp.com/blog/debugging-superpowers-with-flex/analytics events.png" alt="analytics events"/><p>This screen is nothing fancy in terms of design but it gets the job done. And it even has some level of complexity with the filters and segmented control. But it was developed in a very small amount of time, the secret? SwiftUI 😃.</p><blockquote><p>SwiftUI is ideal for this. And since this is not going to production you are more flexible in terms of using cutting edge frameworks. In fact this is the first SwiftUI code that we have on the LifeWorks app. I recommend you to give it a try, SwiftUI for tools is amazing.</p></blockquote><p>Other interesting tools that we have are actions linked to shortcuts. Clearing the image cache is very useful when you want to make sure the initial impression of a screen is as nice as it can be. We also have an action that triggers a local notification with a payload that lets us test the behaviour of the app without having to force a real notification to come from APNS.</p><p>I've already mentioned the logout action, but we also have a login action that triggers what we call <em>the magic login</em> (or is the <em>witchcraft</em> one?). This is probably the most used action of all by a long shot.</p><h2 id="conclusion">Conclusion</h2><p>If you haven't integrated FLEX on your App yet you are probably wasting somebody's time. This tool is a real time saver just with the default tools that it includes.</p><p>But building tools in a team is something really important that helps keep productivity high, so the fact that FLEX offers a menu to have all these things integrated is why I consider this an essential tool.</p><p>If you have other library preferences or ideas for custom tools feel free to <a href="https://twitter.com/alexito4">send me a message</a> 😉</p><p>Enjoy your new superpowers!</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/make-a-publish-theme-with-sass</guid><title>Make a Publish Theme with SASS</title><description></description><link>https://alejandromp.com/blog/make-a-publish-theme-with-sass</link><pubDate>Thu, 9 Apr 2020 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>Publish's Foundation theme is a very nice starter, but at some point you will want to accommodate it to your needs. When you start touching the CSS you will quickly notice that the workflow is far from ideal.</p><p>Because the CSS file is part of the Resources folder it needs to be copied over to the Output every time you modify it. But not only that, you will also need to perform the difficult task of hitting refresh on the browser. This may seem trivial when the site generates in milliseconds, but the more complexity you add the slower is gonna get and breaking the flow of work is the worse that can happen.</p><p>Luckily you can use the simple technique of using SASS for your site. It will give you live reload but also open the gates to a more powerful (and sane) CSS.</p><p>Watch the video to get the full picture of the issue and how to solve it.</p><iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/j-1O_snUCIs?controls=0" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><p>To make this work you will need to <a href="https://sass-lang.com/install">install SASS</a> and make sure <a href="https://github.com/sass/libsass/blob/master/docs/build-on-darwin.md">the library is accessible</a> on your computer. Once you've done that the <a href="https://github.com/Hejki/SassPublishPlugin">Publish SASS Plugin</a> should work out of the box.</p><p>I recommend you that you use <code>compressed: true</code> when deploying your site so the CSS is minified. It you save you some bytes!</p><p>With the live reloading css, in combination with <a href="https://alejandromp.com/blog/publish-live-reload-html/">live reloading the HTML</a>, we have a decent solution for our development workflow.</p><blockquote><p>Make sure to checkout the <a href="https://alejandromp.com/tags/publish/">Publish tag</a> for more content about this static site generator.</p></blockquote>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/publish-live-reload-html</guid><title>Live reload HTML while developing with Publish</title><description></description><link>https://alejandromp.com/blog/publish-live-reload-html</link><pubDate>Tue, 7 Apr 2020 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>While developing the new version of my website with Publish I had the necessity of have live reloading of the page while developing. I'm happy with the solution I've found even if it's not perfect.</p><iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/JWwHG6ogK0Y?controls=0" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><p>You can watch the <a href="https://youtu.be/JWwHG6ogK0Y">video</a> to see how it works and how is implemented.</p><p>You can check out <a href="https://www.browsersync.io/">Browsersync</a> for more information. It does a lot more things that I need but you may find interesting. I'm just using its functionality to live reload the web browser while developing.</p><blockquote><p>Make sure to checkout the <a href="https://alejandromp.com/tags/publish/">Publish tag</a> for more content about this static site generator.</p></blockquote>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/running-danger-on-github-actions</guid><title>Running Danger on GitHub Actions</title><description></description><link>https://alejandromp.com/blog/running-danger-on-github-actions</link><pubDate>Fri, 27 Mar 2020 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>In the past <a href="https://alejandromp.com/blog/speed-up-your-prs-by-splitting-danger-in-two">I've written</a> about the setup I typically use with <a href="https://danger.systems/">Danger</a>. It worked quite well given the limitations but there was always the annoying restriction that to update the checks you had to push a commit so the CI could run Danger again.</p><p>This is something that <a href="https://github.com/danger/peril">Peril</a> was designed to solve, but I never had time to look into it and probably I wouldn't have used it since it required self-hosting (at least the last time I checked).</p><p>But time has passed and GitHub has now a feature that can help with this: <a href="https://github.com/features/actions">GitHub actions</a>. Let's take a look at how they improve the situation!</p><blockquote><p>Checkout <a href="https://alejandromp.com/blog/github-actions-for-your-swift-package/">GitHub Actions for your Swift Package</a> for another great usage of this GitHub feature.</p></blockquote><h1 id="many-dangers">Many Dangers</h1><p>One thing to take into account is that by now there are many different versions of Danger in different languages and ecosystems. The one I'm talking about is Danger Ruby.</p><p>You may wonder why I'm still using Ruby instead of Swift, since Danger accepts that now (although I'm not fond that it needs JS under the hood for that, even if it makes sense for the project). The answer is two folded.</p><p>For one, it's already setup and working and I don't see the need of migrating the rules for not much gain. Writing them in Swift would be cool but then we have he other reason: Android.</p><p>The majority of the rules on our Danger file are about <em>PR etiquette</em> and that is shared between iOS and Android. If wouldn't be nice to make my Android team switch from Ruby to Swift just because I like it more ^^.</p><h1 id="configure-the-action">Configure the action</h1><p>To configure an action you need to make a new yaml file in your repo at the path <code>.github/workflows/file.yml</code>. You can do that manually but I usually just do it from GitHub's own actions interface.</p><img src="https://alejandromp.com/blog/running-danger-on-github-actions/actions.png" alt="actions"/><p>That page will show you relevant actions for your repo but, at least at the time of writing this, the suggestions for iOS/Swift are quite poor. You may find some predefined action for Danger but I was not able to make any work so I just rolled with my own. This gives me more control about what's happening so it's my preferred option anyway, at least for now.</p><img src="https://alejandromp.com/blog/running-danger-on-github-actions/make your own action.png" alt="make your own action"/><p>Let's take a look at the configuration needed to run Danger.</p><pre><code>name: 🚧 <span class="splash-type">Danger</span>
</code></pre><p>The first thing you want to do is give it a name. It may seem a trivial thing but in my case I will have <a href="https://alejandromp.com/blog/speed-up-your-prs-by-splitting-danger-in-two">another Danger instance</a> running so is important that the names help differentiate them.</p><pre><code>on:
  pull_request:
    types: [opened, reopened, edited, synchronize]
</code></pre><p>This is probably the most important setting of the action, since it's what allow us run Danger when we need it (when a PR is <code>opened</code> or <code>modified</code>), not like before that we were stuck on running it only on commit (called <code>synchronize</code> in the action config).</p><pre><code>jobs:
  build:
</code></pre><p>Now let's describe the work that needs to be done. Starting with the machine that needs to run it.</p><pre><code>     runs-on: ubuntu-latest
</code></pre><p>We pick a linux distribution since is usually the standard and we don't have any specific requirements for this job as long as it can run Ruby.</p><p>Let's move on to the steps:</p><pre><code>     steps:
    - uses: actions/checkout@v2
</code></pre><p>The first thing you need to do is checkout your git repo. For it you can use an existing action that will automatically pull the correct commit.</p><blockquote><p>As many modern CI systems GitHub actions use containers that start from scratch every time they run. This ensures that there is no stale state but also means we can't rely on previous files being there.</p></blockquote><pre><code>     - name: <span class="splash-type">Set</span> up <span class="splash-type">Ruby</span>
      uses: actions/setup-ruby@v1
      with:
        ruby-version: '<span class="splash-number">2.6</span>'
</code></pre><p>The ubuntu image we defined above doesn't have the specific Ruby version we need, so we must install it first.</p><p>For that we use another existing action that installs a specific ruby version just by passing it as a parameter.</p><blockquote><p>I was not able to get it to install the specific patch version we use so I'm just asking for the latest version matching the minor we require.</p></blockquote><pre><code>     - uses: actions/cache@v1
      with:
        path: vendor/bundle
        key: ${{ runner.<span class="splash-property">os</span> }}-gems-${{ <span class="splash-call">hashFiles</span>('**/<span class="splash-type">Gemfile</span>.<span class="splash-property">lock</span>') }}
        restore-keys: |
          ${{ runner.<span class="splash-property">os</span> }}-gems-
</code></pre><p>Adding a cache is an optional step but really useful. There is no need to run trough the gem installation every single time since they don't change that often.</p><p>To ensure that when we change a gem version the gems are refreshed we use the <code>Gemfile.lock</code> hash as the key for the cache.</p><p>The cache action uses a very interesting feature that allows it to install a <em>post action</em>. This means that the action will run first at the point that is defined, to restore, but also at the end of the steps, to save, automatically! This is such an improvement compared to other CI systems.</p><pre><code>     - name: <span class="splash-type">Bundle</span> install
      run: |
        gem install bundler
        bundle config path vendor/bundle
        bundle install --jobs <span class="splash-number">4</span> --retry <span class="splash-number">3</span>
</code></pre><p>Now it's time to install bundler and the specific gems that we need. This ensures that we're running the specific version of Danger that we want.</p><p>Note that we also configure the path to store the gems, this needs to match the path specific previously on the caching step.</p><pre><code>     - name: <span class="splash-type">Run</span> danger
      run: |
        bundle exec danger
      env:
        <span class="splash-type">DANGER_GITHUB_API_TOKEN</span>: ${{ secrets.<span class="splash-type">GITHUB_TOKEN</span> }}
</code></pre><p>And finally we run 🚧 Danger! Note how we run it using bundle, to ensure it runs the known version.</p><p>We also pass the environment variable that it expects to access the GitHub API. And this is another great advantage that GitHub actions have. Because they are a first party service you can just use the <code>secrets</code> to get a token for the action, without having to configure anything else.</p><details><summary>See the entire config</summary>
<pre><code>
name: 🚧 Danger

on:
  pull_request:
    types: [opened, reopened, edited, synchronize]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Set up Ruby 2.6.3
      uses: actions/setup-ruby@v1
      with:
        ruby-version: '2.6'
    - uses: actions/cache@v1
      with:
        path: vendor/bundle
        key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
        restore-keys: |
          ${{ runner.os }}-gems-
    - name: Bundle install
      run: |
        gem install bundler
        bundle config path vendor/bundle
        bundle install --jobs 4 --retry 3
    - name: Run danger
      run: |
        bundle exec danger
      env:
        DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
</code></pre>
</details><h2 id="finishing-touches">Finishing touches</h2><p>I recommend you go into your branch setings and select this new Danger check as a requirement, and disable the old one if you were running it in another CI.</p><p>You can now also cleanup your previous Danger setup from Fastlane or wherever you had it before.</p><h2 id="conclusion">Conclusion</h2><p>You can see how easy is to use GitHub actions and how convenient they are since they are fully integrated into GitHub.</p><p>Go and check them out if you haven't yet!</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/getting-into-the-wheel-of-time</guid><title>Getting into The Wheel of Time and audiobooks</title><description></description><link>https://alejandromp.com/blog/getting-into-the-wheel-of-time</link><pubDate>Thu, 26 Mar 2020 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>When somebody asks me what kind of books I read the answer is always the same: fiction. I very rarely read non-fiction books because <em>real life is boring</em>, a funny sentence that I said without thinking many years ago and became a constant joke at work. Jokes aside, I think it describes quite right what I look for when reading: I want to visit other worlds and live other lives.</p><img src="https://upload.wikimedia.org/wikipedia/en/0/00/WoT01_TheEyeOfTheWorld.jpg"/><p>One of the fantasy series that I've always heard good things of is <a href="https://en.wikipedia.org/wiki/The_Wheel_of_Time">The Wheel of Time</a> by Robert Jordan and Brandon Sanderson. I heard ramblings about it but never paid attention or did any research about it. That was until the tv show started to be rumoured. I immediately got worried about that. I didn't want to watch the show without having read the book first!</p><p>Of course, thanks to the creepy Internet we live in, it didn't take even five minutes for Youtube to show me videos from <a href="https://www.youtube.com/channel/UCw--xPGVVxYzRsWyV1nFqgg">Daniel Greene</a> talking about it. And, this time, I'm happy it did because I've become a huge fan of his channel.</p><p><a href="https://www.youtube.com/watch?v=HVq5izd9sF4">His video</a> convinced me on giving this series a chance. Even if I was a little scared, fourteen books are not a joke. But the, very, positive thing is that the series is finished and right now that's something that I'm very keen on.</p><p>So I decided to give it a go. I bought the book for my Kindle and started reading for a couple of evenings. But one of my flaws quickly showed up, I have always some trouble with starts, specially in epic fantasy where they present to you a thousand characters in a couple of pages... and I'm very bad at names!</p><p>The other inconvenience that I found is that my eyes are already drained enough after an entire day in front of a computer to keep forcing them until midnight. I have many issues with eye sight and so I'm always careful with adding more work to them.</p><p>I was about to drop it but then took the decision of switching to the audio-book instead. For me this was the best decisions, it solved all my problems. I have to admit that took me a couple of chapters to get use to the voices, specially since they change the narrator depending on the main character and I'm not a big voice of the woman's narration. But once I got use to it everything changed.</p><p>First of all, I can <em>read</em> more and faster. As you <a href="https://alejandromp.com/blog/how-to-watch-wwdc/">may know</a> I usually consume content at 2x, but reading at double my usual speed would be quite tricky. But whith an audio book I can crank up the speed with no problem. I keep it at 1.5x because of course comprehending a fantasy story is way harder than a youtube video but still, I gain some time with that. But more importantly, I can <em>read</em> while doing chores at home. This means I can read more often and, as a good side effect, that I don't mind doing them ^^.</p><p>I finished the first entry, The Eye of the World, in about a month. Sadly I was not really impressed by it. I was aware that it's really just an introduction to the series, to a huge world and story, but that's not an excuse for moving on so slowly. You can read on Goodreads the <a href="https://www.goodreads.com/review/show/2462782738?book_show_action=false&from_review_page=1">review</a> I left just after finishing it.</p><p>But that didn't made me stop. Just by the end it got interesting so I quickly jumped into the second one before I lost the hype. Right now I'm about 80% on The Great Hunt and I have to say that I'm liking it way more. The story still moves really slow but I think the characters caught my interest already, which is good.</p><p>I hope I can finish it soon and have enough energy to continue with the series!</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/road-to-swift-6-video</guid><title>Road to Swift 6 video</title><description></description><link>https://alejandromp.com/blog/road-to-swift-6-video</link><pubDate>Wed, 12 Feb 2020 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>I shared a very special video on my <a href="https://www.youtube.com/playlist?list=PL2HXX-dkWqS19JTRnw1rbAaSJ__IOVRUE">Following Swift Evolution</a> video series the other day, <a href="https://youtu.be/EBKoB_8mbnI">Road to Swift 6</a>! I think it's an important moment to look at what the future of our beloved language looks like so I spend some time cleaning up a transcript of the video to have it posted in this blog, for posterity.</p><iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/EBKoB_8mbnI" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><h2 id="road-to-*swift-6*">Road to <em>Swift 6</em></h2><img src="https://alejandromp.com/blog/road-to-swift-6-video/1.jpeg" alt="1"/><p>Hello everyone and welcome to this video where we're gonna explore the Road to Swift 6. I'm very excited for what is coming so this video is very special to me.</p><img src="https://alejandromp.com/blog/road-to-swift-6-video/2.jpeg" alt="2"/><p>Ted, from the Swift Core Team, made a <a href="https://forums.swift.org/t/on-the-road-to-swift-6/32862">post</a> on the Swift forums talking about the goals for Swift 6. So it seems like a good oportunity to discuss what's coming and what I'm most excited about.</p><img src="https://alejandromp.com/blog/road-to-swift-6-video/3.jpeg" alt="3"/><p>But before we focus on the future, it is important to surface the big gaols that have been accomplished already, so we have a clear picture of the position we are on before focusing on what's next.</p><p>Of course we had many language improvements and great features, so making a list here would be too much. But there are 2 specific things that make now a good time to discuss what the future looks like.</p><p>The first one is ABI stability. Even if it's not a big deal for platforms outisde Apple, this was a main focus for the engineering team at Apple and it has been going for a while, being Swift 5 the big release for it. Now that it's done it means they can focus on more big things.</p><p>The other big accomplishment is the Swift Package Manager, which has been integrated in Xcode and includes better support for other IDEs. This provides to the Swift community a common and cross-platform solution for building and distributing Swift libraries. This is a MUST if we want the langauge to grow.</p><p>And that's the point, with the introduced features and a good base for the ecosystem now Swift is in a good position to grow and expand.</p><img src="https://alejandromp.com/blog/road-to-swift-6-video/4.jpeg" alt="4"/><p>So what's the deal with Swift 6? The Core Team likes to focus on <em>themes</em> for every Swift release. These are the broad topics that the Core Team would like to see Swift 6 tackle. It doesn't mean that other features won't be added of course, but this servers as a guide to know what to prioritise.</p><img src="https://alejandromp.com/blog/road-to-swift-6-video/5.jpeg" alt="5"/><ol><li>Accelerate growth of the Swift software ecosystem</li><li>Create a fantastic development experience</li><li>Invest in user-empowering language directions</li></ol><p>It is important to understand that, as with many existing features like ABI stability, a specific feature is not the work of only a single release. Features are worked trough mulitple releases and shiped only when they're ready.</p><p>This means that some things we will mention are already being worked on (like the ownership model) but the important thing is that the core team expects Swift 6 to be the culmination of a bunch of those. So we will see more 5 point releases until everything is ready for a big major release.</p><p>But let's dive into each theme because there is so much interesting things to talk about!</p><img src="https://alejandromp.com/blog/road-to-swift-6-video/6.jpeg" alt="6"/><p>The first major theme is to Accelerate the growth of the Swift ecosystem. Swift is the <em>the facto</em> language for Apple platforms, and is growing in other domains (like services and server side or machine learning with Swift for TensorFlow and Apple's own frameworks). But the core team wants to focus on accelerating this growth and making Swift available for EVERYONE.</p><img src="https://alejandromp.com/blog/road-to-swift-6-video/7.jpeg" alt="7"/><ul><li>More Platforms</li><li>Improve installation and deployment of Swift software</li><li>Support cross-platform tooling</li><li>Cultivate a rich open source library ecosystem</li><li>A package registry?</li></ul><p>The main thing that a language needs to keep growing is to expand the number of platforms where is available and supported. Some community members have done a great work on this, like supporting other unix systems, Arduino or even the port to Windows (the responsable of which, is now part of the core team!). But it would be great if the Swift project had official support for all of this. This would mean integrate those into the main compiler, CI infrastructure, official releses and documentation. I personally would love to see an easy to support Windows and official support for WASM.</p><p>An important diasctintion to make here is that we're not talking about supporting other Application Platforms, this would require huge efforts on UI frameworks that are outside of Swift.org, the focus here is on making the language available on more platforms, which, of course, is the first step for anything bigger to occur.</p><p>The next point is to Improve how software written in Swift is installed and deployed. I rarely use Swift software that doesn't come in form of an App, which is easily installed, or that I run myself from a binary as a CLI. But it would nice to see improvements on this last use case and specially around server code deployment.</p><p>Tooling is a really important part of any programming language. So the next focus is about Supporting cross-platform tooling such as the Language Server Protocol, things like, code formatting and refactoring, and of course the Swift Package Manager. Right now I’m perfectly fine with using Xcode for Swift development, I think is a great IDE and is my main tool, but it's true that having more options is always a good thing, specially for people that will mainly target platforms where Xcode is not availalbe, and the Language server protocol is a great solution for this. And of course, the Swift Package Manager, right now is the way to go, it's so nice to use, specially with Xcode integration, that we can say we finally have a decent official package manager. But there is still lots of things to improve so any progress here is always exciting.</p><p>And probably the most important point of all of this: Cultivate a rich open source library ecosystem. I think this is the key. Other languages have such a huge number of libraries, providing solutions for so many problems, that sometimes Swift can't compete with. In my opinion this is the main reason why someobdy would pick another language over Swift, so we must do better here, quickly.</p><p>The goal for the Core Team here is to help cultivate libraries that help on specific domains. For example SSWG is helping with libraries for services, or the release of Swift Numerics which is a big boost for Swift in scientific scenarios.</p><p>But the question is, how can we encourage great libraries? The SSWG is doing a good job with this thanks to its incubation process, maybe this can be expanded to other domains.</p><p>And one thing that is not mentioned here is a package registry. This is something crucial in my opinion. GitHub announced Swift package integration but I still haven't seen anything public about that. Let's hope this is not forgotten.</p><img src="https://alejandromp.com/blog/road-to-swift-6-video/8.jpeg" alt="8"/><p>Moving on. Growing the langauge won't be worth unless developing with it is a great experience. So I'm glad this is another main theme for Swift 5.</p><img src="https://alejandromp.com/blog/road-to-swift-6-video/9.jpeg" alt="9"/><blockquote><p>Simply put, developers should be both highly <em>productive</em> and experience <em>joy</em> when programming in Swift. Ted Kremenek, <a href="https://forums.swift.org/t/on-the-road-to-swift-6/32862">On the road to Swift 6</a></p></blockquote><p>This is a direct quote from the forum post and IT IS great! In my opinion Swift is a joy to program in, is the language I have more fun with and it makes me use it not only for work but also as a hobby.</p><p>I was talking with a friend about languages, and the topic of making games with Unity came up. I love making games with Unity, and I like C#, it's a great language, but at the end of the day i’m more motivated to work with Swift. Is as simple as that.</p><p>But is true that the experience needs to get better, compiling time is one of the big hurdles so I’m glad is the first thing the core team mentions.</p><img src="https://alejandromp.com/blog/road-to-swift-6-video/10.jpeg" alt="10"/><ul><li>Faster builds!</li><li>More informative and accurate diagnostics</li><li>Responsive code completion</li><li>Reliable and fluid debugging experience</li></ul><p>Faster builds! Who doesn't want that! Not publicly announced yet, but checking GitHub you can see how there is work going on already to significantly improve the performance of incremental builds, they are doing some refactors to have a more precise dependency tracking in the compiler itself.</p><p>Diagnostics! Another crucial aspect of a compiler. <a href="https://swift.org/blog/new-diagnostic-arch-overview/">There is a blog post on Swift.org</a> that goes into great detail about this new system, and Xcode 11.4 is already improving them so much. Diagnostics were one of the big issues on early swift versions, on Swift 5 there were not that bad, but then SwiftUI came and its error where really awful, it reminded my about my time writing C where the errors from the compilers could be 50 files away from the original error. The good thing is that these improvements are not about fixing specific diagnostics, but about having a better overall system across all language</p><p>Responsive code completion is somethign else that is already being worked at. Improving code completion performance, reliability, and experience is a really important thing because is the major way a developer interacts with the langauge. Autocmpletion should show up faster than I can write, otherwise is not that much helpful.</p><p>Debugging is a real pain point. lldb is amazing, when it works. And it fails more often than not. It’s getting better, but it still has issues. I was hoping that with a more mature language, with things like ABI stability, this would have a favorable impact on this, but what do I know.</p><img src="https://alejandromp.com/blog/road-to-swift-6-video/11.jpeg" alt="11"/><blockquote><p>These are <em>crucial</em> endeavors, and they represent most engineering work that is happening in the project right now. They will remain an area of focus until these are nothing short of <em>excellent</em>. Ted Kremenek, <a href="https://forums.swift.org/t/on-the-road-to-swift-6/32862">On the road to Swift 6</a></p></blockquote><p>Ted finishes this part of the post by ensuring us that developer experience is a crucial part of the work they want to focus on, and that they won't stop the efforts until is almost excellent! This is music to my hears.</p><img src="https://alejandromp.com/blog/road-to-swift-6-video/12.jpeg" alt="12"/><p>Moving to the last big theme, a theme focused more on the language itself and what is capable of.</p><img src="https://alejandromp.com/blog/road-to-swift-6-video/13.jpeg" alt="13"/><blockquote><p>The Core Team also wants to continue to make Swift a more <em>powerful</em> programming language and a <em>better tool</em> for solving problems. Ted Kremenek, <a href="https://forums.swift.org/t/on-the-road-to-swift-6/32862">On the road to Swift 6</a></p></blockquote><p>I love this quote from Ted because it shows how the original vision of Swift is still intact and pushing harder than ever before!</p><img src="https://alejandromp.com/blog/road-to-swift-6-video/14.jpeg" alt="14"/><ul><li>Round out capabilities to support expressive and elegant APIs</li><li>Refine Swift’s to allow it to be used for low-level systems programming</li><li>Provide excellent solutions for major language features such as memory ownership and concurrency</li></ul><p>The first point of the theme is to keep improving the capabilities of the language to support expressive and elegant APIs. You know that this is one of my favorutie aspects of Swift, is such an expressive language that the APIs you can get with it are beautiful.</p><p>One of the best examples of this is SwiftUI with its usage of function builders and generics. But this framework also showed that the lagnauge needs more improvements around variadic generics and its DSL capabilities. So I'm glad this keeps being a major focus.</p><p>The next point is one that is often forgotten by App developers. Swift wants to shine too in low level systems programming, but right know there is some pain points that need to be fixed. The focus here is to improve Swift internal implementation to allow it to be used in constraint environments. One major aspect here is Swift's depdency to the unicode definitions, there have been talks already exploring what would be the best way to strip that when not required.</p><p>And a really exciting point in terms of new features! I’ve been waiting for the memory ownership model for a while now, I think is one of the aspects that will set Swift apart. Being able to close some of the gap with Rust in this aspect would be amazing.</p><p>And of course the concurrency model! It's one of the features that people makes fun of when talking about Swift, and I think that the sixth version of the language shouldn't miss the opportunity to introduce it.</p><p>But to accomplish all these goals there should be a better organisation of the community, becuase there is so much stuff to do! So what's the idea?</p><img src="https://alejandromp.com/blog/road-to-swift-6-video/15.jpeg" alt="15"/><p>The working group model is something that has worked really well in other communities like Rust. But it Is important to understand that this are not a team of developers, but a group of people that focuses on a specific area to guide and supports the community investment and efforts.</p><p>This is something that has worked really well for Rust and fir Swift Server Working Group. It seems that the new concurrency model will have a working group, because it will need research and agreements to get into an excellent solution.</p><p>But I would love to see more investment on this structure and get even more working groups like Rust. And I think not all groups need to be technical centric. It would be great to have one for documentation, or teaching for example! How cool would it be to work on that?</p><img src="https://alejandromp.com/blog/road-to-swift-6-video/16.jpeg" alt="16"/><p>By this point I know what you're asking, so when is all of this gonna be shipped?</p><img src="https://alejandromp.com/blog/road-to-swift-6-video/17.jpeg" alt="17"/><p>When it's done!</p><p>There are NO RELEASE DATES. This efforts will take time to investigate and implement, but meanwhile we will keep having 5 point releases. The release of Swift 6 is gonna happen when those efforts culminate.</p><p>If I understand this corectly I think is a great way to make the Swift project evolve without being tied with Apple yearly releases.</p><img src="https://alejandromp.com/blog/road-to-swift-6-video/18.jpeg" alt="18"/><ul><li>Coroutines</li><li>Memory Ownership</li><li>Compile Times</li><li>Package ecosystem</li><li>More focused and lovable community</li></ul><p>Let's finish with my favourites.</p><p>Of course coroutines and the concurrency model are the most exciting features that will have a great impact on our day to day coding. The majority of other language have this feature already so it is something that Swift needs to do soon. I don't mind is taking them long because the plans they have are amazing. I'm still exciting about the technical details they shared on the concurrency manifesto. Making the async/await coroutines the building blogs instead of a higher level concept seems like a really exciting proposal.</p><p>And another feature. The memory ownership model. This one has me really excited. Right now the other language that competes with Swift in my personal love for programming is Rust. Rust was a ground breaking language for all the safety and concepts that it added to the main stream. If Swift can learn from it and bring some of those concepts, in a Swifty way, it will be more than great. I've been thinking about talking about what memory ownership implies, for app developers that are not deep into this low level things, but not sure how much interest this topic has. 😀</p><p>Then we get into tooling. Compile times. There is not much to say here. They need to get better, we all know that.</p><p>As I said before, I think what sets apart a language ecosystem is the quantity and quality of their packages. I don't need Swift to have so many packages like other ecosystems, but we need more of them and keeping with the high quality standards expected.</p><p>And finally for all of this to happen I would hope to see this year a more focused community, but specially a more lovable and positivy community. I'm a little tired of seeing people argue and attack members of their own community (I mean you shouldn't attack anybody, never, but cmon share a common love here!). Stop critising the people that dedicates time to the langauge attaching them of langauge nerds, be more open minded and for the love of god, stop confusing the Swift community for Apple. This project is a community project so you should start taking ownership of it. Rant over.</p><p>But tell me, what are you most excited about?</p><img src="https://alejandromp.com/blog/road-to-swift-6-video/19.jpeg" alt="19"/><blockquote><p>Our goals for Swift are <em>ambitious</em>: we want to make programming <em>simple</em> things <em>easy</em>, and <em>difficult</em> things <em>possible</em>.</p></blockquote><p>To finish in a more, I got this quote is from Swift.org, and is what makes Swift so exciting. This clear goal, and not being conformed with the status quo is what makes this such an exciting language, ecosystem and community. Let's keep it that way!</p><img src="https://alejandromp.com/blog/road-to-swift-6-video/20.jpeg" alt="20"/><p>So this has been my video about Swift 6. I hope you enjoyed and got as excited as me with the future our beloved langauge has.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/github-actions-for-your-swift-package</guid><title>GitHub Actions for your Swift Package</title><description></description><link>https://alejandromp.com/blog/github-actions-for-your-swift-package</link><pubDate>Sat, 11 Jan 2020 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>With the release Xcode 11 is now easier than ever before to work with the Swift Package manager. If I enjoyed making CLI tools with Swift before, now it's a pleasure! Lately I've been working on a <a href="https://github.com/alexito4/ReadingTimePublishPlugin">small plugin</a> for the recently released static site generator <a href="https://github.com/JohnSundell/Publish">Publish</a>. And the plugin is itself a Swift Package so I had to opportunity to enjoy SPM and Swift tooling development.</p><p>But one of the things I rarely enjoy when publishing any open source repo is the setup of the CI. Yes, nowadays is not that hard with many companies offering free resources for open source repos, but still, having to create an account, linking it with GitHub, manually creating configuration files... sometimes is too much effort for a simple and small repo.</p><p>Thankfully GitHub has been improving its platform quite a lot this past year, and one of the new features are <a href="https://github.com/features/actions">GitHub actions</a>. These actions allow us to create automated workflows on our repo using GH servers and fully integrated with our commits and pull requests.</p><p>The amazing thing is that adding this to your Swift package repo takes <strong>less than one minute</strong>!</p><p>Try it by yourself:</p><ol><li>Go to your repo's Actions tab.</li></ol><img src="https://alejandromp.com/blog/github-actions-for-your-swift-package/actions_tab.png" alt="actions tab"/><ol start="2"><li>GitHub will detect that your repo is a Swift package and it will already suggest the proper action. Just click on <em>Set up this workflow</em>.</li></ol><img src="https://alejandromp.com/blog/github-actions-for-your-swift-package/suggested_action.png" alt="swift suggested action"/><p>The basics of this workflow should work for most projects. It <strong>builds</strong> and <strong>tests</strong> your Swift package in a macOS machine on every push to the repo.</p><ol start="3"><li><strong>Commit</strong> or create a branch with the changes.</li></ol><p>AND THAT'S IT!</p><p>From now on every push on the repo will trigger this action and report the results back to the commit.</p><img src="https://alejandromp.com/blog/github-actions-for-your-swift-package/commit_status.png" alt="commit status"/><p>And if the commit is part of a PR you will also see the action run as part of the PR checks.</p><img src="https://alejandromp.com/blog/github-actions-for-your-swift-package/pr_checks.png" alt="Screenshot 2020-01-11 at 11.27.47"/><p>From here you can expand your integration as you want, but it is quite amazing that in less than a minute and with 2 clicks we can have a CI integration directly into our repo.</p><p>Now you just need to write unit tests for it 😉</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/swiftui-enumerated</guid><title>SwiftUI, list with indices without enumerated</title><description></description><link>https://alejandromp.com/blog/swiftui-enumerated</link><pubDate>Sat, 4 Jan 2020 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>One of the common things we want to display with SwiftUI are lists of our models. The basics of it are pretty easy, you just need to use a <code>ForEach</code> view.</p><pre><code><span class="splash-type">ForEach</span>(humans) { human <span class="splash-keyword">in</span>
    <span class="splash-type">Text</span>(human.<span class="splash-property">name</span>)
}
</code></pre><blockquote><p>This works out of the box assuming your model is <code>Identifiable</code>. Otherwise you will need to pass a second argument to the <code>ForEach</code> giving a KeyPath to the id.</p></blockquote><img src="https://alejandromp.com/blog/swiftui-enumerated/simple_list.png" alt="simple list"/><p>It gets a little trickier when you want to display no only your data but also its position on the list.</p><img src="https://alejandromp.com/blog/swiftui-enumerated/enumerated_list.png" alt="enumerated list"/><p>You may try the correct solution directly, but I would like to show here the different options we have and discard many of them, since they can provoke errors and even crashes. Sadly those are the ones you will find recommended online so always be careful. Don't even take my word for granted!</p><p>Let's see what options we have.</p><h2 id="enumerated()">enumerated()</h2><p>One of the obvious ways of doing it is using the <code>enumerated()</code> function on your collection. This will return a new collection with a tuple of the element and its offset.</p><blockquote><p><code>element</code> and <code>offset </code> are the labels of the tuple, even if there is no clear documentation saying it, it can be deduced from some signatures.</p></blockquote><p>The first problem we encounter with this approach is that we need to provide an ID, since the tuple of the collection is not Identifiable.</p><pre><code><span class="splash-type">ForEach</span>(humans.<span class="splash-call">enumerated</span>(), id: \.<span class="splash-property">offset</span>)
</code></pre><p>But this doesn't work, the compiler gives us this nice error:</p><pre><code><span class="splash-type">Referencing</span> initializer '<span class="splash-keyword">init</span>(<span class="splash-keyword">_</span>:id:content:)' on '<span class="splash-type">ForEach</span>' requires that '<span class="splash-type">EnumeratedSequence</span>&lt;[<span class="splash-type">Human</span>]&gt;' conform to '<span class="splash-type">RandomAccessCollection</span>'
</code></pre><p>The issue here is that <code>ForEach</code> needs a <code>RandomAccessCollection</code>, presumedly to access directly specific elements of the collection to reload only those that change. But when using <code>enumerated()</code> we get back an <code>EnumeratedSequence</code>, a sequence that doesn't provide random access.</p><h2 id="reversed()">reversed()</h2><p>You can use <code>reversed()</code> to get a <code>RandomAccessCollection</code>.</p><pre><code><span class="splash-type">ForEach</span>(humans.<span class="splash-call">enumerated</span>().<span class="splash-call">reversed</span>(), id: \.<span class="splash-property">offset</span>)
</code></pre><p>This satisfies the compiler and works as expected:</p><img src="https://alejandromp.com/blog/swiftui-enumerated/reversed_list.png" alt="reversed list"/><p>But of course, this is not really useful unless you want your list to be reversed.</p><p>Still, it helps us understand what's going on. The reason this satisfies the compiler is because the reversed function returns an <code>Array</code>, which is a <code>RandomAccessCollection</code>.</p><p>So what if we do that ourselves?</p><h2 id="array">Array</h2><p>One correct approach is to take the enumerated sequence and consume it immediately to create an array. In that way we get our <code>RandomAccessCollection</code> and the <code>ForEach</code> view can do its work.</p><pre><code><span class="splash-type">ForEach</span>(<span class="splash-type">Array</span>(humans.<span class="splash-call">enumerated</span>()), id: \.<span class="splash-property">offset</span>)
</code></pre><p>This works fine and, as far as I know, it won't provoke any errors.</p><p>But... performance. Remember, any performance claim needs to be backed with real data, which I don't have, so don't take this as pure truth but... seeing that Array creation, from a sequence is suspicious. To create that array the sequence needs to be iterated fully, so on big datasets it could be noticeable. And remember that this code is inside SwiftUI View <code>body</code> function, so it will run quite often.</p><p>You can probably live with this for a while if you control your data set and is not that big, you may even want to make it nicer with some extension on collection that gives you directly an enumerated array or even a fancy custom initialiser in the <code>ForEach</code>.</p><p>But there is another alternative.</p><h2 id="ranges">Ranges</h2><p>Using <code>enumerated()</code> is really convenient because it gives you the offset and the element at the same time without more effort. But there is always the alternative of iterating over a range, and with each index of the iteration access the collection to get the element.</p><pre><code><span class="splash-type">ForEach</span>(<span class="splash-number">0</span>..&lt;humans.<span class="splash-property">count</span>) { i <span class="splash-keyword">in</span>
    <span class="splash-type">Text</span>(<span class="splash-string">"</span>\(i+<span class="splash-number">1</span>)<span class="splash-string">.</span> \(humans[i].name)<span class="splash-string">"</span>)
}
</code></pre><p>This is one of the most recommended ways I see online, but in my experience this <strong>can crash</strong> your App.</p><blockquote><p>Note that SwiftUI is still pretty young. This may be intended behaviour or a bug. Maybe it's already fixed or maybe is that my code triggered some edge case.</p></blockquote><p>Because there is not much documentation and we don't have access to the source is quite tricky to know the reasons, but knowing how it may work we can deduce something.</p><p>I've seen this kind of code crash when the collection changes, SwiftUI runs the body function of the views again and suddenly this code accesses an invalid index. Stepping into the debugger you may see how your array has the correct data, but the index is trying to access is from an older version of it.</p><img src="https://alejandromp.com/blog/swiftui-enumerated/crash.png" alt="crash"/><p>This seems to me that SwiftUI is trying to be smart in the way it computes UI differences. Maybe is caching the indices too heavily, but my theory is that the issue comes because we're using a literal range and it assumes that the Range will be static, so when it needs to recompute the layout it just runs the closure again.</p><p>Interestingly enough this doesn't happen if you are in a fully dynamic view since the entire view needs to be recomputed for a diff. But if you're in a static view and this For is the only thing that can change... you may be surprised.</p><h2 id="indices">indices</h2><p>The idea of iterating indices and getting the element afterwards was not bad. A literal Range can cause issues but we can use a function that gives us the indices, avoiding any literal use. We can just use <code>indices()</code>.</p><pre><code><span class="splash-type">ForEach</span>(humans.<span class="splash-property">indices</span>) { i <span class="splash-keyword">in</span>
    <span class="splash-type">Text</span>(<span class="splash-string">"</span>\(i+<span class="splash-number">1</span>)<span class="splash-string">.</span> \(humans[i].name)<span class="splash-string">"</span>)
}
</code></pre><p>This seems safe to use in my experience. When SwiftUI needs to recompute the view it will correctly retrieve a new range of indices avoiding any crash.</p><h2 id="careful-with-slices">Careful with Slices</h2><p>Not specific to SwiftUI, but is worth being reminded. Keep in mind that any use of indices is dangerous unless you know that the collection you're working with is 0-indexed. If you're working directly with an array then you're safe to use this techniques, otherwise be careful.</p><p>Imagine that our data is a slice of the original:</p><pre><code>humans.<span class="splash-call">suffix</span>(<span class="splash-number">2</span>)
</code></pre><p>In my example with 4 original Humans, now we have an ArraySlice of count 2, but the index of them still is based on the original array.</p><p>In the case of a literal range you will get an <strong>Index out of bounds</strong> and crash the App. In the <code>indices</code> case the App won't crash but you won't see the list start at the proper number on the UI:</p><img src="https://alejandromp.com/blog/swiftui-enumerated/slice.png"/><h2 id="indices-as-part-of-your-data">Indices as part of your data</h2><p>One alternative that I haven't mentioned yet is to simply avoid doing this on the UI. You can always bake the index of each element as part of your data model or any other intermidiate layer.</p><p>That depends on your application but is worth mentioning ;)</p><h2 id="conclusion">Conclusion</h2><p>It's quite surprising that something so simple can get so complicated.</p><p>As you can see there is no silver bullet but I hope that with this post at least now you get an understanding of the situation and can analyse the tradeoffs on your situation.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/tips-to-successfully-remove-code-and-assets</guid><title>Tips to successfully remove code and assets</title><description></description><link>https://alejandromp.com/blog/tips-to-successfully-remove-code-and-assets</link><pubDate>Mon, 19 Aug 2019 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>This week I removed a big chunk of code from our app, an entire section/feature. I've been working on this codebase for years and I had the opportunity to do a bunch of cleanups. Thanks to that I've organically developed a strategy to remove code that is quite successful to me.</p><p>The goal of my strategy is to make sure everything is gone, that no traces in the codebase of this old feature last. This is important to understand because this technique doesn't favour speed so doesn't expect tips around that.</p><h2 id="modules">Modules</h2><p>Before we go into the tips, of course I must give you an important recommendation: modules.</p><p>If you split your features in different modules you will have an easier time getting rid of them. But you won't always have this privilege, specially in older codebases.</p><p>But even in the cases you have, maybe that module has dependencies or assets that are pulled from somewhere else that you also want to remove.</p><p>That's why I still use this technique even if my code is properly modularised.</p><h2 id="step-0:-the-note">Step 0: The note</h2><p>The first thing you should do is <strong>open a note</strong> on your notes app of choice.</p><p>This technique relies evenly on keeping track of things in a note, so make sure you setup your environment to quickly jump between your IDE and the note. Multiple screens, split windows, shortcuts… whatever works best for you.</p><p>The only small requirement for the notes App is that it should allow you to paste code without messing with the formatting or quotes. You will need to copy the code from the note later, and if quotes are messed up it will be a pain to find what you're looking for.</p><h2 id="step-1:-removing-code-and-gathering-dependencies">Step 1: Removing code and Gathering dependencies</h2><p><strong>Delete one file at a time</strong>: Removing an entire folder is quicker but I assure you there will be dependencies outside that folder that you will forget to remove. Go file by file skimming the code looking for dependencies, strings, assets, etc. Your IDE should color strings differently so they will be easier to catch.</p><p><strong>Gather the dependencies, don't remove them yet:</strong> It may be tempting to remove every string or other dependency as you find them. But that constant change of context will make you slower and is really error prone. Furthermore, that dependency may be used somewhere else so it shouldn't be removed. Remember that note that I mentioned? <strong>Write down every dependency on the note</strong>.</p><p>If you're removing code in a language with headers you're in luck! The explicit imports will help you trace dependencies down. Copy and paste each import line in the note for later. And don't bother about duplicates for now. Just paste it all there, at this point you don't have to worry about the dependencies, you just gather them all.</p><p>If you're using a modern language without headers, you still can do the same with external modules. For your own code dependencies is gonna be harder. Try to keep an eye open for code that may seem only used in this feature. This is often the case with <strong>helpers</strong> that are used in different parts of the codebase but with time they ended up just using in one place, if this is the last place they should be removed!</p><p>Do the same for strings, assets or other external resources, but make sure you keep each kind of dependency in a separate list, you don't want to be jumping around on the next part.</p><p>The goal of this step is to <strong>gather all the dependencies</strong> in the note while removing the code. It is important that you <strong>don't act on the dependencies yet</strong>.</p><h2 id="step-2:-remove-dependencies">Step 2: Remove dependencies</h2><p>Once you've finished removing all the files from your feature you will likely have a note with a bunch of dependencies: modules, file imports, strings, images, etc. Now is time to get rid of them.</p><p><strong>Start with code dependencies</strong> because this ones are likely to surface more dependencies, and because the compiler is gonna help you more than with the rest.</p><p>One important thing to keep in mind is that during this process you may find other code that you can remove, when that happens keep in mind the methodology. Remove the code, but just gather the dependencies. Iteration!</p><p>Before continuing with any of the list, I recommend you to sort them alphabetically. Your editor will probably have a command to do that, and if not copy paste the list in an editor that has it or some website. The advantage of having the list sorted is that you can very quickly see duplicates and reduce the times pend in the following steps.</p><p>If you have a list of imports, for example in Objective-C, paste them all in a header file and run the compiler. Any import that the compiler can find will mean that is for a file that you removed, good job!</p><p>For the imports that the compiler finds you can to a search for those types and check if they're still used in another part of the codebase. If the only result is the import you just pasted you're in luck, you can remove that code too!</p><p>Now that all the code is removed, you can work on strings, images and other assets. You can just do a search for each item on the list and see if they have any other usages. If they don't it means is time to remove them! Your users will be happy that the App has shrink in size ^^</p><p>If the assets are used in other parts of the code I still recommend you to check them. The usage of those assets may mean that that code can be also removed!</p><h2 id="step-3:-the-pr">Step 3: The PR</h2><p>Once your job is done is time to PR the changes into the main branch. The resulting PR will likely be huge and your colleagues may quickly skip it and approve it, after all is just removing code ¯_(ツ)_/¯ . WRONG!</p><p>First of all, during this removal you're likely to modify slightly some parts of the code to avoid using stuff that you removed <em>(maybe an enum case doesn't make sense anymore, and that affects some switch statements)</em>. Those parts must be reviewed carefully like in any other PR.</p><p>But even more, ask your colleagues to take a look at the files that have been removed, this technique is not infallible so the more eyes there are looking at the PR the more likely it is to <strong>find something you missed</strong>.</p><p>Making sure everything is removed now is important. Yes, you can always do it in some months when you find that something is not used, but when that happens nobody remembers why that thing was there in the first place, and nobody is sure if it can break something else. When that happens in the middle of something more urgent the result is that nobody removes anything. Leaving dead code or assets in the codebase for even longer. You're gonna regret it, and your users won't be happier.</p><h2 id="numbers">Numbers</h2><p>Because this is a tedious process I recommend you that at the end you have some fun.</p><p>Before merging the PR run some analytics to count the number of lines you removed from the codebase. You can use GitHub numbers but if you want to go into more detail I recommend you to manually run <a href="https://github.com/XAMPPRocky/tokei">tokei</a> or any other similar program of your choice.</p><p>The last feature I removed was an important portion of our codebase, specially in terms of assets. More than 200 files and 20k lines of code.</p><blockquote class="twitter-tweet"><p lang="en" dir="ltr">GH may be a little misleading, as that includes strings, an external Pod and tests. <br>Checking only production and test folders (ignoring Pods):<br>209 files removed<br>23,177 lines (including blanks and comments)<br>15,873 lines of code</p>&mdash; Alejandro Martinez (@alexito4) <a href="https://twitter.com/alexito4/status/1162319538840621056?ref_src=twsrc%5Etfw">August 16, 2019</a></blockquote><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script><p>And that was before one of my colleagues found more stuff to remove! That's why the PR is so important! ^^</p><h2 id="tools">Tools</h2><p>A quick note on tools.</p><p>It's likely that there are a bunch of tools that check for dead code, unused assets, etc. I recommend you to use them but <strong>don't rely on them</strong>. Those type of static analysis tools often miss things in complex codebases or if you do anything at runtime.</p><h2 id="conclusion">Conclusion</h2><ol start="0"><li>Open a note</li><li>Delete code. Gather dependencies like other modules, helpers, strings, assets...</li><li>Delete the dependencies.</li><li>PR.</li></ol><p>This may seem like a longwinded way of doing this task. But after doing it many times over the years and always missing stuff I've organically developed this series of tips to try to reduce what's missed.</p><p>If you have any other tips don't hesitate to send them over! ^^</p><p>And be happy! You removed some code! The best feeling eva :P</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/improving-swiftui-modal-presentation-api</guid><title>Improving SwiftUI modal presentation API</title><description></description><link>https://alejandromp.com/blog/improving-swiftui-modal-presentation-api</link><pubDate>Mon, 24 Jun 2019 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>SwiftUI has some presentation modifiers to display alerts, sheets and full screen views. On one hand, presenting an alert is nice and easy, it feels really well designed. But on the other hand presenting a modal screen (or action sheets or popovers) is too cumbersome.</p><img src="https://alejandromp.com/blog/improving-swiftui-modal-presentation-api/swiftui_presentation.png" alt="presentation"/><h2 id="alert-presentation">Alert presentation</h2><p>What makes presenting an alert so nice is the fact that the API uses a binding.</p><pre><code>.<span class="splash-call">presentation</span>(<span class="splash-property">$showAlert</span>, alert: { <span class="splash-type">Alert</span>(title: <span class="splash-type">Text</span>(<span class="splash-string">"Alert!"</span>)) })
<span class="splash-comment">//            ----------
//                ^ this is a binding to a boolean</span>
</code></pre><p>With this simple line the framework takes care of presenting the alert when the flag <code>showAlert</code> is <code>true</code>, and setting it to <code>false</code> when the alert is dismissed. You don't have to manage the presentation or maintain the state, it's all taken care for you.</p><p>This makes it really easy to present alerts. Usually you just need to keep a <code>State</code> property around and set it to <code>true</code> when appropriate.</p><pre><code><span class="splash-keyword">@State var</span> showAlert = <span class="splash-keyword">false</span>
...
<span class="splash-type">VStack</span> {
    <span class="splash-type">Button</span>(action: { <span class="splash-keyword">self</span>.<span class="splash-property">showAlert</span>.<span class="splash-call">toggle</span>() }) {
        <span class="splash-type">Text</span>(<span class="splash-string">"Show alert!"</span>)
    }
}
.<span class="splash-call">presentation</span>(<span class="splash-property">$showAlert</span>, alert: { <span class="splash-type">Alert</span>(title: <span class="splash-type">Text</span>(<span class="splash-string">"Alert!"</span>)) })
</code></pre><h2 id="modal-presentation">Modal presentation</h2><p>Let's take a closer look at the modifier to present a modal:</p><pre><code>.<span class="splash-call">presentation</span>(<span class="splash-type">Modal</span>?)
</code></pre><p>The first thing that you notice is how this method doesn't accept a binding to a boolean. Instead, to decide when to show the modal, it uses an optional. If you pass nil, the modal is not presented; if you pass a <code>Modal</code> the view is presented.</p><p>This seemingly small difference causes a big impact in the way we use it.</p><p>First of all, we still need to know when to present it or not, for the simple case let's use a boolean like we did for the alert. But now instead of just passing it as a binding, we need to perform the check ourselves.</p><pre><code>.<span class="splash-call">presentation</span>(showModal ? <span class="splash-type">Modal</span>(<span class="splash-type">Text</span>(<span class="splash-string">"Modal screen"</span>)) : <span class="splash-keyword">nil</span>)
</code></pre><p>This is not that bad, not as nice as passing a binding but not the worse.</p><pre><code><span class="splash-keyword">@State var</span> showModal = <span class="splash-keyword">false</span>
...
<span class="splash-type">VStack</span> {
    <span class="splash-type">Button</span>(action: { <span class="splash-keyword">self</span>.<span class="splash-property">showModal</span>.<span class="splash-call">toggle</span>() }) {
        <span class="splash-type">Text</span>(<span class="splash-string">"Show modal!"</span>)
    }
}
.<span class="splash-call">presentation</span>(showModal ? <span class="splash-type">Modal</span>(<span class="splash-type">Text</span>(<span class="splash-string">"Modal screen"</span>)) : <span class="splash-keyword">nil</span>)
</code></pre><p>But there is a big problem in this code. When the modal is dismissed the flag it's still set to <code>true</code>, and thus any change that triggers the UI to be re-rendered may cause the modal to appear again. Or more obviously, when the button is pressed again the modal won't show up, because toggle will change the flag from <code>true</code> to <code>false</code>. ☹️</p><p><strong>Our State and UI are out of sync!</strong></p><p>This API is causing the very same problem that SwiftUI promised to fix.</p><p>To implement a proper modal presentation we need to make sure that the flag is changed properly. Maybe your modal screen is so custom that you want to change the flag from the modally presented view, but for the majority of cases it would be enough to change the flag when the screen is dismissed. We can use the <code>onDismiss</code> closure from the <code>Modal</code> view for that:</p><pre><code>.<span class="splash-call">presentation</span>(showModal ? <span class="splash-type">Modal</span>(<span class="splash-type">Text</span>(<span class="splash-string">"Modal screen"</span>), onDismiss: {
    <span class="splash-keyword">self</span>.<span class="splash-property">showModal</span>.<span class="splash-call">toggle</span>()
}) : <span class="splash-keyword">nil</span>)
</code></pre><p>Now our UI and State are in sync again. 😃</p><p>Even if this is problematic and cumbersome it makes sense from an API design point of view. An alert has a fix UI that the framework controls, so it can know when to change the state. Instead, a modal is a completely custom piece of UI and the framework can't know when to change our state.</p><p>That said, I think we could have a simpler API for the typical use case.</p><h2 id="an-improved-modal-api">An improved modal API</h2><p>The default modal presentation doesn't prove any visual way for the user to close the modal, but as of iOS 13 the user can swipe down the view to make it disappear.</p><blockquote><p>This is another reason why it would make sense for the modal API to take care of changing the flag for us.</p></blockquote><p>This interaction is really nice, but 90% of the time you will want to add some affordance for the user to know how to close the modal. And usually this is just done by a <em>Done</em> button.</p><p>Assuming this is the UI we want, is quite simple to build an improved modal API that makes our code look like this:</p><pre><code><span class="splash-type">VStack</span> {
    <span class="splash-type">Button</span>(action: { <span class="splash-keyword">self</span>.<span class="splash-property">showModal</span>.<span class="splash-call">toggle</span>() }) {
        <span class="splash-type">Text</span>(<span class="splash-string">"Show modal!"</span>)
    }
}
.<span class="splash-call">presentation</span>(<span class="splash-property">$showModal</span>, title: <span class="splash-type">Text</span>(<span class="splash-string">"Example modal"</span>), modal: { <span class="splash-type">Text</span>(<span class="splash-string">"Modal screen!"</span>) })
</code></pre><p>Now we're talking! This looks much better, similar to how the <code>Alert</code> API looks like. 🎉</p><p>With this new method we just need to pass a binding to the boolean, like the Alert did.</p><p>We can also pass a title for the modal screen, which is gonna be used to create a <code>NavigationView</code> with a <code>Done</code> button that will help the user close the screen.</p><p>Finally you pass the View that you want to present modally. The method takes care of wrapping that view inside a <code>Modal</code> and changing the status of the flag when appropriate.</p><img src="https://alejandromp.com/blog/improving-swiftui-modal-presentation-api/modal.gif" alt="modal"/><p>The method looks like this:</p><pre><code><span class="splash-keyword">extension</span> <span class="splash-type">View</span> {
    <span class="splash-keyword">func</span> presentation&lt;T: <span class="splash-type">View</span>&gt;(<span class="splash-keyword">_</span> isShown: <span class="splash-type">Binding</span>&lt;<span class="splash-type">Bool</span>&gt;, title: <span class="splash-type">Text</span>, modal: () -&gt; <span class="splash-type">T</span>) -&gt; <span class="splash-keyword">some</span> <span class="splash-type">View</span> {
        <span class="splash-keyword">let</span> view = <span class="splash-type">NavigationView</span> {
            <span class="splash-call">modal</span>()
                .<span class="splash-call">navigationBarTitle</span>(title)
                .<span class="splash-call">navigationBarItems</span>(trailing: <span class="splash-type">Button</span>(action: {
                    isShown.<span class="splash-property">value</span>.<span class="splash-call">toggle</span>()
                }, label: { <span class="splash-type">Text</span>(<span class="splash-string">"Done"</span>) } ))
        }

        <span class="splash-keyword">return</span> <span class="splash-call">presentation</span>(isShown.<span class="splash-property">value</span> ?
            <span class="splash-type">Modal</span>(
                view,
                onDismiss: {
                    isShown.<span class="splash-property">value</span>.<span class="splash-call">toggle</span>()
              }
            )
            : <span class="splash-keyword">nil</span>
        )
    }
}
</code></pre><p>This may not make sense as part of the framework, but there is no doubt that it's a vital method to keep around on your projects.</p><p>But don't take it as is! Tweak it so it makes sense for your app: maybe say <em>Close</em> instead of <em>Done</em>, or add an option to add a <em>Cancel</em> button. The possibilities are endless!</p><h2 id="conclusion">Conclusion</h2><p>What I want you to take from this post, apart from a nice presentation helper method, is not that SwiftUI presentation API is not ideal. Quite the opposite!</p><p>I want you to appreciate how thanks to the design of the framework (based on value types, protocols and function modifiers) it's really easy for us to learn from its API and extend it to accommodate for our needs.</p><blockquote><p>Check out the rest of <a href="https://alejandromp.com/tags/swiftui">SwiftUI posts</a>.</p></blockquote>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/swiftui-reusable-button-style</guid><title>SwiftUI reusable Button style</title><description></description><link>https://alejandromp.com/blog/swiftui-reusable-button-style</link><pubDate>Sat, 22 Jun 2019 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>In my previous post about <a href="https://alejandromp.com/blog/playing-with-swiftui-buttons/">SwiftUI buttons</a> I described a technique to reuse button configuration with a <code>ViewModifier</code>. Now that beta 2 is out, we finally have the proper tools to reuse styles in a much better way!</p><h2 id="styles-with-`viewmodifier`">Styles with <code>ViewModifier</code></h2><p>Let's start by having a simple default SwiftUI button:</p><pre><code><span class="splash-type">Button</span>(action: {}) {
    <span class="splash-type">Text</span>(<span class="splash-string">"Default style"</span>)
}
</code></pre><p>In the previous post I used <code>ViewModifier</code> to encapsulate and reuse some styles. The problem with that technique is that you're forced to apply the modifier to the content of the button (SwiftUI calls this <code>Label</code>).</p><pre><code><span class="splash-type">Button</span>(action: {}) {
  	<span class="splash-type">VStack</span> {
        <span class="splash-type">Image</span>(...)
        <span class="splash-type">Text</span>(<span class="splash-string">"..."</span>)
    }
    .<span class="splash-call">myButtonStyle</span>() <span class="splash-comment">// &lt;- my custom modifier</span>
}
</code></pre><p>This was acceptable for a provisional workaround, but it's kind of weird to apply styles to the content of the button instead of the button itself.</p><p>And remember that we could not apply the modifier to the button itself because then things like padding and background were applied at the incorrect level of the view hierarchy. <em>(read the previous post if you don't understand this because is a crucial aspect of SwiftUI)</em></p><h2 id="buttonstyle">ButtonStyle</h2><p>Luckily for us SwiftUI has a better way of doing this. A button has a modifier that accepts a <code>ButtonStyle</code>:</p><pre><code><span class="splash-type">Button</span>(action: {}) {
    <span class="splash-type">Text</span>(<span class="splash-string">"..."</span>)
}
.<span class="splash-call">buttonStyle</span>(.<span class="splash-dotAccess">default</span>)
</code></pre><p>We can use this ourselves and create our own custom styles as <code>struct</code>s conforming to the <code>ButtonStyle</code> protocol.</p><pre><code><span class="splash-keyword">public struct</span> BackgroundButtonStyle: <span class="splash-type">ButtonStyle</span> {
    
    <span class="splash-keyword">public func</span> body(configuration: <span class="splash-type">Button</span>&lt;<span class="splash-type">Self</span>.<span class="splash-type">Label</span>&gt;, isPressed: <span class="splash-type">Bool</span>) -&gt; <span class="splash-keyword">some</span> <span class="splash-type">View</span> {
        configuration
            .<span class="splash-call">accentColor</span>(.<span class="splash-dotAccess">red</span>)
            .<span class="splash-call">padding</span>()
            .<span class="splash-call">background</span>(.<span class="splash-dotAccess">yellow</span>)
            .<span class="splash-call">cornerRadius</span>(<span class="splash-number">4</span>)
    }
}
</code></pre><p>This follows a recurring pattern on SwiftUI, you create a struct conforming to a protocol. This is quite nice because it becomes familiar pretty quickly.</p><p>In this case the protocol is similar to <code>ViewModifier</code>. It defines a function <code>body</code> that accepts a configuration <code>Button</code> . This is the view to which you need to apply the modifiers.</p><p>It also has a second parameter, a boolean that tells us if the button is pressed or not. This is something that we don't have access with other styling techniques. It helps us <strong>change the style of the button based on the pressed state</strong> of it. As usual with SwiftUI, the body function will be called when this state changes, so you just need to declare the style based on it. SwiftUi takes care of the rest.</p><pre><code><span class="splash-keyword">public struct</span> BackgroundButtonStyle: <span class="splash-type">ButtonStyle</span> {
    <span class="splash-keyword">public func</span> body(configuration: <span class="splash-type">Button</span>&lt;<span class="splash-type">Self</span>.<span class="splash-type">Label</span>&gt;, isPressed: <span class="splash-type">Bool</span>) -&gt; <span class="splash-keyword">some</span> <span class="splash-type">View</span> {
        configuration
            .<span class="splash-call">accentColor</span>(isPressed ? .<span class="splash-dotAccess">yellow</span> : .<span class="splash-dotAccess">red</span>)
            .<span class="splash-call">padding</span>()
            .<span class="splash-call">background</span>(isPressed ? <span class="splash-type">Color</span>.<span class="splash-property">red</span> : .<span class="splash-dotAccess">yellow</span>)
            .<span class="splash-call">cornerRadius</span>(<span class="splash-number">4</span>)
    }
}
</code></pre><p>In this example we change the background and accent colors of the button depending on the pressed state.</p><img src="https://alejandromp.com/blog/swiftui-reusable-button-style/button2.gif"/><p>The question now is, how do we apply this style to the button?</p><h2 id="staticmember">StaticMember</h2><p>I'm not gonna lie, took me a while to figure out how this is supposed to work.</p><p>The first thing that you may try is to just pass the style to the modifier:</p><pre><code>.<span class="splash-call">buttonStyle</span>(<span class="splash-type">BackgroundButtonStyle</span>())
</code></pre><p>But this doesn't work. The signature of that modifier expects a <code>StaticMember</code>:</p><pre><code>.<span class="splash-call">buttonStyle</span>(<span class="splash-type">StaticMember</span>&lt;<span class="splash-type">ButtonStyle</span>&gt;)
</code></pre><p>But what is a static member?</p><p>The documentation describes it like this:</p><blockquote><p>A concrete wrapper for enabling implicit member expressions.</p></blockquote><img src="https://alejandromp.com/blog/swiftui-reusable-button-style/say_what.gif"/><p>Let me try to explain this. <em>implicit member expressions</em> are most commonly known by "dot syntax" on static members. This is when you can use <code>.red</code> in a method that accepts a <code>UIColor</code>. Because the compiler knows that the method expects a <code>UIColor</code>, and that this class has a static property called <code>red</code> that returns a <code>UIColor</code> itself, then it let us use this dot syntax without having to write UIColor at all.</p><p>The limitation with this is quite big. The compiler only looks for properties on the type of the parameter, and of course, it only accepts properties that return the same type.</p><p>This is quite an issue in some API designs. For example if you want your methods to accept protocols your users won't be able to use the implicit member expressions because the compiler won't look for static properties on the concrete types that implement the protocol.</p><p>In SwiftUI this is a big deal.</p><p>Think about the <code>buttonStyle</code> modifier for example. This modifier wants to accept a <code>ButtonStyle</code>, this makes it really flexible but also not that nice to use as you wouldn't be able to do <code>.buttonStyle(.default)</code>.</p><p>To workaround this the framework provides a <code>StaticMember</code>, a simple generic type that helps to avoid this problem. You can see a <a href="https://developer.apple.com/documentation/swiftui/staticmember">detailed example on Apple's documentation</a>.</p><p>SwiftUI declares the modifier to accept a <code>StaticMember</code> that wraps a <code>ButtonStyle</code>. It's just a workaround for the type system and the compiler. Hopefully in the future this won't be needed.</p><p>What it means for us is that in order to be able to use this custom style we need to accept this dance with the compiler 💃🏻. We need to extend <code>StaticMember</code> to add a static property that returns our style.</p><pre><code><span class="splash-keyword">extension</span> <span class="splash-type">StaticMember</span> <span class="splash-keyword">where</span> <span class="splash-type">Base</span> : <span class="splash-type">ButtonStyle</span> {
    <span class="splash-keyword">public static var</span> background: <span class="splash-type">BackgroundButtonStyle</span>.<span class="splash-type">Member</span> {
        <span class="splash-type">StaticMember</span>&lt;<span class="splash-type">BackgroundButtonStyle</span>&gt;(<span class="splash-type">BackgroundButtonStyle</span>())
    }
}
</code></pre><blockquote><p>As an aside, I'm omitting the return in this single line function. Watch my video about <a href="https://www.youtube.com/watch?v=BFmEnyO_37U&ab_channel=Alexito'sWorld">Swift's new Implicit Return</a> if you want to know more.</p></blockquote><p>Now that we have all the pieces in place we're free to use our custom style!</p><pre><code><span class="splash-type">Button</span>(action: {}) {
    <span class="splash-type">Text</span>(<span class="splash-string">"Background style"</span>)
}
.<span class="splash-call">buttonStyle</span>(.<span class="splash-dotAccess">background</span>)
</code></pre><img src="https://alejandromp.com/blog/swiftui-reusable-button-style/button2.gif"/><h2 id="combining-styles">Combining styles</h2><p>The nice thing about styles being just views that wrap other views is that we benefit from their composability.</p><p>Let's make another custom style. Just for fun and to show you how easy is to do nice effects with SwiftUI, let's make the button scale when pressed.</p><pre><code><span class="splash-keyword">public struct</span> ScaledButtonStyle: <span class="splash-type">ButtonStyle</span> {
    <span class="splash-keyword">public func</span> body(configuration: <span class="splash-type">Button</span>&lt;<span class="splash-type">Self</span>.<span class="splash-type">Label</span>&gt;, isPressed: <span class="splash-type">Bool</span>) -&gt; <span class="splash-keyword">some</span> <span class="splash-type">View</span> {
        configuration
            .<span class="splash-call">scaleEffect</span>(isPressed ? <span class="splash-number">1.4</span> : <span class="splash-number">1</span>)
            .<span class="splash-call">animation</span>(<span class="splash-type">Animation</span>.<span class="splash-call">spring</span>().<span class="splash-call">speed</span>(<span class="splash-number">2</span>))
    }
}
</code></pre><p>Now you can combine both styles as you combine any other view in SwiftUI.</p><pre><code><span class="splash-type">Button</span>(action: {}) {
    <span class="splash-type">Text</span>(<span class="splash-string">"Background style"</span>)
}
.<span class="splash-call">buttonStyle</span>(.<span class="splash-dotAccess">scaled</span>)
.<span class="splash-call">buttonStyle</span>(.<span class="splash-dotAccess">background</span>)
</code></pre><img src="https://alejandromp.com/blog/swiftui-reusable-button-style/buttonzoom.gif"/><p>Take a moment to appreciate how nice an powerful this is.</p><p>##Conclusion</p><p>Making custom styles in SwiftUI is as easy as making normal views. SwiftUI uses the same pattern of structs implementing a protocol that returns a body <code>View</code> for many of its APIs.</p><p>In this case it's a little more complicated because we need to use this <code>StaticMember</code> workaround. But once you know it is quite easy to repeat. And the final syntax is as nice as it can be 😊 .</p><blockquote><p>A concern that I have, with beta 2 at least, is that Xcode is not able to suggest this static members yet. So even if <code>.buttonStyle(.background)</code> compiles, it's quite obscure to figure out what styles you have available. Hopefully is fixed in upcoming betas.</p></blockquote>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/implementing-a-equally-spaced-stack-in-swiftui-thanks-to-tupleview</guid><title>SwiftUI TupleView and equally spaced stacks</title><description></description><link>https://alejandromp.com/blog/implementing-a-equally-spaced-stack-in-swiftui-thanks-to-tupleview</link><pubDate>Thu, 13 Jun 2019 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>Yesterday I <a href="https://alejandromp.com/blog/custom-layouts-in-swiftui/">shared with you</a> a post where I was trying to understand SwiftUI's layout system in order to implement equally spaced distribution for views inside stacks.</p><p>I was able to do it by requiring a <code>ForEach</code> but I was not happy as that's not how <code>HStack</code> works. SwiftUI stacks allow you to nest views individually or use a <code>ForEach</code>. I wanted to support both systems also.</p><p>Then, while editing the <a href="https://youtu.be/EH8QQyCP8Oc">video about Opaque Result Types</a>, I realised how <code>HStack</code> keeps the information of its views in the type thanks to <code>TupleView</code>.</p><p><code>TupleView</code> is a generic view with a tuple as its type. This allows it to keep the information of every single subview. Then I remembered some discussions on the forums about Swift not having, yet, variadic generics, and a possible solution came to my mind.</p><p>The trick is to make different <code>init</code> with <code>@ViewBuilder</code> that are overloaded on the return type of the closure.</p><pre><code><span class="splash-keyword">init</span>&lt;A: <span class="splash-type">View</span>, B: <span class="splash-type">View</span>&gt;(<span class="splash-keyword">@ViewBuilder</span> content: () -&gt; <span class="splash-type">TupleView</span>&lt;(<span class="splash-type">A</span>, <span class="splash-type">B</span>)&gt;)
<span class="splash-keyword">init</span>&lt;A: <span class="splash-type">View</span>, B: <span class="splash-type">View</span>, C: <span class="splash-type">View</span>&gt;(<span class="splash-keyword">@ViewBuilder</span> content: () -&gt; <span class="splash-type">TupleView</span>&lt;(<span class="splash-type">A</span>, <span class="splash-type">B</span>, <span class="splash-type">C</span>)&gt;)
<span class="splash-keyword">init</span>&lt;A: <span class="splash-type">View</span>, B: <span class="splash-type">View</span>, C: <span class="splash-type">View</span>, D: <span class="splash-type">View</span>&gt;(<span class="splash-keyword">@ViewBuilder</span> content: () -&gt; <span class="splash-type">TupleView</span>&lt;(<span class="splash-type">A</span>, <span class="splash-type">B</span>, <span class="splash-type">C</span>, <span class="splash-type">D</span>)&gt;)
...
</code></pre><p>You can see the pattern.</p><p>This allows me to get access to the specific subviews of the stack, store them in an array and then add a <code>Spacer</code> between them in the body, in the same way that was done in the previous post.</p><p>But this journey doesn't end here. There are still a couple of things that I don't like.</p><p>To support a single subview overloading the init with a tuple of 1 element doesn't work, the <code>TupleView</code> needs to disappear:</p><pre><code><span class="splash-comment">// This doesnt' allow for a single subview:</span>
<span class="splash-keyword">init</span>&lt;A: <span class="splash-type">View</span>&gt;(<span class="splash-keyword">@ViewBuilder</span> content: () -&gt; <span class="splash-type">TupleView</span>&lt;(<span class="splash-type">A</span>)&gt;)
<span class="splash-comment">// It needs this overload instead:</span>
<span class="splash-keyword">init</span>&lt;A: <span class="splash-type">View</span>&gt;(<span class="splash-keyword">@ViewBuilder</span> content: () -&gt; <span class="splash-type">A</span>)
</code></pre><p>The problem with having that overload is that it's called when there are a number of subviews that we don't have another init for, so in that init we receive a TupleView and we treat it as a single view without adding spacing. Too fragile.</p><p>The other problem is that in order to gather the views they need to be wrapped in <code>AnyView</code>, a type erased container. (Watch <a href="https://youtu.be/EH8QQyCP8Oc">Opaque Result Types</a> to know more about this view)</p><p>So this is still not the ideal solution implementation wise, but at the API surface is what I wanted:</p><pre><code><span class="splash-type">Text</span>(<span class="splash-string">"With reusable view manual"</span>)

<span class="splash-type">EquallySpacedHStack</span> {
    <span class="splash-type">Color</span>.<span class="splash-property">red</span>.<span class="splash-call">frame</span>(width: <span class="splash-number">50</span>, height: <span class="splash-number">50</span>)
    <span class="splash-type">Color</span>.<span class="splash-property">blue</span>.<span class="splash-call">frame</span>(width: <span class="splash-number">50</span>, height: <span class="splash-number">50</span>)
    <span class="splash-type">Color</span>.<span class="splash-property">green</span>.<span class="splash-call">frame</span>(width: <span class="splash-number">50</span>, height: <span class="splash-number">50</span>)
}

<span class="splash-type">Text</span>(<span class="splash-string">"With reusable view for each"</span>)

<span class="splash-type">EquallySpacedHStack</span> {
    <span class="splash-type">ForEach</span>(<span class="splash-number">1</span>...<span class="splash-number">4</span>) { <span class="splash-keyword">_ in</span>
        <span class="splash-type">Color</span>.<span class="splash-property">red</span>.<span class="splash-call">frame</span>(width: <span class="splash-number">50</span>, height: <span class="splash-number">50</span>)
    }
}
</code></pre><img src="https://alejandromp.com/blog/implementing-a-equally-spaced-stack-in-swiftui-thanks-to-tupleview/distributed_stack.png"/><p>Check the <a href="https://github.com/alexito4/EquallySpacedStack">GitHub repo</a>.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/custom-layouts-in-swiftui</guid><title>Trying to understand custom layouts in SwiftUI</title><description></description><link>https://alejandromp.com/blog/custom-layouts-in-swiftui</link><pubDate>Wed, 12 Jun 2019 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>One of the things that I still don't fully understand about SwiftUI is how to customise the layout of views.</p><p><code>HStack</code> and <code>VStack</code> are fine for the majority of cases, but there is one case that bothers me that is not as easy as it should.</p><p>This is how a <code>HStack</code> with 3 views looks like:</p><pre><code><span class="splash-type">HStack</span>() {
    <span class="splash-type">ForEach</span>(<span class="splash-number">1</span>...<span class="splash-number">3</span>) { <span class="splash-keyword">_ in</span>
        <span class="splash-type">Color</span>.<span class="splash-property">red</span>.<span class="splash-call">frame</span>(width: <span class="splash-number">50.0</span>, height: <span class="splash-number">50</span>)
    }
}
</code></pre><img src="https://alejandromp.com/blog/custom-layouts-in-swiftui/stock_distribution.png"/><p>The 3 views are centred and with a default spacing. You can change the alignment if you need to, but you don't have any options for what <code>UIStackView</code> called "distribution".</p><p>What if you want it not to be centred but with equal spacings?</p><img src="https://alejandromp.com/blog/custom-layouts-in-swiftui/spaces_distribution.png"/><p>This is totally doable by using the <code>Spacer</code> view. The problem is that is a little cumbersome.</p><pre><code><span class="splash-type">HStack</span> {
    <span class="splash-type">Spacer</span>()
    <span class="splash-type">ForEach</span>(<span class="splash-number">1</span>...<span class="splash-number">3</span>) { <span class="splash-keyword">_ in</span>
        <span class="splash-type">Color</span>.<span class="splash-property">red</span>.<span class="splash-call">frame</span>(width: <span class="splash-number">50</span>, height: <span class="splash-number">50</span>)
        <span class="splash-type">Spacer</span>()
    }
}
</code></pre><p>Of course you can extract that into a function that given some data it calls a given closure.</p><pre><code><span class="splash-keyword">func</span> EquallySpacedHStack&lt;Data, Content&gt;(<span class="splash-keyword">_</span> data: <span class="splash-type">Data</span>, content: <span class="splash-keyword">@escaping</span> (<span class="splash-type">Data</span>.<span class="splash-type">Element</span>.<span class="splash-type">IdentifiedValue</span>) -&gt; <span class="splash-type">Content</span>) -&gt; <span class="splash-keyword">some</span> <span class="splash-type">View</span> <span class="splash-keyword">where</span> <span class="splash-type">Data</span> : <span class="splash-type">RandomAccessCollection</span>, <span class="splash-type">Content</span> : <span class="splash-type">View</span>, <span class="splash-type">Data</span>.<span class="splash-type">Element</span> : <span class="splash-type">Identifiable</span>  {
    
    <span class="splash-type">HStack</span> {
        <span class="splash-type">Spacer</span>()
        <span class="splash-type">ForEach</span>(data) { item <span class="splash-keyword">in</span>
            <span class="splash-call">content</span>(item)
            <span class="splash-type">Spacer</span>()
        }
    }
}
</code></pre><p>Now you can create it like if it was a <code>ForEach</code>:</p><pre><code><span class="splash-type">EquallySpacedHStack</span>(<span class="splash-number">1</span>...<span class="splash-number">3</span>) { <span class="splash-keyword">_ in</span>
    <span class="splash-type">Color</span>.<span class="splash-property">red</span>.<span class="splash-call">frame</span>(width: <span class="splash-number">50</span>, height: <span class="splash-number">50</span>)
}
</code></pre><p>And that's something I don't like. I don't want to have to pass the data in and be limited to a for each like structure. I want it to be able to use it as any other stack.</p><p>I've tried to replicate it with a custom view that uses the <code>@ViewBuilder</code> in the initialiser, and is better:</p><pre><code><span class="splash-keyword">struct</span> EquallySpacedHStack2&lt;Items: <span class="splash-type">View</span>&gt;: <span class="splash-type">View</span> {
    <span class="splash-keyword">let</span> items: [<span class="splash-type">AnyView</span>]
    
    <span class="splash-keyword">init</span>&lt;Data, Content: <span class="splash-type">View</span>&gt;(<span class="splash-keyword">@ViewBuilder</span> content: () -&gt; <span class="splash-type">Items</span>) <span class="splash-keyword">where</span> <span class="splash-type">Items</span> == <span class="splash-type">ForEach</span>&lt;<span class="splash-type">Data</span>, <span class="splash-type">Content</span>&gt; {
        <span class="splash-keyword">let</span> views = <span class="splash-call">content</span>()
        <span class="splash-keyword">self</span>.<span class="splash-property">items</span> = views.<span class="splash-property">data</span>.<span class="splash-call">map</span>({ <span class="splash-type">AnyView</span>(views.<span class="splash-call">content</span>($0.<span class="splash-property">identifiedValue</span>)) })
    }
    
    <span class="splash-keyword">var</span> body: <span class="splash-keyword">some</span> <span class="splash-type">View</span> {
        <span class="splash-type">HStack</span> {
            <span class="splash-type">Spacer</span>()
            <span class="splash-type">ForEach</span>(<span class="splash-number">0</span>..&lt;items.<span class="splash-property">count</span>) { index <span class="splash-keyword">in
                self</span>.<span class="splash-property">items</span>[index]
                <span class="splash-type">Spacer</span>()
            }
        }
    }
}
</code></pre><p>but I'm also forced to use a <code>ForEach</code>:</p><pre><code><span class="splash-type">EquallySpacedHStack2</span> {
    <span class="splash-type">ForEach</span>(<span class="splash-number">1</span>...<span class="splash-number">3</span>) {
        <span class="splash-type">Color</span>.<span class="splash-property">red</span>.<span class="splash-call">frame</span>(width: <span class="splash-number">50</span>, height: <span class="splash-number">50</span>)
    }
}
</code></pre><p>so it's not that much better.</p><p>The missing piece here is to be able to get each individual subview and layout it individually. So I'm free to use a <code>ForEach</code> or specifying one by one the views that I want.</p><pre><code><span class="splash-type">EquallySpacedHStack</span> {
    <span class="splash-type">Color</span>.<span class="splash-property">red</span>.<span class="splash-call">frame</span>(width: <span class="splash-number">50</span>, height: <span class="splash-number">50</span>)
    <span class="splash-type">Color</span>.<span class="splash-property">blue</span>.<span class="splash-call">frame</span>(width: <span class="splash-number">50</span>, height: <span class="splash-number">50</span>)
    <span class="splash-type">Color</span>.<span class="splash-property">green</span>.<span class="splash-call">frame</span>(width: <span class="splash-number">50</span>, height: <span class="splash-number">50</span>)
}
</code></pre><p>But I still haven't figured it out yet ^^</p><p>I'm sure there is some lower level part of the layout system that could be used, but the documentation right now is quite poor and I haven't found anything yet.</p><p>I will keep looking :)</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/playing-with-swiftui-buttons</guid><title>Playing with SwiftUI Buttons</title><description></description><link>https://alejandromp.com/blog/playing-with-swiftui-buttons</link><pubDate>Tue, 11 Jun 2019 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>The abstractions on SwiftUI are so composable that customising the UI it's basically an intrinsic property of the framework. Let's take a quick look at some things you can do with <code>Button</code>.</p><p>As per documentation a <code>Button</code> is <em>"A control that performs an action when triggered.</em>. That's it. A button handles a click interaction for you, including highlighting and focusing. And it adapts the triggering mechanism to the platform.</p><p>But the way it looks is just based on what are the contents of the button, and as with other SwiftUI views, it's up to you to put things on it. In fact, you can't create a button without giving other views.</p><pre><code><span class="splash-type">Button</span>(action: ...) <span class="splash-comment">// nope</span>
</code></pre><p>The most simple button is already a composition, you will need a <code>Text</code>.</p><pre><code><span class="splash-type">Button</span>(action: doSomething) {
    <span class="splash-type">Text</span>(<span class="splash-string">"Simple button"</span>)
}
</code></pre><img src="https://alejandromp.com/blog/playing-with-swiftui-buttons/simple_button.png" alt="SwiftUI simple button"/><p>Keep in mind that the button will adapt to its context, this is a really powerful feature of SwiftUI: Adaptive Views. For example when a button is inside a <code>List</code> it will change is look to behave like a cell.</p><img src="https://alejandromp.com/blog/playing-with-swiftui-buttons/cell_button.png" alt="SwiftUI cell"/><p>But for this post let's look at buttons that are treated as buttons.</p><p>You probably want to make a button look like a button, not a floating blue text (sorry Jony). For that you can add a background color.</p><pre><code><span class="splash-type">Button</span>(action: doSomething) {
    <span class="splash-type">Text</span>(<span class="splash-string">"Basic button"</span>)
}
.<span class="splash-call">background</span>(<span class="splash-type">Color</span>.<span class="splash-property">yellow</span>)
</code></pre><img src="https://alejandromp.com/blog/playing-with-swiftui-buttons/basic_button.png" alt="SwiftUI basic button"/><p>This gives us a nice background color, but careful because there is something wrong here. Let's explore what it is.</p><p>Keep in mind that <code>Text</code> in SwiftUI doesn't have any intrinsic padding, something crucial to make the layout system work as intended. Let's add some padding to the button ourselves then.</p><pre><code><span class="splash-type">Button</span>(action: doSomething) {
    <span class="splash-type">Text</span>(<span class="splash-string">"Default padding"</span>)
}
.<span class="splash-call">padding</span>()
.<span class="splash-call">background</span>(<span class="splash-type">Color</span>.<span class="splash-property">yellow</span>)
</code></pre><img src="https://alejandromp.com/blog/playing-with-swiftui-buttons/default_padding.png" alt="SwiftUI button with padding"/><p>Now we have the default padding, depending on the platform, to our beautiful button. And now is pretty obvious what's wrong with it:</p><img src="https://alejandromp.com/blog/playing-with-swiftui-buttons/tap_area_fail.gif"/><p>The tap area is wrong!</p><p>The problem with our code is that we're adding the padding and background to the button view, but in reality what that is doing is creating a background view, with padding inside, and the button inside it. The button hasn't changed, we just have extra views around it.</p><p>This is fundamental to understanding SwiftUI. The modifiers don't change the views, they create new views.</p><p>To have the expected behaviour we need to apply our transformations to the content of the button, not the button itself. In this case, to the <code>Text</code>.</p><pre><code><span class="splash-type">Button</span>(action: doSomething) {
    <span class="splash-type">Text</span>(<span class="splash-string">"Default padding"</span>)
        .<span class="splash-call">padding</span>()
        .<span class="splash-call">background</span>(<span class="splash-type">Color</span>.<span class="splash-property">yellow</span>)
}
</code></pre><img src="https://alejandromp.com/blog/playing-with-swiftui-buttons/tap_area_ok.gif" alt="SwiftUI button correct tap area"/><p>Now you can see how no matter where I tap on the background, it reacts as a button. And now you can even see how the background itself changes color when taped.</p><p>Take a moment to interiorise this as it's quite important and different from what we're use to in UIKit.</p><p>Now let's try to add an icon to our button, something pretty common in Apps. Usually, with a UIKit mentality, you would think on setting some <em>image</em> property on the button. But again, SwiftUI is all about composition, so to add an image you… just add it ¯_(ツ)_/¯</p><pre><code><span class="splash-type">Button</span>(action: doSomething) {
    <span class="splash-type">HStack</span> {
        <span class="splash-type">Image</span>(systemName: <span class="splash-string">"rectangle.grid.1x2.fill"</span>)
        <span class="splash-type">Text</span>(<span class="splash-string">"Button with image"</span>)
    }
    .<span class="splash-call">padding</span>()
    .<span class="splash-call">background</span>(<span class="splash-type">Color</span>.<span class="splash-property">yellow</span>)
}
</code></pre><p>Because we want to apply the padding and background to the entire content we wrap the <code>Text</code> and <code>Image</code> in another view, let's pick <code>HStack</code> to stack them horizontally. This is how it looks:</p><img src="https://alejandromp.com/blog/playing-with-swiftui-buttons/button_with_image.png"/><p>Nice and easy.</p><p>This is something we're pretty used to do in UIKit, but SwiftUI is much more powerful than this. What if we want an image on each side? Just add another one!</p><pre><code><span class="splash-type">Button</span>(action: doSomething) {
    <span class="splash-type">HStack</span> {
        <span class="splash-type">Image</span>(systemName: <span class="splash-string">"rectangle.grid.1x2.fill"</span>)
        <span class="splash-type">Text</span>(<span class="splash-string">"Button with image"</span>)
        <span class="splash-type">Image</span>(systemName: <span class="splash-string">"rectangle.grid.1x2.fill"</span>)
    }
    .<span class="splash-call">padding</span>()
    .<span class="splash-call">background</span>(<span class="splash-type">Color</span>.<span class="splash-property">yellow</span>)
}
</code></pre><img src="https://alejandromp.com/blog/playing-with-swiftui-buttons/button_with_2_images.png"/><p>This is already so powerful. But if you've been doing app development long enough you will have faced the horror that it's to make a button with an image on top of the text. There are many way of doing it in UIKit (from playing with insets to making a custom control) but all of them require too much effort. But with SwiftUI is a single line change, replace the <code>HStack</code> for a <code>VStack</code>:</p><pre><code><span class="splash-type">Button</span>(action: doSomething) {
    <span class="splash-type">VStack</span> {
        <span class="splash-type">Image</span>(systemName: <span class="splash-string">"rectangle.grid.1x2.fill"</span>)
        <span class="splash-type">Text</span>(<span class="splash-string">"Vertical Button!"</span>)
    }
    .<span class="splash-call">padding</span>()
    .<span class="splash-call">background</span>(<span class="splash-type">Color</span>.<span class="splash-property">yellow</span>)
}
</code></pre><img src="https://alejandromp.com/blog/playing-with-swiftui-buttons/vertical_button.png"/><p>Very nice! The expressiveness and power of this framework is so great! But what's not so great are those pointy corners. So let's make them rounded by using another modifier: <code>cornerRadius</code>.</p><pre><code><span class="splash-type">Button</span>(action: doSomething) {
    <span class="splash-type">VStack</span> {
        <span class="splash-type">Image</span>(systemName: <span class="splash-string">"rectangle.grid.1x2.fill"</span>)
        <span class="splash-type">Text</span>(<span class="splash-string">"Vertical Button!"</span>)
    }
    .<span class="splash-call">padding</span>()
    .<span class="splash-call">background</span>(<span class="splash-type">Color</span>.<span class="splash-property">yellow</span>)
    .<span class="splash-call">cornerRadius</span>(<span class="splash-number">5</span>)
}
</code></pre><img src="https://alejandromp.com/blog/playing-with-swiftui-buttons/corner_radius.png"/><p>All of this shows you how nice and easy is to work with SwiftUI and customise its controls. But writing all those modifiers every time we want a button is tedious an error prone.</p><blockquote><p>SwiftUI is supposed to have a ButtonStyle type and .buttonStyle() modifier, but they don't seem available on the first beta. But we can build our own.</p></blockquote><p>To simplify our lives lets build our own custom modifier.</p><p>To start, we need a type that conforms to <code>ViewModifier</code>. This protocol is very similar to <code>View</code>, but instead of returning a view from the computed property, we do it from a function where the framework passes in the existing view we want to modify.</p><pre><code><span class="splash-keyword">struct</span> MyButtonStyle: <span class="splash-type">ViewModifier</span> {
    <span class="splash-keyword">func</span> body(content: <span class="splash-type">Content</span>) -&gt; <span class="splash-keyword">some</span> <span class="splash-type">View</span> {
        content
            .<span class="splash-call">padding</span>()
            .<span class="splash-call">background</span>(<span class="splash-type">Color</span>.<span class="splash-property">yellow</span>)
            .<span class="splash-call">cornerRadius</span>(<span class="splash-number">5</span>)
    }
}
</code></pre><p>We just use the same modifiers and return the new view.</p><p>To use this in conjunction with the rest of the view code, we need to make it nice to use. For that we can just extend the <code>View</code> type and add our own modifier function.</p><pre><code><span class="splash-keyword">extension</span> <span class="splash-type">View</span> {
    <span class="splash-keyword">func</span> myButtonStyle() -&gt; <span class="splash-keyword">some</span> <span class="splash-type">View</span> {
        <span class="splash-type">Modified</span>(content: <span class="splash-keyword">self</span>, modifier: <span class="splash-type">MyButtonStyle</span>())
    }
}
</code></pre><p>In it we just create and return a <code>Modified</code> type, which represents a new view by modifying the existing one with our ViewModifier.</p><p>With these two simple peaces in place we can now reduce the boilerplate of our code.</p><pre><code><span class="splash-type">Button</span>(action: doSomething) {
    <span class="splash-type">VStack</span> {
        <span class="splash-type">Image</span>(systemName: <span class="splash-string">"rectangle.grid.1x2.fill"</span>)
        <span class="splash-type">Text</span>(<span class="splash-string">"Vertical Button!"</span>)
    }
    .<span class="splash-call">myButtonStyle</span>()
}
</code></pre><p>The best thing is that by using this custom modifier we're not limiting us to this specific customisation. We can keep adding modifications on top of it.</p><p>For example, let's make a circular button!</p><pre><code><span class="splash-type">Button</span>(action: doSomething) {
    <span class="splash-type">VStack</span> {
        <span class="splash-type">Image</span>(systemName: <span class="splash-string">"rectangle.grid.1x2.fill"</span>)
        <span class="splash-type">Text</span>(<span class="splash-string">"Circle!"</span>)
    }
    .<span class="splash-call">myButtonStyle</span>()
    .<span class="splash-call">mask</span>(<span class="splash-type">Circle</span>())
}
</code></pre><img src="https://alejandromp.com/blog/playing-with-swiftui-buttons/circle_button.png"/><p>Or any other shape that we want!</p><img src="https://alejandromp.com/blog/playing-with-swiftui-buttons/hexagon_button.png"/><blockquote><p>I suspect there are better ways of doing shaped buttons respecting the size of the text. But this works for illustration purposes.</p></blockquote><p>These simple examples show the flexibility and power of SwiftUI. But are also useful to interiorise the differences with UIKit or another traditional UI framework.</p><p><a href="https://alejandromp.com/tags/swiftui">More SwiftUI posts.</a></p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/first-days-with-swiftui</guid><title>First days with SwiftUI</title><description></description><link>https://alejandromp.com/blog/first-days-with-swiftui</link><pubDate>Mon, 10 Jun 2019 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p><a href="https://alejandromp.com/blog/swiftui-and-the-best-wwdc-ever/">WWDC'19 has been great</a> and I'm obviously hyper <a href="https://youtu.be/p8q5ANt-22o">excited about SwiftUI</a> but if there is one thing that I like more than watching a great announcement is watching great video content, and the WWDC sessions are the best!</p><p>As <a href="https://alejandromp.com/tags/wwdc">every year</a> I'm using my <a href="https://alejandromp.com/blog/how-to-watch-wwdc/">technique to watch the videos</a>. But I haven't been able to resist and play with SwiftUI!</p><p>At the moment of writing this I'm still in Mojave so I'm using SwiftUI by running it in the iOS simulator and in Playgrounds.</p><blockquote><p>Tip: Use <code>UIHostingController</code> to display a SwiftUI view in the playground live view. <img src="https://alejandromp.com/blog/first-days-with-swiftui/swiftui_playgrounds.png" alt="SwiftUI Playground"/></p></blockquote><p>After doing some simple exercises with SwiftUI it's quite obvious that is a first beta. Some stuff doesn't fully work yet and I personally find some crucial controls missing (where is my activity indicator!?).</p><p>The example I've been working on looks like this:</p><img src="https://alejandromp.com/blog/first-days-with-swiftui/swift_ui_example.png" alt="SwiftUI example"/><h2 id="mixed-lists">Mixed lists</h2><p>The <code>List</code> in SwiftUI is super powerful. You can pass a <code>RandomAccessCollection</code> to get a view for each model. This is like a simple TableView where each cell represents the same model.</p><pre><code><span class="splash-type">List</span>(data.<span class="splash-property">users</span>) { user <span class="splash-keyword">in</span>
    <span class="splash-type">Text</span>(user.<span class="splash-property">name</span>)
}
</code></pre><p>This is a great way to get a nice UI, but <code>List</code> can do so much more! Instead of passing the data in the <code>init</code> you can just provide each element of the list manually instead. That allows you to make a list with mixed views and content.</p><pre><code><span class="splash-type">List</span> {
    <span class="splash-type">Image</span>(<span class="splash-string">"swiftui"</span>)
        .<span class="splash-call">background</span>(<span class="splash-type">Color</span>.<span class="splash-property">black</span>)
    <span class="splash-type">Text</span>(<span class="splash-string">"First user"</span>)
    <span class="splash-keyword">if</span> !data.<span class="splash-property">users</span>.<span class="splash-property">isEmpty</span> {
        <span class="splash-type">Text</span>(data.<span class="splash-property">users</span>[<span class="splash-number">0</span>].name)
    }
}
</code></pre><p>Wow! This example is already packing up a lot of stuff. First of all, we just implemented a list with mixed content: an image and one or two texts.</p><p>I keep saying <code>List</code> and that's important, this is not just a vertical stack of views, this is a fully powered list, with scroll, reusing of the cells and the usual performance niceties that we're used to from <code>UITableView</code>.</p><p>But that snippet also shows the power of this <a href="https://youtu.be/YG5u0aFgGQI">Swift DSL</a>: we're using an <code>if</code> a Swift language construct to create our UI. SwiftUI will take care of rendering the name of the first user when there are users available, and not show it when they're not.</p><p>But what if we want to show all the users? It would be a pain to write them all in there. Ideally we would just use a <code>for in</code> in the same way we're using the <code>if</code>, but as of right now, the Swift feature that allows us to have this nice DSLs doesn't support <code>for</code> loops. But wait! SwiftUI fixes this by providing its own <code>ForEach</code> "view".</p><p><code>ForEach</code> accepts a collection and calls the given closure for each element allow you to create multiple views. It's similar to <code>List</code> but it's not intended to be used on its own, as it won't create a performant scroll for you.</p><pre><code><span class="splash-type">List</span> {
    <span class="splash-type">Image</span>(<span class="splash-string">"swiftui"</span>)
        .<span class="splash-call">background</span>(<span class="splash-type">Color</span>.<span class="splash-property">black</span>)
    <span class="splash-type">ForEach</span>(data.<span class="splash-property">users</span>) { user <span class="splash-keyword">in</span>
        <span class="splash-type">Text</span>(user.<span class="splash-property">name</span>)
    }
}
</code></pre><p>There you go!</p><h2 id="views-are-cheap">Views are cheap</h2><p>If you take a look at the example image you will see a list of users and a couple of horizontal carousels.</p><blockquote><p>I was trying to create horizontal lists to replicate an App Store like interface, but for now I haven't figure out how to build them yet. I think I'm missing a <code>UICollectionView</code></p></blockquote><p>Those 3 things are displaying users and so it makes sense to have a view for them (maybe not, but is an example so indulge me). Doing this is as easy as pulling out the code into its own view and passing the data to the init.</p><p>Views are <code>struct</code> so they are really cheap. Their cost in memory is only the cost of the data they have, and SwiftUI will create the best view hierarchy so we don't have to worry about it.</p><blockquote><p>If you don't trust me try making some stack of text and check the UI debugger. Stacks are not UIStackView and Text don't need UILabels.</p></blockquote><p>Let's make our <code>UsersView</code></p><pre><code><span class="splash-keyword">struct</span> UsersView: <span class="splash-type">View</span> {
    <span class="splash-keyword">@Binding var</span> users: [<span class="splash-type">User</span>]

    <span class="splash-keyword">init</span>(users: <span class="splash-type">Binding</span>&lt;[<span class="splash-type">User</span>]&gt;) {
        <span class="splash-property">$users</span> = users
    }

    <span class="splash-keyword">var</span> body: <span class="splash-keyword">some</span> <span class="splash-type">View</span> {
        <span class="splash-type">Group</span> {
            <span class="splash-type">HStack</span>() {
                <span class="splash-type">Spacer</span>()
                <span class="splash-type">ForEach</span>(users.<span class="splash-call">prefix</span>(<span class="splash-number">4</span>)) { user <span class="splash-keyword">in</span>
                    <span class="splash-type">RemoteImage</span>(url: user.<span class="splash-property">avatar</span>, placeholder: <span class="splash-type">Image</span>(systemName: <span class="splash-string">"person.circle.fill"</span>))
                        .<span class="splash-call">circle</span>()
                    <span class="splash-type">Spacer</span>()
                }
                }
                .<span class="splash-call">padding</span>(.<span class="splash-dotAccess">vertical</span>, <span class="splash-number">10</span>)

            <span class="splash-type">HStack</span>() {
                <span class="splash-type">ForEach</span>(users.<span class="splash-call">prefix</span>(<span class="splash-number">4</span>)) { user <span class="splash-keyword">in</span>
                    <span class="splash-type">RemoteImage</span>(url: user.<span class="splash-property">avatar</span>)
                        .<span class="splash-call">circle</span>()
                }
                }
                .<span class="splash-call">padding</span>(.<span class="splash-dotAccess">vertical</span>, <span class="splash-number">10</span>)

            <span class="splash-type">ForEach</span>(users) { user <span class="splash-keyword">in</span>
                <span class="splash-type">HStack</span>() {
                    <span class="splash-type">RemoteImage</span>(url: user.<span class="splash-property">avatar</span>)
                    <span class="splash-type">VStack</span>(alignment: .<span class="splash-dotAccess">leading</span>) {
                        <span class="splash-type">Text</span>(user.<span class="splash-property">name</span>).<span class="splash-call">font</span>(.<span class="splash-dotAccess">title</span>)
                        <span class="splash-type">Text</span>(user.<span class="splash-property">email</span>)
                    }

                }
            }
        }
    }
}
</code></pre><p>We return a <code>Group</code> because we can only return a single <code>View</code> from the body. A group doesn't represent anything specific, it just allows us to group a bunch of views into one.</p><p>Then you can see <code>HStack</code> and <code>VStack</code>. If you've done some design with <a href="https://flexboxfroggy.com">flexbox</a> it will be familiar. For iOS devs this is like a <code>UIStackView</code>. It just stacks views horizontally or vertically. It's really flexible and super quick to compose views and make the layout you want.</p><blockquote><p>One thing I'm missing is a "distribution" option or modifier. That's why I tried 2 ways of replicating it, it works but it's not really reusable. I hope that watching the rest of SwiftUI sessions will give a better answer ^^</p></blockquote><p>The <code>Spacer</code> view is quite cool. It doesn't have any visual representation but instead it fills space in the layout.</p><p>I'm super curious to know more about how SwiftUI implementation calculate the layout and renders. It would seem like at some point the layout engine has access to this views and uses them to calculate the frames. I'm interested to know if there is a way to hook into that, so we could replicate a "distribution" property or even implement some "constraints" between views.</p><p>The last view that you see is a <code>RemoteImage</code>. This is a <a href="https://gist.github.com/alexito4/59436b9ab0489b00fb137a8382f38ea5">custom view</a> that uses <code>AlamofireImage</code> to download and cache images. It took me a little bit of effort to make it work. My mistake was not using @State properly and relying on a BindableObject that didn't work as expected. There is still things to learn here! ^^</p><p>Finally the data. We don't just pass the array of users to the view, we pass a binding to that array. This allows the framework to create the dependency graph, important to know what to refresh and do it in a performant way.</p><p>This is the final incarnation of the main view:</p><pre><code><span class="splash-keyword">struct</span> ContentView : <span class="splash-type">View</span> {
    <span class="splash-keyword">@ObjectBinding var</span> data: <span class="splash-type">DataFetcher</span>
    <span class="splash-keyword">@State var</span> value = <span class="splash-keyword">true

    var</span> body: <span class="splash-keyword">some</span> <span class="splash-type">View</span> {
        <span class="splash-type">List</span> {
            <span class="splash-type">Image</span>(<span class="splash-string">"swiftui"</span>)
                .<span class="splash-call">background</span>(<span class="splash-type">Color</span>.<span class="splash-property">black</span>)

            <span class="splash-type">Button</span>(action: { <span class="splash-keyword">self</span>.<span class="splash-property">value</span>.<span class="splash-call">toggle</span>() }) {
                <span class="splash-type">Text</span>(<span class="splash-string">"The button is</span> \(<span class="splash-type">String</span>(describing: <span class="splash-keyword">self</span>.<span class="splash-property">value</span>))<span class="splash-string">"</span>)
            }
            .<span class="splash-call">padding</span>([.<span class="splash-dotAccess">horizontal</span>], <span class="splash-number">5</span>)
            .<span class="splash-call">background</span>(<span class="splash-keyword">self</span>.<span class="splash-property">value</span> ? <span class="splash-type">Color</span>.<span class="splash-property">green</span> : .<span class="splash-dotAccess">red</span>)

            <span class="splash-keyword">if</span> data.<span class="splash-property">users</span>.<span class="splash-property">isEmpty</span> {
                <span class="splash-type">Text</span>(<span class="splash-string">"Loading..."</span>)
                    .<span class="splash-call">frame</span>(height: <span class="splash-number">300</span>)
            } <span class="splash-keyword">else</span> {
                <span class="splash-type">UsersView</span>(users: <span class="splash-property">$data</span>.<span class="splash-property">users</span>)
            }
        }

    }
}
</code></pre><h2 id="it's-not-uikit-under-the-hood">It's not UIKit under the hood</h2><p>Well, it is in some parts. But this is an IMPLEMENTATION DETAIL!</p><p>Really, this is super important to keep in mind, specially in these first days. SwiftUI is not a layer on top of UIKit. SwiftUI is its own UI framework, its own layer of abstraction. What Apple decides to use to render the Views is just details, part of the framework.</p><p>If you play around with the UI debugger you will see that a lot of views don't endup on the screen, the system flattens the hierarchy as much as it can.</p><p>While others, like <code>List</code> are baked by a <code>UITableView</code> on iOS. But we don't care about that. It makes sense for Apple to reuse the existing UI infrastructure, specially something like <code>UITableView</code> with so many years of improvements and so battle tested.</p><p>But this is just an implementation detail (yes I"m gonna say it again ^^). On macOS a <code>List</code> will be another thing, and in watchOS or tvOS. Maybe in November they implemented something different, and maybe next year they release SwiftUI for the web.</p><p>This is the beauty of a framework like this, our <strong>views are just descriptions</strong> of what we want on the screen. The way those descriptions are rendered is not our concern and we can't rely on that.</p><h2 id="an-official-river">An official river</h2><p>I'm happy I can use <a href="https://alejandromp.com/blog/let-if-flow-a-talk-about-functional-reactive-programming/">the river metaphor</a> for an official framework! Combine looks really cool and pretty familiar if you have any FRP experience. There are many details to learn, and some stuff is not in the betas yet (I'm looking at you URLSession extensions!) but it looks really promising.</p><p>It's quite interesting that they followed the <a href="https://www.reactive-streams.org">Reactive Streams spec</a> with some changes.</p><p>It's also interesting that they provide not only "steams" (<code>Publisher</code>) but also a <code>Future</code>. I imagine that it would become important the day Swift gets <code>async</code> functionality.</p><h2 id="conclusion">Conclusion</h2><p>This has been the first post of SwiftUI that I've written. There is nothing special on it, nothing you could have not learn by doing the <em>tuto</em>, but I wanted to leave proof on my blog, to myself, of the beginnings of this new era. And after one day of playing with it I had enough in my chest that I could not resist it!</p><p>If you're still reading this, thank you! If you have any insight on the questions I've written here please <a href="https://twitter.com/alexito4">send them over</a>.</p><p><strong>The SwiftUI era has begun!</strong></p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/apple-listens-to-the-community</guid><title>Apple listens to the community</title><description></description><link>https://alejandromp.com/blog/apple-listens-to-the-community</link><pubDate>Sun, 9 Jun 2019 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>After all the <a href="https://alejandromp.com/blog/swiftui-and-the-best-wwdc-ever/">game changing announcements</a> on the WWDC one of the words that is used a lot is "finally!". We're excited and happy that Apple as <em>finally</em> given us a new UI framework, FRP, etc. But it's interesting how the way we all talk implies that Apple has been ignoring us for years and until they woke up in 2019.</p><p>And although part of this is to blame to their secrecy, we need to be realistic. They can't announce something until is ready and they know it's a good compromise. Because everything official they give us will have to be maintained for decades to come. This is something that is often forgotten.</p><p>But everything indicates that this is far from the truth. That Apple is always working on what's next, that they listen, and when is ready for us, they give it to us.</p><p>Check out <a href="https://twitter.com/jckarter/status/1135903779071483906">this tweet from Joe Groff</a> that give us some insight into this:</p><blockquote class="twitter-tweet" data-conversation="none" data-lang="es"><p lang="en" dir="ltr">Combine goes back before even Swift existed. I’ve been helping the SwiftUI folks for at least three years, and they were probably working on stuff before I knew about it</p>&mdash; Joe Groff (@jckarter) <a href="https://twitter.com/jckarter/status/1135903779071483906?ref_src=twsrc%5Etfw">4 de junio de 2019</a></blockquote><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script><p>Combine started before Swift existed!</p><p>And <a href="https://twitter.com/Catfish_Man/status/1136164841389867009">David Smith</a> gives us more info:</p><blockquote class="twitter-tweet" data-conversation="none" data-lang="es"><p lang="en" dir="ltr">I was curious what the earliest Combine-related file I have on my computer is, and it turns out it&#39;s August 14th 2013. I filed the radar it references on 10/23/2012.<br><br>Also apparently yet another short-lived project name I forgot about?? <a href="https://t.co/FR6NADWrs5">pic.twitter.com/FR6NADWrs5</a></p>&mdash; David Smith (@Catfish_Man) <a href="https://twitter.com/Catfish_Man/status/1136164841389867009?ref_src=twsrc%5Etfw">5 de junio de 2019</a></blockquote><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script><p>This means that while everybody was arguing if FRP was the future or not, Apple was already giving it a try internally. And that when I was complaining years ago and wishing for a declarative UI, they're working on it.</p><p>This is really interesting because it proof us that Apple doesn't live on its own bubble. They listen.</p><p>We often forget that great things take years to bake. Another interesting tweet is <a href="https://twitter.com/steipete/status/1136650922031869953">from Peter Steinberger</a></p><blockquote class="twitter-tweet" data-lang="es"><p lang="en" dir="ltr">Heard that Marzipan and Amber weren’t supposed to launch the same year. Catalyst took longer and SwiftUI was faster ready as what was planned.</p>&mdash; Peter Steinberger @ WWDC (@steipete) <a href="https://twitter.com/steipete/status/1136650922031869953?ref_src=twsrc%5Etfw">6 de junio de 2019</a></blockquote><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script><p>Catalyst (Marzipan) was supposed to be ready last year, and SwiftUI probably next one. The fact that we got everything at the same time also shows us how as big as Apple is, they still deal with software estimations, they're humans just like us.</p><p>I guess what I'm trying to say is that we should have a little more faith on them, if not for the company, for the individuals working on it. Remember this when we get frustrated again because something is missing. It's all a question of time.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/swiftui-and-the-best-wwdc-ever</guid><title>WWDC'19 marks the start of a new era</title><description></description><link>https://alejandromp.com/blog/swiftui-and-the-best-wwdc-ever</link><pubDate>Sat, 8 Jun 2019 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>WWDC '19 is over, and what a week! Let me start by saying that this is probably the best WWDC ever. We have seen the announcement of game changing technologies for the Apple developer community, but even ignoring those big announcements, the rest of smaller details make on itself a great WWDC.</p><p>There are many new things that would be interesting to talk about, and I plan to <a href="https://www.youtube.com/channel/UCfiBFlVY8s-tmJGDMNCd26w?view_as=subscriber">release a video</a> discussing this WWDC announcements in general and talking about <a href="https://alejandromp.com/blog/wwdc-2019-wishes/">my wishes</a>. But there is no doubt that for me the announcement of the year is <a href="https://developer.apple.com/xcode/swiftui/">SwiftUI</a>.</p><p>It's something I've been <a href="https://alejandromp.com/blog/wwdc-2019-wishes/%23declarative-ui-framework">desiring for years</a> and that I thought we would never have. At the moment of the announcement I was so excited that I had to jump and scream, and I even recorded my <a href="https://www.youtube.com/watch?v=p8q5ANt-22o&t=3s&ab_channel=Alexito%27sWorld">most successful video</a> on the same afternoon.<br><br>&gt; I wish I had more time to dedicate to this because it would have been a great chance to give more to the community and grow my audience, but one has other responsibilities and limited time.</p><p>But back to SwiftUI.</p><img src="https://alejandromp.com/blog/swiftui-and-the-best-wwdc-ever/hero-lockup-large_2x.png" alt="SwiftUI"/><p><strong>SwiftUI is a GAME CHANGER</strong>. As simple as that. As I said on the video, this is our future. I'm super excited to have a development environment that finally can compete, in terms of productivity, with others like React, Flutter, Elm. Trust me, functional programming and the theory behind are really nice, and something that I love to talk about (maybe too much), but at the end of the day what matters is the effect that it has on our day to day. And a declarative UI framework like the mentioned ones has been shown to be the best way of building UIs. A productivity boost compared to more imperative approaches.</p><p>But what is more incredible to me is that Apple hasn't just give us a UI declarative framework, they have give us a whole new system, they've gone the extra mile (and kilometer!). The SwiftUI syntax is just the tip of the iceberg, it's the whole package that makes this something amazing and <em>revolutionary</em>.</p><p>Let me give you a big picture of the whole package 📦:</p><p>Starting with the obvius. The <strong>SwiftUI DSL</strong> is beautiful and makes it super easy to write and read UI code. It leverages new Swift features like <a href="https://youtu.be/YG5u0aFgGQI">function builders</a> to reduce the clutter and make a nice DSL.</p><img src="https://alejandromp.com/blog/swiftui-and-the-best-wwdc-ever/example-syntax-dark-large_2x.jpg" alt="SwiftUI example"/><p>But because Apple is able to improve not only the framework, but also the language and the tools, we finally have <strong>Swift hot reloading</strong>. Change something in your Swift file, save, and those changes are compiled and injected in the running binary. (<em>this works for other Swift code, not only SwiftUI, but it shines with it</em>). This was possible in the past with some dodgy hacks, but the hope is that with official Apple support this is now just part of our day to day development. The amount of time that this will save it's uncountable.</p><p>This great integration between framework, language and tooling is what allows them to bring us next level UI development. Something that I've seen sometimes on other communities, but I've never seen it done in such a beautiful and integrated way. Xcode previews.</p><p>Xcode previews are the other part of the puzzle that is gonna change our lives. An empowered <em>playground driven development</em> with the best of interface builder, but much better because the previews are literally your code running. It doesn't show a fake rendered UI, no. It compiles and runs your code to show you the real UI. All of it without running the app, without having to navigate to the specific screens, with live and immediate changes. The feedback cycle is as fast as it can be.</p><img src="https://alejandromp.com/blog/swiftui-and-the-best-wwdc-ever/example-design-large_2x.jpg" alt="SwiftUI interface builder"/><p>But Xcode previews don't stop there, and this was only part of my deepest dreams. The preview of your code is not only a preview, but also an interface design tool. You can drag and drop UI elements, click on them to change their properties, etc. And the craziest thing is that it changes the code for you to reflect the changes, the code is the source of truth. This gives us the best of both worlds, you can write code or use the design tool, interchangeably. And if that was not enough, you can click on the code elements to show the inspector panels to change properties of the views, in the code.</p><p>But the story doesn't end with the UI. Apple has also released Combine, an FRP framework. This means that Apple finally sees FRP as the way of dealing with asynchronous programming. It makes it easy to benefit from the declarative aspect of SwiftUI if we can hook the rest of our logic in a similar way.</p><p>It's still early days of all this tech. SwiftUI is still buggy and sometimes frustrating to learn. But the doors have been opened, things will just get better from here.</p><p>A new era has begun.</p><blockquote><p>If you want to know more about what's behind SwiftUI <a href="https://www.youtube.com/channel/UCfiBFlVY8s-tmJGDMNCd26w">subscribe to my channel</a> as new Swift videos are in the works.</p></blockquote><iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/p8q5ANt-22o" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/wwdc-2019-wishes</guid><title>WWDC 2019 wishes</title><description></description><link>https://alejandromp.com/blog/wwdc-2019-wishes</link><pubDate>Tue, 28 May 2019 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>Is that time of the year again 🎉 WWDC '19 is happening next week and as usual we all have our expectations, wishes and predictions.</p><p>I have to admit that this year feels a little weird with so many leaks, feels like we already know everything and I'm a #nospoiler kinda guy. But even with that unpleasant sensation, I've already started tweeting about it!</p><blockquote><p>Check out this <a href="https://twitter.com/alexito4/timelines/1114469530791813120">twitter collection</a> of my tweets about #wwdc19</p></blockquote><p>I will get my popcorn ready for next Monday. 🍿</p><p>But before that, I wanted to write down my wishes for this year. This is not what I expect to get, what's rumoured or leaked, but what I would love to see. I got some of my <a href="https://alejandromp.com/blog/wwdc-expectations-review/">last year wishes</a> but not all, so expect them to come back again on this year's list.</p><p>Here is the list of my wishes for WWDC 2019</p><ul><li><a href="#declarative-ui-framework">Declarative UI framework</a></li><li><a href="#dynamic-heights-that-work">Dynamic heights that work</a></li><li><a href="#uikit-on-the-mac">UIKit on the Mac</a></li><li><a href="#swiftcore">SwiftCore</a></li><li><a href="#scripting-with-swift">Scripting with Swift</a></li><li><a href="#better-shortcuts-integration">Better shortcuts integration</a></li><li><a href="#cloudkit-functions">CloudKit functions</a></li><li><a href="#custom-watch-faces">Custom Watch faces</a></li><li><a href="#better-deep-linking-integration">Better deep linking integration</a></li><li><a href="#drawing-view">Drawing view</a></li><li><a href="#custom-view-controller-and-non-ui-extension-providers">Custom View Controller and Non-UI Extension Providers</a></li><li><a href="#more-control-on-app-version-updates">More control on App version updates</a></li><li><a href="#dark-mode-on-ios">Dark mode on iOS</a></li><li><a href="#shortcuts-on-macos">Shortcuts on macOS</a></li><li><a href="#screentime-on-macos">Screentime on macOS</a></li><li><a href="#cheaper-icloud">Cheaper iCloud</a></li><li><a href="#performance-improvements-and-bugfixes">Performance improvements and bugfixes</a></li></ul><h1 id="declarative-ui-framework">Declarative UI framework</h1><p>This is probably my biggest wish, something that has being rumoured in the past few years but that feels so far away. The industry has moved forward from imperative UI (<a href="https://reactjs.org">React</a>, <a href="https://flutter.dev">Flutter</a>...) but Apple still hasn't shown anything about what the next UI framework would be.</p><p>On my 2016 (so old!) post <a href=" /blog/modern-declarative-software/">The trip to modern declarative software</a> I already discussed how while part of the iOS community was focusing on Rx the rest of the world was already moving to <a href="https://guide.elm-lang.org/architecture/">the next step</a>. I don't want us to be like the JS community rewriting everything every other month, but it's completely true that it feels like we're always a couple of steps behind. Even Android has now a <a href="https://developer.android.com/jetpack/compose">pre-alpha</a> (yes, you've read correctly) of an official declarative UI framework!</p><p>I started iOS development enjoying every piece of UIKit, it was amazing and really well thought. Over the years it has grown a lot, making it now the biggest pain point of an iOS developer. Some of the pain is legit, we have to deal with much more things now (remember the good old 320x480 days?), but other stuff could be much better handled by a declarative system.</p><p>I've talked about what my ideal UI framework is in other places, but as a quick summary: build on top of UIKit (we still want an imperative access when needed), embracing Swift fully and integrated with interface builder (IB writes code, not XML. And the code gets rendered by IB).</p><p>This is a wet dream of mine, I don't think we're gonna get it anytime soon, but wishes are wishes.</p><h1 id="dynamic-heights-that-work">Dynamic heights that work</h1><p>I know declarative UI is far away so at least can we have automatic sizing work once and for all, please? Implementing any modern UI requires adapting to dynamic content, font sizes and multiple languages.</p><p>And even with that reality, implementing a list with dynamic height is prone to errors, bugs and edge cases that still don't work. Dynamic heights is probably the biggest contributor to UIKit issues I've encountered, maybe after our beloved notch.</p><h1 id="uikit-on-the-mac">UIKit on the Mac</h1><p>Marzipan! Of course we all want this, but in all honestly it's not one of my main wishes. One concern I have is about the technical details. How much freedom are we gonna have in terms of mixing AppKit and UIKit in the same codebase? Is gonna be quite unproductive if you need to pick one of them for a whole project. That's unless they start porting all the exclusive feature from macOS to UIKit.</p><p>The excitement for Marzipan is around finally seeing what's Apple strategy for the future of their platforms.</p><h1 id="swiftcore">SwiftCore</h1><p><a href="https://developer.apple.com/documentation/javascriptcore">JavaScriptCore</a> is a really powerful framework that allows native apps to execute Javascript and bridge between JS and native code. It's main use is to interact with webviews but it also empowers famous non-trivial frameworks (that actually give us declarative UI… hurry up Apple!).</p><p>What I want is to be able to evaluate Swift code at runtime. Of course it should be properly sandboxed and secure and all that jazz. This is not something that all Apps need but with how amazing Swift is one could imagine many apps that could profit from letting advanced users tweak or program some aspects of them.</p><p>Swift has a REPL and Apps like Swift Playgrounds and usages like jupiter notebooks proof that it can be done. I just wish Apple would give a little more love to their creation.</p><h1 id="scripting-with-swift">Scripting with Swift</h1><p>One of the main things that SwiftCore could power (apart from Playgrounds) is being able to use code to script Shortcuts. There is a lot of people that wants to graduate from visual programming in the Shortcuts app to a more traditional and flexible approach.</p><p>Of course the easy route would be to just let people use JS, and that's a valid solution, but it would be a lost opportunity. I think Apple has a great opportunity here to introduce Swift to a new broad range of people that would never think about learning it. And remember that being a language to learn programming is one of Swift goals.</p><h1 id="better-shortcuts-integration">Better shortcuts integration</h1><p>What last year was a wish for a Workflow framework, now it has evolved to improving what we already have :)</p><p>Shortcuts is really powerful but we need better integrations with applications. And this is something that not only devs are asking for, but users are seeing as a weakness of the system.</p><p>The main pain point being not letting the end user to have "parameters" to Siri queries. This limits a lot of the useful things that can be automated, the problem that I see here is that I'm not sure Siri is ready to accept this extra complication.</p><h1 id="cloudkit-functions">CloudKit functions</h1><p>Another place were Apple needs to make Swift shine. Swift on the server is already a reality, and CloudKit is a framework that developers that can use it love. Just put them both together!</p><p>I feel like this is one of those areas that Apple just needs to work on without any question. It would be a big win for developers that use iCloud but, more importantly, it would show to the world how confident Apple is with the future of Swift.</p><h1 id="custom-watch-faces">Custom Watch faces</h1><p>Is about time developers have access to watch faces. There are so many cool prorotypes people is doing that we can't wait for this anymore!</p><h1 id="better-deep-linking-integration">Better deep linking integration</h1><p>As much as I love to keep things simple, complex navigation in a big app is something real. And with apps becoming more complex for the pro market this is happening more and more.</p><p>There is a point when you want to move your pushes out of your ViewControllers, and it makes things so much better! But still, I dream of a version of Storyboards that has automatic integration with deep linking and with my code. Again, routers in any web framework are much better than what we have.</p><h1 id="drawing-view">Drawing view</h1><p>A late addition directly taken from <a href="https://www.macstories.net/stories/wwdc-a-wish-list-2019-edition/">macstories</a>. This is not something that every app needs, but I've had many ideas of places where it would be amazing to easily get free flow user input. But of course, implementing a drawing view from scratch is not trivial. I implemented one from scratch years ago and it was good enough for the time, but is not something that you want every developer to go trough.</p><h1 id="custom-view-controller-and-non-ui-extension-providers">Custom View Controller and Non-UI Extension Providers</h1><p>In previous years the whole thing about opening the remote ViewController system to third party developers was a wish that many of us had, but after the introduction of so many "extension points" the majority got satisfied.</p><p>But as mentioned in <a href="https://www.macstories.net/stories/wwdc-a-wish-list-2019-edition/">macstories</a> there are still so many missing things on the extensions API that are needed. Inter-app communication is not an easy problem to solve but is something that needs to keep improving year after year.</p><h1 id="more-control-on-app-version-updates">More control on App version updates</h1><p>iOS app updates happen really fast, on my experience it takes only 1 week to get 90% of the user base updated, which is amazing. But sometimes we need more than this.</p><p>It's about time that we get a standard UI to prompt our users to update and even to force them to update. Having a standard UI for this would help users familiarise with keeping Apps up to date, but also would make developers use the changelog feature again!</p><h1 id="dark-mode-on-ios">Dark mode on iOS</h1><p>This is gonna be big for developers but I really want it as a user. I run everything I can with a dark theme, it makes it so much easier to the eyes.</p><p>With the existing support for it on the asset catalogs I'm expecting (and wishing) that many Apps are already ready for it.</p><h1 id="shortcuts-on-macos">Shortcuts on macOS</h1><p>Another one that needs to come from iOS, with all mentioned improvements please! It would be good to have a single automation system for all Apple platforms, and Shortcuts is a really good take on it.</p><h1 id="screentime-on-macos">Screentime on macOS</h1><p>One of the best additions from last year, needs to come to macOS where we spend most of our time. Let's hope Marzipan helps Apple internal developers to get this going easily ;)</p><h1 id="cheaper-icloud">Cheaper iCloud</h1><p>Really 💸</p><h1 id="performance-improvements-and-bugfixes">Performance improvements and bugfixes</h1><p>And last but not least, please give us good bugfixes and performance improvements. Last year was amazing!</p><p>Every summer that Apple focuses on this instead of breaking UIKit is a great summer for me. So if they don't give me any of my wishes at least let me have an easy summer ^^</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/beartodo-a-menubar-app-to-manage-your-tasks</guid><title>BearTodo, a menubar app to manage your tasks</title><description></description><link>https://alejandromp.com/blog/beartodo-a-menubar-app-to-manage-your-tasks</link><pubDate>Wed, 22 May 2019 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>After writing about my <a href="https://alejandromp.com/blog/my-perfect-notes-app/">perfect notes app</a> and comparing the <a href="https://alejandromp.com/blog/notes-app-comparison/">available options</a> I decided to move to Bear. My <a href="https://alejandromp.com/blog/from-todoist-to-bear/">tasks from Todoist</a> were one of the first things that I moved, and with that change I immediately noticed that in some occasions I really needed a quick way of seeing my tasks.</p><p>Bear has a Todo filter that displays only the notes with a task item in them. This is somewhat useful but it's far from ideal to see your tasks. The fact is that the app is a note taking app, so this is a filter for notes, there is no special view for tasks.</p><img src="https://alejandromp.com/blog/beartodo-a-menubar-app-to-manage-your-tasks/bear_todo_filter.png" alt="Bear filter"/><p>But I was decided to keep using Bear because so many of the other features are really good. So, as an alternative, I just decided to program my own solution for this specific problem.</p><p>This is how <strong>BearTodo</strong> came to be.</p><img src="https://alejandromp.com/blog/beartodo-a-menubar-app-to-manage-your-tasks/bear_todo_app.png" alt="Bear todo screenshoot"/><p>BearTodo is a menubar app that helps visualise and manage the tasks from your notes in Bear.</p><p>I've worked on it on my spare time, so it's not a high quality polished mac app, but I've been using it <a href="https://twitter.com/alexito4/status/1096856860051808256">for a while</a> and it works perfectly fine for my use case. As I wrote on my post about the perfect notes app, some task management features would be pretty amazing to have, and I may tackle some of them in the near future.</p><p>Ultimately I'm not sure how much time I will spend on it so I decided to share a build with the current feature set, as it is. If it can help somebody else apart from me it would be great.</p><p>The app doesn't keep it's own list of tasks, it reads them from Bear using the official x-callback-url API. I thought about reading directly from the sqlite database but that seemed too dangerous and fragile.</p><p>The biggest inconvenience with the url scheme API is the fact that it forces the app to become active and its window to be on the foreground. I've contacted the devs and this is a limitation of macOS, so it doesn't seem likely that is ever gonna be fixed. The workaround is to minimise Bear, the app would still become active but won't show up on the foreground. ¯_(ツ)_/¯</p><p>Here are the implemented features:</p><ul><li>Displays all tasks from your Bear notes.</li><li>The tasks are grouped by the originating Note, which you can expand and collapse.</li><li>Mark a task as done/not done and it syncs that change back to the original note.</li><li>Filter to focus on your current tasks.</li><li>Quickly add a new task to an Inbox note or</li><li>quickly add a new task to a specific note if it's the only note being displayed by a filter.</li></ul><p><a href="https://alejandromp.com/beartodo/BearTodo.zip">Download</a></p><blockquote><p><strong>The first thing you need to do is set a</strong> <a href="<https://bear.app/faq/X-callback-url> Scheme documentation/#token-generation">Bear token</a> <strong>in the settings screen.</strong></p></blockquote>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/preventing-the-collapse-of-civilization-a-talk-by-jonathan-blow</guid><title>Preventing the Collapse of Civilization a talk by Jonathan Blow</title><description></description><link>https://alejandromp.com/blog/preventing-the-collapse-of-civilization-a-talk-by-jonathan-blow</link><pubDate>Sun, 19 May 2019 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>I'm so thankful to have people like <a href="https://twitter.com/Jonathan_Blow">Jonathan Blow</a> that is able to challenge the status quo of our industry. Software quality is decaying and we're part of the problem. If you still think that caring about this things is a waste of time <a href="https://www.youtube.com/watch?v=pW-SOdj4Kkk">watch this talk</a>, it may help you open your eyes.</p><iframe width="560" height="315" src="https://www.youtube.com/embed/pW-SOdj4Kkk" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/swift-script-to-export-lists-from-remindersapp</guid><title>Swift script to export lists from Reminders.app</title><description></description><link>https://alejandromp.com/blog/swift-script-to-export-lists-from-remindersapp</link><pubDate>Wed, 8 May 2019 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>I've already mentioned how I moved tasks from <a href="https://alejandromp.com/blog/from-todoist-to-bear/">Todoist to Bear</a> but one of the missing pieces of the migration was some lists that I had on Reminders.</p><p>These lists were not really reminders or tasks, it was an easy way I had to keep a list of books or games I want to check on the future.</p><p>Reminders has an export option, but it only exports to an <code>.ics</code> file (a calendar file format), so it's not really useful as it is.</p><p>I've just written a quick Swift script to gather each item and print it to the console so it can be copy pasted as a simple list. <a href="https://gist.github.com/alexito4/f921aebdadb90b78b44831ef103ab370">Gist</a>.</p><script src="https://gist.github.com/alexito4/f921aebdadb90b78b44831ef103ab370.js"></script><p>As you can see the code is really simple and rudimentary. I haven't spend much time on it and it just does what I needed. That's <strong>the beauty of scripts</strong> and being able to use your <a href="https://alejandromp.com/tags/swift/">beloved language</a>.</p><p>You can see how I use <a href="https://github.com/mxcl/swift-sh">swift sh</a> to run the script. I always start with that line because anticipate the need to import some library, but at the end there was no need for it.</p><p>There is no nice ICS parsing package in Swift, yet. And maybe this would have been an opportunity for me to create it and contribute back to the community but honestly this script took me 10min to write, I don't think I could have make a decent parser in the same amount of time 😂</p><p>And it's not something I want to be proud of. If we don't make these packages ourselves nobody else is gonna make them. So who knows, maybe I put some time to do it, or maybe you can do it and <strong>fill a gap in the swift ecosystem</strong> 😉</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/se-0258-property-delegates-proposal</guid><title>Property Delegates and the diligent community</title><description></description><link>https://alejandromp.com/blog/se-0258-property-delegates-proposal</link><pubDate>Thu, 25 Apr 2019 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>The <a href="https://forums.swift.org/t/se-0258-property-delegates/23139">Property Delegates</a> proposal has been in review for some days by now and is a good example of the strength of the Swift community.</p><p>This is a feature that many of us have followed for years, its previous incarnation called Property Behaviours.</p><p>The idea is to have a really nice way to change the behaviour of properties, to make them much more than just storage with a getter and setter. It also implies that we can generalise some scenarios that right now are hardcoded in the compiler (like <code>lazy</code>) which is always a good sign.</p><p>But the greatnesses of the feature itself is not the point I want to make in this post.</p><p>I recently made a <a href="https://www.youtube.com/watch?v=66NjQkqTEK4">video</a> about the proposal because I was so excited about it. Luckily for us, even with an amazing proposal and feature, we have really smart people on the community that knows exactly how to challenge some assumptions. That is exactly what's going on right now with SE-0258.</p><p>Everybody is excited and wants to see this feature in the language, but that doesn't blind the community, we're still able to provide useful feedback and keep searching for the best solution we can come up with.</p><p>Some people complains that Swift changes too much or that is really complicated, others think that it goes too slowly and lacks basic features. But I honestly think that the language is in the right path, improving and evolution at a steady pace with really bright people behind it.</p><p>Every release is a day to celebrate, and meanwhile I can still enjoy the language as it is every day.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/implementing-using-in-swift-with-swiftsyntax</guid><title>Implementing using in Swift with SwiftSyntax</title><description></description><link>https://alejandromp.com/blog/implementing-using-in-swift-with-swiftsyntax</link><pubDate>Mon, 22 Apr 2019 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>Last year I wrote about <a href="https://alejandromp.com/blog/using-structs-swift-jai-oop/">Improving struct composition in Swift</a> by levering the <code>using</code> keyword and feature taken from <a href="https://alejandromp.com/tags/jai/">Jai</a>. Recently I've been <a href="https://www.pointfree.co/episodes/ep53-swift-syntax-enum-properties">inspired by pointfree</a> to implement this feature using code generation.</p><p>In this post I want to dive in on the development of this tool and analyse the shortcomings of it.</p><h2 id="what-is-`using`">What is <code>using</code></h2><p>I already went into detail in <a href="https://alejandromp.com/blog/using-structs-swift-jai-oop/">my previous post</a> but basically <code>using</code> is a feature from Jai the, still in development, language started by <a href="https://twitter.com/Jonathan_Blow">Jonathan Blow</a>. It lets you expose properties from a type as if they were part of the enclosing type.</p><p>The nice thing about it is that it brings one of the main advantages that class inheritance have over struct composition. But it is even more powerful because by using composition you can basically "inherit from multiple types".</p><img src="https://alejandromp.com/blog/implementing-using-in-swift-with-swiftsyntax/jai_using.jpeg" alt="JAI using feature example"/><h2 id="swiftsyntax">SwiftSyntax</h2><p><a href="https://github.com/apple/swift-syntax">SwiftSyntax</a> is an SPM package that lets you use libSyntax from Swift. It is a tool that allows you to work with Swift code, using an AST. The interesting thing is that the AST is made specifically to keep syntactic information, as opposed to a purely semantic AST that compilers usually use.</p><p>The way to interact with the library is by implementing classes following the Visitor pattern. You subclass <code>SyntaxVisitor</code> or <code>SyntaxRewriter</code> and overwrite the methods for the specific syntax node you care about.</p><p>If you just want to do local changes or analysis this approach seems really good. But in my case I had to adopt a multiple step process, and for that, the visitor API seems too restrictive. I have to admit that the lack of documentation is probably the cause of making this trickier than it may be, specially since there are a lot of syntax nodes in a simple peace of Swift code that you don't really think about but that you need to deal with when using this tool.</p><p>It all went better when I found this <a href="https://swift-ast-explorer.kishikawakatsumi.com">AST explorer</a>. I still missed a better visualisation of what each node has, but it helped me a lot when having to navigate the deep hierarchies of member declarations and pattern bindings. Even with that tool I was relying a lot on LLDB and <a href="https://github.com/alexito4/SwiftUsing/commit/eecfef764dcb319c907229647a419b4f085221a1#diff-778de675c096a0e2284c6f96dd269e86R12">printing the runtime types</a> of the nodes.</p><img src="https://alejandromp.com/blog/implementing-using-in-swift-with-swiftsyntax/swift_ast.jpg" alt="Example Swift AST"/><p>I left in GitHub <a href="https://github.com/alexito4/SwiftUsing/commit/eecfef764dcb319c907229647a419b4f085221a1#diff-328baca25433db0b31f64ce6d70fd73eR30">the ugly code</a> I was using when implementing the prototype, the level of casting and nesting was too much for me to try to simplify at that point. That code was being used for a while until I was able to refactor it to something more sensible.</p><p>The main problem is that what I needed doesn't match the level of abstraction that SwiftSyntax operates at. For example all that code is just trying to get the identifier and type of a member declaration. The problem is that with the AST being at syntactic level it needs to distinguish between <code>let name: String</code> vs. <code>let name, surname: String</code> or even <code>let name = ""</code>. All of those cases are basically the same, a variable named <code>name</code> of the type <code>String</code>, but if you just want that information it takes a bunch of code to unify all the scenarios.</p><p>Even in the current version I'm <a href="https://github.com/alexito4/SwiftUsing/commit/eecfef764dcb319c907229647a419b4f085221a1#diff-778de675c096a0e2284c6f96dd269e86R62">not supporting all those scenarios</a>. Now that I have a better understanding of the AST and the relation between the nodes it wouldn't be too hard to include support for them.</p><p>As a word of advice, approaching the code generation with String literals and interpolation can seem nice in the beginning, that's how I started. But I realised later that it made other things difficult. For example, of the features I had to implement was to find and update already generated code instead of duplicating it. With the generated code being just strings it was quite hard to find a match, and even harder to modify it. After losing some time with different String indices versions I decided to switch to code generation using the AST APIs.</p><p>SwiftSyntax provides different sets of APIs to create AST nodes. I was using the <a href="https://github.com/apple/swift/blob/master/lib/Syntax/README.md#make-apis">make API</a> and <a href="https://github.com/apple/swift/blob/master/lib/Syntax/README.md#with-apis">with API</a> via the <code>SyntaxFactory</code>. These APIs are not bad at all. Make it quite clear what's the structure of the nodes and helped me get a better understand of Swift syntax. That said, I can see how writting string templates (Swift code) is way nicer. You can see an example of how to <a href="https://github.com/alexito4/SwiftUsing/commit/eecfef764dcb319c907229647a419b4f085221a1#diff-778de675c096a0e2284c6f96dd269e86R227">generate a getter</a> and is not super clear. I ended up factoring out portions of code into extensions of the factory which improved the legibility by a lot. As Stephen pointed out to me in an email, maybe a middle ground could be found by making a small DSL for the syntax nodes, kind of what <a href="https://github.com/pointfreeco/swift-html">swift-html</a> does for HTML nodes. I find myself thinking about Rust macros and how some DSL in Rust look much nicer than the code I wrote for this tool.</p><p>One of the trickier parts to get right is dealing with the <em>trivia</em>, the name the library gives to spaces, new lines, etc. As you expect from a tool focused on refactoring and formatting working with trivia is an integral part of the API. I tried to keep the unspoken rule (I heard it in some video a while ago) that the trivia should be part of the previous node, so I put as much trivia as I could into the trailing. To know exactly where it should go I used the AST explorer and tried to mimic that behaviour. Having to manually format code like this makes you appreciate all the nuances that simple code has.</p><h2 id="swiftusing">SwiftUsing</h2><p>The current version of this tool allows you to code generate extensions with computed properties for types found in the same file. You can see how this goes further than "local changes" and why the visitor pattern was quite limiting.</p><p>The first approach I tried was to gather the information (nodes) and then modify them manually. I wanted to do all in a single pass because doing more seemed wasteful. This got me far but when I tried to save the file with a text representation of those nodes, including the extra logic to update existing code, it got really complicated. As I mentioned before, working with strings is not the ideal situation.</p><p>Instead the current approach of doing <a href="https://github.com/alexito4/SwiftUsing/commit/eecfef764dcb319c907229647a419b4f085221a1#diff-4f7599dd8612dc33c513ef022de2f837R12">multiple passes</a> seems to work much better. First I gather the type information and the variables that want this feature; then I code generate the extensions; and finally I rewrite the original syntax tree.</p><p>The first and last steps are both integrated into a "pass" using a <code>SyntaxVisitor</code> and a <code>SyntaxRewriter</code> respectively. This defiantly seems to be a better approach that matches SwiftSyntax API design.</p><p>You can see an example of the tool in action on <a href="https://github.com/alexito4/SwiftUsing/blob/eecfef764dcb319c907229647a419b4f085221a1/Example/File.swift">the example file</a>.</p><p>The tool is capable of understanding mutability by checking if the properties are <code>var</code> or <code>let</code>. When it detects that a variable is immutable it skips the generation of the setters. This matches the programmer intend and makes the code compile 😊.</p><p>As mentioned before, there are other scenarios that are not handled, specially around different syntaxes. But one of the main shortcomings of this prototype is the inability to get type information from multiple files or libraries. I haven't worked on that yet because the occasions I've been using this I haven't really needed it, and, honestly, because seems quite tricky with SwiftSyntax. This is something that would be nice to improve in the future.</p><h2 id="deeper-integration">Deeper integration</h2><p>Code generation with external tools is powerful but I always feel that is just poor man metaprogramming. My desire would be that this could be made as a plugin that runs as part of the compiler. This would imply that no source code needs to be generated, no files have to be touched and that the user doesn't have to run the tool manually or deal with multiple compilation steps. It would be completely transparent for the user.</p><p>As the tool creator, a plugin system like this would let me fed the changes on the AST directly into the compiler pipeline at the right moment, that's the dream. Hopefully this would make it easier to gather more information and to reduce the performance cost of this functionality.</p><p>But also keep in mind that this code generation only get us that far. The original <code>using</code> design in Jai allows you to use it in many more places, for example inside local scopes to expose type properties as if they were local variables! This would definitely need to have a proper feature design and integration directly into the language and the compiler.</p><h2 id="alternatives">Alternatives</h2><p>Of course this flexible compiler is not gonna come any time soon, and I doubt this feature would pass trough Swift Evolution. But there are some other alternatives that we could consider to improve it.</p><p>First, from Swift Evolution, seems like soon we may get <a href="https://forums.swift.org/t/pitch-static-custom-attributes-round-2/22938">Custom Attributes</a>. This won't get us compiler integration but at least we don't have to rely on ugly comments to annotate the properties that want to use the feature.</p><p>And of course, I'm pretty sure many of you are thinking about <a href="https://github.com/krzysztofzablocki/Sourcery">Sourcery</a>. Being honest the only reason to use SwiftSyntax is because I wanted to learn and try what could be done with a library that is closer to the compiler and uses an AST. For AdHoc code generation Sourcery is the king no doubt, but I feel like for building a tool like this working at the AST level instead of string templates is much better. But honestly, I just wanted to play with SwiftSyntax 😋</p><h2 id="conclusion">Conclusion</h2><p><a href="https://github.com/alexito4/SwiftUsing">SwiftUsing is available on GitHub</a> and I'm personally using in a couple of projects. I'm really happy of how it turned out specially for something that started as a prototype just a few days ago.</p><p>It's almost 100% unit tested, and this is a great reminder that the numbers alone don't mean anything, there are many scenarios that the tool doesn't cover 😉</p><p>I may keep working on it if I find that I need more from it or if Swift itself improves and makes some of this things easier.</p><p>Thanks for reading!</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/the-fiasco-of-configuration-objects</guid><title>The fiasco of configuration objects</title><description></description><link>https://alejandromp.com/blog/the-fiasco-of-configuration-objects</link><pubDate>Sat, 20 Apr 2019 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>There is this commonly followed programming rule that says that parameter lists must be short.</p><p>Nobody wants to see a constructor with more than 2 arguments right?</p><p>Right?</p><p>Well, let me tell you what annoys me more than that. Start writing the type constructor and not seeing the suggestion for what parameters it needs, specially when you know that at least it accepts one argument of type X.</p><p>The usual scenario:</p><ul><li>Start typing <code>View(title...</code></li><li>Xcode be like ¯_(ツ)_/¯</li><li>Lose time going to the documentation and seeing <code>View(configuration: View.Config)</code></li><li>Lost more timing going to the Config configuration to know what's configurable.</li><li>Go back to your code and create and configure 2 objects instead of 1.</li><li>🤦🏻‍♂️</li></ul><p>This may be ideal in some scenarios and other languages, and Swift making it so easy to create lightweight types makes it an ideal technique.</p><p>But I think that we can rely in another Swift feature that gives us the best of both worlds: default arguments.</p><p>With default arguments we have the advantages of keeping the configuration in the constructor (where it should be) and we are still able to evolve the arguments without breaking the usages. And if you just want to use one or two parameters you can!</p><blockquote><p>This is one of those posts that I like to write just to raise the concern against dogma. Don't be confused, this is not trying to impose a new rule that you must follow, quite the opposite!</p></blockquote><p>Swift gives us (better) alternatives to old solutions. We should try to use them before deciding to go back to the old habits.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/using-protocols-to-associate-types</guid><title>Using protocols to associate types</title><description></description><link>https://alejandromp.com/blog/using-protocols-to-associate-types</link><pubDate>Wed, 10 Apr 2019 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>Today I've used Protocols to make a generic function only accept a certain number of types. The interesting part is that the only thing the protocol has is an <code>associatedtype</code>, there are no other requirements, which may seem a little weird at first.</p><h1 id="some-context">Some context</h1><p>In the Lifeworks codebase we use <a href="https://github.com/Quick/Nimble">Nimble</a> to write our expectations and we have some custom matchers for some specific scenarios. The nice thing about these matchers is that they are just free functions than return a <code>Predicate&lt;T&gt;</code>.</p><p>In some tests we have checks to make sure that what we sent to our API is correct. That part of the code relies on <a href="https://github.com/kylef/Mockingjay">Mockingjay</a> to intercept and stub the requests, and with a custom matcher we can compare the body we're sending.</p><p>The expectation code needs to check that an original typed Dictionary/Array equals to the blob of Data (a.k.a. JSON) we are sending. One approach would be to check the string representation of the JSON and the dictionary/array, but that's not reliable as the hash of the Dictionary is not stable.</p><p>Instead we use Nimble matchers that check the equality of the Dictionary and Array.</p><p>To make this work, in one side we need to cast our values to NSDictionary:</p><pre><code><span class="splash-keyword">let</span> expected = expectedValue <span class="splash-keyword">as</span> <span class="splash-type">NSDictionary</span>?
</code></pre><p>on the other we need to create a NSDictionary from the JSON blob of Data:</p><pre><code><span class="splash-keyword">let</span> jsonDictionary = (<span class="splash-keyword">try</span>? <span class="splash-type">JSONSerialization</span>.<span class="splash-call">jsonObject</span>(with: jsonData, options: [])) <span class="splash-keyword">as</span>? <span class="splash-type">NSDictionary</span>
</code></pre><p>with this you can then easily just compare them with Nimble:</p><pre><code><span class="splash-call">expect</span>(jsonDictionary).<span class="splash-call">to</span>(expected)
</code></pre><p>We have this logic nicely wrapped in a function that we can use inside our custom Mockinjay stub</p><pre><code><span class="splash-keyword">func</span> equalDictionary(<span class="splash-keyword">_</span> expectedValue: <span class="splash-type">Dictionary</span>&lt;<span class="splash-type">String</span>, <span class="splash-type">Any</span>&gt;?) -&gt; <span class="splash-type">Predicate</span>&lt;<span class="splash-type">Data</span>&gt; {
    <span class="splash-keyword">let</span> expected = expectedValue <span class="splash-keyword">as</span> <span class="splash-type">NSDictionary</span>?
    <span class="splash-keyword">return</span> <span class="splash-call">equal</span>(expected).<span class="splash-call">contramap</span>({ (jsonData) -&gt; <span class="splash-type">NSDictionary</span>? <span class="splash-keyword">in
        let</span> jsonDictionary = (<span class="splash-keyword">try</span>? <span class="splash-type">JSONSerialization</span>.<span class="splash-call">jsonObject</span>(with: jsonData, options: [])) <span class="splash-keyword">as</span>? <span class="splash-type">NSDictionary</span>
        <span class="splash-keyword">return</span> jsonDictionary
    })
}
</code></pre><pre><code><span class="splash-call">http</span>(.<span class="splash-dotAccess">patch</span>, uri: <span class="splash-string">"/endpoint"</span>, bodyCheck: { body <span class="splash-keyword">in</span>
    <span class="splash-call">expect</span>(body).<span class="splash-call">to</span>(<span class="splash-call">equalDictionary</span>(parameters))
    <span class="splash-keyword">return true</span>
})
</code></pre><p>This worked fine for Dictionary but in some endpoints we upload an Array as the root object of the JSON. The initial fix I did was to just overload the `</p><pre><code><span class="splash-call">http</span>(.<span class="splash-dotAccess">patch</span>, uri: <span class="splash-string">"/endpoint"</span>, bodyCheck: { body <span class="splash-keyword">in</span>
    <span class="splash-call">expect</span>(body).<span class="splash-call">to</span>(<span class="splash-call">equalDictionary</span>(parameters))
    <span class="splash-keyword">return true</span>
})
</code></pre><h1 id="the-problem">The problem</h1><p>This worked fine for Dictionary but in some endpoints we upload an Array as the root object of the JSON. The initial fix I did was to just add another function for Array. The problem is that this was too limiting as it mean that any further composition of this check would force me to overload the rest of functions. Overloads shouldn't be used lightly as they quickly explode.</p><p>I preferred to have a single generic function for it, the tricky part was restricting it to only accept parameters that worked as JSON. Basically it should only accept Dictionary or Array.</p><h1 id="protocols-to-the-rescue">Protocols to the rescue</h1><p>If Swift had Unions that would have been my initial approach:</p><pre><code><span class="splash-keyword">func</span> equalJSON(<span class="splash-keyword">_</span> expectedValue: <span class="splash-type">Dictionary</span> | <span class="splash-type">Array</span>) -&gt; <span class="splash-type">Predicate</span>&lt;<span class="splash-type">Data</span>&gt; {
    ...
}
</code></pre><p>But of course, we can simulate that with a protocol.</p><pre><code><span class="splash-keyword">protocol</span> AsJSONRoot {}

<span class="splash-keyword">extension</span> <span class="splash-type">Dictionary</span>: <span class="splash-type">AsJSONRoot</span> {}
<span class="splash-keyword">extension</span> <span class="splash-type">Array</span>: <span class="splash-type">AsJSONRoot</span> {}

<span class="splash-keyword">func</span> equalJSON&lt;T: <span class="splash-type">AsJSONRoot</span>&gt;(<span class="splash-keyword">_</span> expectedValue: <span class="splash-type">T</span>?) -&gt; <span class="splash-type">Predicate</span>&lt;<span class="splash-type">Data</span>&gt; {
	...
}
</code></pre><p>That's something really easy to do in Swift and quite powerful. It ensures the function can only be used with the types I want.</p><p>But if you pay close attention to the function implementation, is not enough. And that's because what we really need are <code>NSDictionary</code> and <code>NSArray</code> to work with <code>JSONSerialization</code> but also to Nimble matcher.</p><blockquote><p>Nimble can work with Dictionary and Array but that starts going the rabbit whole of constraining the protocols to Equatable.</p></blockquote><h1 id="associatedtype-to-the-rescue">associatedtype to the rescue</h1><p>The solution to our problem is to let the compiler know that <code>Array</code> is related to <code>NSArray</code> and the same for dictionaries. Luckily for us Swift protocols allow us to do exactly that with <code>associatedtype</code>.</p><pre><code><span class="splash-keyword">protocol</span> AsJSONRoot {
    <span class="splash-keyword">associatedtype</span> JSONRoot: <span class="splash-type">Equatable</span>
}

<span class="splash-keyword">extension</span> <span class="splash-type">Dictionary</span>: <span class="splash-type">AsJSONRoot</span> {
    <span class="splash-keyword">typealias</span> JSONRoot = <span class="splash-type">NSDictionary</span>
}

<span class="splash-keyword">extension</span> <span class="splash-type">Array</span>: <span class="splash-type">AsJSONRoot</span> {
    <span class="splash-keyword">typealias</span> JSONRoot = <span class="splash-type">NSArray</span>
}
</code></pre><p>It may seem a little weird because the protocol is empty and only has an <code>associatedtype</code>, but only with this change we can generalise our function to work with both types and interoperate with JSON.</p><pre><code><span class="splash-keyword">func</span> equalJSON&lt;T: <span class="splash-type">AsJSONRoot</span>&gt;(<span class="splash-keyword">_</span> expectedValue: <span class="splash-type">T</span>?) -&gt; <span class="splash-type">Predicate</span>&lt;<span class="splash-type">Data</span>&gt; {
    <span class="splash-keyword">let</span> expected = expectedValue <span class="splash-keyword">as</span>? <span class="splash-type">T</span>.<span class="splash-type">JSONRoot</span>
    <span class="splash-keyword">return</span> <span class="splash-call">equal</span>(expected).<span class="splash-call">contramap</span>({ (jsonData) -&gt; <span class="splash-type">T</span>.<span class="splash-type">JSONRoot</span>? <span class="splash-keyword">in
        let</span> jsonDictionary = (<span class="splash-keyword">try</span>? <span class="splash-type">JSONSerialization</span>.<span class="splash-call">jsonObject</span>(with: jsonData, options: [])) <span class="splash-keyword">as</span>? <span class="splash-type">T</span>.<span class="splash-type">JSONRoot</span>
        <span class="splash-keyword">return</span> jsonDictionary
    })
}
</code></pre><p>Gotta love the type system! 💕</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/safe-string-example-safe-xml-and-url-part-4</guid><title>Safe string example, Safe XML and URL</title><description></description><link>https://alejandromp.com/blog/safe-string-example-safe-xml-and-url-part-4</link><pubDate>Sun, 7 Apr 2019 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>After finalising the <code>InterpolableLanguage</code> protocol in the <a href="https://alejandromp.com/blog/generalising-swift-string-interpolation-part-3/">third part of this series</a> we will finally put it to good use and show an example of this can be used on day to day code.</p><h2 id="sharing-an-article">Sharing an article</h2><p>Let make a simple example that can use the XML and URL types created in previous article: sharing an article.</p><p>For that we can create an XML string that includes a link to the article.</p><pre><code><span class="splash-keyword">struct</span> Article {
    <span class="splash-keyword">let</span> title: <span class="splash-type">String</span>
    <span class="splash-keyword">let</span> url: <span class="splash-type">SafeURL</span>
}
</code></pre><p>The <code>Article</code> type uses a normal <code>String</code> for the title because it could be anything, we don't have any restriction on it, we don't have a "language" for titles. But for the URL we do, so we use our <code>SafeURL</code> type.</p><p>Thanks to that we can freely assume that the url of an article is completely safe at any point of our program.</p><p>Let's create an instance of an article</p><pre><code><span class="splash-keyword">let</span> test = <span class="splash-type">Article</span>(
    title: <span class="splash-string">"A type-based solution to the “strings problem”: a fitting end to XSS &amp; SQL-injection holes?"</span>,
    url: <span class="splash-string">"</span>\(safe:"https://blog.<span class="splash-property">moertel</span>.<span class="splash-property">com</span>/posts/<span class="splash-number">2006</span>-<span class="splash-number">10</span>-<span class="splash-number">18</span>-a-type-based-solution-to-the-strings-problem.<span class="splash-property">html"</span>)<span class="splash-string">"</span>
)
</code></pre><p>Note how easy is to create a safe URL, in this case because we're pasting it ourselves and we know is correct we can just use the <code>safe</code> interpolation overload. 👌🏻</p><p>Now let's make use of the XML type to construct some XML to share the link to the article.</p><pre><code><span class="splash-keyword">extension</span> <span class="splash-type">Article</span> {
    <span class="splash-keyword">func</span> share() -&gt; <span class="splash-type">XML</span> {
        <span class="splash-keyword">let</span> shareURL: <span class="splash-type">SafeURL</span> = <span class="splash-string">"https://reddit.com/submit?url=</span>\(url)<span class="splash-string">&amp;title=</span>\(unsafe: title)<span class="splash-string">"</span>
        <span class="splash-keyword">let</span> redditLink: <span class="splash-type">XML</span> = <span class="splash-string">"&lt;a href=\"</span>\(shareURL)<span class="splash-string">\"&gt;Reddit</span> \(<span class="splash-call">imageTag</span>("https://i.<span class="splash-property">imgur</span>.<span class="splash-property">com</span>/sdO8tAw.<span class="splash-property">png"</span>))<span class="splash-string">&lt;/a&gt;"</span>
        <span class="splash-keyword">return</span> <span class="splash-string">"&lt;p&gt;Share &lt;b&gt;</span>\(unsafe: title)<span class="splash-string">&lt;/b&gt; to</span> \(redditLink)<span class="splash-string">&lt;/p&gt;"</span>
    }
}
</code></pre><p>You can see how easy it is to combine and construct XML thanks to the interpolation capabilities. For this snippet of code we've implemented a couple of extra functions to make it really nice.</p><p>First, to combine Languages we've added an interpolation overload assuming that mixing different languages is a safe operation.</p><pre><code>  <span class="splash-keyword">mutating func</span> appendInterpolation(<span class="splash-keyword">_</span> safe: <span class="splash-type">Language</span>) {
  <span class="splash-keyword">self</span>.<span class="splash-call">appendFragment</span>(safe.<span class="splash-property">value</span>)
 }
</code></pre><blockquote><p>This is just to illustrate the power of this system. It's quite likely that this is an unsafe operation and that specific conversions for some languages would be needed.</p></blockquote><p>We're also using a small free function to create the XML needed to display an image:</p><pre><code><span class="splash-keyword">func</span> imageTag(<span class="splash-keyword">_</span> imageUrl: <span class="splash-type">SafeURL</span>) -&gt; <span class="splash-type">XML</span> {
    <span class="splash-keyword">return</span> <span class="splash-string">"&lt;img width=10 src=\"</span>\(imageUrl)<span class="splash-string">\" /&gt;"</span>
}
</code></pre><p>With all of this now you have the ability to share this article from any part of your codebase, mixing URLs, XML and other strings in a safely manner.</p><pre><code>test.<span class="splash-call">share</span>().<span class="splash-property">value</span>
</code></pre><h2 id="conclusion">Conclusion</h2><p>This series has been an exploration on how to make safer Strings while keeping the easy of use of them. We've seen how Swift 5 interpolation has taken the language to another level.</p><p>Even with this being a toy example it is enough to show the power of Swift Strings. I'm super excited to see what kind of new APIs and DSLs the community starts building.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/generalising-swift-string-interpolation-part-3</guid><title>Generalising Swift string interpolation</title><description></description><link>https://alejandromp.com/blog/generalising-swift-string-interpolation-part-3</link><pubDate>Sat, 6 Apr 2019 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>In the <a href="https://alejandromp.com/blog/solving-the-string-problem-with-swift-5-interpolation-part-1/">first article</a> of this series we made a <em>safe string</em> type that was safe to use but with a cumbersome API, and on <a href="https://alejandromp.com/blog/making-String-problem-safe-interpolation-part-2/">the second article</a> we made that API much nicer to Swift 5 interpolation. On this post we will generalise that conformance to make it easy to create new safe languages.</p><h2 id="making-xml-a-safe-string">Making XML a safe string</h2><p>As an example let's use XML.</p><pre><code><span class="splash-keyword">struct</span> XML: <span class="splash-type">Language</span> {
    <span class="splash-keyword">let</span> name = <span class="splash-string">"XML"</span>
    
    <span class="splash-keyword">var</span> value: <span class="splash-type">String</span> = <span class="splash-string">""</span>
    
    <span class="splash-keyword">mutating func</span> appendFragment(<span class="splash-keyword">_</span> fragment: <span class="splash-type">String</span>) {
        value.<span class="splash-call">append</span>(fragment)
    }
    
    <span class="splash-keyword">mutating func</span> appendText(<span class="splash-keyword">_</span> text: <span class="splash-type">String</span>) {
        value.<span class="splash-call">append</span>(<span class="splash-call">escapeXML</span>(xml: text))
    }
    
    <span class="splash-keyword">private func</span> escapeXML(xml: <span class="splash-type">String</span>) -&gt; <span class="splash-type">String</span> {
        <span class="splash-keyword">return</span> <span class="splash-type">CFXMLCreateStringByEscapingEntities</span>(<span class="splash-keyword">nil</span>, xml <span class="splash-keyword">as</span> <span class="splash-type">CFString</span>, <span class="splash-keyword">nil</span>) <span class="splash-keyword">as</span> <span class="splash-type">String</span>
    }
}
</code></pre><blockquote><p>Don't take this implementation as production ready as it's just for example purposes.</p></blockquote><p>Now we can create a safe version of an XML string combining fragments of unsafe text that will be properly escaped.</p><pre><code><span class="splash-keyword">var</span> xml = <span class="splash-type">XML</span>()
xml.<span class="splash-call">appendFragment</span>(<span class="splash-string">"&lt;b&gt;"</span>)
xml.<span class="splash-call">appendText</span>(<span class="splash-string">"danger &amp; warnings"</span>)
xml.<span class="splash-call">appendFragment</span>(<span class="splash-string">"&lt;/b&gt;"</span>)
xml.<span class="splash-property">value</span> <span class="splash-comment">// "&lt;b&gt;danger &amp;amp; warnings&lt;/b&gt;"</span>
</code></pre><h2 id="protocols-to-the-rescue">Protocols to the rescue</h2><p>Thanks to powerful Swift protocols we can easily generalise the String interpolation conformance from the previous posts directly into the Language protocol.</p><pre><code><span class="splash-keyword">protocol</span> InterpolableLanguage: <span class="splash-type">Language</span>, <span class="splash-type">ExpressibleByStringLiteral</span>, <span class="splash-type">StringInterpolationProtocol</span>, <span class="splash-type">ExpressibleByStringInterpolation</span> {
    <span class="splash-keyword">init</span>()
}
</code></pre><blockquote><p>ExpressibleByStringInterpolation already brings ExpressibleByStringLiteral so that conformance is redundant. Is just displayed here for clarity.</p></blockquote><p>I decided here to create a new protocol <code>InterpolableLanguage</code> because we can't extend the Language protocol and because we will need an initialiser to be available; I didn't want to pollute the basic <code>Language</code> protocol.</p><blockquote><p>There are many other design possibilities. From creating a generic type SafeString<T: Language> like the original post, or even using more protocols and extensions. It would be an interesting design space for anybody interested in making a library with these concepts.

Now let's implement all the conformances in extensions to that protocol. This code looks identical at the one from the previous post, except now is implemented in the protocol

```swift
extension InterpolableLanguage { // ExpressibleByStringLiteral
    init(stringLiteral value: String) {
        self.init()
        self.appendText(value)
    }
}
extension InterpolableLanguage { // StringInterpolationProtocol
    init(literalCapacity: Int, interpolationCount: Int) {
        self.init()
    }
    mutating func appendLiteral(_ literal: String) {
        self.appendFragment(literal)
    }
    mutating func appendInterpolation(unsafe text: String) {
        self.appendText(text)
    }
    mutating func appendInterpolation(safe text: String) {
        self.appendFragment(text)
    }
}
extension InterpolableLanguage { // ExpressibleByStringInterpolation
    init(stringInterpolation: Self) {
        self.init()
        appendFragment(stringInterpolation.value)
    }
}
```

This is one of the beauties of Swift. Going from code that was specifically written for a type and generalising it to a lot of types thanks to protocol extensions. 

Now we can make our new `XML` type get all these features with a single line:

```swift
extension XML: InterpolableLanguage {}
```

And with only that line we get all the interpolation capabilities:

```swift
let xml: XML = "<b>\(unsafe: "danger & warnings")</b>"
xml.value // "<b>danger &amp; warnings</b>"
```

And thanks to the `safe` and `unsafe` overloads we can combine XML strings easily:

```swift
let startP = "<p>"
let endP = "</p>"
let final: XML = """
\(safe: startP)
\(unsafe: "danger & warnings")
\(safe: endP)
"""
```

We can even use Swift multiline strings with it!

## Conclusion

In this post we've seen how Swift makes it easy to get a powerful feature implemented for a specific type and generalise it to many more. 

Now we can create safe string languages easily and without much effort. 

In the [next article](/blog/safe-string-example-safe-xml-and-url-part-4/) we will reimplement the original example from years ago with this new and updated system.</p></blockquote>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/making-String-problem-safe-interpolation-part-2</guid><title>Making String safe with interpolation</title><description></description><link>https://alejandromp.com/blog/making-String-problem-safe-interpolation-part-2</link><pubDate>Sun, 24 Mar 2019 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>In the <a href="https://alejandromp.com/blog/solving-the-string-problem-with-swift-5-interpolation-part-1/">previous article</a> we made a <em>safe string</em> type that was safe to use but with a cumbersome API. In this part we will use new Swift 5 interpolation system to make it really nice to use.</p><h2 id="swift-5-interpolation">Swift 5 interpolation</h2><p>The goal is to provide a way to use nice string literals but keeping the safety of having custom types for <em>safe strings</em>, allowing us to combine safe and unsafe strings with ease.</p><p>Up until now there was no nice solution in Swift as the interpolation system was quite limited and discarded any types. But Swift 5 revamps the interpolation system giving us a chance to keep the type safety that we love from the language. This opens a bast array of possibilities for designing new APIs in Swift.</p><p>The new system introduces a protocol <code>StringInterpolationProtocol</code> that allows us to define a type that will gather the information during the interpolation. Later in the process this intermediate type is given to the final type that implements <code>ExpressibleByStringInterpolation</code>.</p><p>It's a nice design because is not far from what we had before, the difference is that before string interpolation methods just got Strings so we lost any type information. Now we can keep the type information thanks to specific method overloads for different types.</p><p>But if you check the <a href="https://developer.apple.com/documentation/swift/stringinterpolationprotocol#topics">protocol</a> expecting to find those methods you will be surprised:</p><pre><code><span class="splash-keyword">public protocol</span> StringInterpolationProtocol {
    <span class="splash-keyword">init</span>(literalCapacity: <span class="splash-type">Int</span>, interpolationCount: <span class="splash-type">Int</span>)
    <span class="splash-keyword">mutating func</span> appendLiteral(<span class="splash-keyword">_</span> literal: <span class="splash-type">Self</span>.<span class="splash-type">StringLiteralType</span>)
}
</code></pre><p>It only has 2 methods! Where are all those methods that will help us keep the type information?</p><p>Well, the trick here is that the protocol has <em>informal</em> requirements. We can write methods with the form</p><pre><code><span class="splash-keyword">mutating func</span> appendInterpolation(label: <span class="splash-type">Type</span>)
</code></pre><p>and the compiler will recognise them and use them as appropriate with the default overloading system. Furthermore it will offer the <code>label</code> to the string interpolation system.</p><blockquote><p>This compiler magic serves as a workaround for a limitation of the language in this kind of designs. There is no way to define a protocol with this flexibility. A similar issue was found with the Dynamic Member Lookup feature.</p></blockquote><p>This little compiler magic allows us to be able to write as many special <code>appendInterpolation</code> methods as we want, with different labels and types, and thus offer a nice API for interpolation.</p><h2 id="conforming-to-stringinterpolationprotocol">Conforming to StringInterpolationProtocol</h2><p>We can extend our type to conform to <code>StringInterpolationProtocol</code>:</p><pre><code><span class="splash-keyword">extension</span> <span class="splash-type">SafeURL</span>: <span class="splash-type">StringInterpolationProtocol</span> {
</code></pre><blockquote><p>There are many ways of implementing this interpolation system. Usually you can have an intermediate type (conforming to StringInterpolationProtocol) that gathers the information and the final type that uses it (conforming to ExpressibleByStringInterpolation). I'm just gonna use the same type for both, just for the simplicity of the example. Furthermore it will make it easier to implement because the API of the Language protocol already matches quite well the StringInterpolation API.</p></blockquote><p>The first method we need to implement is the initializer.</p><pre><code>     <span class="splash-keyword">init</span>(literalCapacity: <span class="splash-type">Int</span>, interpolationCount: <span class="splash-type">Int</span>) {
        <span class="splash-keyword">self</span>.<span class="splash-keyword">init</span>()
    }
</code></pre><p>This initializer gives a chance to the conforming type to preallocate the memory needed. It's a nice way of improving performance although usually you don't have all the information needed to allocate exactly the amount of memory you need.</p><p>For example if we wanted to create a string literal with <code>"https://example.com/\("this should be escaped")"</code> in the initialiser we would receive a literal capacity of 19 and an interpolation count of 1. The literal capacity is fine but we still have no clue of how much data we will need for the interpolation. In any case is a nice design that can help improve the performance of string code.</p><pre><code>     <span class="splash-keyword">mutating func</span> appendLiteral(<span class="splash-keyword">_</span> literal: <span class="splash-type">String</span>) 		 {
        <span class="splash-keyword">self</span>.<span class="splash-call">appendFragment</span>(literal)
    }
</code></pre><p>This method is called for each literal String segment. Just as before we get these literal segments as String, but the nice thing now is that this method will only be called for the segments that are Strings. We can add other methods for specific types or labels! No more lost of types at runtime.</p><p>Because of this we can assume the literals to be safe. If the developer is using interpolation it will be able to use other labels to specify unsafe code, so we can make the default case nicer to use.</p><p>Now is time to use the power of the new system. Let's add a couple of <code>appendInterpolation</code> method overloads to accommodate for different situations.</p><pre><code>     <span class="splash-keyword">mutating func</span> appendInterpolation(unsafe text: <span class="splash-type">String</span>) {
        <span class="splash-keyword">self</span>.<span class="splash-call">appendText</span>(text)
    }
</code></pre><p>This method will allow us to support the interpolation of unsafe strings. As mentioned before, this is not part of the formal protocol, but the compiler knows about it.</p><p>In our case we offer a label <code>unsafe</code> and the type <code>String</code>. This will be used on the interpolation syntax and overload resolution.</p><p>Thanks to <code>appendLiteral</code> we have a way of adding safe segments, but that only works when the String is a literal. If we want to support adding a String at runtime that we know is safe we can add a new overload. Of course this is a little more dangerous, but the nice thing is that because we're using a label it's harder to happen by mistake.</p><pre><code>     <span class="splash-keyword">mutating func</span> appendInterpolation(safe text: <span class="splash-type">String</span>) {
        <span class="splash-keyword">self</span>.<span class="splash-call">appendFragment</span>(text)
    }
</code></pre><h2 id="conforming-to-expressiblebystringinterpolation">Conforming to ExpressibleByStringInterpolation</h2><p>Finally we need to conform to <code>ExpressibleByStringInterpolation</code> and make its <code>StringInterpolation</code> associated type be of the type we made conform to <code>StringInterpolationProtocol</code>.</p><blockquote><p>As I said above, I'm using the same type for both protocols. But if you have another type, you will use the associated type to tell the system which type to use.</p></blockquote><p>In our case we just need to extract the value and treat it as a safe fragment.</p><pre><code><span class="splash-keyword">extension</span> <span class="splash-type">SafeURL</span>: <span class="splash-type">ExpressibleByStringInterpolation</span> {
    <span class="splash-keyword">init</span>(stringInterpolation: <span class="splash-type">SafeURL</span>) {
        <span class="splash-keyword">self</span>.<span class="splash-keyword">init</span>()
        <span class="splash-call">appendFragment</span>(stringInterpolation.<span class="splash-property">value</span>)
    }
}
</code></pre><h2 id="enjoy">Enjoy</h2><p>With this now we can rewrite the examples of the previous post with a nicer syntax and being safe and correct:</p><pre><code><span class="splash-keyword">let</span> url: <span class="splash-type">SafeURL</span> = <span class="splash-string">"https://example.com/</span>\(unsafe:"this should be escaped")<span class="splash-string">"</span>
url.<span class="splash-property">value</span> <span class="splash-comment">// https://example.com/this%20should%20be%20escaped</span>
</code></pre><p>And to demonstrate some safety. If we had those literals as strings instead, we wouldn't be able to use interpolation because it would be unsafe:</p><pre><code><span class="splash-keyword">let</span> base = <span class="splash-string">"https://example.com"</span>
<span class="splash-keyword">let</span> path = <span class="splash-string">"this should be escaped"</span>
<span class="splash-keyword">let</span> url: <span class="splash-type">SafeURL</span> = <span class="splash-string">"</span>\(base)<span class="splash-string">/</span>\(unsafe:path)<span class="splash-string">"</span>
<span class="splash-comment">// error: argument labels '(_:)' do not match any available overloads</span>
</code></pre><p>The compiler complains that the first interpolation doesn't match any overload. And that is correct because there is no label! Without a label we can only interpolate string literals.</p><p>But in this case we know that is safe to do, so we can use the other overload we added:</p><pre><code><span class="splash-keyword">let</span> url: <span class="splash-type">SafeURL</span> = <span class="splash-string">"</span>\(safe:base)<span class="splash-string">/</span>\(unsafe:path)<span class="splash-string">"</span>
url.<span class="splash-property">value</span> <span class="splash-comment">// https://example.com/this%20should%20be%20escaped</span>
</code></pre><p>And this compiles and works as expected. Safe and nice. 👍🏻</p><h2 id="what's-the-compiler-doing?">What's the compiler doing?</h2><p>If you add some print statements on every method it is really easy to see how the compiler transforms the interpolated string into a series of calls to our methods.</p><p>The example</p><pre><code><span class="splash-keyword">let</span> url: <span class="splash-type">SafeURL</span> = <span class="splash-string">"</span>\(safe:base)<span class="splash-string">/</span>\(unsafe:path)<span class="splash-string">"</span>
</code></pre><p>is transformed into</p><pre><code><span class="splash-type">StringInterpolationProtocol</span>.<span class="splash-keyword">init</span>(literalCapacity: <span class="splash-number">1</span>, interpolationCount: <span class="splash-number">2</span>)
appendLiteral: <span class="splash-string">""</span>
<span class="splash-call">appendInterpolation</span>(safe: <span class="splash-string">"https://example.com"</span>)
appendLiteral: <span class="splash-string">"/"</span>
<span class="splash-call">appendInterpolation</span>(unsafe: <span class="splash-string">"this should be escaped"</span>)
appendLiteral: <span class="splash-string">""</span>
<span class="splash-type">ExpressibleByStringInterpolation</span>.<span class="splash-keyword">init</span>(stringInterpolation: <span class="splash-type">SafeURL</span>(name: <span class="splash-string">"URL"</span>, url: <span class="splash-string">"https://example.com/this%20should%20be%20escaped"</span>))
</code></pre><h2 id="generalising-the-conformance">Generalising the conformance</h2><p>Now that we have a nice <em>safe string</em> type using the Swift 5 string interpolation we can see how nice the API can be.</p><p>But right now we would have to rewrite a bunch of code if we wanted to make more <em>safe string</em> types.</p><p>On the <a href="https://alejandromp.com/blog/generalising-swift-string-interpolation-part-3/">next post</a> of the series we will do some changes do make that way easier.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/solving-the-string-problem-with-swift-5-interpolation-part-1</guid><title>Solving the String problem with Swift 5</title><description></description><link>https://alejandromp.com/blog/solving-the-string-problem-with-swift-5-interpolation-part-1</link><pubDate>Sun, 17 Mar 2019 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>The String problem is something that I've explored before, in my 2015 post <a href="https://alejandromp.com/blog/solving-the-strings-problem-in-swift/">Solving the Strings Problem in Swift</a>. The solution back then was far from ideal as Swift was missing a powerful String interpolation system.</p><p>Swift 5 has revamped the Strings and it's time to take another look at the same problem. I'm not gonna follow the exact same steps as I did before, instead I'm gonna try to make a more Swifty solution.</p><h2 id="the-problem">The problem</h2><p>Let's quickly recap what <a href="https://blog.moertel.com/posts/2006-10-18-a-type-based-solution-to-the-strings-problem.html">the problem</a> is.</p><p>The String type is a type that can represent absolutely everything. It's usage to display text is justified, but programmers are used to reach to it for every single problem. Things like URLs, paths, email, XML, etc… all should have their own types.</p><p>The issue with relying so much in Strings is that we lose all type safety. The compiler won't stop you from passing a string representing a email to a function that expects that string to be a URL.</p><p>A general solution for this problem accepts that strings have different meaning and so they should be represented with their own types.</p><p>A nice solution needs to be easy to adopt and safe. The safety will come from the type system but making nice to use it's also important.</p><h2 id="define-a-language">Define a Language</h2><p>Let's start by defining a <code>Language</code> protocol. The different kinds of string will conform to it.</p><pre><code><span class="splash-keyword">protocol</span> Language {
    <span class="splash-comment">/// The name of the language</span>
    <span class="splash-keyword">var</span> name: <span class="splash-type">String</span> { <span class="splash-keyword">get</span> }
    
    <span class="splash-comment">/// Get the underlaying well constructed String</span>
    <span class="splash-keyword">var</span> value: <span class="splash-type">String</span> { <span class="splash-keyword">get</span> }
    
    <span class="splash-comment">/// Appends a fragment of the language, safe</span>
    <span class="splash-keyword">mutating func</span> appendFragment(<span class="splash-keyword">_</span> fragment: <span class="splash-type">String</span>)
    
    <span class="splash-comment">/// Appends an arbitrary string, unsafe</span>
    <span class="splash-keyword">mutating func</span> appendText(<span class="splash-keyword">_</span> text: <span class="splash-type">String</span>)
}
</code></pre><p>The protocol defines four things that any <em>safe string type</em> will need.</p><p>The name of the language: this is really not needed and mainly added here for debugging purposes. In a more dynamic environment one could imagine having to take decisions based on this, but I haven't found a reason for it. We can always add a default implementation using the name of the type so it's not a huge burden.</p><p>We will need a way to <strong>extract a String</strong> from a language instance. In our program we will use the specific type as much as we can to keep the type safety, but at some point that <em>safe string</em> will have to be displayed on the screen or sent to another system. Only at that point is when we will escape the safety of our types.</p><p>The last two methods are what makes the type flexible but safe. We define a <em>fragment</em> as a correct and safe string, already in the specific language of the type. But we also allow to add unsafe text, an arbitrary string, that the type will have to make sure is processed to conform to the specifications of the language.</p><h2 id="a-safe-url-as-an-example">A safe URL as an example</h2><p>Let's start by defining a <code>SafeURL</code> type. Its purpose would be to keep the URL safe and properly escaped.</p><p>Conforming the type to the protocol is easy:</p><pre><code><span class="splash-keyword">struct</span> SafeURL: <span class="splash-type">Language</span> {
  <span class="splash-keyword">var</span> url: <span class="splash-type">String</span>
  ...
  <span class="splash-keyword">mutating func</span> appendFragment(<span class="splash-keyword">_</span> fragment: <span class="splash-type">String</span>) {
      url.<span class="splash-call">append</span>(fragment)
  }

  <span class="splash-keyword">mutating func</span> appendText(<span class="splash-keyword">_</span> text: <span class="splash-type">String</span>) {
      url.<span class="splash-call">append</span>(<span class="splash-call">urlEncoded</span>(string: text))
  }
}
</code></pre><p>As you can see the interesting part is the <code>appendText</code> function. It's where the type needs to make sure the incoming string is processed properly. In this case it needs to make sure is encoded with the proper characters for a URL. For example a space should become a <code>%20</code>.</p><h2 id="basic-usage">Basic usage</h2><p>Now that we have our first <code>Langauge</code> type <code>SafeURL</code> we can start using it to create a URL from unsafe strings.</p><pre><code><span class="splash-keyword">var</span> url = <span class="splash-type">SafeURL</span>()
url.<span class="splash-call">appendFragment</span>(<span class="splash-string">"https://example.com/"</span>)
url.<span class="splash-call">appendText</span>(<span class="splash-string">"this should be escaped"</span>)
url.<span class="splash-property">value</span> <span class="splash-comment">// https://example.com/this%20should%20be%20escaped</span>
</code></pre><p>The fragments are treated as safe an untouched, but the arbitrary text is correctly escaped to not break the URL.</p><p>Now the type system protects us from using this as a String. We can't add a string directly with the String API:</p><pre><code>url.<span class="splash-call">appending</span>(<span class="splash-string">"wrong!"</span>)
<span class="splash-comment">// Value of type 'SafeURL' has no member 'appending'; did you mean 'appendText'?</span>
</code></pre><p>And we can't pass it to a function that expects a String.</p><pre><code><span class="splash-call">expectString</span>(url)
<span class="splash-comment">// Cannot convert value of type 'SafeURL' to expected argument type 'String'</span>
</code></pre><h2 id="expressiblebystringliteral">ExpressibleByStringLiteral</h2><p>Now we have a safer type but using it is more cumbersome than using a String. Let's try to fix that.</p><p>First we can make the type conform to <code>ExpressibleByStringLiteral</code> so we can initialise it with a literal.</p><pre><code><span class="splash-keyword">extension</span> <span class="splash-type">SafeURL</span>: <span class="splash-type">ExpressibleByStringLiteral</span> {
    <span class="splash-keyword">init</span>(stringLiteral value: <span class="splash-type">String</span>) {
        <span class="splash-keyword">self</span>.<span class="splash-keyword">init</span>()
        <span class="splash-keyword">self</span>.<span class="splash-call">appendText</span>(value)
    }
}
</code></pre><p>This is an important part of the system to get right. We need to make sure that we're treating this string literal as unsafe.</p><p>This initialiser is used in different scenarios. The most obvious one is when declaring a variable of the type:</p><pre><code><span class="splash-keyword">let</span> url: <span class="splash-type">SafeURL</span> = <span class="splash-string">""</span>
</code></pre><p>In this we could argue that the developer is writing the literal string so it should make sure is properly escaped.</p><p>But the problem is that with our type conforming to this protocol now we lost some safety because now Swift will automatically convert a string to our type when passing it as an argument to functions. And in those scenarios asking a developer to take care of it is not that nice anymore.</p><pre><code><span class="splash-call">expectSafeURL</span>(<span class="splash-string">"https://example.com/this should be escaped"</span>)
</code></pre><p>Now we can create a <code>SafeURL</code> from a string literal but the issue is that it will always escape it even if we've already done it ourselves.</p><pre><code><span class="splash-keyword">let</span> url: <span class="splash-type">SafeURL</span> = <span class="splash-string">"https://example.com/this%20should%20be%20escaped"</span>
url.<span class="splash-property">value</span> <span class="splash-comment">// "http%3A%2F%2Fexample.com%2Fthis%2520should%2520be%2520escaped</span>
</code></pre><p>We should provide the developer a way to create our type directly with an already safe string. We can easily do that with an initialiser in an extension.</p><pre><code><span class="splash-keyword">extension</span> <span class="splash-type">SafeURL</span> {
    <span class="splash-keyword">init</span>(safe: <span class="splash-type">String</span>) {
        <span class="splash-keyword">self</span>.<span class="splash-keyword">init</span>()
        <span class="splash-keyword">self</span>.<span class="splash-call">appendFragment</span>(safe)
    }
}

<span class="splash-keyword">let</span> url = <span class="splash-type">SafeURL</span>(safe: <span class="splash-string">"https://example.com/this%20should%20be%20escaped"</span>)
url.<span class="splash-property">value</span> <span class="splash-comment">// https://example.com/this%20should%20be%20escaped</span>
</code></pre><p>Now we can create our type from string literals that keeps it safe by default but we also have a way to skip the escaping if we know the string is already correct.</p><h2 id="improving-the-api">Improving the API</h2><p>This is nice but we haven't improved much the situation since the solution on 2015. We still need to escape the characters ourselves if we want to use nice APIs, something that will rarely happen.</p><p>Check the <a href="https://alejandromp.com/blog/making-String-problem-safe-interpolation-part-2/">next article</a> on this series to see how Swift 5 new String interpolation system will help us.</p>]]></content:encoded></item><item><guid isPermaLink="true">https://alejandromp.com/blog/swift-collections-prefix-for-quick-tests</guid><title>Swift Collection's prefix for quick tests</title><description></description><link>https://alejandromp.com/blog/swift-collections-prefix-for-quick-tests</link><pubDate>Sat, 16 Mar 2019 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>This is a small trick that I use when I'm writing a script in Swift that performs some operation in a large number of objects, usually files. More often than not this operation is somehow destructive and ends up overwriting the original file, so I want to make sure that I got the changes right before applying it to the entire set of data.</p><p>Usually this means that I just want to stop a loop on its first iteration.</p><p>There are many ways of doing this, probably the most common one you can think of is using a <code>break</code> if you're using a <code>for in</code> :</p><pre><code><span class="splash-keyword">for</span> file <span class="splash-keyword">in</span> files {
    ....
    <span class="splash-keyword">break</span>
}
</code></pre><p>Another way is by just getting the first element of the array an applying the operation to it manually, but this means commenting some code, which is too invasive for my taste:</p><pre><code><span class="splash-comment">//for file in files {</span>
    <span class="splash-keyword">let</span> file = files[<span class="splash-number">0</span>]
    ....
<span class="splash-comment">//}</span>
</code></pre><p>For me the best way is by using Swift Collection's <a href="https://developer.apple.com/documentation/swift/collection/1641714-prefix">prefix</a> operations, in this case by getting a prefix of 1.</p><pre><code><span class="splash-keyword">for</span> file <span class="splash-keyword">in</span> files.<span class="splash-call">prefix</span>(<span class="splash-number">1</span>) {
    ....
}
</code></pre><p>The advantage of this technique is that the change is located on the loop itself and that the body, the meat of the operation, is not affected by it. Is the less invasive technique that I've found and it allows me to quickly debug a change with a single file without affecting the entire set.</p><p>Another advantage of using <code>prefix</code> as opposed to <code>break</code> is that it works with <code>forEach</code>, which I tend to use very often.</p><pre><code>files.<span class="splash-call">prefix</span>(<span class="splash-number">1</span>).<span class="splash-call">forEach</span> { file <span class="splash-keyword">in</span>
    ...
}
</code></pre><p>That's it! I quick tip for your Swift scripts ^^</p>]]></content:encoded></item></channel></rss>