<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Get Swifty]]></title><description><![CDATA[A Swift Development Blog]]></description><link>https://getswifty.dev/</link><image><url>https://getswifty.dev/favicon.png</url><title>Get Swifty</title><link>https://getswifty.dev/</link></image><generator>Ghost 4.1</generator><lastBuildDate>Sun, 05 Apr 2026 20:33:07 GMT</lastBuildDate><atom:link href="https://getswifty.dev/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[How to dismiss keyboard on a multi-line TextField in SwiftUI]]></title><description><![CDATA[<p>Another situation where SwiftUI falls short. <br><br>When using the TextField initialiser containing the <code>axis</code> paremeter, you no longer get access to <code>onSubmit</code> but because SwiftUI is sooooo gooood at giving you warnings when you&apos;ve implemented something incorrectly, it&apos;s easy to assume all is well.<br><br>Sorry, but</p>]]></description><link>https://getswifty.dev/how-to-dismiss-keyboard-on-a-multi-line-textfield-in-swiftui/</link><guid isPermaLink="false">63ba856670c4530901548ee7</guid><dc:creator><![CDATA[Beau Nouvelle]]></dc:creator><pubDate>Sun, 08 Jan 2023 09:02:45 GMT</pubDate><content:encoded><![CDATA[<p>Another situation where SwiftUI falls short. <br><br>When using the TextField initialiser containing the <code>axis</code> paremeter, you no longer get access to <code>onSubmit</code> but because SwiftUI is sooooo gooood at giving you warnings when you&apos;ve implemented something incorrectly, it&apos;s easy to assume all is well.<br><br>Sorry, but it&apos;s not. Here&apos;s the solution and it&apos;s stupid.</p><!--kg-card-begin: markdown--><pre><code class="language-language-swift">@FocusState private var campaignTitleIsFocussed: Bool

TextField(&quot;New Campaign&quot;, text: $campaign.name, axis: .vertical)
    .focused($campaignTitleIsFocussed)
    .onChange(of: campaign.name) { newValue in
        guard let newValueLastChar = newValue.last else { return }
        if newValueLastChar == &quot;\n&quot; {
            campaign.name.removeLast()
            campaignTitleIsFocussed = false
        }
    }
</code></pre>
<!--kg-card-end: markdown--><p>How does it work?<br><br>Well, any time a new character is typed, we check to see if its a newline &#x2014; user has tapped the &quot;return&quot; key. This appends a <code>\n</code> to the end of the string. We then remove this newline, and set the focus for that TextField to false. <br><br>Easy Peasy.</p>]]></content:encoded></item><item><title><![CDATA[What is the best text editor for opening large files?]]></title><description><![CDATA[<p>A highly specific question, and unlike asking &quot;what&apos;s the best text editor for programmers?&quot;, this one we can answer with almost 100% objectivity.<br><br>If you would rather watch a video on this subject, I&apos;ve got that covered for you</p><figure class="kg-card kg-embed-card"><iframe width="356" height="200" src="https://www.youtube.com/embed/ZZ6I4xG3fu4?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><p><br>To do this, we&apos;</p>]]></description><link>https://getswifty.dev/what-is-the-best-text-editor-for-opening-large-files/</link><guid isPermaLink="false">5fd95667a6a4bb5eaf643b3a</guid><dc:creator><![CDATA[Beau Nouvelle]]></dc:creator><pubDate>Wed, 16 Dec 2020 01:30:58 GMT</pubDate><content:encoded><![CDATA[<p>A highly specific question, and unlike asking &quot;what&apos;s the best text editor for programmers?&quot;, this one we can answer with almost 100% objectivity.<br><br>If you would rather watch a video on this subject, I&apos;ve got that covered for you</p><figure class="kg-card kg-embed-card"><iframe width="356" height="200" src="https://www.youtube.com/embed/ZZ6I4xG3fu4?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><p><br>To do this, we&apos;ll need to do some stress testing, so let&apos;s meet our competitiors.<br></p><hr><figure class="kg-card kg-image-card"><img src="https://getswifty.dev/content/images/2020/12/index-teletype-screenshot-1de356892e9bab0f5a1e95b4a003dfecaab0d9e67a91fd60b63006a32f147db0.png" class="kg-image" alt loading="lazy" width="1560" height="976" srcset="https://getswifty.dev/content/images/size/w600/2020/12/index-teletype-screenshot-1de356892e9bab0f5a1e95b4a003dfecaab0d9e67a91fd60b63006a32f147db0.png 600w, https://getswifty.dev/content/images/size/w1000/2020/12/index-teletype-screenshot-1de356892e9bab0f5a1e95b4a003dfecaab0d9e67a91fd60b63006a32f147db0.png 1000w, https://getswifty.dev/content/images/2020/12/index-teletype-screenshot-1de356892e9bab0f5a1e95b4a003dfecaab0d9e67a91fd60b63006a32f147db0.png 1560w" sizes="(min-width: 720px) 720px"></figure><h3 id="atom">Atom</h3><p>It calls itself<em> &quot;A hackable text editor for the 21st century&quot;</em>. Up until recently, this was my text editor of choice. Free and open source. It&apos;s only downside? Electron. It&apos;s not as light weight as I like in a text editor. These things should be speedy, with just enough features to get the job done. If I wanted something bloated, I would just use Xcode. </p><p>Now I&apos;m not saying Atom is bloated. Absolutely not. In fact most of the text editors on this list are perfectly fine. It&apos;s just that, because Electron, you&apos;ve already used up about 300mb of ram for just launching the app in an empty state. With no files loaded.<br><br></p><figure class="kg-card kg-image-card"><img src="https://getswifty.dev/content/images/2020/12/screenshot-main.png" class="kg-image" alt loading="lazy" width="578" height="372"></figure><h3 id="bbedit">BBEdit</h3><p>This is a popular choice for a lot of people and has been around for a very long time (like since the early 90s?). It&apos;s THE standard for which all editors should be compared. <br><br>Written in C, so it&apos;s a native app, and super light weight.</p><p>It&apos;s not free though, but very well priced. I also don&apos;t own this app myself so I used the trial version for my tests.</p><p></p><figure class="kg-card kg-image-card"><img src="https://getswifty.dev/content/images/2020/12/linux@2x.png" class="kg-image" alt loading="lazy" width="2000" height="1007" srcset="https://getswifty.dev/content/images/size/w600/2020/12/linux@2x.png 600w, https://getswifty.dev/content/images/size/w1000/2020/12/linux@2x.png 1000w, https://getswifty.dev/content/images/size/w1600/2020/12/linux@2x.png 1600w, https://getswifty.dev/content/images/2020/12/linux@2x.png 2400w" sizes="(min-width: 720px) 720px"></figure><h3 id="sublime-text">Sublime Text</h3><p>I have used this app for many years. This was my number 1 text editor for a long time, and I&apos;m sure that&apos;s the same for many other developers out there.</p><p></p><figure class="kg-card kg-image-card"><img src="https://getswifty.dev/content/images/2020/12/3.png" class="kg-image" alt loading="lazy" width="2000" height="1463" srcset="https://getswifty.dev/content/images/size/w600/2020/12/3.png 600w, https://getswifty.dev/content/images/size/w1000/2020/12/3.png 1000w, https://getswifty.dev/content/images/size/w1600/2020/12/3.png 1600w, https://getswifty.dev/content/images/2020/12/3.png 2384w" sizes="(min-width: 720px) 720px"></figure><h3 id="nova">Nova</h3><p>This is a fairly new text editor released by the same people who created Coda. Coda has been around for a long time, and was a great little editor you could use on iOS, mostly focussing on web development.<br><br>I&apos;ve been using nova for a little while now and not entirely sure how I feel about it. It has replaced Sublime Text and Atom for most tasks, but I&apos;m still working things out, and settling into a workflow that works for me.</p><p>Plus, it just looks really cool, if not a little distracting.</p><p></p><h3 id="macvim">MacVim</h3><p>Honestly? I&apos;ve never used it since before writing this article. Vim isn&apos;t something that is ever even mentioned in iOS development. All we really need a text editor for is opening a few config, script, or JSON files and that&apos;s about it.<br><br>Vim has been around for a very long time (similar age to BBEdit?). But, this app was very performant, and I can certainly see the appeal, but it&apos;s just not for me.<br></p><h3 id="xcode"><br>Xcode</h3><p>We all know Xcode. I&apos;m not even going to bother with a screenshot here. This thing is a bloated mess. If you already have it open, and the text file you&apos;re editing is part of your project, then go for it.<br><br>However, for any smaller quick tasks, you could probably finish the job in any other editor before Xcode even opens.</p><h2></h2><figure class="kg-card kg-image-card"><img src="https://getswifty.dev/content/images/2020/12/26d8ac93e2a4c38c0140bda00372c740.png" class="kg-image" alt loading="lazy" width="931" height="508" srcset="https://getswifty.dev/content/images/size/w600/2020/12/26d8ac93e2a4c38c0140bda00372c740.png 600w, https://getswifty.dev/content/images/2020/12/26d8ac93e2a4c38c0140bda00372c740.png 931w" sizes="(min-width: 720px) 720px"></figure><h3 id="textedit">TextEdit</h3><p>Built into macOS this editor is just plain fine. It works. No syntax highlighting, or code completion. No addons. Just plain and simple.<br><br>I&apos;ve known a lot of web developers who use this, day to day, and nothing else. How? I have no idea.<br></p><figure class="kg-card kg-image-card"><img src="https://getswifty.dev/content/images/2020/12/hex_icon.png" class="kg-image" alt loading="lazy" width="190" height="215"></figure><h3 id="hex-fiend">Hex Fiend</h3><p>This app will open anything. Instantly. Full stop. Is this the best for opening large files?</p><p>Maybe.</p><h2 id="results">Results</h2><p>I know you skipped past everything just to get to this point, and that&apos;s okay. I would have done that too, and honestly, you didn&apos;t miss much.<br><br>What you will need to know though is that I ran these tests on a 2018 Mac mini, 3.2 Intel Core i7, with 32GB of RAM and an external RX 580 GPU. So take the times and usability with a big grain of salt. This is by no means scientific, and you computer may have a better time with this than mine.</p><p>This is the script I used to generate the 10GB file I used for testing. (Thanks to Bare Bones Software for helping me out on this). It came out to around 11GB in total. Line breaks every 100 characters, and ASCII text only.</p><!--kg-card-begin: markdown--><pre><code>export LC_ALL=C; dd if=/dev/urandom bs=1000000000 count=30 | tr -dc &apos;A-Za-z0-9!&quot;#$%&amp;&apos;\&apos;&apos;()*+,-./:;&lt;=&gt;?@[\]^_`{|}~&apos; | fold -s -w 100 &gt; ~/Desktop/10GB_text.txt
</code></pre>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><p>|  App | Can Open  | Time  | Usable  |<br>
|---|---|---|---|---|<br>
|  Atom |  &#x274C; | failed at 2min 48sec  | N/A  |<br>
|  BBEdit | &#x2705;  | 9min 52sec  | &#x274C;  |<br>
|  Sublime Text | &#x274C;  | 1hr 13min 24sec  | N/A  |<br>
|  Nova | &#x2705;  | 10min 18sec  | &#x274C;  |<br>
|  MacVim | &#x2705;  | 33sec  | &#x274C;  |<br>
|  Xcode | &#x2705;  | 17min 57sec  | &#x274C;  |<br>
|  TextEdit | &#x274C;  | N/A  |  &#x274C;  |<br>
|  Hex Fiend | &#x2705;  | Too fast to count  |  &#x2705; |</p>
<!--kg-card-end: markdown--><p>I... don&apos;t really have anything else to say about it. The results speak for themselves.<br>Is this useful? Maybe to someone out there. </p><p>What do <em>I </em>think?<br><br>The need for opening large files like this is rare. It&apos;s more likely you&apos;ll want to open a 1GB log file than a 10GB one. In those cases, speed does matter, and what I&apos;d love to see is a compatibility mode built in to most text editors that will open up these larger files in the same way as Hex Fiend, without syntax highlighting or parsing.<br><br>Keep using your favorite editor, but install Hex Fiend as a nice little backup for those tricky files, even corrupt ones!</p>]]></content:encoded></item><item><title><![CDATA[iOS - Programatic UI Development in Xcode 11]]></title><description><![CDATA[<p>When you start a new project, Xcode 11 gives you two options on how you&apos;d like to handle the development of your UI. SwiftUI or Storboards. Those are your only options when using Xcodes built in templates. Many more devs these days are preferring to go with a</p>]]></description><link>https://getswifty.dev/programatic-ui-development-in-xcode-11/</link><guid isPermaLink="false">5e7d422256710029c43fec74</guid><category><![CDATA[Swift]]></category><category><![CDATA[iOS]]></category><category><![CDATA[UIKit]]></category><category><![CDATA[Getting Started]]></category><dc:creator><![CDATA[Beau Nouvelle]]></dc:creator><pubDate>Fri, 27 Mar 2020 04:01:30 GMT</pubDate><content:encoded><![CDATA[<p>When you start a new project, Xcode 11 gives you two options on how you&apos;d like to handle the development of your UI. SwiftUI or Storboards. Those are your only options when using Xcodes built in templates. Many more devs these days are preferring to go with a programatic approach, bypassing WYSIWYG editors altogether. </p><p>True, SwiftUI is all done in code and includes a neat way to preview your layouts, but I feel that it&apos;s not quite ready for primetime just yet. So what can we do?<br><br>Unfortuneately Xcode no longer allows you to setup a project without either of these options. If we want to go full programatic, handle segues, animations and wrestle with autolayout manually, we&apos;ll have to choose an option and modify it to our use case.<br><br>I&apos;ll run through getting setup with a new project, modifying it for programatic UI development, show you how to arrange a few views and navigate to other controllers.</p><h3 id="new-project">New Project</h3><!--kg-card-begin: markdown--><p><em>You can skip the next two sections by downloading this <a href="https://github.com/verebes1/XCode-Templates">Xcode template</a> that will handle all of this for you</em>.</p>
<!--kg-card-end: markdown--><p>1. We&apos;ll get started by creating a new iOS project using the single view template.</p><figure class="kg-card kg-image-card"><img src="https://getswifty.dev/content/images/2020/03/Screen-Shot-2020-03-27-at-11.14.40-am.jpg" class="kg-image" alt loading="lazy"></figure><p>2. In the next step create a name for your project and make sure that you have the Storyboard option selected in the dropdown. Don&apos;t worry, we&apos;ll be deleting it anyway.</p><figure class="kg-card kg-image-card"><img src="https://getswifty.dev/content/images/2020/03/Screen-Shot-2020-03-27-at-12.35.23-pm.jpg" class="kg-image" alt loading="lazy"></figure><p>3. On the final, choose a save location, and for this guide we won&apos;t worry about setting up git, so you can uncheck that box.<br></p><h3 id="your-project">Your Project</h3><p>1. Next you&apos;ll be presented with the main Xcode interface, with the project settings displayed in the center of the window. On the left of the screen you should see the project navigator:</p><figure class="kg-card kg-image-card"><img src="https://getswifty.dev/content/images/2020/03/Screen-Shot-2020-03-27-at-1.49.42-pm.png" class="kg-image" alt loading="lazy"></figure><p>2. Delete <code>Main.storyboard</code> from within the project navigator.</p><p>3. In the project settings, delete the text inside Main Interface</p><figure class="kg-card kg-image-card"><img src="https://getswifty.dev/content/images/2020/03/Screen-Shot-2020-03-27-at-1.50.58-pm.png" class="kg-image" alt loading="lazy"></figure><p>4. Click on the Info tab, open up <code>Application Scene Manifest</code> row and find the line with <code>Storyboard Name</code>. Delete this row, and change <code>Enable Multiple Windows</code> value from <code>NO</code> to <code>YES</code>.</p><figure class="kg-card kg-image-card"><img src="https://getswifty.dev/content/images/2020/03/Screen-Shot-2020-03-27-at-2.16.35-pm.png" class="kg-image" alt loading="lazy"></figure><p>5. Open up <code>SceneDelegate.swift</code> and replace the code inside the <code>willConnectTo</code> function with the following:</p><pre><code class="language-swift">guard let windowScene = (scene as? UIWindowScene) else { return }

window = UIWindow(frame: UIScreen.main.bounds)
window?.windowScene = windowScene

let navC = UINavigationController(rootViewController: ViewController())
window?.rootViewController = navC
window?.makeKeyAndVisible()</code></pre><p>If you run your app now, you should see a black screen.</p><h3 id="layout-out-views">Layout Out Views</h3><p>1. Open up <code>ViewController.swift</code> and create a new <code>UIButton</code> at the top of the class.</p><pre><code class="language-swift">let button = UIButton()</code></pre><p>Notice how there&apos;s no <code>@IBOutlet</code> or a weak reference. <code>@IBOutlet</code> is what links the button to a storyboard or xib file. Usually with storyboards, it&apos;s the <em>view</em> that has a strong reference, which is why we give the view controller a weak one. Since this button has been created entirely within the view controller, we give it a strong reference. There&apos;s loads of articles out there explaining the differences between strong and weak references. Hit up google you&apos;d like to know more.<br><br>2. Inside the <code>viewDidLoad</code> function we&apos;ll add the button as a subview and setup a few constraints.</p><pre><code class="language-swift">override func viewDidLoad() {
    super.viewDidLoad()

    button.setTitle(&quot;Next View&quot;, for: .normal)
    view.addSubview(button)
    button.translatesAutoresizingMaskIntoConstraints = false

    button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
}</code></pre><p>In my own personal projects I use a library called SnapKit for doing the contraints. It produces code that&apos;s easier to read and less verbose. Another reason is that it handles the <code>isActive</code> states and <code>translatesAutoresizingMaskIntoConstraints</code> flag for me. This is good, because I always forget to set them, and find myself wondering why my layouts aren&apos;t working.</p><p>When doing your layouts in code, be sure to always add your subview to it&apos;s superview <em>before</em> settings up constraints. Otherwise your app will crash at runtime because the view won&apos;t have anything to constrain itself to.<br><br>Run your app and you&apos;ll see your button in the middle of the screen.</p><h3 id="navigation">Navigation</h3><p>1. Next we&apos;ll setup an action on the button so that we can load another view controller when the user taps it. Place this code just after the last constraint.</p><pre><code class="language-swift">button.addTarget(self, action: #selector(nextVC), for: .touchUpInside)
</code></pre><p>4. Now we have an error. Let&apos;s fix this by creating the <code>nextVC</code> function.</p><pre><code class="language-swift">@objc func nextVC() {
    let nextVC = UIViewController()
    navigationController?.pushViewController(nextVC, animated: true)
}</code></pre><p>This code creates a new view controller and pushes it onto the navigation controllers stack of view controllers. In this example we&apos;re just using a <code>UIViewController()</code> but you can replace that with any view controller subclass you like.</p><p>Notice how <code>navigationController</code> is an optional. This is a property on <code>ViewController</code>, if <code>ViewController</code> were to <em>not</em> be embedded withing a <code>UINavigationController</code>, this property would be nil and the push wouldn&apos;t work.<br><br>If you&apos;re not using navigation controllers, you can replace this line with the <code>present(animated:completion:)</code> which will popup the next view controller as a modal. The biggest benifit of using navigation controllers is that you don&apos;t have to worry about creating back buttons or title bars as this is all handled for you.</p><p>Launch your app and try it out!</p><h3 id="sharing-information">Sharing Information</h3><p>Great, we can now launch another controller, but let&apos;s customize before pushing it to the viewer.</p><p>1. We&apos;ll modify <code>nextVC()</code> to generate a random background color for our new view controllers view.</p><pre><code class="language-swift">@objc func nextVC() {
    let colors: [UIColor] = [.red, .blue, .yellow, .green, .white, .cyan, .orange]
    let randomColor = colors.randomElement()

    let nextVC = UIViewController()
    nextVC.view.backgroundColor = randomColor
    navigationController?.pushViewController(nextVC, animated: true)
}</code></pre><p>Launch the app again and tap on the Next View button...</p><p>Tap the back button and tap on the Next View button again... you should see a different color this time. Pretty cool huh?</p><p>That&apos;s it for this post. You can grab the code for this project from <a href="https://github.com/BeauNouvelle/CodeLayoutExample">my github here</a>.<br></p>]]></content:encoded></item><item><title><![CDATA[Unit Testing Network Calls in Swift: Dependency Injection]]></title><description><![CDATA[<p></p><p>Recently, I was having issues with performing tests over the closed network we have at work. While our development Macs have access to the internet, our CI box does not (don&#x2019;t ask me why).</p><p>Turns out there&#x2019;s a whole bunch of reasons for why you don&</p>]]></description><link>https://getswifty.dev/unit-testing-network-calls-in-swift-dependency-injection/</link><guid isPermaLink="false">5d85948e2f5fc40e4ddf953a</guid><category><![CDATA[Swift]]></category><category><![CDATA[Code]]></category><dc:creator><![CDATA[Beau Nouvelle]]></dc:creator><pubDate>Sat, 21 Sep 2019 03:11:36 GMT</pubDate><content:encoded><![CDATA[<p></p><p>Recently, I was having issues with performing tests over the closed network we have at work. While our development Macs have access to the internet, our CI box does not (don&#x2019;t ask me why).</p><p>Turns out there&#x2019;s a whole bunch of reasons for why you don&#x2019;t actually <em><em>want</em></em>your CI boxes running tests over a network anyway.</p><p>For starters, you shouldn&#x2019;t be testing someone else&#x2019;s code. Servers can go down, and APIs can change. Your backend devs should already have this covered in their own tests, and if they don&#x2019;t, then you have bigger problems.</p><p>What about when you <em><em>want</em></em> your network calls to fail? How do you do <em><em>that</em> </em>reliably? If your request returns mangled data, you&#x2019;ll need to make sure your app can handle it elegantly, rather than just straight up crashing.</p><h3 id="nsurlsession">NSURLSession</h3><p>The obvious place to start would be having a way for us to <em><em>fake</em></em> our network calls. Overriding a few functions in NSURLSession and NSURLSessionDataTask should just about do it.</p><p>This is a great little snippet that you can just copy/paste into any project. Throw it in the test bundle so you&#x2019;re not shipping it with the rest of your code.</p><pre><code class="language-swift">class MockSession: URLSession {
    
    var completionHandler: ((Data, URLResponse, Error) -&gt; Void)?
    static var mockResponse: (data: Data?, URLResponse: URLResponse?, error: Error?)

    override class var shared: URLSession {
        return MockSession()
    }
    
    override func dataTask(with request: URLRequest, completionHandler: @escaping (Data?, URLResponse?, Error?) -&gt; Void) -&gt; URLSessionDataTask {
        self.completionHandler = completionHandler
        return MockTask(response: MockSession.mockResponse, completionHandler: completionHandler)
    }
    
}</code></pre><pre><code class="language-swift">class MockTask: URLSessionDataTask {
    
    typealias Response = (data: Data?, URLResponse: URLResponse?, error: Error?)
    var mockResponse: Response
    let completionHandler: ((Data?, URLResponse?, Error?) -&gt; Void)?
    
    init(response: Response, completionHandler: ((Data?, URLResponse?, Error?) -&gt; Void)?) {
        self.mockResponse = response
        self.completionHandler = completionHandler
    }
    
    override func resume() {
        completionHandler!(mockResponse.data, mockResponse.URLResponse, mockResponse.error)
    }
}</code></pre><p>Admittedly it looks a little weird, but what we&#x2019;re essentially doing is overriding dataTaskWithRequest returning a <em><em>fake</em></em> task, where resume() is also overridden, which is what gives us back our <em><em>fake</em></em> response &#x2014; that we will create in the next step &#x2014; through the completion handler. Does that make sense?</p><p>Maybe an example of how to use it will help.</p><h3 id="unit-testing">Unit Testing</h3><p>So lets say we need to fetch a bunch of products, something we might want customers to buy through our app.</p><p>Products are added/removed all the time, so testing on real data would be an issue. Instead, we can create our own response and pass that into our mockResponse property on our MockSession &#x2014; NSURLSession subclass. This way we have a consistent local datasource to test that our objects are being created correctly.</p><pre><code class="language-swift">func testRetrieveProductsValidResponse() {
    // we have a locally stored product list in JSON format to test against.
    let testBundle = Bundle(forClass: type(of: self))
    let filepath = testBundle.pathForResource(&quot;products&quot;, ofType: &quot;txt&quot;)
    let data = Data(contentsOfFile: filepath!)
    let urlResponse = HTTPURLResponse(url: URL(string: &quot;https://anyurl.doesntmatter.com&quot;)!, statusCode: 200, httpVersion: nil, headerFields: nil)
    // setup our mock response with the above data and fake response.
    MockSession.mockResponse = (data, urlResponse: urlResponse, error: nil)
    let requestsClass = RequestManager()
    // All our network calls are in here.
    requestsClass.Session = MockSession.self
    // Replace NSURLSession with our own MockSession.
    // We still need to test as if it&apos;s asynchronous. Because well, it is.
    let expectation = XCTestExpectation(description: &quot;ready&quot;)
    // For this test, no need to pass in anything useful since it doesn&apos;t affect our mocked response.
    // This particular function fetches JSON, converts it to custom objects, and returns them.
    requestsClass.retrieveProducts(&quot;N/A&quot;, products: { (products) -&gt; () in
        XCTAssertTrue(products.count == 7)
        expectation.fulfill()
    }) { (error) -&gt; () in
        XCTAssertFalse(error == Errors.NetworkError, &quot;Its a network error&quot;)
        XCTAssertFalse(error == Errors.ParseError, &quot;Its a parsing error&quot;)
        XCTFail(&quot;Error not covered by previous asserts.&quot;)
        expectation.fulfill()
    }
    waitForExpectations(timeout: 3.0, handler: nil)
}</code></pre><p>Thats about it!</p>]]></content:encoded></item><item><title><![CDATA[Game of Life in Swift Playgrounds - Part 3]]></title><description><![CDATA[<p></p><p>If you haven&apos;t already, you&apos;ll want to check out <a href="https://getswifty.dev/game-of-life-in-swift-playgrounds-part-2/">part 2</a> before continuing with this chapter.</p><hr><h3 id="game-rules">Game Rules</h3><p>We now have cells populating the world, but they&#x2019;re currently frozen in time. They&#x2019;re born, but then nothing happens. We&#x2019;ll need a</p>]]></description><link>https://getswifty.dev/game-of-life-in-swift-playgrounds-part-3/</link><guid isPermaLink="false">5d84d71a2f5fc40e4ddf94f5</guid><category><![CDATA[playgrounds]]></category><category><![CDATA[Swift]]></category><dc:creator><![CDATA[Beau Nouvelle]]></dc:creator><pubDate>Fri, 20 Sep 2019 13:50:12 GMT</pubDate><content:encoded><![CDATA[<p></p><p>If you haven&apos;t already, you&apos;ll want to check out <a href="https://getswifty.dev/game-of-life-in-swift-playgrounds-part-2/">part 2</a> before continuing with this chapter.</p><hr><h3 id="game-rules">Game Rules</h3><p>We now have cells populating the world, but they&#x2019;re currently frozen in time. They&#x2019;re born, but then nothing happens. We&#x2019;ll need a way to step the world forward and apply the game rules.</p><p>Go back to <code>World.swift</code> and create a new function called <code>updateCells()</code>. Inside this function, we&#x2019;ll create a new temporary array that will hold our updated cells, along with an array of live cells.</p><pre><code class="language-swift">var updatedCells = [Cell]()
let liveCells = cells.filter { $0.state == .alive }

for cell in cells {

}

cells = updatedCells</code></pre><p>We&#x2019;ll be using <code>liveCells</code> to find the living neighbors of each cell in the loop. Filtering out dead cells early on means that we don&#x2019;t have to waste resources looping over them.</p><p>So inside the for loop, we&#x2019;ll grab the living neighbors using the function on <code>Cell</code> that we wrote earlier.</p><pre><code class="language-swift">let livingNeighbors = liveCells.filter { $0.isNeighbor(to: cell) }</code></pre><p>Then we&#x2019;re going to add a switch statement. This is where we&#x2019;ll apply our rules. The simplest way is to break up them up into three steps, even though there are four rules. Here they are again.</p><ol><li>Any live cell with fewer than two live neighbors will die.</li><li>Any live cell with two or three live neighbors will live on to the next generation.</li><li>Any live cell with more than three live neighbors will die.</li><li>Any dead cell with exactly three live neighbors will become a live cell.</li></ol><p>So if the cell is alive, and its number of live neighbors is two or three, it lives on otherwise it dies. So let&#x2019;s do that first, still inside the for loop.</p><pre><code class="language-swift">switch livingNeighbors.count {
case 2...3 where cell.state == .alive:
    updatedCells.append(cell)
}</code></pre><p>Here we&#x2019;re switching on the number of live neighbors. We could also perform a switch on the state of the cell, but I wanted to show you another little trick that we can do with number ranges.</p><p>Since the cell is already alive, we&#x2019;ll append it, as is, to the <code>updatedCells</code>array.</p><p>Next, we want to handle the fourth rule. If the cell is dead and has three live neighbors, it becomes alive.</p><pre><code class="language-swift">case 3 where cell.state == .dead:
    let liveCell = Cell(x: cell.x, y: cell.y, state: .alive)
    updatedCells.append(liveCell)</code></pre><p>We&#x2019;ll use the same coordinates as the current cell and set its state to <code>.alive</code>.</p><p>For every other case that these two don&#x2019;t cover, we want to append a dead cell to the <code>updatedCells</code> array. To do that, we add a default case.</p><pre><code class="language-swift">
default:
    let deadCell = Cell(x: cell.x, y: cell.y, state: .dead)
    updatedCells.append(deadCell)</code></pre><p>The switch statement is now complete.</p><pre><code class="language-swift">switch livingNeighbors.count {
case 2...3 where cell.state == .alive:
    updatedCells.append(cell)
case 3 where cell.state == .dead:
    let liveCell = Cell(x: cell.x, y: cell.y, state: .alive)
    updatedCells.append(liveCell)
default:
    let deadCell = Cell(x: cell.x, y: cell.y, state: .dead)
    updatedCells.append(deadCell)
}</code></pre><p>I bet you didn&#x2019;t think it was going to be this simple. Before we can test it though, we&#x2019;ll need to make a slight change to the <code>WorldView.swift</code> file. We don&#x2019;t have anything triggering the <code>updateCells</code> function yet, so we&#x2019;ll need to fix that up first.</p><h3 id="touch-gestures">Touch Gestures</h3><p>Since we&#x2019;re using <code>UIKit</code> in our playgrounds, all interactions with the live view are touch-based &#x2014; even if we&#x2019;re using a mouse. At the bottom of the <code>WorldView</code> class, we need to override <code>touchesBegan</code> to capture a touch event sent to the live view so we can run our <code>updateCells</code> function.</p><pre><code class="language-swift">public override func touchesBegan(_ touches: Set&lt;UITouch&gt;, with event: UIEvent?) {
    world.updateCells()
    setNeedsDisplay()
}</code></pre><p>Calling <code>updateCells()</code> will apply all of our game rules. Following that with <code>setNeedsDisplay()</code> tells our view that it needs to redraw its contents, which in turn calls <code>draw(rect:)</code>. Now its ready to test.</p><h3 id="game-of-life">Game of Life</h3><p>Go back to the main playground file, and make sure you have the live view open in the assistant editor.</p><figure class="kg-card kg-image-card"><img src="https://getswifty.dev/content/images/2019/09/1-bTcZ6rOwW3fWfpPSnPwi1g.png" class="kg-image" alt loading="lazy"></figure><p>Each time you click on the view, the game steps forward another generation. Over time, the simulation will eventually settle in. You&#x2019;ll find that some common patterns will emerge over many games. There&#x2019;s a great list of them on <a href="https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life" rel="noopener">Wikipedia</a> if you&#x2019;re interested in learning more.</p><h3 id="bonus">Bonus</h3><p>Constantly clicking to see results gets boring after a while. So let&#x2019;s get the game running on its own.</p><p>Navigate to your <code>WorldView.swift</code> file and add this function at the bottom of the class:</p><pre><code class="language-swift">public func autoRun() {
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
        self.world.updateCells()
        self.setNeedsDisplay()
        self.autoRun()
    }
}</code></pre><p><code>.now()</code> is the current time, but if we want the code to pause for a moment, we can add some extra time. In this case it&#x2019;s <code>0.2</code> seconds.</p><p>Then, go back to your main swift file and call <code>autoRun()</code> on <code>view</code>.</p><pre><code class="language-swift">let view = WorldView(worldSize: 100, cellSize: 5)
view.autoRun()
PlaygroundPage.current.liveView = view</code></pre><p>The playground will now run forever, or until you end it manually.</p><hr><p>You should now have a thorough understanding of how you can start to think about and create cell-based simulations of your own. You&#x2019;ll find other projects like this, as well as how to use simulations to create procedural art in my book titled &#x201C;Simulations in Swift&#x201D;. I&#x2019;ve also included a &#x201C;getting started with swift playgrounds&#x201D; section for people who might be new to the language.</p>]]></content:encoded></item><item><title><![CDATA[Game of Life in Swift Playgrounds - Part 2]]></title><description><![CDATA[<p></p><p>If you haven&apos;t already, you&apos;ll want to check out <a href="https://getswifty.dev/game-of-life-in-swift-playgrounds/">part 1</a> before continuing with this chapter.</p><hr><h3 id="world">World</h3><p>The <code>World</code> is where our cells will live out their entire lives. It&#x2019;s also where we will set up most of the logic and rules for the</p>]]></description><link>https://getswifty.dev/game-of-life-in-swift-playgrounds-part-2/</link><guid isPermaLink="false">5d84d4082f5fc40e4ddf948f</guid><category><![CDATA[playgrounds]]></category><category><![CDATA[Swift]]></category><dc:creator><![CDATA[Beau Nouvelle]]></dc:creator><pubDate>Fri, 20 Sep 2019 13:37:57 GMT</pubDate><content:encoded><![CDATA[<p></p><p>If you haven&apos;t already, you&apos;ll want to check out <a href="https://getswifty.dev/game-of-life-in-swift-playgrounds/">part 1</a> before continuing with this chapter.</p><hr><h3 id="world">World</h3><p>The <code>World</code> is where our cells will live out their entire lives. It&#x2019;s also where we will set up most of the logic and rules for the game. So naturally, a few things might already be coming to mind with what properties we might need.</p><p>For starters, we&#x2019;ll need somewhere to store our cells, and we&#x2019;ll also need to know how many cells are required to fill the world.</p><pre><code class="language-swift">public class World {
    public var cells = [Cell]()
    public let size: Int
}</code></pre><p><code>size</code> will be the number of cells that can fit across both axis of the world grid. So a world with the size of <code>10</code> would be able to support one hundred cells.</p><p>Let&#x2019;s write an initializer for our world class.</p><pre><code class="language-swift">public init(size: Int) {
    self.size = size
}</code></pre><p>This initializer gives us an excellent entry point into this class. Being able to specify a size at initialization is important because the next step is to fill the <code>cells</code> array with cells.</p><p>Still, inside the <code>World</code> initializer, add the following code.</p><pre><code class="language-swift">for x in 0..&lt;size {
    for y in 0..&lt;size {
        let randomState = arc4random_uniform(3)
        let cell = Cell(x: x, y: y, state: randomState == 0 ? .alive : .dead)
        cells.append(cell)
    }
}</code></pre><p>Here we have a 2D array. 2D arrays are used almost exclusively for building out a grid. You&#x2019;ll find them in nearly every grid type tile game. <code>x</code> loop for one axis <code>y</code> loop for another. However, we&#x2019;re using the results a little different than what would be considered conventional. The cells are being inserted directly into a list &#x2014; a single array. This is because we&#x2019;ve opted to have the <em><em>cells</em></em> know their position in the world, rather than having their position determined by where they might be in a nested array. The benefit here is that this will be the only place in our program that you&#x2019;ll see a nested for loop. This gives our game a slight performance increase. So when it comes time to check the neighbors of a cell, or draw it to a view, we&#x2019;ll only need to iterate over a single array.</p><p>I&#x2019;ve opted to go for a random distribution of alive and dead cells in my world as I find that random world generation is much more interesting. In many versions of the Game of Life, players can set which cells they&#x2019;d like to be alive, and sometimes even make changes after the game has started running.</p><p>In our version, about a third of the cells will be alive when the game starts. You can adjust this to your taste by changing the input integer for <code>arc4random_uniform()</code>. The higher the number, the less live cells will be created.</p><p>To test this out, we&#x2019;ll go back to the main playground file, remove the code we have in there for testing `Cell` and replace it with this:</p><pre><code class="language-swift">let world = World(size: 2)
dump(world.cells)</code></pre><blockquote><em>When it comes to things like arrays or nested object types, they can be difficult to read when their contents are printed out all on a single line. </em><code><em>dump</em></code><em> will output the contents of an object to the console in an excellently structured and readable way.</em></blockquote><p>A world with the size of <code>2</code> should print out four cells to the console.</p><figure class="kg-card kg-image-card"><img src="https://getswifty.dev/content/images/2019/09/1-OdSXHHlBXefExXnULP_rsQ.png" class="kg-image" alt loading="lazy"></figure><h3 id="world-view"><br>World View</h3><p>The <code>WorldView.swift</code> will be a class where we put our all of our drawing code. This will be a subclass of <code>UIView</code> and get passed into the <code>liveView</code>property of our playground. Its also there look after our <code>World</code> object.</p><p>The first thing we need to do is import <code>UIKit</code> at the top of the file.</p><pre><code class="language-swift">import UIKit

public class WorldView: UIView {
    var world: World = World(size: 100)
    var cellSize: Int = 10
}</code></pre><p>The only two properties we&#x2019;ll need is the <code>world</code> and <code>cellSize</code>. The <code>cellSize</code> is what we&#x2019;ll use to draw each cell as well as calculate how big the view needs to be.</p><p>If each cell is <code>10x10</code> pixels, and the world is a size of <code>5</code>, then the view would need to draw its cells on a square canvas of <code>50x50</code> pixels.</p><p>Notice that while the class has been made public, these two properties are private. We won&#x2019;t need to access them outside of this class, but we will need a way to set them. Unfortunately, since we&#x2019;re using a subclass of <code>UIView</code>, we must make use of its designated initializers. To do this, we&#x2019;ll create our own <code>convenience</code> initializer to pass in a few parameters which will then call a designated one.</p><pre><code class="language-swift">public convenience init(worldSize: Int, cellSize: Int) {
    let frame = CGRect(x: 0, y: 0, width: worldSize * cellSize, height: worldSize * cellSize)
    self.init(frame: frame)
    self.world = World(size: worldSize)
    self.cellSize = cellSize
}</code></pre><p>Here we&#x2019;re calculating the size of the canvas based on the <code>worldSize</code> and <code>cellSize</code> parameters, then creating a frame which gets passed into the views init function.</p><p>Since we also have <code>world</code> and <code>cellSize</code> initialized in their property declarations, we may as well use these as a default for setting up <code>WorldView</code>. So let&#x2019;s create another convenience initializer for that too.</p><pre><code class="language-swift">public convenience init() {
    let frame = CGRect(x: 0, y: 0, width: 1000, height: 1000)
    self.init(frame: frame)
}</code></pre><p>Now we have a few errors. <code>UIView</code> has a <code>required</code> init function that we must implement whenever we subclass it. Even though we won&#x2019;t be using it, we still need to have it in there.</p><figure class="kg-card kg-image-card"><img src="https://getswifty.dev/content/images/2019/09/1-LE7I4PU_85yf7lC-QQl3-w.png" class="kg-image" alt loading="lazy"></figure><p>You can get Xcode to stub this out for you, but if that doesn&#x2019;t work, use the following code:</p><pre><code class="language-swift">public required init?(coder aDecoder: NSCoder) {
    fatalError(&quot;Not implemented&quot;)
}</code></pre><p>We want the program to crash if something tries to initialize <code>WorldView</code> with this function. Crashing is a great way to inform ourselves and future developers that nothing is supposed to call this function. The program will exit early, and we&#x2019;ll get a little error message in the console.</p><p>To fix the last compilation error, we also need to add the <code>init(frame:)</code>function that one of our convenience initializers are calling.</p><pre><code class="language-swift">public override init(frame: CGRect) {
    super.init(frame: frame)
}</code></pre><p>Finally, let&#x2019;s start drawing some cells.</p><p>We&#x2019;re going to override <code>UIView</code>s draw function.</p><pre><code class="language-swift">public override func draw(_ rect: CGRect) {
}</code></pre><p>The default implementation of this method doesn&#x2019;t do anything, so there&#x2019;s no need to call super as we do with the init functions. We also never need to call this method directly. iOS will call <code>draw(rect:)</code> when the view is first displayed, or any time an event occurs that invalidates a visible part of the view. Later on, we&#x2019;ll force a drawing update indirectly by calling <code>setNeedsDisplay</code> any time a touch is detected.</p><p>It&#x2019;s important to remember that this function should only be responsible for rendering view content. Any other code you put in here that might take a significant amount of time to execute will impact the performance of your application. I highly encourage you to have a read through of Apple&#x2019;s documentation on <code>draw(rect:)</code>.</p><p>Inside the draw method, we&#x2019;ll grab a reference to the <code>CGContext</code> provided by Core Graphics.</p><pre><code class="language-swift">let context = UIGraphicsGetCurrentContext()
context?.saveGState()</code></pre><p>We&#x2019;ll be passing messages to this context; telling it what to draw for every cell that exists in the world.</p><pre><code class="language-swift">for cell in world.cells {
  let rect = CGRect(x: cell.x * cellSize, y: cell.y * cellSize, width: cellSize, height: cellSize)
	let color = cell.state == .alive ? UIColor.green.cgColor : UIColor.white.cgColor
	context?.addRect(rect)
	context?.setFillColor(color)
	context?.fill(rect)
}</code></pre><p>So the position of each cell is based on the product of its coordinates and <code>cellSize</code>. This places them at regular intervals within the view. I&#x2019;ve also set the color of my live cells to green, but you&#x2019;re free to set any color here.</p><p>Then, at the end of the draw method, we&#x2019;ll set our changes so that they can appear in the view.</p><pre><code class="language-swift">context?.restoreGState()</code></pre><p>Let&#x2019;s test this out and get some cells appearing in our playgrounds live view!</p><p>Go back to you main playgrounds file and replace the code from our previous test with these two lines:</p><pre><code class="language-swift">let view = WorldView(worldSize: 10, cellSize: 10)
PlaygroundPage.current.liveView = view</code></pre><figure class="kg-card kg-image-card"><img src="https://getswifty.dev/content/images/2019/09/1-vz2l5mRczPQ_1C5AwxJbZg.png" class="kg-image" alt loading="lazy"></figure><p>Run the playground, and you should see live and dead cells randomly distributed in a 10x10 grid.</p><p>In part 3 we&#x2019;ll go over creating the game rules.</p>]]></content:encoded></item><item><title><![CDATA[Game of Life in Swift Playgrounds - Part 1]]></title><description><![CDATA[<p></p><blockquote><em>This Game of Life series is an adapted chapter from my book titled &#x201C;<a href="https://gum.co/HwCc" rel="noopener">Simulations in Swift</a>&#x201D;. Because I already cover the basics in my book, this post assumes you already have some working knowledge of Swift Playgrounds.</em></blockquote><blockquote><em>If you&#x2019;re interested in learning more about writing simulations</em></blockquote>]]></description><link>https://getswifty.dev/game-of-life-in-swift-playgrounds/</link><guid isPermaLink="false">5d84d1562f5fc40e4ddf9451</guid><category><![CDATA[playgrounds]]></category><category><![CDATA[Swift]]></category><dc:creator><![CDATA[Beau Nouvelle]]></dc:creator><pubDate>Fri, 20 Sep 2019 13:22:06 GMT</pubDate><media:content url="https://getswifty.dev/content/images/2019/09/marjan_blan-9--McZPOCCs-unsplash.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://getswifty.dev/content/images/2019/09/marjan_blan-9--McZPOCCs-unsplash.jpg" alt="Game of Life in Swift Playgrounds - Part 1"><p></p><blockquote><em>This Game of Life series is an adapted chapter from my book titled &#x201C;<a href="https://gum.co/HwCc" rel="noopener">Simulations in Swift</a>&#x201D;. Because I already cover the basics in my book, this post assumes you already have some working knowledge of Swift Playgrounds.</em></blockquote><blockquote><em>If you&#x2019;re interested in learning more about writing simulations using the Swift programming language, or struggling with with Playgrounds, you can purchase my book from most popular online retailers in paperback or eBook format.</em></blockquote><!--kg-card-begin: html--><script src="https://gumroad.com/js/gumroad.js"></script>
<a class="gumroad-button" href="https://gumroad.com/l/HwCc" target="_blank">Buy Simulations in Swift</a><!--kg-card-end: html--><hr><h2 id="what-is-the-game-of-life">What is the Game of Life?</h2><p>Developed by John Conway in 1970, the Game of Life is a cellular-automaton, zero-player game. A game in the lightest sense as there is no user interaction beyond the initial starting conditions and neither is there an end.</p><p>The game takes place on a grid of cells. Each cell can either be alive or dead. Four simple rules determine the vitality of each cell.</p><ol><li>Any live cell with fewer than two live neighbors will die.</li><li>Any live cell with two or three live neighbors will live on to the next generation.</li><li>Any live cell with more than three live neighbors will die.</li><li>Any dead cell with exactly three live neighbors will become a live cell.</li></ol><p>If you&#x2019;re unfamiliar with the game and its rules, I highly recommend finding an online version of the game to play around with before continuing.</p><h2 id="new-playground">New Playground</h2><p>Create a new playground and name it &#x201C;GameOfLife&#x201D;. From the above description of the game, you might already have an idea of the kind of elements we&#x2019;ll need to create. A cell and world object is a great place to start.</p><p>So let&#x2019;s create two new files in the source folder of our playground and call them <code>Cell.swift</code> and <code>World.swift</code>.</p><p>We&#x2019;re also going to be making use of Swift Playgrounds live views. While it might be ok to print out results to the console, being able to <em><em>see</em></em> them is even better. So create another file and call it <code>WorldView.swift</code>.</p><h2 id="cells">Cells</h2><p>Cells represent each of the little lives in the simulation. They can be in one of two states &#x2014; dead or alive &#x2014; they also know their position in the world. These are the properties we&#x2019;ll add to our cell.</p><p>Open up <code>Cell.swift</code> and under <code>import Foundation</code> create a new public enum and name it <code>State</code>.</p><pre><code class="language-swift">public enum State {
    case alive
    case dead
}</code></pre><p>Below the enum is where we will create our cell struct.</p><pre><code class="language-swift">public struct Cell {
    public let x: Int
    public let y: Int
    public var state: State
}</code></pre><p><br>Usually, we&#x2019;d take advantage of the fact that structures give us an initializer without doing any further work. We&#x2019;re using playgrounds though, and that means we need to have a public initializer to create our cells inside the main playground file. Unfortunately, we don&#x2019;t get a public initializer for free, so let&#x2019;s add that real quick.</p><pre><code class="language-swift">public init(x: Int, y: Int, state: State) {
    self.x = x
    self.y = y
    self.state = state
}</code></pre><p>We&#x2019;ll also give a cell the ability to tell us if it is the neighbor to a given cell. This will help when enforcing our game rules where we determine if the cell should be dead or alive based on those surrounding it.</p><p>Inside the cell struct, below the properties, we&#x2019;ll add a new function and make it public.</p><pre><code class="language-swift">
public func isNeighbor(to cell: Cell) -&gt; Bool {

    let xDelta = abs(self.x - cell.x)
    let yDelta = abs(self.y - cell.y)

    switch (xDelta, yDelta) {
    case (1, 1), (0, 1), (1, 0):
        return true
    default:
        return false
    }

}</code></pre><p>So the calculations performed here will take the coordinates of both cells and check if they are situated right next to each other. It&#x2019;s quite simple:</p><p>If one cell is at <code>x</code> position of <code>10</code> and the other cell is at <code>x</code> position of <code>11</code>; <code>11&#x2013;10 = 1</code> or <code>10&#x2013;11 = -1</code>. Wrapping the result in <code>abs()</code> gives us an &#x201C;absolute value&#x201D;. So <code>-1</code> becomes <code>1</code>. Whether the subtraction is <code>10&#x2013;11</code> or <code>11&#x2013;10</code>, we get the same result either way. This indicates that the cells are neighbors on the <code>x</code> axis. For cells to be neighbors, they cannot be any further than<code>1</code> point away from each other on either axis.</p><p>We can test that this works by going back to our main playground file and creating a few cells.</p><pre><code class="language-swift">let firstCell = Cell(x: 10, y: 10, state: .dead)
let secondCell = Cell(x: 11, y: 11, state: .dead)

print(firstCell.isNeighbor(to: secondCell))
// true - Adjacent row, adjacent column.</code></pre><p>This code will print <code>true</code> to the console as <code>secondCell</code> is one step away on both axes from <code>firstCell</code>. Let&#x2019;s try some more combinations.</p><pre><code class="language-swift">let firstCell = Cell(x: 10, y: 10, state: .dead)
let secondCell = Cell(x: 11, y: 10, state: .dead)
print(firstCell.isNeighbor(to: secondCell))
// true - Same row, adjacent column.

let firstCell = Cell(x: 10, y: 10, state: .dead)
let secondCell = Cell(x: 20, y: 10, state: .dead)
print(firstCell.isNeighbor(to: secondCell))
// false - Same row, vastly different column.

let firstCell = Cell(x: 10, y: 10, state: .dead)
let secondCell = Cell(x: 10, y: 10, state: .dead)
print(firstCell.isNeighbor(to: secondCell))
// false - Same row, same column. They&apos;re identical cells!</code></pre><p>Okay so the last one probably won&#x2019;t happen in our simulation, but it&#x2019;s worth testing out anyway.</p><p>In <a href="https://getswifty.dev/game-of-life-in-swift-playgrounds-part-2/">part 2</a> we&#x2019;ll look at filling our world with the cells we&#x2019;ve just created.</p>]]></content:encoded></item><item><title><![CDATA[Type safe networking with URLSession, Result, and Decodable.]]></title><description><![CDATA[<p>We all know it&apos;s best practice to separate our code into individual components, each dedicated to a single task. This <em>sounds</em> simple enough, but rarely do we get it right the first time. Or even the fourth time. </p><p>I find that within my projects, it can take me</p>]]></description><link>https://getswifty.dev/typesafe-networking-with-urlsession-and-codable/</link><guid isPermaLink="false">5d8216ae674e070c89b56ed9</guid><category><![CDATA[Extensions]]></category><category><![CDATA[Code]]></category><category><![CDATA[Swift]]></category><dc:creator><![CDATA[Beau Nouvelle]]></dc:creator><pubDate>Thu, 19 Sep 2019 07:34:52 GMT</pubDate><media:content url="https://getswifty.dev/content/images/2019/09/pawel-czerwinski-LEbkdsB8OMg-unsplash.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://getswifty.dev/content/images/2019/09/pawel-czerwinski-LEbkdsB8OMg-unsplash.jpg" alt="Type safe networking with URLSession, Result, and Decodable."><p>We all know it&apos;s best practice to separate our code into individual components, each dedicated to a single task. This <em>sounds</em> simple enough, but rarely do we get it right the first time. Or even the fourth time. </p><p>I find that within my projects, it can take me several attempts &#x2014; or even several projects &#x2014; before I settle on an architecture that works so well that I feel the need to shout &quot;I&apos;m a genius!&quot; to everyone around me in the open office. </p><blockquote>They hate that by the way.</blockquote><p>I&apos;ve had a new method floating around in my head lately and have been testing it out at my current workplace. It&apos;s not groundbreaking by any means, but it has made performing network calls so much simpler, faster, and intuitive. It also hides away all that messy URLSession implementation people tend to duplicate in every one of their view controllers.</p><h3 id="current-state-of-affairs">Current State of Affairs</h3><p>Most projects I&apos;ve worked on usually handle their networking code in one of the three following ways.</p><ol><li>MVC pattern, but URLSession is implemented within the View Controller.</li><li>MVC pattern, but URLSession is wrapped up in it&apos;s own http service type class. This handles all config, request creation, caching rules and cookies. This is then called from the View Controller.</li><li>MVVM pattern, but URLSession is implemented within the View Model.</li></ol><p>I preferred the second option for a long time, which is what most other developers I know had also settled into. It&apos;s pretty much a standard. </p><p>With these approaches you need to parse JSON, check for errors, check the response codes, and usually do this in every place that your app is making requests. Of course, you could have a wrapper that does this for you. A wrapper will take care of those error cases, but they still usually only pass back JSON. Which then gets pushed to another layer &#x2014; or multiple layers &#x2014; that parse the JSON into usable objects, or even worse, the JSON is handled directly by the view controller.</p><p>There&apos;s a much more elegant solution using <code>Decodable</code>, and <code>Result</code>, that eliminates a lot of boilerplate from your network requests. Let&apos;s get into it.</p><h3 id="extending-urlsession">Extending URLSession</h3><p>Rather than creating a whole new wrapper around <code>URLSession</code>, I find it&apos;s much better to write an extension. This gives us access to the new functionality anywhere in our project without having to come up with new class names. It also has the added benefit of forcing us to remain fairly neutral and &quot;Apple&quot; like when writing new APIs. Future devs and future you will be glad you took the extra time.</p><pre><code class="language-Swift">extension URLSession {

    func perform&lt;T: Decodable&gt;(_ request: URLRequest, decode decodable: T.Type, result: @escaping (Result&lt;T, Error&gt;) -&gt; Void) {

        URLSession.shared.dataTask(with: request) { (data, response, error) in

            // handle error scenarios... `result(.failure(error))`
            // handle bad response... `result(.failure(responseError))`
            // handle no data... `result(.failure(dataError))`

            do {
                let object = try JSONDecoder().decode(decodable, from: data)
                result(.success(object))
            } catch {
                result(.failure(error))
            }

        }.resume()

    }

}</code></pre><p>What we&apos;ve done here is wrap our usual <code>URLSession.shared</code> code in a static function, hiding away all the handling of the data, response, and errors. </p><p>The <code>perform</code> function accepts a <code>request</code>, and a <code>decodable</code> object &#x2014; that is, an object that conforms to the <code>Decodable</code> protocol. We then take that decodable object and try to decode the json returned from the request. If successful, an initialized object is returned in the closure.</p><blockquote>For this example we&apos;re using Swift Error type, but I highly reccomend creating your own enum error type with cases covering the kinds of errors you&apos;re most likley to run into e.g. bad status codes, invalid URLs, timeouts, json decoder problems, etc.</blockquote><p>The call site would then look something like this:</p><pre><code class="language-swift">let url = URL(string: &quot;https://example.com&quot;)!
let request = URLRequest(url: url)

URLSession.perform(request, decode: Object.self) { (result) in
    switch result {
    case .failure(let error):
        print(error)
    case .success(let object):
        print(object)
    }
}</code></pre><p>Once the request has completed, we get a <code>Result</code> back that can have only one or two outcomes. Success or Failure. There&apos;s no unwrapping or JSON parsing to do, our object is either available, or there was an error. So simple.</p><p>In most projects I&apos;ve worked on, what&apos;s returned is usually an array or dictionary and the view controller or view model is responsible for pulling out the information it needs to display. This eliminates that entire step.</p><h3 id="requestable-protocol">Requestable Protocol</h3><p>That&apos;s great, but we&apos;re still creating a new request each time this function is called. In cases where we need to call the same endpoint in different areas of the app, having duplicated requests like this means that anytime we need to update one, we have to update them all. This can introduce bugs during refactoring, and it&apos;s also just more code that we have to write and maintain.</p><p>The best place I can think of is to put the request on the object we&apos;re requesting. It already knows how to encode/decode itself, so it&apos;s not that much of a stretch for it to understand how to also fetch itself.</p><p>Obviously we can&apos;t just add a new variable to <code>Object</code>. Our <code>perform</code> function only knows how to handle <code>Decodable</code> items that are passed in. If we then decided to switch it to accept a type of <code>Object</code>, we&apos;d then be locking out all other types from making use of the <code>perform</code> function. </p><p>Instead, we&apos;ll create a new protocol that conforms to <code>Decodable</code> and adds a <code>urlRequest</code> property that our <code>perform</code> function can use.</p><pre><code class="language-swift">protocol Requestable: Decodable {
    static var urlRequest: URLRequest { get }
}</code></pre><p>We have a static variable that is get only. </p><pre><code class="language-swift">struct Object: Requestable {
    static var urlRequest: URLRequest {
        let url = URL(string: &quot;https://example.com&quot;)!
        let request = URLRequest(url: url)
        return request
    }
}</code></pre><p>We then make our <code>Object</code> type conform to <code>Requestable</code>. </p><blockquote>There may be times when you&apos;ll need more flexibility here, like passing in a http method such as GET, DELETE or POST where they&apos;re hitting the same endpoint. There&apos;s a few ways to handle this, like changing this to a function, and passing in your info that way. Instead I would suggest having two <code>perform</code> functions in your <code>URLSession</code> extension. One that takes <code>Requestable</code> as a parameter (like you&apos;ll see soon), and one that takes a <code>Decodable</code> and <code>URLRequest</code> (like the one shown above). You can always add new <code>postRequest</code> or <code>deleteRequest</code> variables to your objects and just pass them through to the request param i.e. <code>perform(request: object.deleteRequest, decode: Object.self)</code>.</blockquote><pre><code class="language-swift">extension URLSession {

    static func performRequest&lt;T: Requestable&gt;(on decodable: T.Type, result: @escaping (Result&lt;T, Error&gt;) -&gt; Void) {

        URLSession.shared.dataTask(with: decodable.urlRequest) { (data, response, error) in

            // handle error scenarios... `result(.failure(error))`
            // handle bad response... `result(.failure(responseError))`
            // handle no data... `result(.failure(dataError))`

            guard let data = data else { return }
            do {
                let object = try JSONDecoder().decode(decodable, from: data)
                result(.success(object))
            } catch {
                result(.failure(error))
            }

        }.resume()

    }

}</code></pre><p>This is our slightly modified <code>perform</code> function that now takes a single <code>Requestable</code> parameter.</p><p>Then at the call site we just have:</p><pre><code class="language-swift">URLSession.performRequest(on: Object.self) { (result) in
    switch result {
    case .failure(let error):
        print(error)
    case .success(let object):
        print(object)
    }
}</code></pre><p>Isn&apos;t this so much simpler? All it takes now is just a few lines of code inside your View Controller to fetch new data from a server. </p><p>If you don&apos;t care about the types of errors you&apos;ll get, you could even remove the <code>Result</code> type and just return an optional, possibly reducing your networking code to three lines. </p><p>This is a huge win in readable, reusable code. It&apos;s far easier to work with than the older method, and if you&apos;re still trying to convince your team to start using Codable, this might just do it.</p><hr><p>Photo by <a href="https://unsplash.com/@pawel_czerwinski?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Pawe&#x142; Czerwi&#x144;ski</a> on <a href="https://unsplash.com/s/photos/game-of-life?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></p>]]></content:encoded></item><item><title><![CDATA[Working with very large numbers in Swift —  BigInt]]></title><description><![CDATA[Numbers are fundamental to every programming language in existence. Depending on the systems architecture that you’re programming for, there are restrictions the size of the numbers it can support.]]></description><link>https://getswifty.dev/create-your-own-bigint-in-swift/</link><guid isPermaLink="false">5cbdbf46674e070c89b56e5c</guid><category><![CDATA[Swift]]></category><category><![CDATA[iOS]]></category><category><![CDATA[Code]]></category><dc:creator><![CDATA[Beau Nouvelle]]></dc:creator><pubDate>Mon, 22 Apr 2019 13:30:10 GMT</pubDate><content:encoded><![CDATA[<p>Numbers are fundamental to every programming language in existence. Depending on the systems architecture that you&#x2019;re programming for, there are restrictions the size of the numbers it can support.</p><p>Engineers writing code for an 8-bit system such as the NES, only had access to integers between -128 to 127 (signed). However with some tricks, such as breaking the numbers into smaller pieces, any cpu is capable of working with numbers of any size.</p><p>This method of breaking the numbers up can be performed at the hardware level, but there are some software tricks we can use too.</p><hr><p>The following table describes some common available integer sizes.</p><pre><code>&#x2554;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2566;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2557;
&#x2551; Type  &#x2551;                      Output Range                       &#x2551;
&#x2560;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x256C;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2563;
&#x2551; int8  &#x2551; -128 to 127                                             &#x2551;
&#x2551; int16 &#x2551; -32,768 to 32,767                                       &#x2551;
&#x2551; int32 &#x2551; -2,147,483,648 to 2,147,483,647                         &#x2551;
&#x2551; int64 &#x2551; -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 &#x2551;
&#x255A;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2569;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x2550;&#x255D;</code></pre><p>Notice the <code>int64</code> range. You may have seen these numbers somewhere before. &#x1F31A; Back when Game Center was a thing...</p><figure class="kg-card kg-image-card"><img src="https://getswifty.dev/content/images/2019/04/1-D3KdSKl89PUveAs2RX60Ww.jpeg" class="kg-image" alt loading="lazy"></figure><h3 id="using-strings-to-represent-numbers">Using strings to represent numbers</h3><p>What we&#x2019;re going to do is create our own number type. A type that can handle operations on obscenely large numbers, and we&#x2019;re going to use <code>String</code>s to do this.</p><p>Currently there&#x2019;s no way to add, subtract, multiply or divide integers with strings directly in Swift. So we need to construct our own type to handle this.</p><p>We&#x2019;ll start out with a new struct and call it <code>BigInt</code>.</p><pre><code class="language-swift">struct BigInt {  
    var value: String
}</code></pre><p>We&#x2019;ll start out with a variable called <code>value</code>. There&apos;s also no need to create an initializer because Swift will provide this for us.</p><h3 id="calculations">Calculations</h3><p>Our BigInt is pretty useless without being able to perform a few calculations. So lets jump right into something a little tricky like multiplication.</p><p>We&#x2019;ll use the same method you did when learning how to multiply larger numbers on paper in school.</p><p>We start by splitting both values into arrays, where a single character is mapped to each index. The arrays are then reversed to make things a little easier. Finally we loop over both arrays, and multiply the single digits found at each index with each other.</p><pre><code class="language-swift">func multiply(left: String, right: String) -&gt; String {
    var leftCharacterArray = left.characters.reversed().map { Int(String($0))! }
    var rightCharacterArray = right.characters.reversed().map { Int(String($0))! }
    var result = [Int](repeating: 0, count: leftCharacterArray.count+rightCharacterArray.count)
    
    for leftIndex in 0..&lt;leftCharacterArray.count {
        for rightIndex in 0..&lt;rightCharacterArray.count {
            
            let resultIndex = leftIndex + rightIndex
            
            result[resultIndex] = leftCharacterArray[leftIndex] * rightCharacterArray[rightIndex] + (resultIndex &gt;= result.count ? 0 : result[resultIndex])
            if result[resultIndex] &gt; 9 {
                result[resultIndex + 1] = (result[resultIndex] / 10) + (resultIndex+1 &gt;= result.count ? 0 : result[resultIndex + 1])
                result[resultIndex] -= (result[resultIndex] / 10) * 10
            }
            
        }
        
    }
    
    result = Array(result.reversed())
    return result.map { String($0) }.joined(separator: &quot;&quot;)
}

multiply(left: &quot;2844858348834855723432430&quot;, right: &quot;134534523453454540998798789&quot;)</code></pre><p>There&#x2019;s a lot going on here, you be fine to copy and paste it into a playground if you want a closer look at what&#x2019;s going on.</p><p>This method isn&#x2019;t the most performant or safest piece of code.</p><p>There&#x2019;s also nothing stopping someone from entering a character that isn&#x2019;t a number, which would of course result in a crash.</p><p>Now this is just a stand alone function. Which really could just be added anywhere within our project and do a good job as it is. However, we want something that will work with our <code>BigInt</code> type.</p><p>We want to be able to do something like this:</p><pre><code class="language-swift">let int1 = BigInt(&quot;10&quot;)  
let int2 = BigInt(&quot;5&quot;)  
let product = int1 * int2  </code></pre><h3 id="bigint">BigInt</h3><p>Alright so let&#x2019;s add the function to our struct and alter it a bit to make it more to our liking.</p><pre><code class="language-swift">struct BigInt {

    var value: String

    func multiply(right: String) -&gt; String {
        // We&apos;ll change this line to use value
        var leftCharacterArray = value.characters.reversed().map { Int(String($0))! }
        var rightCharacterArray = right.characters.reversed().map { Int(String($0))! }
    ...


// Now we can do this
let int1 = BigInt(value: &quot;34&quot;)  
let int2 = BigInt(value: &quot;45&quot;)  
let product = int1.multiply(int2.value)</code></pre><p>Close but still doesn&#x2019;t give us what we&#x2019;re after.</p><p>Let&#x2019;s remove the <code>String</code> requirement and pass our <code>BigInt</code> right into our multiply function.</p><pre><code class="language-swift">func multiply(right: BigInt) -&gt; BigInt {

    var a1 = value.characters.reversed().map { Int(String($0))! }
    var a2 = right.value.characters.reversed().map { Int(String($0))! }
    ...
    ...

    // And change the last line
    return BigInt(value: result.map { String($0) }.joined(separator: &quot;&quot;))
}

// Our calculation now looks like this.
let int1 = BigInt(value: &quot;34&quot;)  
let int2 = BigInt(value: &quot;45&quot;)  
let product = int1.multiply(int2)  </code></pre><p>A bit cleaner, but lets go all the way and define our own <code>*</code> operator.</p><h3 id="operator-overloading-">Operator Overloading <code>*</code></h3><p>All you need to do is add this line somewhere outside our <code>BigInt</code> struct.</p><pre><code class="language-swift">func * (left: BigInt, right: BigInt) -&gt; BigInt { return left.multiply(right) }</code></pre><p>Operator overloading allows you to change how existing operators behave with types that both already exist (Int, Float, String), and any custom types you have created. In this example, we&#x2019;re letting our program know how to multiply two BigInt types the same way we would any other primitive number type.</p><h3 id="finally">Finally</h3><p>This is what it should all look like once you&#x2019;re done.</p><pre><code class="language-swift">import UIKit
import Foundation

struct BigInt {
    
    var value: String
    
    func multiply(right: BigInt) -&gt; BigInt {
        var leftCharacterArray = value.characters.reversed().map { Int(String($0))! }
        var rightCharacterArray = right.value.characters.reversed().map { Int(String($0))! }
        var result = [Int](repeating: 0, count: leftCharacterArray.count+rightCharacterArray.count)
        
        for leftIndex in 0..&lt;leftCharacterArray.count {
            for rightIndex in 0..&lt;rightCharacterArray.count {
                
                let resultIndex = leftIndex + rightIndex
                
                result[resultIndex] = leftCharacterArray[leftIndex] * rightCharacterArray[rightIndex] + (resultIndex &gt;= result.count ? 0 : result[resultIndex])
                if result[resultIndex] &gt; 9 {
                    result[resultIndex + 1] = (result[resultIndex] / 10) + (resultIndex+1 &gt;= result.count ? 0 : result[resultIndex + 1])
                    result[resultIndex] -= (result[resultIndex] / 10) * 10
                }
                
            }
            
        }
        
        result = Array(result.reversed())

        while result.count &gt; 0 &amp;&amp; result.first == 0 {
            result.removeFirst(1)
        }
        
        return  BigInt(value: result.map { String($0) }.joined(separator: &quot;&quot;))
    }
    
}

func * (left: BigInt, right: BigInt) -&gt; BigInt { return left.multiply(right: right) }</code></pre><p>Multiplying two <code>BigInts</code> together should be as simple as:</p><pre><code class="language-swift">let int1 = BigInt(value: &quot;34757377374573285823949593499549646311234&quot;)  
let int2 = BigInt(value: &quot;45123498348958923845838948528381283721377123454345&quot;)  
let product = int1 * int2  
// result: 1568374460575699918065222772187576926314538959488859994856690985365041943440429553059611730</code></pre><p>There you have it. It&#x2019;s not perfect, but it does give you an idea of how we can work around some of the hardware restrictions we face as developers.</p>]]></content:encoded></item><item><title><![CDATA[Extending UITableView to Register and Dequeue Cells Safely]]></title><description><![CDATA[Dequeuing and registering cells for table and collection views has always been a little bit messy. UITableView was first released in iOS 2.0 and we have seen some significant improvements to the API since then. ]]></description><link>https://getswifty.dev/extending-uitableview-to-register-and-dequeue-cells-safely/</link><guid isPermaLink="false">5caeedb6674e070c89b56dd0</guid><category><![CDATA[Code]]></category><category><![CDATA[Swift]]></category><category><![CDATA[UIKit]]></category><category><![CDATA[Extensions]]></category><category><![CDATA[iOS]]></category><dc:creator><![CDATA[Beau Nouvelle]]></dc:creator><pubDate>Thu, 11 Apr 2019 17:00:00 GMT</pubDate><media:content url="https://getswifty.dev/content/images/2019/04/chuttersnap-473350-unsplash.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://getswifty.dev/content/images/2019/04/chuttersnap-473350-unsplash.jpg" alt="Extending UITableView to Register and Dequeue Cells Safely"><p>Dequeuing and registering cells for table and collection views has always been a little bit messy. <code>UITableView</code> was first released in iOS 2.0 and we <em>have</em> seen some significant improvements to the API since then. </p><p>iOS 6.0 gave us the <code>register</code> and <code>dequeueReusableCell</code> methods to help with performance issues people were having. At the time Swift didn&apos;t exist. <code>if cell != cell</code> and throwing around strings for registering these cells was, and still is, considered normal.<br><br>Now that Swift 5 is out and the language seems to be stabalizing, I hope that Apple &#xA0;can begin to rewrite some UIKit components to be a little more Swift friendly. </p><p>Until then, we can do some of the work ourselves and hide these verbose Objective-C methods away in extensions, and remove the stringly typed reuse identifiers.</p><!--kg-card-begin: markdown--><h3 id="uitableviewcell">UITableViewCell</h3>
<!--kg-card-end: markdown--><p>One of the first things we&apos;ll do to clean things up a bit is hide away that reuse identifier. You shouldn&apos;t have to deal with that (unless you want to).</p><pre><code class="language-swift">extension UITableViewCell {
    
    static var reuseIdentifier: String {
        return NSStringFromClass(self)
    }
    
}</code></pre><p>This will generate a reuse identifier for you based on the name of the class. So if your class was called <code>TweetTableViewCell</code>, then your reuse identifier would be the same. If it&apos;s in a separate module, it&apos;ll even be prefixed with that modules name. </p><p>Now you don&apos;t have to worry about remembering what this identifier is, or accidentally misspelling it.</p><p>Perfect, so let&apos;s use it to register our cell.</p><!--kg-card-begin: markdown--><h3 id="uitableview">UITableView</h3>
<!--kg-card-end: markdown--><pre><code class="language-swift">extension UITableView {
    
    public func register&lt;T: UITableViewCell&gt;(cellClass: T.Type) {
        register(cellClass, forCellReuseIdentifier: cellClass.reuseIdentifier)
    }
    
}</code></pre><p>All we need to pass in is the cells class. <code>tableView.register(cellClass: MyCell.self)</code>. Simple.</p><p>Okay, but what about dequeuing?</p><p>The problem <em>I</em> have with the current dequeue methods is that what I get back is usually an optional. So your code looks like:</p><p><code>let cell = tableView.dequeueReusableCell(withIdentifier: id, forIndexPath: indexPath) as? MyCell</code></p><p>Then you have to unwrap it because <code>cellForRow</code> won&apos;t let you return an optional. Of course we could create our own wrapper around <code>cellForRow</code> &#x2014; you can do this if you wish &#x2014; but I want to clean up the code <em>in</em> <code>cellForRow</code> because that&apos;s what I&apos;m going to be looking at every day.</p><pre><code class="language-swift">extension UITableView {
    
    public func dequeue&lt;T: UITableViewCell&gt;(cellClass: T.Type) -&gt; T? {
        return dequeueReusableCell(withIdentifier: cellClass.reuseIdentifier) as? T
    }

    public func dequeue&lt;T: UITableViewCell&gt;(cellClass: T.Type, forIndexPath indexPath: IndexPath) -&gt; T {
        guard let cell = dequeueReusableCell(
            withIdentifier: cellClass.reuseIdentifier, for: indexPath) as? T else {
                fatalError(
                    &quot;Error: cell with id: \(cellClass.reuseIdentifier) for indexPath: \(indexPath) is not \(T.self)&quot;)
        }
        return cell
    }
    
}</code></pre><p>Generics to the rescue again!</p><p><code>let cell = tableView.dequeue(cellClass: MyCell.self, forIndexPath: indexPath)</code></p><p>Now we have an unwrapped cell that&apos;s guaranteed to be the type we passed in, all without having to worry about reuse identifiers. </p><p>Should anything go wrong, you&apos;ll get a fatal error at runtime. Which isn&apos;t ideal for everyones use case, but it works for me. An alternative would be to mark this function with the <code>throws</code> keyword and introduce error handling that way.</p><p>This idea can be applied to collection views and other register/dequeue functions that table views make use of (section headers, footers, etc).</p><p>It&apos;s not groundbreaking but I find that it has had a positive impact on the readability and conciseness of my view controller code.</p>]]></content:encoded></item><item><title><![CDATA[Adding Closures to Buttons in Swift]]></title><description><![CDATA[One of the things I still find a little backward and unnatural to use in Swift is the Target-Action pattern.]]></description><link>https://getswifty.dev/adding-closures-to-buttons-in-swift/</link><guid isPermaLink="false">5cae99bb674e070c89b56c5d</guid><category><![CDATA[Swift]]></category><category><![CDATA[UIKit]]></category><category><![CDATA[Code]]></category><category><![CDATA[iOS]]></category><category><![CDATA[Extensions]]></category><dc:creator><![CDATA[Beau Nouvelle]]></dc:creator><pubDate>Thu, 11 Apr 2019 03:48:47 GMT</pubDate><media:content url="https://getswifty.dev/content/images/2019/04/backlit-blogging-business-34153.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://getswifty.dev/content/images/2019/04/backlit-blogging-business-34153.jpg" alt="Adding Closures to Buttons in Swift"><p>One of the things I still find a little backward and unnatural to use in Swift is the Target-Action pattern.</p><p>You can avoid this for the most part if you&apos;re using interface builder and you have all of your actions hooked up with <code>IBOutlet</code>s.</p><p>Apple did eventually give us <code>#selector</code>. This added type safety and code completion, but that hardly feels like a <em>real</em> solution. You still have to use the <code>@objc</code> flag to expose the called methods to Objective-C, and the syntax is a little ugly. It certainly doesn&#x2019;t feel Swifty&#x2026;</p><p><em>Closures</em> <em>are</em> <em>Swifty. </em>So let&#x2019;s add some of those!</p><p>We&#x2019;ll start by setting up our wrapper class and begin filling out our extension with some boilerplate. This will help us get around the stored property restrictions we currently have with extensions in Swift.</p><!--kg-card-begin: markdown--><h3 id="uibarbuttonitem">UIBarButtonItem</h3>
<!--kg-card-end: markdown--><pre><code class="language-swift">extension UIBarButtonItem {
    
    /// Typealias for UIBarButtonItem closure.
    private typealias UIBarButtonItemTargetClosure = (UIBarButtonItem) -&gt; ()

    private class UIBarButtonItemClosureWrapper: NSObject {
        let closure: UIBarButtonItemTargetClosure
        init(_ closure: @escaping UIBarButtonItemTargetClosure) {
            self.closure = closure
        }
    }
    
    private struct AssociatedKeys {
        static var targetClosure = &quot;targetClosure&quot;
    }
    
    private var targetClosure: UIBarButtonItemTargetClosure? {
        get {
            guard let closureWrapper = objc_getAssociatedObject(self, &amp;AssociatedKeys.targetClosure) as? UIBarButtonItemClosureWrapper else { return nil }
            return closureWrapper.closure
        }
        set(newValue) {
            guard let newValue = newValue else { return }
            objc_setAssociatedObject(self, &amp;AssociatedKeys.targetClosure, UIBarButtonItemClosureWrapper(newValue), objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
}</code></pre><p><code>UIBarButtonItem</code> is a special case as it has an initialiser that accepts a target and action as parameters, whereas <code>UIButton</code> allows you to modify its target-action after initialisation. This is because <code>UIBarButtonItem</code> is a direct subclass of <code>UIBarButton</code>, which is a subclass of <code>NSObject</code>. Neither of which have target-action methods. Whereas <code>UIButton</code> inherits from <code>UIControl</code>, which is where it gets its target-action from.</p><p>So for <code>UIBarButtonItem</code>, what we&apos;re going to do is create a new convenience initialiser which will do some extra setup before calling the designated initialiser.</p><p>Add the following code to the bottom of the extension:</p><pre><code class="language-swift">convenience init(title: String?, style: UIBarButtonItem.Style, closure: @escaping UIBarButtonItemTargetClosure) {
    self.init(title: title, style: style, target: nil, action: nil)
    targetClosure = closure
    action = #selector(UIBarButtonItem.closureAction)
}

@objc func closureAction() {
    guard let targetClosure = targetClosure else { return }
    targetClosure(self)
}</code></pre><p>We start off by calling <code>self.init</code>, apply our <code>title</code> and <code>style</code>, but leave target-action empty. Afterwards we store a reference to the passed in closure into our <code>targetClosure</code> that we created earlier.</p><p>Then finally the action property on <code>UIBarButtonItem</code> is set to a selector, which will run the closure stored in <code>targetClosure</code> any time the action is triggered, such as tapping the button. </p><p>Under the hood the same operations are happening, so all we&apos;ve really done is add a little extra layer of abstraction. One huge benefit here is that you now have access to a central area to run some other reusable code such as logging button presses, or capturing analytics.</p><p>This is how you can now set up your <code>UIBarButtonItem</code>.</p><pre><code class="language-swift">// Old way of doing things.
let actionButton = UIBarButtonItem(title: &quot;Done&quot;, style: .done, target: self, action: #selector(someMethod()))

// New way of doing things.
let button = UIBarButtonItem(title: &quot;Done&quot;, style: .done) { _ in
    // Do stuff here.            
}</code></pre><p>I feel like that looks much better and far more useful. You can now call multiple functions within the closure. You get a reference to your button object, and also access to other code within the same scope.</p><p>Thats great but the title of this article mentions the plural &#x2014; <em>buttons</em>. So let&apos;s explore how we might add a closure to as many objects as we can with the least amount of repeated code.</p><!--kg-card-begin: markdown--><h3 id="uicontrol">UIControl</h3>
<!--kg-card-end: markdown--><p>As mentioned earlier, it&apos;s this class that <code>UIButton</code> inherits from. There&apos;s actually quite a few subclasses for <code>UIControl</code> including <code>UISegmentedControl</code>, <code>UISwitch</code>, &#xA0;<code>UISlider</code>, and it&apos;s also from this class that you should be creating your custom controls. Adding the closure extension at this point would cover all of its subclasses. </p><p>So let&apos;s do that!</p><pre><code class="language-swift">extension UIControl {
    
    /// Typealias for UIControl closure.
    public typealias UIControlTargetClosure = (UIControl) -&gt; ()
    
    private class UIControlClosureWrapper: NSObject {
        let closure: UIControlTargetClosure
        init(_ closure: @escaping UIControlTargetClosure) {
            self.closure = closure
        }
    }
    
    private struct AssociatedKeys {
        static var targetClosure = &quot;targetClosure&quot;
    }
    
    private var targetClosure: UIControlTargetClosure? {
        get {
            guard let closureWrapper = objc_getAssociatedObject(self, &amp;AssociatedKeys.targetClosure) as? UIControlClosureWrapper else { return nil }
            return closureWrapper.closure
        }
        set(newValue) {
            guard let newValue = newValue else { return }
            objc_setAssociatedObject(self, &amp;AssociatedKeys.targetClosure, UIControlClosureWrapper(newValue), objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    @objc func closureAction() {
        guard let targetClosure = targetClosure else { return }
        targetClosure(self)
    }
    
    public func addAction(for event: UIControl.Event, closure: @escaping UIControlTargetClosure) {
        targetClosure = closure
        addTarget(self, action: #selector(UIControl.closureAction), for: event)
    }
    
}</code></pre><p>This code is almost identical to what we created for <code>UIBarButtonItem</code>, with just a few names changed around. We also removed the convenience initialiser, and created a new <code>addAction</code> function that accepts a <code>UIControl.Event</code> type.</p><p> This is how you use it.</p><pre><code class="language-swift">let button = UIButton()
button.addAction(for: .touchUpInside) { (button) in
    // Run code
}

let slider = UISlider()
slider.addAction(for: .valueChanged) { (slider) in
    // Run code
}

let segmentedControl = UISegmentedControl()
segmentedControl.addAction(for: .valueChanged) { (segmentedControl) in
    // Run code
}</code></pre><p>I&apos;d love to replace the <code>UIControl</code> return type for the closure with a generic. So for <code>addAction</code> on <code>UIButton</code> we would have access to a <code>UIButton</code> in the closure, and not <code>UIControl</code>. You don&apos;t <em>need</em> this though. In fact, you <em>could</em> clean things up even further by removing the type from the closure altogether. In most cases you&apos;ll have access to the control anyway, in the above example, it&apos;s local. In most code bases, these controls will be properties on the class, and therefore accessible from anywhere. Instead, I&apos;ve gone with a similar approach to how I believe Apple would have done it. </p>]]></content:encoded></item></channel></rss>